ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Viewport control update
Posted by Andrew on Feb-04-2020 08:21
Attachments:
I have successfully built a form with three separate chart viewers, each with its own viewport control.  I would like zoom actions to affect all three graphs, regardless of which viewport the zoom action was triggered in.

I have successfully updated all three graphs with zoom control from the first viewport, but only the viewport gets updated (showing the new zoom window).  The other two viewports do not update (but the chart viewers do).

In the attached screenshot, I've used the viewport control for the RMS graph at the top to zoom out of the data set.  All three graphs update, but the lower two viewports still show the highlighted section at the far right of the data set.

What triggers the update to the viewport?  I started with the viewportcontroldemo.cs file and merged items into my own project.
Screenshot (33).png

  Re: Viewport control update
Posted by Peter Kwan on Feb-04-2020 17:44
Hi Andrew,

Is it a .NET desktop application?

The viewport is updated when a ViewPortChanged event is triggered. There are two ways the ViewPortChanged event can be triggered:

(a) By certain user action, such as when using the mouse wheel on a chart to zoom in/out.

(b) By calling the WinChartViewer.updateViewPort method (or WPFChartViewer.updateViewPort for WPF).

The method (b) is commonly used when the viewport is changed by other controls. For example, in the "XY Zooming and Scrolling (Windows)" sample code, the viewport can be changed by a "Zoom Level" slider on the left side of the window.

https://www.advsofteng.com/doc/cdnet.htm#xyzoomscroll.htm

For your case, if the viewport of one chart is changed, in its ViewPortChanged event handler, you can use WinChartViewer.updateViewPort to update the other WinChartViewers.

Suppose you have 3 independent charts with independent viewports. There will be 3 ViewPortChanged event handlers for the 3 WinChartViewers, each updates its own chart. A typical ViewPortChanged event handler will be like:

private void winChartViewer1_ViewPortChanged(object sender, WinViewPortEventArgs e)
{
    // Update the chart if necessary
    if (e.NeedUpdateChart)
        drawChart(winChartViewer1);
}

To synchronize the 3 charts, insert code in all 3 ViewPortChanged event handlers to call updateViewPort for the other WinChartViewers.

private void winChartViewer1_ViewPortChanged(object sender, WinViewPortEventArgs e)
{
    // Update the chart if necessary
    if (e.NeedUpdateChart)
        drawChart(winChartViewer1);

    // Assume 3 WinChartViewers in total
    WinChartViewer self = sender as WinChartViewer;
    WinChartViewer[] allViewers = { winChartViewer1, winChartViewer2, winChartViewer3};
    foreach (WinChartViewer v in allViewers)
    {
         // update other WinChartViewers if necessary
         if ((v.ViewPortLeft != self.ViewPortLeft) || (v.ViewPortWidth != self.ViewPortWidth))
         {
             v.ViewPortLeft = self.ViewPortLeft;
             v.ViewPortWidth = self.ViewPortWidth;
             v.updateViewPort(e.NeedUpdateChart, e.NeedUpdateImageMap);
         }
    }
}

The above code checks if the other WinChartViewer needs to be updated before updating it. It is because every WinChartViewer being updated can update other WinChartViewers and this can cause infinite loop. So we need to check if the other WinChartViewer have not yet been updated before updating them.

Hope this can help.

Regards
Peter Kwan

  Re: Viewport control update
Posted by Andrew on Feb-05-2020 01:56
Peter,
Thank you for the very fast reply.  It is a .net desktop app.  My code was similar (sorry for not posting a code snippet) but instead of calling updateViewPort for each WinChartViewer, I was calling the _ViewPortChanged routine.

My original code for each _ViewPortChanged routine looked like this:

if (e.NeedUpdateChart)
  drawChart(mainRMS_Graph);

mainPeak_Graph.ViewPortLeft = mainRMS_Graph.ViewPortLeft;
mainPeak_Graph.ViewPortWidth = mainRMS_Graph.ViewPortWidth;
mainPeak_Graph_ViewPortChanged(sender, e);

mainTrueRMS_Graph.ViewPortLeft = mainRMS_Graph.ViewPortLeft;
mainTrueRMS_Graph.ViewPortWidth = mainRMS_Graph.ViewPortWidth;
mainTrueRMS_Graph_ViewPortChanged(sender, e);

This successfully updated the chart itself, but left the viewport unchanged.  Your suggestion did exactly what I wanted.

Thanks again.