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

Message ListMessage List     Post MessagePost Message

  How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Murugan on Jan-13-2015 14:00
Attachments:
Hi,

First I would like to thank you for your prompt support on my previous queries.

Now i have a situation.
For Eg.  I have to draw a graph in which i have to display graph data with Specific YAxis
range of 0 to 20 though the data Points may go beyond those set. But user should be able
to manually pan vertically & view those points which are out of PlotArea.

I have Shared the Sample i have tried. In that i am not able to see the data points out of
the PlotRegion through vertical panning. Vertical panning works only when ZoomIn.

I know i am missing something in the code but not able to figure it out. I would appreciate
if u guide me to get this done.

I am using C# DotNet Chart. Attached the sample code i use.

Pls Revert back for any clarification.
GraphVerticalPanSample.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ChartDirector;

namespace Graph
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
         // XY data points for the chart
        private double[] dataX;

        private void Form1_Load(object sender, EventArgs e)
        {
            // Load the data
            loadData();

            // Initialize the WinChartViewer
            initChartViewer(winChartViewer1);

            // Some Visual Studio versions do not expose the MouseWheel event in the Property window, so we
            // need to set up the event handler with our own code.
            winChartViewer1.MouseWheel += new MouseEventHandler(winChartViewer1_MouseWheel);

            // Trigger the ViewPortChanged event to draw the chart
            winChartViewer1.updateViewPort(true, true);
        }

        //
        // Load the data
        //
        private void loadData()
        {
            dataX = new double[] { 10, 15, 6, 14, 13, 25, 12, 10.5, 3, -2, 5, 23, 19, 2, 5, 9, 14 };

            this.winChartViewer1.ScrollDirection = ChartDirector.WinChartDirection.HorizontalVertical;
            this.winChartViewer1.ZoomDirection = ChartDirector.WinChartDirection.HorizontalVertical;
        }

        //
        // Initialize the WinChartViewer
        //
        private void initChartViewer(WinChartViewer viewer)
        {
            // Initially set the mouse usage to "Pointer" mode (Drag to Scroll mode)
            pointerPB.Checked = true;
        }

        //
        // The ViewPortChanged event handler. This event occurs if the user scrolls or zooms in
        // or out the chart by dragging or clicking on the chart. It can also be triggered by
        // calling WinChartViewer.updateViewPort.
        //
        private void winChartViewer1_ViewPortChanged(object sender, WinViewPortEventArgs e)
        {
            // Update the chart if necessary
            if (e.NeedUpdateChart)
                drawChart(winChartViewer1);

            // We need to update the track line too. If the mouse is moving on the chart (eg. if 
            // the user drags the mouse on the chart to scroll it), the track line will be updated
            // in the MouseMovePlotArea event. Otherwise, we need to update the track line here.
            if ((!winChartViewer1.IsInMouseMoveEvent) && winChartViewer1.IsMouseOnPlotArea)
            {
                crossHair((XYChart)winChartViewer1.Chart, winChartViewer1.PlotAreaMouseX, 
                    winChartViewer1.PlotAreaMouseY);
                winChartViewer1.updateDisplay();
            }
        }

        //
        // Draw the chart.
        //
        private void drawChart(WinChartViewer viewer)
        {
            // Create an XYChart object 500 x 480 pixels in size, with the same background color
            // as the container
            XYChart c = new XYChart(500, 480, Chart.CColor(BackColor));

            // Set the plotarea at (50, 40) and of size 400 x 400 pixels. Use light grey (c0c0c0)
            // horizontal and vertical grid lines. Set 4 quadrant coloring, where the colors of 
            // the quadrants alternate between lighter and deeper grey (dddddd/eeeeee). 
            c.setPlotArea(50, 40, 400, 400, -1, -1, -1, 0xc0c0c0, 0xc0c0c0
                ).set4QBgColor(0xdddddd, 0xeeeeee, 0xdddddd, 0xeeeeee, 0x000000);

            // Enable clipping mode to clip the part of the data that is outside the plot area.
            c.setClipping();

            // Add a legend box at (450, 40) (top right corner of the chart) with vertical layout
            // and 8 pts Arial Bold font. Set the background color to semi-transparent grey.
            LegendBox b = c.addLegend(450, 40, true, "Arial Bold", 8);
            b.setAlignment(Chart.TopRight);
            b.setBackground(0x40dddddd);

            // Add a titles to axes
            c.xAxis().setTitle("Data Index");
            c.yAxis().setTitle("Y-AXIS");

            // Set axes width to 2 pixels
            c.xAxis().setWidth(2);
            c.yAxis().setWidth(2);

            // The default ChartDirector settings has a denser y-axis grid spacing and less-dense
            // x-axis grid spacing. In this demo, we want the tick spacing to be symmetrical.
            // We use around 50 pixels between major ticks and 25 pixels between minor ticks.
            c.xAxis().setTickDensity(50, 10);
            //c.yAxis().setTickDensity(50, 10);

            LineLayer layer = c.addLineLayer2();
            layer.setLineWidth(2);
            layer.addDataSet(dataX, 0xff3333, "Datas");

            //
            // In this example, we have not explicitly configured the full x and y range. In this case, the
            // first time syncLinearAxisWithViewPort is called, ChartDirector will auto-scale the axis and
            // assume the resulting range is the full range. In subsequent calls, ChartDirector will set the
            // axis range based on the view port and the full range.
            //
            c.yAxis().setLinearScale(0, 20);
            viewer.syncLinearAxisWithViewPort("x", c.xAxis());
            viewer.syncLinearAxisWithViewPort("y", c.yAxis());

            // Set the chart image to the WinChartViewer
            viewer.Chart = c;
        }

        //
        // Pointer (Drag to Scroll) button event handler
        //
        private void pointerPB_CheckedChanged(object sender, EventArgs e)
        {
            if (((RadioButton)sender).Checked)
                winChartViewer1.MouseUsage = WinChartMouseUsage.ScrollOnDrag;
        }

        //
        // We want to use the mouse wheel for zoom in/out when the mouse is over the chart. To to do, we need
        // to set the WinChartViewer to be the "active control" when the mouse enters the chart.
        //

        // Variable to save the original active control
        private Control activeControlSave = null;

        //
        // Mouse Enter event handler
        //
        private void winChartViewer1_MouseEnter(object sender, System.EventArgs e)
        {
            // Save the original active control and set the WinChartViewer to be the active control, so that
            // the WinChartViewer can receive the mouse wheel event.
            activeControlSave = winChartViewer1.FindForm().ActiveControl;
            winChartViewer1.FindForm().ActiveControl = winChartViewer1;
        }

        //
        // Mouse Leave event handler
        //
        private void winChartViewer1_MouseLeave(object sender, System.EventArgs e)
        {
            // Restore the original active control.
            winChartViewer1.FindForm().ActiveControl = activeControlSave;
        }

        //
        // Mouse Wheel event handler
        //
        private void winChartViewer1_MouseWheel(object sender, MouseEventArgs e)
        {
            // We zoom in or out by 10% depending on the mouse wheel direction.
            double rx = e.Delta > 0 ? 0.9 : 1 / 0.9;
            double ry = rx;

            // We do not zoom in beyond the zoom in width or height limit.
            rx = Math.Max(rx, winChartViewer1.ZoomInWidthLimit / winChartViewer1.ViewPortWidth);
            ry = Math.Max(ry, winChartViewer1.ZoomInWidthLimit / winChartViewer1.ViewPortHeight);
            if ((rx == 1) && (ry == 1))
                return;

            XYChart c = (XYChart)winChartViewer1.Chart;

            //
            // Set the view port position and size so that it is zoom in/out around the mouse by the 
            // desired ratio.
            //

            double mouseOffset = (winChartViewer1.ChartMouseX - c.getPlotArea().getLeftX()) / 
                (double)c.getPlotArea().getWidth();
            winChartViewer1.ViewPortLeft += mouseOffset * (1 - rx) * winChartViewer1.ViewPortWidth;
            winChartViewer1.ViewPortWidth *= rx;

            double mouseOffsetY = (winChartViewer1.ChartMouseY - c.getPlotArea().getTopY()) / 
                (double)c.getPlotArea().getHeight();
            winChartViewer1.ViewPortTop += mouseOffsetY * (1 - ry) * winChartViewer1.ViewPortHeight;
            winChartViewer1.ViewPortHeight *= ry;

            // Trigger a view port changed event to update the chart
            winChartViewer1.updateViewPort(true, false);
        }
    }
}

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Murugan on Jan-13-2015 14:03
Just adding to the query.

