0

Is there a way to copy a chart control to a new form? I have a Windows Form with a chart control on it, but the form is not allowed to be resizable. For that reason I have a button "Zoom" that opens the chart in a new form that is resizable. I have set a lot of chart properties in the "original" chart (axis color, axis intervalls etc.) and would like to just reuse this properties. I tried to call the constructor of the new form with the chart as parameter, but that didn't work.

public ZoomChartSeriesForm(Chart myChart)

My main problem is, that I allow zooming inside of the chart and that crashes, when I just copy the chart.

Here is the code of my "original chart" (example):

        System.Drawing.Color color = System.Drawing.Color.Red;
        //plot new doublelist
        var series = new Series
        {
            Name = "Series2",
            Color = color,
            ChartType = SeriesChartType.Line,
            ChartArea = "ChartArea1",
            IsXValueIndexed = true,
        };

        this.chart1.Series.Add(series);

        List<double> doubleList = new List<double>();
        doubleList.Add(1.0);
        doubleList.Add(5.0);
        doubleList.Add(3.0);
        doubleList.Add(1.0);
        doubleList.Add(4.0);

        series.Points.DataBindY(doubleList);

        var chartArea = chart1.ChartAreas["ChartArea1"];
        LabelStyle ls = new LabelStyle();
        ls.ForeColor = color;
        Axis a = chartArea.AxisY;
        a.TitleForeColor = color; //color of axis title
        a.MajorTickMark.LineColor = color; //color of ticks                  
        a.LabelStyle = ls; //color of tick labels

        chartArea.Visible = true;
        chartArea.AxisY.Title = "TEST";
        chartArea.RecalculateAxesScale();
        chartArea.AxisX.Minimum = 1;
        chartArea.AxisX.Maximum = doubleList.Count;

        // Set automatic scrolling 
        chartArea.CursorX.AutoScroll = true;
        chartArea.CursorY.AutoScroll = true;
        // Allow user to select area for zooming
        chartArea.CursorX.IsUserEnabled = true;
        chartArea.CursorX.IsUserSelectionEnabled = true;
        chartArea.CursorY.IsUserEnabled = true;
        chartArea.CursorY.IsUserSelectionEnabled = true;
        // Set automatic zooming
        chartArea.AxisX.ScaleView.Zoomable = true;
        chartArea.AxisY.ScaleView.Zoomable = true;
        chartArea.AxisX.ScrollBar.IsPositionedInside = true;
        chartArea.AxisY.ScrollBar.IsPositionedInside = true;
        //reset zoom
        chartArea.AxisX.ScaleView.ZoomReset();
        chartArea.AxisY.ScaleView.ZoomReset();

        chart1.Invalidate();
purbsel
  • 307
  • 8
  • 21

1 Answers1

1

Copy as in deep copying the object?

I ran into this exact problem recently myself. Unfortunately, MS Chart has no method to clone their chart object and their class is not marked as serializable so you can't use the method suggested here.

If you want to do this the right way, you'll have to introduce a third party control such as Copyable or handle the reflection yourself, but this won't be easy.

A really nice workaround I found is to use the built-in serialization inside MS Chart control. The idea is to serialize the chart using memorystream, create a new instance of the chart and deserialize the chart.

private Chart CloneChart(Chart chart)
{
    MemoryStream stream = new MemoryStream();
    Chart clonedChart = chart;
    clonedChart.Serializer.Save(stream);
    clonedChart = new Chart();
    clonedChart.Serializer.Load(stream);
    return clonedChart;
}

Not exactly an efficient solution, but if performance isn't your priority, this works like a charm.

Community
  • 1
  • 1
TtT23
  • 6,876
  • 34
  • 103
  • 174
  • I don't know what I'm doing wrong, but my chart does not get displayed. Chart, Series, ChartAreas are all set to visible or enabled and everything looks ok. `private void btnZoomChart_Click(object sender, EventArgs e) { ZoomChartSeriesForm frm = new ZoomChartSeriesForm(CloneChart(chart1)); frm.ShowDialog(this); } public ZoomChartSeriesForm(Chart myChart) { InitializeComponent(); this.chart1=myChart;}` – purbsel Jul 29 '13 at 10:53
  • @purbsel Are you calling Show() on your newly created chart? Also bring your chart to front using BringToFront() – TtT23 Jul 30 '13 at 02:59
  • I used Show(), BringToFront(), CreateObject(), and everything else I could think of. no displaying...Somehow `this.chart1 = CloneChart(myChart);` seems to be the problem. I now added an extra step where I loop over my series and chart areas in myChart and add them to chart1. This is working for me and everything is fine. I just don't understand why the first way is not working. – purbsel Jul 30 '13 at 07:15