Let column charts overlap in Chart Control

前端 未结 2 1577
遥遥无期
遥遥无期 2021-01-21 15:00

I have following issue: I need to show multiple columns in a chart control (about seven series in one chart area). Now when I have a chart of type \"Column\" all seven columns g

相关标签:
2条回答
  • 2021-01-21 15:11

    Column Series has a CustomProperties named DrawSideBySide, set it to False will result columns drawing overlap.

    series1.CustomProperties = "DrawSideBySide=False";
    

    It can also be set in IDE, by going to Properties window, Series Collection Editor, then find CustomProperties, DrawSideBySide.

    0 讨论(0)
  • 2021-01-21 15:26

    There is no built-in way to do that.

    • One workaround is to turn on 3-d, but that will completely change the look of the chart..

    • The other is to owner-draw the chart.

    This is not exactly easy for column and bar types, since the sizeof the columns is not exposed.

    Also note that overlapping columns do get somewhat harder to read, esp. when you also have Labels.

    Here is an example of a owner-drawing column chart. It has several simplifications:

    All Series have the same number of points and are aligned, all y-values are positive and there are no other adornments. They may all be overcome, but probably with some extra efforts..

    private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
    {
        if (!checkBox2.Checked) return;
    
        int sMax = chart1.Series.Count;
        ChartArea ca = chart1.ChartAreas[0];
        Axis ax = ca.AxisX;
        Axis ay = ca.AxisY;
        float py0 = (float)ay.ValueToPixelPosition(ay.Minimum);
        Rectangle ipr = Rectangle.Round(InnerPlotPositionClientRectangle(chart1, ca));
        int pMax = chart1.Series[0].Points.Count;
        float shift = (overlap * sMax) / 2f;
        float deltaX = 1f * ipr.Width / (pMax+1);
        float colWidth = 1f * deltaX / sMax;
    
        for (int j = 0; j < chart1.Series.Count; j++)
            for (int i = 0; i < chart1.Series[j].Points.Count; i++)
            {
                DataPoint dp = chart1.Series[j].Points[i];
                float px = (float)ax.ValueToPixelPosition(dp.XValue);
                float py = (float)ay.ValueToPixelPosition(dp.YValues[0]);
                using (SolidBrush brush = new SolidBrush(chart1.Series[j].Color))
                    e.ChartGraphics.Graphics.FillRectangle(brush, 
                        px + j * colWidth - deltaX / 2 - overlap * j + shift,   py,
                        colWidth, py0 -  py );
            }
    }
    

    It makes use of a function InnerPlotPositionClientRectangle which you can find here

    Here is the result:

    Note that to access the Series Colors you need to apply them to the Chart:

      chart1.ApplyPaletteColors();
    

    The Column width is set like this:

    private void numericUpDown1_ValueChanged(object sender, EventArgs e)
    {
        for (int j = 0; j < chart1.Series.Count; j++)
            chart1.Series[j]["PointWidth"] = numericUpDown1.Value.ToString();
    }
    

    At "0" the columns disappear.

    0 讨论(0)
提交回复
热议问题