I use 'c.yAxis().setLinearScale(0, 20);' because that's the range i have to show by default.
However the user shall pan vertically to see the data out of these range.

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Peter Kwan on Jan-14-2015 03:48
Hi Murugan,

To use zooming and scrolling, ChartDirector would need to know the "full range" of the
data, so it can know where are the limits of the scrolling or zooming.

In many applications, the "full data" are not passed to ChartDirector initially. For example,
for a financial chart, the "full data" may span 50 years. However, the first chart may just
be displaying the last 30 days of data, and most people are only interested in recent
data. It would be very inefficient to retrieve 50 years of data from the database to just
plot the last 30 days. So often, the code only passes the last 30 days of data to
ChartDirector. In this case, ChartDirector would not know the full range, so the code
needs to specify the full range by using the setFullRange API.

If the setFullRange API is not used, the syncLinearAxisWithViewPort will assume the axis
range of the first chart is the full range.

For your case, the first chart is configured to use 0 to 20 for the y-axis. So it is assumed
to be the full range. As a result, you can only zoom in, not out.

To achieve what you need, the code would need to be like the "Simple Zooming and
Scrolling" sample code, in which the setFullRange is used. For your case, in the
initChartViewer function, you can add:

viewer.setFullRange("y", 200, -200);

//The initial view port top is 20, and the bottom is 0
viewer.ViewPortTop = viewer.getViewPortAtValue("y", 20);
viewer.ViewPortHeight = viewer.getViewPortAtValue("y", 0) - viewer.ViewPortTop;

