Nevron Forum

Chart over virtual data set

https://www.nevron.com/Forum/Topic4776.aspx

By Plamen Dimitrov - Thursday, January 27, 2011

Guys,

Do you have any sample that demos the chart over a virtual data set?

What I need is something similar to Google Finance where the chart dynamically requests data points while the user's scrolling?

Thanks in advance,

Plamen

By Nevron Support - Thursday, January 27, 2011

Hi Plamen,
Yes, the following code snippet shows how to create a simple line chart that is populated with data according to the current zoom range:

using System;

using System.Windows.Forms;

using Nevron.Chart;

using Nevron.Chart.WinForm;

using Nevron.GraphicsCore;

 

namespace WindowsFormsApplication22

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        double[] Values;

        double[] XValues;

        NLineSeries Line;

        NCartesianChart Chart;

 

        private void Form1_Load(object sender, EventArgs e)

        {

            Values = new double[100000];

                  XValues = new double[100000];

 

                  Random rand = new Random();

                  for (int i = 0; i < Values.Length; i++)

                  {

                        Values[i] = 500 + 500 * Math.Sin(i / 10000.0);

                        XValues[i] = i;

                  }

 

                  NChartControl1.Document.RootPanel.ChildPanels.Clear();

 

                  // create a simple header

                  NLabel header = new NLabel("Some Header Text");

                  header.Margins = new NMarginsL(10, 10, 10, 10);

                  header.Dock = DockStyle.Top;

                  NChartControl1.Panels.Add(header);

 

                  Chart = new NCartesianChart();

                  NRangeSelection rs = new NRangeSelection();

                  rs.VerticalValueSnapper = new NAxisRulerMinMaxSnapper();

                  Chart.RangeSelections.Add(rs);

                  NChartControl1.Panels.Add(Chart);

 

                  // associate chart with the legend

                  Chart.Dock = DockStyle.Fill;

                  Chart.Margins = new NMarginsL(10, 0, 10, 10);

                  Chart.BoundsMode = BoundsMode.Stretch;

 

                  Line = new NLineSeries();

                  Line.DataLabelStyle.Visible = false;

                  Line.SamplingMode = SeriesSamplingMode.Enabled;

                  Line.UseXValues = true;

                  Chart.Series.Add(Line);

 

                  NOrdinalScaleConfigurator scale = Chart.Axis(StandardAxis.PrimaryX).ScaleConfigurator as NOrdinalScaleConfigurator;

                  scale.RoundToTickMax = false;

                  scale.RoundToTickMin = false;

                  Chart.Axis(StandardAxis.PrimaryX).ScrollBar.Visible = true;

                  Chart.Axis(StandardAxis.PrimaryX).View = new NRangeAxisView(new NRange1DD(0, Values.Length), true, true);

                  Chart.Axis(StandardAxis.PrimaryY).View = new NRangeAxisView(new NRange1DD(0, 1000), true, true);

                  Chart.PaintCallback = new NCustomPaintCallback(this);

 

                  NChartControl1.Controller.Selection.Clear();

                  NChartControl1.Controller.Selection.SelectedObjects.Add(Chart);

                 

                  NChartControl1.Controller.Tools.Add(new NAxisScrollTool());

                  NDataZoomTool dzt = new NDataZoomTool();

 

                  NChartControl1.Controller.Tools.Add(dzt);

            }

 

            class NCustomPaintCallback : NPaintCallback

            {

                  Form1 Form;

 

                  public NCustomPaintCallback(Form1 form)

                  {

                        Form = form;

                  }

                  public override void OnBeforePaint(NPanel panel, NPanelPaintEventArgs eventArgs)

                  {

                        NRange1DD range = Form.Chart.Axis(StandardAxis.PrimaryX).Scale.RulerRange;

 

                        int count = Form.Line.XValues.Count;

 

                        if (count > 0)

                        {

                              if (((double)Form.Line.XValues[0] == (int)range.Begin &&

                                    (double)Form.Line.XValues[count - 1] == (int)range.End))

                              {

                                    return;

                              }                       }

 

                        Form.Line.Values.Clear();

                        Form.Line.XValues.Clear();

 

                        int length = (int)Math.Round(range.End - range.Begin);

                        double[] yValues = new double[length];

                        double[] xValues = new double[length];

 

                        Array.Copy(Form.Values, (int)range.Begin, yValues, 0, length);

                        Array.Copy(Form.XValues, (int)range.Begin, xValues, 0, length);

 

                        Form.Line.Values.AddRange(yValues);

                        Form.Line.XValues.AddRange(xValues);

 

                        Form.NChartControl1.Document.Calculate();

                        Form.NChartControl1.Refresh();

                  }

            }

      }

}

The idea is simple:

1. You have to fix the view ranges on both the x and y axes. In the code above this is done by:
Chart.Axis(StandardAxis.PrimaryX).View = new NRangeAxisView(new NRange1DD(0, Values.Length), true, true);
Chart.Axis(StandardAxis.PrimaryY).View = new NRangeAxisView(new NRange1DD(0, 1000), true, true);

2. Then on before paint the code checks the current zoom range of the x axis and populates the data for that range in the line values and xvalues arrays

Hope this helps.

By Plamen Dimitrov - Thursday, January 27, 2011

Exactly what I needed - thanks guys!