Joel Anderson
Joel Anderson

Reputation: 535

Set Position of Point Label in System.Windows.Forms.DataVisualization.Charting

Using the System.Windows.Forms.DataVisualization.Charting library, the positioning of line chart point labels is pretty bad.

By default the labels sometimes are positioned on the line rather than above or below.

label unreadable

If the SmartLabelStyle is set on the series

series.SmartLabelStyle = new SmartLabelStyle()
{
    MovingDirection = LabelAlignmentStyles.Top | LabelAlignmentStyles.Bottom,
};

The labels are no longer moved horizontally, but the higher point's label can be placed below while the smaller point's label is placed above!

labels are layer confusingly

Is there a way to explicitly place a point label?

Upvotes: 1

Views: 2379

Answers (1)

Joel Anderson
Joel Anderson

Reputation: 535

This can be accomplished via the PostPaint event on the chart. Some documentation and tutorial here: https://msdn.microsoft.com/en-us/library/dd456612.aspx

A limited solution that worked within the constraints of my chart, that might be of some help for anyone who comes across this question.

chart.PostPaint += (sender, args) =>
{
    for (var j = 0; j < 2; j++)
    {
        for (var i = 0; i < args.Chart.Series[j].Points.Count; i++)
        {
            var point = args.Chart.Series[j].Points[i];
            var altPoint = args.Chart.Series[j == 0 ? 1 : 0].Points[i];
            var above = point.YValues[0] > altPoint.YValues[0] || (point.YValues[0] == altPoint.YValues[0] && j == 0);

            var pos = PointF.Empty;
            pos.X =
                (float)
                args.ChartGraphics.GetPositionFromAxis("ChartArea1", AxisName.X,
                    point.XValue);
            pos.Y =
                (float)
                args.ChartGraphics.GetPositionFromAxis("ChartArea1", AxisName.Y,
                    point.YValues[0]);

            pos = args.ChartGraphics.GetAbsolutePoint(pos);
            pos.Y += (above ? - 20 : 10);
            pos.X += -10;
            args.ChartGraphics.Graphics.DrawString($"{values[j][i]}%",
                new Font(FontFamily.GenericSansSerif, 10),
                new SolidBrush(_colorPallette[j]), pos);
        }
    }
};

enter image description here

Upvotes: 1

Related Questions