The setLinearScale is not needed, as the scale is configured by the view port.

Hope this can help.

Regards
Peter Kwan

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Murugan on Jan-19-2015 21:27
Attachments:
Hi Peter,

Thanks for guiding me through this.

I have tried your suggestion. But still Y-Axis range is not displayed properly as i expect.

Here what i did after ur suggestion.
1. Removed "setLinearScale()" from the code.
2. "setFullRange()" is set for Y-axis.
    I have set the "setFullRange("y", -2, 25)" after finding the minimum and maximum in
dataValues array.
3. ViewPortTop & ViewPortHeight is also set as per the Y-Axis range to be displayed. (i.e.
0 to 20)
    Top & Height is configured to show y-values only between 0 & 20. The values which are
outside of these range will be scrolled & view by user manually.

Attached the graph's screenshot to show what i am expecting and what i got after the
above changes.

Also attached the project for ur quick understanding on what i did.

This is one important feature in our project so I am currently trying different possibilities
to achieve the above.

Thank you.
Graph_ScreenShot.png
Graph.zip
Graph.zip

13.84 Kb

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Peter Kwan on Jan-20-2015 00:51
Hi Murugan,

Sorry for the mistake in my code. Because of the way the y-axis is used, in which the "Top"
is the maximum value (for the x-axis, the "Left" is the minimum value), so the forumula
should be modified to:

viewer.setFullRange("y", -2, 25);
viewer.ViewPortTop = 1 - viewer.getViewPortAtValue("y", 20);
viewer.ViewPortHeight = 1 - viewer.getViewPortAtValue("y", 0) - viewer.ViewPortTop;

Hope this can help.

Regards
Peter Kwan

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Murugan on Jan-20-2015 21:12
It works. Thank a lot Peter. :)

You saved my day.

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Murugan on Feb-05-2015 16:15
Hi Peter,

One quick question.

The above implementation which works awesome as intended after removing the line
"c.yAxis().setLinearScale(0, 20)" from the DrawChart method. So the YAxis is always
displayed in LinearScale.

But i wanted the above feature with LogScale. so where can i set the LogScale if not in
DrawChart method?

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Peter Kwan on Feb-06-2015 02:32
Hi Murugan,

You probably are aware that you can only take logarithm of positive numbers. It means the
log scale should be purely positive (that is, you cannot use a full range like -2 to 25 or 0 to
25, because the logarithm of -2 or 0 is mathematically undefined).

To use log scale, the steps are:

(a) Use syncLogAxisWithViewPort instead of syncLinearAxisWithViewPort. For example:

