Author |
Topic  |
|
mswlogo
10 Posts |
Posted - 16 Feb 2006 : 12:15:12
|
Unfortunately the Chart does not support what I call dynamic compression (only static). That is, you compress your data once and pass it to the chart, if you then zoom the data you just get a courser view of the data rather than finer detail. A good analogy of what I'd like it to do is how fonts work. As you zoom into a font you get finer and finer detail. That's what many chart applications need to do as well. As they zoom in you want more detail.
My data is 100k to 200k points updated a couple times a second.
I have implemented this dynamic compression on many charts including the old C++ charts from quinn-curtis.
The solution is to basically not use the built zooming and do it yourself and as the user zooms in you pass the chart a new set of data (basically you compress or decompress the data yourself as the user zooms out and in respectively). The number of points is always fixed in the chart because that is a function of screen resolution and chart size.
I have it working rather crudely below, but I also have either a bug or there is a bug in the chart. I suspect it is my code and I'm doing something illegal with the chart. I’m not clear on the rules of redefining the data and axis range.
It works ok for the first zoom in, but for the second zoom in when I translate the mouse coordinates to data coordinates the two mouse coordinates (which are different) translate to the same data coordinate and it all blows up.
I've tried various objects CalcNearestPoint (Plot, DataSet etc.) with different algorithms (FNG_NORMDIST, etc.); they all have the same problem.
After I change the data I apply an AutoScale to the transform and update the view (again this all works fine on the first zoom). But trying to translate mouse to data coordinates after that are busted.
I also know I'm not translating from mouse to data coordinate correctly. I seem to be getting an index of some sort and I convert that myself to data coordinate. How can I translate to a AXIS data coordinate. The data may have gaps and I don't want to translate to a nearest data point. I want to translate to the X and Y axis coordinate. But the Axis seems to have everything in Physical Coordinates and no CalcNearestPoint function (I assume that it depends on the DataSet or Plots transform).
Sorry for the rather sloppy code I'm just experimenting.
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms;
using System.Drawing.Drawing2D; using com.quinncurtis.chart2dnet;
namespace UserChartExample1 { public class UserChartControl1 : com.quinncurtis.chart2dnet.ChartView { private System.ComponentModel.IContainer components = null; public SimpleDataset Dataset1; public SimpleDataset Dataset2; ChartView chartVu; Font theFont; CartesianCoordinates pTransform1; public const int RESOLUTION = 2000; const int MINX = 0; const int MINY = 0; const int MAXX = 100000; const int MAXY = 3; int xmin = MINX; int xmax = MAXX; int ymin = MINY; int ymax = MAXY; int binsize = 0; SimpleBarPlot thePlot1; SimpleBarPlot thePlot2;
public UserChartControl1() { // This call is required by the Windows Form Designer. InitializeComponent();
// TODO: Add any initialization after the InitializeComponent call // Better to do this in main form //InitializeChart(); }
public void UpdateSpectrumChart(double[][] newY) { int binsize = (int)((double)(xmax - xmin) / (double)RESOLUTION);
Console.WriteLine("BinSize = " + binsize + "," + "Xmin = " + xmin + "," + "Xmax = " + xmax + "," + "Ymin = " + ymin + "," + "Ymax = " + ymax);
for (int i = 0; i < Dataset1.GetNumberDatapoints(); i++) { // Use accessor methods Point2D p = Dataset1[i]; // Get xy values at index i p.Y = 0.0; for (int j = 0; j < binsize; j++) { p.Y += newY[0][xmin + i * binsize + j]; } p.Y /= binsize; p.X = xmin + i * binsize; Dataset1[i] = p; // Set xy values at index i }
for (int i = 0; i < Dataset2.GetNumberDatapoints(); i++) { // Use accessor methods Point2D p = Dataset2[i]; // Get xy values at index i p.Y = 0.0; for (int j = 0; j < binsize; j++) { p.Y += newY[1][xmin + i * binsize + j]; } p.Y /= binsize; p.X = xmin + i * binsize; Dataset2[i] = p; // Set xy values at index i }
pTransform1.AutoScale(Dataset1, ChartObj.AUTOAXES_FAR, ChartObj.AUTOAXES_FAR); chartVu.UpdateDraw(); }
public void InitializeData() { double[] x1; double[] y1; double[] x2; double[] y2;
x1 = new double[RESOLUTION]; y1 = new double[RESOLUTION];
xmin = MINX; xmax = MAXX; ymin = MINY; ymax = MAXY;
binsize = (int)((xmax - xmin) / RESOLUTION);
for (int i = 0; i < RESOLUTION; i++) { x1[i] = (double)i * binsize; y1[i] = (double)i; }
Dataset1 = new SimpleDataset("Channel 1", x1, y1);
x2 = new double[RESOLUTION]; y2 = new double[RESOLUTION];
for (int i = 0; i < RESOLUTION; i++) { x2[i] = (double)i * binsize; y2[i] = (double)i; }
Dataset2 = new SimpleDataset("Channel 2", x2, y2); }
private class ZoomWithStack : ChartZoom { UserChartControl1 mComponent; Point mDownLocation;
public ZoomWithStack(ChartView component, CartesianCoordinates transform, bool brescale, SimpleBarPlot plot, SimpleDataset dataset) /*: base(component, transform, brescale)*/ { mComponent = (UserChartControl1)component; }
public override void OnMouseUp(MouseEventArgs mouseevent) { if ((mouseevent.Button & MouseButtons.Left) != 0) { NearestPointData nearestpoint1 = new NearestPointData(); NearestPointData nearestpoint2 = new NearestPointData();
mComponent.Dataset1.CalcNearestPoint(mComponent.pTransform1, new Point2D((double)mDownLocation.X, (double)mDownLocation.Y), ChartObj.FNP_NORMDIST, nearestpoint1); mComponent.Dataset1.CalcNearestPoint(mComponent.pTransform1, new Point2D((double)mouseevent.X, (double)mouseevent.Y), ChartObj.FNP_NORMDIST, nearestpoint2);
mComponent.xmin = (int) (nearestpoint1.GetNearestPoint().X * mComponent.binsize * 2.0); mComponent.xmax = (int) (nearestpoint2.GetNearestPoint().X * mComponent.binsize * 2.0); mComponent.binsize = (int)((mComponent.xmax - mComponent.xmin) / RESOLUTION); }
if ((mouseevent.Button & MouseButtons.Right) != 0) { mComponent.xmin = UserChartControl1.MINX; mComponent.xmax = UserChartControl1.MAXX; mComponent.binsize = (int)((mComponent.xmax - mComponent.xmin) / RESOLUTION); }
Console.WriteLine("#2 BinSize = " + mComponent.binsize + "," + "Xmin = " + mComponent.xmin + "," + "Xmax = " + mComponent.xmax + "," + "Ymin = " + mComponent.ymin + "," + "Ymax = " + mComponent.ymax); }
public override void OnMouseDown(MouseEventArgs mouseevent) { if ((mouseevent.Button & MouseButtons.Right) != 0) { // this.PopZoomStack(); } else { mDownLocation = mouseevent.Location; // base.OnMouseDown(mouseevent); } } }
public void InitializeChart() { chartVu = this;
theFont = new Font("Microsoft Sans Serif", 10, FontStyle.Bold);
pTransform1 = new CartesianCoordinates(); pTransform1.AutoScale(Dataset1, ChartObj.AUTOAXES_FAR, ChartObj.AUTOAXES_FAR); pTransform1.SetScaleStartY(MINY); pTransform1.SetScaleStopY(MAXY); pTransform1.SetScaleStartX(MINX); pTransform1.SetScaleStopX(MAXX);
pTransform1.SetGraphBorderDiagonal(0.05, 0.05, 0.95, 0.95); Background graphbackground = new Background(pTransform1, ChartObj.GRAPH_BACKGROUND, Color.LightGray); chartVu.AddChartObject(graphbackground); Background plotbackground = new Background(pTransform1, ChartObj.PLOT_BACKGROUND, Color.Black); chartVu.AddChartObject(plotbackground);
LinearAxis xAxis = new LinearAxis(pTransform1, ChartObj.X_AXIS); xAxis.SetColor(Color.Black); chartVu.AddChartObject(xAxis);
LinearAxis yAxis = new LinearAxis(pTransform1, ChartObj.Y_AXIS); yAxis.SetColor(Color.Black); chartVu.AddChartObject(yAxis);
NumericAxisLabels xAxisLab = new NumericAxisLabels(xAxis); xAxisLab.SetColor(Color.Black); chartVu.AddChartObject(xAxisLab);
NumericAxisLabels yAxisLab = new NumericAxisLabels(yAxis); yAxisLab.SetColor(Color.Black); chartVu.AddChartObject(yAxisLab);
Grid ygrid = new Grid(xAxis, yAxis, ChartObj.Y_AXIS, ChartObj.GRID_MAJOR); ygrid.SetColor(Color.White); ygrid.SetLineWidth(1); chartVu.AddChartObject(ygrid);
ChartAttribute attrib1 = new ChartAttribute(Color.Yellow, 0, DashStyle.Solid, Color.Yellow); attrib1.SetFillFlag(false); thePlot1 = new SimpleBarPlot(pTransform1, Dataset1, 0.001, 0.0, attrib1, ChartObj.JUSTIFY_MIN); chartVu.AddChartObject(thePlot1);
ChartAttribute attrib2 = new ChartAttribute(Color.Red, 0, DashStyle.Solid, Color.Red); attrib1.SetFillFlag(false); thePlot2 = new SimpleBarPlot(pTransform1, Dataset2, 0.001, 0.0, attrib2, ChartObj.JUSTIFY_MIN); chartVu.AddChartObject(thePlot2);
Font theTitleFont = new Font("Microsoft Sans Serif", 10, FontStyle.Bold); ChartTitle mainTitle = new ChartTitle(pTransform1, theTitleFont, "Spectrum for Nebula XD31ACY-9SDD8"); mainTitle.SetTitleType(ChartObj.CHART_HEADER); mainTitle.SetTitlePosition(ChartObj.CENTER_GRAPH); mainTitle.SetColor(Color.Black); chartVu.AddChartObject(mainTitle);
Font theFooterFont = new Font("Microsoft Sans Serif", 10, FontStyle.Bold); ChartTitle footer = new ChartTitle(pTransform1, theFooterFont, "spectrum analyzer."); footer.SetTitleType(ChartObj.CHART_FOOTER); footer.SetTitlePosition(ChartObj.CENTER_GRAPH); footer.SetTitleOffset(8); footer.SetColor(Color.Black); chartVu.AddChartObject(footer);
ZoomWithStack zoomObj = new ZoomWithStack(chartVu, pTransform1, true, thePlot1, Dataset1); //zoomObj.SetButtonMask(MouseButtons.Left); //zoomObj.SetZoomYEnable(false); //zoomObj.SetZoomXEnable(false); //zoomObj.SetZoomXRoundMode(ChartObj.AUTOAXES_FAR); //zoomObj.SetZoomYRoundMode(ChartObj.AUTOAXES_FAR); //zoomObj.SetEnable(true); //zoomObj.SetZoomStackEnable(true); chartVu.SetCurrentMouseListener(zoomObj); }
/// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose(bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); }
#region Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.SuspendLayout(); // // UserChartControl1 // this.Name = "UserChartControl1"; this.PreferredSize = new System.Drawing.Size(936, 701); this.Size = new System.Drawing.Size(936, 701); this.ResumeLayout(false);
} #endregion } }
|
|
quinncurtis
1164 Posts |
Posted - 16 Feb 2006 : 13:40:56
|
That is too much code for us to tell you anything by inspection. We understand what you want and what you are doing is 1000x more complicated than what we would do. You can get the source to the QCChart2D library and just add a couple of lines to the data plotting routines that you plan to use. The following code shows the modification you would make to the SimpleLinePlot class:
public void DrawLinePlot(Graphics g2, GraphicsPath path)
{
int i;
int nnumpnts = 1;
DisplayDataset = theDataset.GetFastClipDataset("", chartObjScale, fastClipMode, ref fastClipOffset) ;
// Start of added code
// Compress dataset if the number of points in the truncated (clipped) dataset exceeds 5000
//
if (DisplayDataset.NumberDatapoints > 5000)
{
int interval = theDataset.NumberDatapoints / 2000;
DisplayDataset = DisplayDataset.CompressSimpleDataset(DATACOMPRESS_NONE, DATACOMPRESS_MINMAX,
interval, 0, DisplayDataset.NumberDatapoints-1,"Compressed");
}
// End of added code
You will probably need to adjust the CompressSimpleDataset for your unique cirumstances.
We know of no way of implementing a similar feature without having the source code to the underlying QCChart2D library. |
 |
|
mswlogo
10 Posts |
Posted - 16 Feb 2006 : 18:18:31
|
I don't doubt using the charts source it would be simple to add but I think it may involve a bit more than you show above (maybe). I don't want to have to buy the source on each major release either.
Anyway I found my problem, CalcNearestPoint() doesn't take Physical (mouse) Coordinate. oops. I found DataCursor.GetLocation() gives me the Data Coordinate for the mouse position. I'd prefer not be forced to use DataCursor but I can't seem to figure out how it converts a MousePosition to a Data Coordinate.
The code should look familiar since it's mostly UserChartExample1 I just gave all code (for this class) for completeness.
I cleaned up the code a bunch so it should be easier to read. Drop it into VS and reformat it because indenting is lost when posting it.
I had to delete the Axis, AxisLabel and Grid and rebuild it using the updated transform. If there is a cleaner way to do this please let me know.
I'm just asking if I'm doing things harder than I need to.
My biggest concern is I'd like to get rid of the DataCursor but it's the only thing that seem to implement GetLocation() in the correct corrdinate system.
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms;
using System.Drawing.Drawing2D; using com.quinncurtis.chart2dnet;
namespace UserChartExample1 { public class UserChartControl1 : ChartView { private IContainer mComponents = null; private SimpleDataset mDataset1; private SimpleDataset mDataset2; private ChartView mChartView; private Font mTheFont; private CartesianCoordinates mTransform1; private LinearAxis mxAxis; private LinearAxis myAxis; private NumericAxisLabels mxAxisLab; private NumericAxisLabels myAxisLab; private Grid myGrid; private const int RESOLUTION = 1000; private const int MINX = 0; private const int MINY = 0; private const int MAXX = 100000; private const int MAXY = 3;
public UserChartControl1() { // This call is required by the Windows Form Designer. InitializeComponent();
// TODO: Add any initialization after the InitializeComponent call // Better to do this in main form //InitializeChart(); }
public void UpdateSpectrumChart(double[][] newY) { // This routine "Bins" the data effectively the same // as the Charts Compress Data and this probably could // adapted to use it.
int xMin = (int)mTransform1.GetScaleStartX(); int xMax = (int)mTransform1.GetScaleStopX();
int binSize = (int)((double)(xMax - xMin) / (double)RESOLUTION);
for (int i = 0; i < mDataset1.GetNumberDatapoints(); i++) { Point2D p = mDataset1[i]; p.Y = 0.0; for (int j = 0; j < binSize; j++) { p.Y += newY[0][xMin + i * binSize + j]; } p.Y /= binSize; p.X = xMin + i * binSize; mDataset1[i] = p; }
for (int i = 0; i < mDataset2.GetNumberDatapoints(); i++) { // Use accessor methods Point2D p = mDataset2[i]; p.Y = 0.0; for (int j = 0; j < binSize; j++) { p.Y += newY[1][xMin + i * binSize + j]; } p.Y /= binSize; p.X = xMin + i * binSize; mDataset2[i] = p; }
mChartView.UpdateDraw(); }
public void UpdateAxis(Point2D location1, Point2D location2) { mTransform1.SetScaleStartX(location1.X); mTransform1.SetScaleStopX(location2.X); mTransform1.SetScaleStartY(UserChartControl1.MINY); // We don't Zoom Y on this application. mTransform1.SetScaleStopY(UserChartControl1.MAXY);
// if bin size too small back off
int xMin = (int)mTransform1.GetScaleStartX(); int xMax = (int)mTransform1.GetScaleStopX(); int binSize = (int)((double)(xMax - xMin) / (double)RESOLUTION);
if (binSize == 0) { int xcenter = xMin + (xMax - xMin) / 2; xMin = xcenter - RESOLUTION / 2; xMax = xcenter + RESOLUTION / 2; mTransform1.SetScaleStartX(xMin); mTransform1.SetScaleStopX(xMax); }
// Rebuild everything that depends on the new scale
mChartView.DeleteChartObject(myGrid); mChartView.DeleteChartObject(myAxisLab); mChartView.DeleteChartObject(myAxis); mChartView.DeleteChartObject(mxAxisLab); mChartView.DeleteChartObject(mxAxis);
mxAxis = new LinearAxis(mTransform1, ChartObj.X_AXIS); mxAxis.SetColor(Color.Black); mChartView.AddChartObject(mxAxis);
myAxis = new LinearAxis(mTransform1, ChartObj.Y_AXIS); myAxis.SetColor(Color.Black); mChartView.AddChartObject(myAxis);
mxAxisLab = new NumericAxisLabels(mxAxis); mxAxisLab.SetColor(Color.Black); mChartView.AddChartObject(mxAxisLab);
myAxisLab = new NumericAxisLabels(myAxis); myAxisLab.SetColor(Color.Black); mChartView.AddChartObject(myAxisLab);
myGrid = new Grid(mxAxis, myAxis, ChartObj.Y_AXIS, ChartObj.GRID_MAJOR); myGrid.SetColor(Color.White); myGrid.SetLineWidth(1); mChartView.AddChartObject(myGrid);
mChartView.UpdateDraw(); }
public void InitializeData() { double[] x1; double[] y1; double[] x2; double[] y2;
x1 = new double[RESOLUTION]; y1 = new double[RESOLUTION];
int xMin = MINX; int xMax = MAXX;
int binSize = (int)((xMax - xMin) / RESOLUTION);
for (int i = 0; i < RESOLUTION; i++) { x1[i] = (double)i * binSize; y1[i] = (double)i; }
mDataset1 = new SimpleDataset("Channel 1", x1, y1);
x2 = new double[RESOLUTION]; y2 = new double[RESOLUTION];
for (int i = 0; i < RESOLUTION; i++) { x2[i] = (double)i * binSize; y2[i] = (double)i; }
mDataset2 = new SimpleDataset("Channel 2", x2, y2); }
private class CustomDataCursor : DataCursor { UserChartControl1 mComponent; Point2D location1; Point2D location2;
public CustomDataCursor(ChartView component, CartesianCoordinates transform) : base(component, transform, ChartObj.MARKER_HVLINE, 8.0) { mComponent = (UserChartControl1)component; }
public override void OnMouseUp(MouseEventArgs mouseevent) { base.OnMouseUp(mouseevent);
if ((mouseevent.Button & MouseButtons.Left) != 0) { location2 = GetLocation();
mComponent.UpdateAxis(location1, location2); }
if ((mouseevent.Button & MouseButtons.Right) != 0) { mComponent.UpdateAxis(new Point2D(UserChartControl1.MINX, UserChartControl1.MINY), new Point2D(UserChartControl1.MAXX, UserChartControl1.MAXY)); } }
public override void OnMouseDown(MouseEventArgs mouseevent) { base.OnMouseDown(mouseevent);
if ((mouseevent.Button & MouseButtons.Left) != 0) { location1 = GetLocation(); } } }
public void InitializeChart() { mChartView = this;
mTheFont = new Font("Microsoft Sans Serif", 10, FontStyle.Bold);
mTransform1 = new CartesianCoordinates();
UpdateAxis(new Point2D(MINX, MINY), new Point2D(MAXX, MAXY));
mTransform1.SetGraphBorderDiagonal(0.05, 0.05, 0.95, 0.95); Background graphbackground = new Background(mTransform1, ChartObj.GRAPH_BACKGROUND, Color.LightGray); mChartView.AddChartObject(graphbackground); Background plotbackground = new Background(mTransform1, ChartObj.PLOT_BACKGROUND, Color.Black); mChartView.AddChartObject(plotbackground);
ChartAttribute attrib1 = new ChartAttribute(Color.Yellow, 0, DashStyle.Solid, Color.Yellow); attrib1.SetFillFlag(false); SimpleBarPlot thePlot1 = new SimpleBarPlot(mTransform1, mDataset1, 0.001, 0.0, attrib1, ChartObj.JUSTIFY_MIN); mChartView.AddChartObject(thePlot1);
ChartAttribute attrib2 = new ChartAttribute(Color.Red, 0, DashStyle.Solid, Color.Red); attrib1.SetFillFlag(false); SimpleBarPlot thePlot2 = new SimpleBarPlot(mTransform1, mDataset2, 0.001, 0.0, attrib2, ChartObj.JUSTIFY_MIN); mChartView.AddChartObject(thePlot2);
Font theTitleFont = new Font("Microsoft Sans Serif", 10, FontStyle.Bold); ChartTitle mainTitle = new ChartTitle(mTransform1, theTitleFont, "Spectrum"); mainTitle.SetTitleType(ChartObj.CHART_HEADER); mainTitle.SetTitlePosition(ChartObj.CENTER_GRAPH); mainTitle.SetColor(Color.Black); mChartView.AddChartObject(mainTitle);
CustomDataCursor cursorObj = new CustomDataCursor(mChartView, mTransform1); cursorObj.SetEnable(false); mChartView.SetCurrentMouseListener(cursorObj); }
/// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose(bool disposing) { if (disposing) { if (mComponents != null) { mComponents.Dispose(); } } base.Dispose(disposing); }
#region Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.SuspendLayout(); // // UserChartControl1 // this.Name = "UserChartControl1"; this.PreferredSize = new System.Drawing.Size(936, 701); this.Size = new System.Drawing.Size(936, 701); this.ResumeLayout(false);
} #endregion } }
|
 |
|
quinncurtis
1164 Posts |
Posted - 16 Feb 2006 : 18:39:48
|
Actually, we do know the modification to our source is as easy as we show, since we tested it while zooming in on two 1M point lineplots. Updates during zooming took less than one second in all cases. It is not generalized though and will not work with all types of data.
If you want to continue with your own method you should be able to convert mouse (or device coordinates) to physical coordinates (and back) using the coordinate systems ConvertCoord method.
CartesianCoordinates transform;
transform.ConvertCoord(dest, ChartObj.PHYS_POS, source, ChartObj.DEV_POS);
where dest and source are Point2D objects and transform is a CartesianCoordinates object.
Otherwise, we are not able to analyze or support programs of this complexity in this forum. |
 |
|
mswlogo
10 Posts |
Posted - 17 Feb 2006 : 12:57:08
|
Thanks that worked great.
In case any one is interested here is the final code. I reduced it to one channel, added the suggestion above and did a little more cleanup. The example is not that complex.
In a nut shell, to zoom it updates the transform and has to rebuild everything that depended on that transform (axis, axislabel and grid). Then when updated data comes in it bins it (compresses) at rate depending on the current zoom level. As you zoom you get more detail. When you zoom in past the resolution (i.e. binsize less than 1) I just stop, normally you replicate to fill the screen.
As Richard said it depends on your data on how you "bin" (compress) it. It my case I choose the Max value in the bin (chart refers this as the interval). It is basically the exact same issue using the built in compression except that this adjusts the compression dynamically as you zoom.
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms;
using System.Drawing.Drawing2D; using com.quinncurtis.chart2dnet;
namespace UserChartExample1 { public class UserChartControl1 : ChartView { private const int RESOLUTION = 1000; private const int MINX = 0; private const int MINY = 0; private const int MAXX = 100000; private const int MAXY = 3;
private IContainer mComponents = null; private SimpleDataset mDataset1; private ChartView mChartView; private CartesianCoordinates mTransform1; private LinearAxis mxAxis; private LinearAxis myAxis; private NumericAxisLabels mxAxisLab; private NumericAxisLabels myAxisLab; private Grid mxGrid; private Grid myGrid;
public UserChartControl1() { InitializeComponent(); //InitializeChart(); }
public void UpdateSpectrumChart(double[] newY) { int xMin = (int)mTransform1.GetScaleStartX(); int xMax = (int)mTransform1.GetScaleStopX();
int binSize = (int)((double)(xMax - xMin) / (double)RESOLUTION);
// Using Max (other choices would be Min, Avg, MinMax);
for (int i = 0; i < mDataset1.GetNumberDatapoints(); i++) { Point2D p = mDataset1[i]; p.Y = double.MinValue; for (int j = 0; j < binSize; j++) { p.Y = Math.Max(newY[xMin + i * binSize + j], p.Y); } p.X = xMin + i * binSize; mDataset1[i] = p; }
mChartView.UpdateDraw(); }
public void UpdateAxis(Point2D location1, Point2D location2) { mTransform1.SetScaleStartX(location1.X); mTransform1.SetScaleStopX(location2.X); mTransform1.SetScaleStartY(UserChartControl1.MINY); // We don't Zoom Y on this application. mTransform1.SetScaleStopY(UserChartControl1.MAXY);
// if bin size too small back off
int xMin = (int)mTransform1.GetScaleStartX(); int xMax = (int)mTransform1.GetScaleStopX(); int binSize = (int)((double)(xMax - xMin) / (double)RESOLUTION);
if (binSize == 0) { int xcenter = xMin + (xMax - xMin) / 2; xMin = xcenter - RESOLUTION / 2; xMax = xcenter + RESOLUTION / 2; mTransform1.SetScaleStartX(xMin); mTransform1.SetScaleStopX(xMax); }
// Rebuild everything that depends on the new scale
mChartView.DeleteChartObject(myGrid); mChartView.DeleteChartObject(mxGrid); mChartView.DeleteChartObject(myAxisLab); mChartView.DeleteChartObject(myAxis); mChartView.DeleteChartObject(mxAxisLab); mChartView.DeleteChartObject(mxAxis);
mxAxis = new LinearAxis(mTransform1, ChartObj.X_AXIS); mxAxis.SetColor(Color.Black); mChartView.AddChartObject(mxAxis);
myAxis = new LinearAxis(mTransform1, ChartObj.Y_AXIS); myAxis.SetColor(Color.Black); mChartView.AddChartObject(myAxis);
mxAxisLab = new NumericAxisLabels(mxAxis); mxAxisLab.SetColor(Color.Black); mChartView.AddChartObject(mxAxisLab);
myAxisLab = new NumericAxisLabels(myAxis); myAxisLab.SetColor(Color.Black); mChartView.AddChartObject(myAxisLab);
mxGrid = new Grid(mxAxis, myAxis, ChartObj.X_AXIS, ChartObj.GRID_MAJOR); mxGrid.SetColor(Color.White); mxGrid.SetLineWidth(1); mChartView.AddChartObject(mxGrid);
myGrid = new Grid(mxAxis, myAxis, ChartObj.Y_AXIS, ChartObj.GRID_MAJOR); myGrid.SetColor(Color.White); myGrid.SetLineWidth(1); mChartView.AddChartObject(myGrid);
mChartView.UpdateDraw(); }
private class CustomDataCursor : MouseListener { UserChartControl1 mComponent; Point2D location1; Point2D location2;
public CustomDataCursor(ChartView component, CartesianCoordinates transform) : base(component) { mComponent = (UserChartControl1)component; }
public override object Clone() { return null; }
public override void OnDoubleClick(EventArgs mouseevent) { }
public override void OnClick(EventArgs mouseevent) { }
public override void OnMouseMove(MouseEventArgs mouseevent) { }
public override void OnMouseUp(MouseEventArgs mouseevent) { if ((mouseevent.Button & MouseButtons.Left) != 0) { location2 = new Point2D(); mComponent.mTransform1.ConvertCoord(location2, ChartObj.PHYS_POS, new Point2D(mouseevent.X, mouseevent.Y), ChartObj.DEV_POS);
mComponent.UpdateAxis(location1, location2); }
if ((mouseevent.Button & MouseButtons.Right) != 0) { mComponent.UpdateAxis(new Point2D(UserChartControl1.MINX, UserChartControl1.MINY), new Point2D(UserChartControl1.MAXX, UserChartControl1.MAXY)); } }
public override void OnMouseDown(MouseEventArgs mouseevent) { if ((mouseevent.Button & MouseButtons.Left) != 0) { location1 = new Point2D(); mComponent.mTransform1.ConvertCoord(location1, ChartObj.PHYS_POS, new Point2D(mouseevent.X, mouseevent.Y), ChartObj.DEV_POS); } } }
public void InitializeChart() { mDataset1 = new SimpleDataset("Channel 1", RESOLUTION);
mChartView = this;
mTransform1 = new CartesianCoordinates();
UpdateAxis(new Point2D(MINX, MINY), new Point2D(MAXX, MAXY));
mTransform1.SetGraphBorderDiagonal(0.05, 0.05, 0.95, 0.95); Background graphbackground = new Background(mTransform1, ChartObj.GRAPH_BACKGROUND, Color.LightGray); mChartView.AddChartObject(graphbackground); Background plotbackground = new Background(mTransform1, ChartObj.PLOT_BACKGROUND, Color.Black); mChartView.AddChartObject(plotbackground);
ChartAttribute attrib1 = new ChartAttribute(Color.Yellow, 0, DashStyle.Solid, Color.Yellow); attrib1.SetFillFlag(false); SimpleBarPlot thePlot1 = new SimpleBarPlot(mTransform1, mDataset1, 0.001, 0.0, attrib1, ChartObj.JUSTIFY_MIN); mChartView.AddChartObject(thePlot1);
Font theTitleFont = new Font("Microsoft Sans Serif", 10, FontStyle.Bold); ChartTitle mainTitle = new ChartTitle(mTransform1, theTitleFont, "Spectrum"); mainTitle.SetTitleType(ChartObj.CHART_HEADER); mainTitle.SetTitlePosition(ChartObj.CENTER_GRAPH); mainTitle.SetColor(Color.Black); mChartView.AddChartObject(mainTitle);
CustomDataCursor cursorObj = new CustomDataCursor(mChartView, mTransform1); cursorObj.SetEnable(true); mChartView.SetCurrentMouseListener(cursorObj); }
/// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose(bool disposing) { if (disposing) { if (mComponents != null) { mComponents.Dispose(); } } base.Dispose(disposing); }
#region Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.SuspendLayout(); // // UserChartControl1 // this.Name = "UserChartControl1"; this.PreferredSize = new System.Drawing.Size(936, 701); this.Size = new System.Drawing.Size(936, 701); this.ResumeLayout(false);
} #endregion } }
|
 |
|
|
Topic  |
|
|
|