Question

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();
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top