viewer.syncLogAxisWithViewPort("y", c.yAxis());

(b) During initialization, make sure the full range is positive. If you need to use
getViewPortAtValue, please make sure you set the third parameter to true to specify log
scale. For example:

viewer.setFullRange("y", 1, 30);
viewer.ViewPortTop = 1 - viewer.getViewPortAtValue("y", 20, true);
viewer.ViewPortHeight = 1 - viewer.getViewPortAtValue("y", 2, true) - viewer.ViewPortTop;

Hope this can help.

Regards
Peter Kwan

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Murugan on Feb-10-2015 16:07
Hi Peter,

I have a query on Tooltip on Chart, Legend & Axis.

I am using XYChart in C# Winform. I want to display Tooltip with extended information on
click of Hotspot, Axis (Both Xaxis & Yaxis) and on the legend.

Right now when i set the 'viewer.ImageMap =
c.getLegend().getHTMLImageMap("clickable", "", 'SomeData")' then i get tooltip on Legend,
but the ClickHotSpot is not getting triggerd.

How to display Tooltips on click or  OnMouseOver of axis, chart & Legend?

Any suggestion welcome.

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Murugan on Feb-10-2015 23:29
Attachments:
Just adding to the above query.

I have a multiple classes (eg. below) with Label, Help and Data series which i plot as
linelayers.

class lineSeries1
{
string Label = "Finance data";
String Help = "Contains the data from source123"
string Unit = "$"
double dataseriesY = {.....};
double dataseriesY = {.....};
}

I want to display the Label and Help on 'OnMouseOver' or 'Click' on the DataPoints and the
legend too as a tooltip like below. I dont want to display the datapoint values in tooltip.



Similarly, Axis also have help & other extended information which needs to be displayed
on demand.

Pls provide me some information on how to get this done. I am using C# Winform.
Tooltip2.png

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Peter Kwan on Feb-11-2015 00:57
Hi Murugan,

I have just tried using the "NetWinCharts" sample Visual Studio solution that comes with
ChartDirector. In the "stackbar.cs" sample code, the original code for the image map is:

viewer.ImageMap = c.getHTMLImageMap("clickable", "",
                "title='{dataSetName} on {xLabel}: {value} MBytes/hour'");

I modified it to:

viewer.ImageMap = c.getHTMLImageMap("clickable", "",
                "title='{dataSetName} on {xLabel}: {value} MBytes/hour'")
                + c.getLegend().getHTMLImageMap("clickable", "", "title='abc'");

Then I run the sample CSharpCharts project, and it works correctly. All hot spots (including
the ones on the legend box) have tooltips. When I clicked on any hot spot (including those
on the legend box), a pop up dialog box will appear that displays the information about the
hot spot.

May be you can try to modify the sample code as above to verify if the hot spots on the
legend box are clickable or not.

If the above still does not solve the problem, is it possible to project a simple sample project
(may be a project containing just one form with one chart) that can help me to reproduce
the problem?

Regards
Peter Kwan

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Murugan on Feb-11-2015 14:51
Hi Peter,

Great. That works as expected. :)

By bad that I did not see that the 'viewer.ImageMap' is a string in the first place. So now i
am able to add multiple tooltip for Plot, Legend & Axis.

But the tooltip occurs on mouseover, is it possible to show the tooltip only on click event?

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Murugan on Feb-11-2015 14:58
Hi Peter,

Great. That works as expected. :)

By bad that I did not see that the 'viewer.ImageMap' is a string in the first place. So now i
am able to add multiple tooltip for Plot, Legend & Axis.

But the tooltip occurs on mouseover, is it possible to show the tooltip only on click event?

  Re: How to Pan & View the Data Points in Graph which outside the PlotArea
Posted by Peter Kwan on Feb-12-2015 00:26
Hi Murugan,

The sample code products both a tooltip on mouseover, and a pop up dialog onclick. You
can remove the tooltip on mouseover by removing the title='xxx' code. In this way, there is
only the pop up dialog onclick. You can modify the code in the ClickHotSpot event handler
so that instead of popping up a dialog, you can display a textbox on the chart with the text
you want to show. In this way, you can have "show tooltip on click".

Hope this can help.

Regards
Peter Kwan