0

The results I want are one main chart and several sub charts which are synchronized with the main chart. (Sub charts must share the same x-axis with the main chart.)

At first, I tried it using multiple chartAreas. I can sync sub chartAreas with the main chartArea. (Using this: How to align two (or more) charts in size, scroll and grid) This one is what I want exactly. But I can't only vertical scroll the sub-chartAreas. If I scroll, all the charts are scrolled. I want to vertical scroll only sub-chartAreas. (to show the main chartArea at top anytime even when the scroll bar is down)

So, I reverse a decision to use multiple charts (not chart Areas). I can place them into TableLayoutPanel. One chart per row. Then, I cannot sync their x-axes...

Is there any way to sync an x-axis with multiple charts? Or to scroll only sub-chartAreas using multiple chartAreas?

By 'scroll' I mean Vertical scroll. See here:

enter image description here

Lee
  • 11
  • 7
  • Hm, you want them to be aligned yet scroll them independently? Doesn't that simply mean you need to keep the scale of the x-axis equal? – TaW Sep 18 '17 at 07:56
  • sorry for ambiguous expression. I mean, I want all to be aligned. and I want to scroll the others (at once) except the first chart area. I'm not sure what is 'simply keep the scale' but, what i want is the answer's gif in the above link. – Lee Sep 18 '17 at 08:02
  • Well if you want one (main) chartarea to stay put, simply don't write code for it in the `AxisViewChanged` event! – TaW Sep 18 '17 at 08:05
  • By Scale I mean basically the amount of data shown on an axis. You can control it by setting minimum&Maximum. After zooming it is the .ScaleView.ViewMinimum&Maximum. – TaW Sep 18 '17 at 08:10
  • Oops you thought the 'scroll' is horizontal, right? I didn't specify. My apologizes... The scroll is **vertical** scroll. I updated my question with snapshot. – Lee Sep 18 '17 at 08:50
  • Ah, if yu mean you want to scroll among the secondary chartareas but freeze the 1st one, well that's not really possible. You would have to work around.. Eiher by putting the main data in a separate chart or, maybe you simulating the scrolling with a scrollbar control and moving the 2ndary ca's up and down inclluding under the main one; tricky! – TaW Sep 18 '17 at 08:55
  • Yep so I changed sub-chartAreas to each charts. Then, as I write, the several charts can't be synchronized.. – Lee Sep 18 '17 at 09:03
  • Well, if all 'sub-Charts' are in separate chartareas in chart2 they will work as before. You need to make sure all have the same axis scale. Note that the linked solution only synch's two chartareas, not many! – TaW Sep 18 '17 at 09:57
  • Ok, Thanks a lot!! I will try it. – Lee Sep 18 '17 at 11:43
  • Btw, I just tried the workaround with a VerticalScrollbar and adjusting the chartArea.Positions of all but the main CA. It work rather well; complexity depends on how uniform the CSa are; if they are all the same size it is just 5-10 lines.. – TaW Sep 18 '17 at 11:48
  • WOW, the sub-chartAreas are all same size! Only main is bigger than others. – Lee Sep 18 '17 at 12:07

1 Answers1

3

From the image and the comments I gather that you actually want to scroll down a chart with several ChartArea but keep one fixed at the top.

((If that is so you should correct the question title!))

By default a Chart can only scroll the data within a zoomed ChartArea, not several ChartAreas within the Chart.

Here is an example of faking both ChartArea scrolling and freeezing the top ChartArea.

Here are the necessary steps:

  • We need a VerticalScrollbar control and anchor it to the right of the Chart.

  • We need to set its Minumum and Maximum fields to suitable values; I left the minimum at 0 and calculate the max with a few params..

  • Then we can code its Scroll event..:


private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
{
    float h = (100 - yOffTop - yOffBottom) / visibleCount;
    ChartArea main = chart1.ChartAreas[0];

    for (int i = 1; i < chart1.ChartAreas.Count; i++)
    {
        ChartArea ca = chart1.ChartAreas[i];
        ca.Position = new ElementPosition(0, h * i - vScrollBar1.Value + mainExtra, 80, h);
        ca.Visible = ca.Position.Y  >= main.Position.Bottom ;
    }
}

visibleCount controls how many ChartAreas are visible. In this example I have one for the year, fixed at the top and 12 more for the months..:

enter image description here

For this to work you need to set up the chart so that the chartareas are intialized in a suitable way.

I used this piece of code, do use your own code for stuff like right space (I left 20% for the legend) etc..:

    int visibleCount = 5;
    float yOffTop = 0;     // no extra top space for a chart title
    float yOffBottom = 0;  // no extra  bottom space either
    float mainExtra = 6;   // a few extra% for the main CA's axis labels

    private void Init_button_Click(object sender, EventArgs e)
    {
        chart1.Series.Clear();
        chart1.ChartAreas.Clear();
        chart1.BackColor = Color.Snow;
        float h = (100 - yOffTop - yOffBottom) / visibleCount;
        for (int i = 0; i < 13; i++)
        {
            float yOff = i != 0 ? mainExtra : 0;
            float yExtra = i == 0 ? mainExtra : 0;
            ChartArea ca = chart1.ChartAreas.Add("ca" + i);
            ca.Position = new ElementPosition(0, h * i + yOff , 80, h + yExtra);
            ca.BackColor = Color.FromArgb(i * 20, 255 - i * 3, 255);
            ca.AxisX.IntervalOffset = 1;

            Series s = chart1.Series.Add("s" + i);
            s.ChartArea = ca.Name;
            for (int j = 1; j < 30; j++)
            {
                s.Points.AddXY(j, rnd.Next(100) - rnd.Next(20));
            }
            chart1.ChartAreas[0].BackColor = Color.Silver;
            ca.AxisY.Title = i == 0 ? "Year" :
                                       DateTimeFormatInfo.CurrentInfo.GetMonthName(i);
            ca.AxisX.Enabled = (i == 0) ? AxisEnabled.True :  AxisEnabled.False;
        }
        vScrollBar1.Minimum = 0;// (int)( h);
        vScrollBar1.Maximum = (int)((chart1.ChartAreas.Count - visibleCount + 0.5f) * h
                                   + mainExtra );
    }

I draw extra rectangles around each CA, just for testing; do ignore them!

Note: Working with those percentages is always a little tricky and may take some tweaking!

TaW
  • 53,122
  • 8
  • 69
  • 111