private void plotSeries(Canvas _graph, plotData _plotData, eZoom eZoom, eRescale eRescale) { if (isPlotting) return; isPlotting = true; if (!mouseScrollX && !mouseScrollY) setEvents(false); double gw = _graph.ActualWidth - offsetL - offsetR; double gh = _graph.ActualHeight - offsetT - offsetB; double _nTickX = _plotData.nTickX > 0 ? _plotData.nTickX : nTickX; double _nTickY = _plotData.nTickY > 0 ? _plotData.nTickY : nTickY; _graph.Background = getBrush(borderColour); // Possible user change /******************************************************************************* * Axes scaling ******************************************************************************/ if (eZoom == eZoom.TRUE) { double minXtemp = _plotData.minX - _plotData.shiftX + posDown.X / gw * (_plotData.maxX - _plotData.minX); double minYtemp = _plotData.maxY - _plotData.shiftY + posUp.Y / gh * (_plotData.minY - _plotData.maxY); double maxXtemp = _plotData.minX - _plotData.shiftX + posUp.X / gw * (_plotData.maxX - _plotData.minX); double maxYtemp = _plotData.maxY - _plotData.shiftY + posDown.Y / gh * (_plotData.minY - _plotData.maxY); _plotData.minX = System.Math.Min(minXtemp, maxXtemp); _plotData.minY = System.Math.Min(minYtemp, maxYtemp); _plotData.maxX = System.Math.Max(minXtemp, maxXtemp); _plotData.maxY = System.Math.Max(minYtemp, maxYtemp); _plotData.shiftX = 0.0; _plotData.shiftY = 0.0; } else if (eRescale == eRescale.TRUE) { _plotData.minX = 1.0e20; _plotData.minY = 1.0e20; _plotData.maxX = -1.0e20; _plotData.maxY = -1.0e20; foreach (seriesData _series in _plotData.series) { _plotData.minX = System.Math.Min(_plotData.minX, _series.minX); _plotData.minY = System.Math.Min(_plotData.minY, _series.minY); _plotData.maxX = System.Math.Max(_plotData.maxX, _series.maxX); _plotData.maxY = System.Math.Max(_plotData.maxY, _series.maxY); } _plotData.shiftX = 0.0; _plotData.shiftY = 0.0; if (_plotData.userIntervalX == 0 && _plotData.userMaxX < _plotData.userMinX) { if (autoScale) { double interval = getInterval((_plotData.maxX - _plotData.minX) / nTickX); _plotData.minX = interval * (int)(_plotData.minX / interval - 1); _nTickX = 1 + (int)((_plotData.maxX - _plotData.minX) / interval); _plotData.maxX = _plotData.minX + _nTickX * interval; _plotData.nTickX = _nTickX; } else { round(ref _plotData.minX, ref _plotData.maxX); _plotData.nTickX = 0; _nTickX = nTickX; } } else { if (_plotData.userMaxX >= _plotData.userMinX) _plotData.minX = _plotData.userMinX; if (_plotData.userMaxX > _plotData.userMinX) _plotData.maxX = _plotData.userMaxX; double interval = _plotData.userIntervalX > 0 ? _plotData.userIntervalX : getInterval((_plotData.maxX - _plotData.minX) / nTickX); if (_plotData.userMaxX < _plotData.userMinX) _plotData.minX = interval * (int)(_plotData.minX / interval - 1); _nTickX = (int)((_plotData.maxX - _plotData.minX) / interval); if (_plotData.userMaxX <= _plotData.userMinX || _plotData.userMaxX > _plotData.userMinX + _nTickX * interval) _nTickX++; _plotData.maxX = _plotData.minX + _nTickX * interval; _plotData.nTickX = _nTickX; } if (_plotData.userIntervalY == 0 && _plotData.userMaxY < _plotData.userMinY) { if (autoScale) { double interval = getInterval((_plotData.maxY - _plotData.minY) / nTickY); _plotData.minY = interval * (int)(_plotData.minY / interval - 1); _nTickY = 1 + (int)((_plotData.maxY - _plotData.minY) / interval); _plotData.maxY = _plotData.minY + _nTickY * interval; _plotData.nTickY = _nTickY; } else { round(ref _plotData.minY, ref _plotData.maxY); _plotData.nTickY = 0; _nTickY = nTickY; } } else { if (_plotData.userMaxY >= _plotData.userMinY) _plotData.minY = _plotData.userMinY; if (_plotData.userMaxY > _plotData.userMinY) _plotData.maxY = _plotData.userMaxY; double interval = _plotData.userIntervalY > 0 ? _plotData.userIntervalY : getInterval((_plotData.maxY - _plotData.minY) / nTickY); if (_plotData.userMaxY < _plotData.userMinY) _plotData.minY = interval * (int)(_plotData.minY / interval - 1); _nTickY = (int)((_plotData.maxY - _plotData.minY) / interval); if (_plotData.userMaxY <= _plotData.userMinY || _plotData.userMaxY > _plotData.userMinY + _nTickY * interval) _nTickY++; _plotData.maxY = _plotData.minY + _nTickY * interval; _plotData.nTickY = _nTickY; } } /******************************************************************************* * Create all children objects ******************************************************************************/ _graph.Children.Clear(); RotateTransform rotate90 = new RotateTransform(); rotate90.Angle = -90; ScaleTransform bgLayer = new ScaleTransform(); bgLayer.ScaleY = 1.2; bgLayer.CenterY = 11.0; /******************************************************************************* * Axes labeling ******************************************************************************/ TextBlock _title = new TextBlock(); _title.Text = _plotData.title; _title.Width = gw; _title.TextAlignment = TextAlignment.Center; _title.FontSize = 18; _title.Foreground = getBrush(textColour); _title.FontWeight = FontWeights.Bold; _graph.Children.Add(_title); Canvas.SetLeft(_title, offsetL); Canvas.SetTop(_title, 2); TextBlock _titleX = new TextBlock(); _titleX.Text = _plotData.labelX; _titleX.Width = gw; _titleX.TextAlignment = TextAlignment.Center; _titleX.FontSize = 14; _titleX.Foreground = getBrush(textColour); _titleX.FontWeight = FontWeights.Bold; _graph.Children.Add(_titleX); Canvas.SetLeft(_titleX, offsetL); Canvas.SetTop(_titleX, _graph.ActualHeight - 20); TextBlock _titleY = new TextBlock(); _titleY.Text = _plotData.labelY; _titleY.Width = gh; _titleY.TextAlignment = TextAlignment.Center; _titleY.FontSize = 14; _titleY.Foreground = getBrush(textColour); _titleY.FontWeight = FontWeights.Bold; _graph.Children.Add(_titleY); Canvas.SetLeft(_titleY, 2); Canvas.SetTop(_titleY, _graph.ActualHeight - offsetB); _titleY.RenderTransform = rotate90; /******************************************************************************* * Plot area ******************************************************************************/ Canvas _plotarea = new Canvas(); _plotData.plotarea = _plotarea; _plotarea.Width = gw; _plotarea.Height = gh; _plotarea.Background = getBrush(interiorColour); _plotarea.ClipToBounds = true; _plotarea.Cursor = Cursors.Cross; _graph.Children.Add(_plotarea); Canvas.SetLeft(_plotarea, offsetL); Canvas.SetTop(_plotarea, offsetT); /******************************************************************************* * Hover values ******************************************************************************/ _plotData.hoverValBG = new TextBlock(); _plotData.hoverValBG.Text = ""; _plotData.hoverValBG.Foreground = getBrush(interiorColour); _plotData.hoverValBG.FontWeight = FontWeights.Bold; _plotData.hoverValBG.RenderTransform = bgLayer; Canvas.SetZIndex(_plotData.hoverValBG, 1); _plotarea.Children.Add(_plotData.hoverValBG); _plotData.hoverVal = new TextBlock(); _plotData.hoverVal.Text = ""; _plotData.hoverVal.Foreground = getBrush(textColour); _plotData.hoverVal.FontWeight = FontWeights.Bold; Canvas.SetZIndex(_plotData.hoverVal, 1); _plotarea.Children.Add(_plotData.hoverVal); /******************************************************************************* * Plot area Border ******************************************************************************/ Rectangle _border = new Rectangle(); _border.Width = gw; _border.Height = gh; _border.Stroke = getBrush(linesColour); _border.StrokeThickness = 1.0; _graph.Children.Add(_border); Canvas.SetLeft(_border, offsetL); Canvas.SetTop(_border, offsetT); /******************************************************************************* * X axis tick marks and labels ******************************************************************************/ Line _line; int i, j; double iTick; for (i = 0; i < _nTickX + 1; i++) { j = i - (int)System.Math.Floor(_plotData.shiftX * _nTickX / (_plotData.maxX - _plotData.minX)); iTick = j + _plotData.shiftX * _nTickX / (_plotData.maxX - _plotData.minX); if (iTick >= 0 && iTick <= _nTickX) { _line = new Line(); _line.X1 = iTick * gw / _nTickX; _line.Y1 = gh; _line.X2 = iTick * gw / _nTickX; _line.Y2 = 0; _line.Stroke = getBrush(faintlinesColour); _line.StrokeThickness = 0.5; _plotarea.Children.Add(_line); _line = new Line(); _line.X1 = iTick * gw / _nTickX; _line.Y1 = gh; _line.X2 = iTick * gw / _nTickX; _line.Y2 = gh - 10; _line.Stroke = getBrush(linesColour); _line.StrokeThickness = 1.0; _plotarea.Children.Add(_line); TextBlock _val = new TextBlock(); _val.Text = sigfig((_plotData.minX - _plotData.shiftX + iTick / _nTickX * (_plotData.maxX - _plotData.minX)), 3).ToString(); _val.Foreground = getBrush(textColour); _graph.Children.Add(_val); Canvas.SetLeft(_val, offsetL + iTick / _nTickX * gw - 3 * _val.Text.Length); Canvas.SetTop(_val, offsetT + gh + 2); } } /******************************************************************************* * Y axis tick marks and labels ******************************************************************************/ for (i = 0; i < _nTickY + 1; i++) { j = i - (int)System.Math.Floor(_plotData.shiftY * _nTickY / (_plotData.minY - _plotData.maxY)); iTick = j + _plotData.shiftY * _nTickY / (_plotData.minY - _plotData.maxY); if (iTick >= 0 && iTick <= _nTickY) { _line = new Line(); _line.X1 = 0; _line.Y1 = iTick * gh / _nTickY; _line.X2 = gw; _line.Y2 = iTick * gh / _nTickY; _line.Stroke = getBrush(faintlinesColour); _line.StrokeThickness = 0.5; _plotarea.Children.Add(_line); _line = new Line(); _line.X1 = 0; _line.Y1 = iTick * gh / _nTickY; _line.X2 = 10; _line.Y2 = iTick * gh / _nTickY; _line.Stroke = getBrush(linesColour); _plotarea.Children.Add(_line); TextBlock _val = new TextBlock(); _val.Text = sigfig((_plotData.maxY - _plotData.shiftY + iTick / _nTickY * (_plotData.minY - _plotData.maxY)), 3).ToString(); _val.Foreground = getBrush(textColour); _graph.Children.Add(_val); Canvas.SetLeft(_val, offsetL - 20); Canvas.SetTop(_val, offsetT + iTick / _nTickY * gh + 3 * _val.Text.Length); _val.RenderTransform = rotate90; } } /******************************************************************************* * Axes scroll areas ******************************************************************************/ Canvas _scrollX = new Canvas(); _scrollX.Width = gw; _scrollX.Height = offsetB; _scrollX.Background = getBrush("#00ffffff"); _graph.Children.Add(_scrollX); _plotData.scrollX = _scrollX; Canvas.SetLeft(_scrollX, offsetL); Canvas.SetTop(_scrollX, gh + offsetT); if (doEvents) _scrollX.Cursor = Cursors.Hand; Canvas _scrollY = new Canvas(); _scrollY.Width = offsetL; _scrollY.Height = gh; _scrollY.Background = getBrush("#00ffffff"); _graph.Children.Add(_scrollY); _plotData.scrollY = _scrollY; Canvas.SetLeft(_scrollY, 0); Canvas.SetTop(_scrollY, offsetT); if (doEvents) _scrollY.Cursor = Cursors.Hand; /******************************************************************************* * Legend ******************************************************************************/ if (_plotData.displayLegend) { Canvas _legend = new Canvas(); _plotData.legend = _legend; _legend.Width = 60; _legend.Height = 20*_plotData.series.Count; _legend.Background = getBrush("#00ffffff"); if (doEvents) _legend.Cursor = Cursors.Hand; i = 0; foreach (seriesData _series in _plotData.series) { Brush seriesBrush = getBrush(_series.colour); _line = new Line(); _line.X1 = 10; _line.Y1 = 10+20*i; _line.X2 = 50; _line.Y2 = 10 + 20 * i; _line.Stroke = seriesBrush; _line.StrokeThickness = 2; _legend.Children.Add(_line); TextBlock _val = new TextBlock(); _val.Text = _series.name; _val.Foreground = getBrush(textColour); _legend.Children.Add(_val); Canvas.SetLeft(_val, 55); Canvas.SetTop(_val, 20 * i); i++; } _graph.Children.Add(_legend); Canvas.SetLeft(_legend, offsetL + _plotData.legendPosition.X); Canvas.SetTop(_legend, offsetT + _plotData.legendPosition.Y); } /******************************************************************************* * Plot the series data ******************************************************************************/ double dSeries = 0; int iCount = 0; foreach (seriesData _series in _plotData.series) { for (i = 0; i < _series.dataX.Count; i++) { if (_series.dataX[i] > (_plotData.minX - _plotData.shiftX) && _series.dataX[i] < (_plotData.maxX - _plotData.shiftX)) iCount++; } if (_series.type == eLineType.HISTOGRAM) dSeries++; // Number of histograms; } double dOffest = -(dSeries - 1.0) / 2.0; dSeries = 0;; double dWL = 2.0; // Width for line double dWH = 0.8 * System.Math.Min(50.0, System.Math.Max(2.0, gw / (double) iCount)); // Width for histogram double dWP = System.Math.Min(12.0, System.Math.Max(6.0, gw / (double)iCount)); // Width for points foreach (seriesData _series in _plotData.series) { Brush seriesBrush = getBrush(_series.colour); switch (_series.type) { case eLineType.LINE: // Line { for (i = 1; i < _series.dataX.Count; i++) { double X1 = gw * (_series.dataX[i - 1] - (_plotData.minX - _plotData.shiftX)) / (_plotData.maxX - _plotData.minX); double Y1 = gh * ((_plotData.maxY - _plotData.shiftY) - _series.dataY[i - 1]) / (_plotData.maxY - _plotData.minY); double X2 = gw * (_series.dataX[i] - (_plotData.minX - _plotData.shiftX)) / (_plotData.maxX - _plotData.minX); double Y2 = gh * ((_plotData.maxY - _plotData.shiftY) - _series.dataY[i]) / (_plotData.maxY - _plotData.minY); if (((X2 >= 0 && X1 <= gw) || (X1 >= 0 && X2 <= gw)) && ((Y2 >= 0 && Y1 <= gh) || (Y1 >= 0 && Y2 <= gh))) { _line = new Line(); _line.X1 = X1; _line.Y1 = Y1; _line.X2 = X2; _line.Y2 = Y2; _line.Stroke = seriesBrush; _line.StrokeThickness = dWL; _plotarea.Children.Add(_line); } } } break; case eLineType.HISTOGRAM: // Histogram { Rectangle _rect; for (i = 0; i < _series.dataX.Count; i++) { double X = gw * (_series.dataX[i] - (_plotData.minX - _plotData.shiftX)) / (_plotData.maxX - _plotData.minX); double Y1 = gh * ((_plotData.maxY - _plotData.shiftY) - System.Math.Max(0.0, _series.dataY[i])) / (_plotData.maxY - _plotData.minY); double Y2 = gh * ((_plotData.maxY - _plotData.shiftY) - System.Math.Min(0.0, _series.dataY[i])) / (_plotData.maxY - _plotData.minY); if ((X >= 0 && X <= gw) && (Y1 <= gh && Y2 >= 0)) { _rect = new Rectangle(); _rect.Width = 0.8 * dWH; _rect.Height = Y2 - Y1; _rect.Fill = seriesBrush; _rect.StrokeThickness = 0; _plotarea.Children.Add(_rect); Canvas.SetLeft(_rect, X + dWH * (dOffest + dSeries) - 0.8 * dWH / 2.0); Canvas.SetTop(_rect, Y1); } } dSeries++; } break; case eLineType.POINTS: // Points { Ellipse _ellip; for (i = 0; i < _series.dataX.Count; i++) { double X = gw * (_series.dataX[i] - (_plotData.minX - _plotData.shiftX)) / (_plotData.maxX - _plotData.minX); double Y = gh * ((_plotData.maxY - _plotData.shiftY) - _series.dataY[i]) / (_plotData.maxY - _plotData.minY); if ((X >= 0 && X <= gw) && (Y >= 0 && Y <= gh)) { _ellip = new Ellipse(); _ellip.Width = dWP; _ellip.Height = dWP; _ellip.Fill = seriesBrush; _ellip.StrokeThickness = 0; _plotarea.Children.Add(_ellip); Canvas.SetLeft(_ellip, X - dWP / 2.0); Canvas.SetTop(_ellip, Y - dWP / 2.0); } } } break; } } setEvents(doEvents); isPlotting = false; }
public void exportCSV(plotData _plotData, string fileName) { string line; StreamWriter file = new StreamWriter(fileName); line = ""; for (int i = 0; i < _plotData.series.Count; i++) { line += _plotData.series[i].name + Utilities.CSV + Utilities.CSV + Utilities.CSV; } file.WriteLine(line); line = ""; for (int i = 0; i < _plotData.series.Count; i++) { line += _plotData.labelX + Utilities.CSV + _plotData.labelY + Utilities.CSV + Utilities.CSV; } file.WriteLine(line); line = ""; for (int i = 0; i < _plotData.series.Count; i++) { line += Utilities.CSV + Utilities.CSV + Utilities.CSV; } file.WriteLine(line); int max = 0; for (int i = 0; i < _plotData.series.Count; i++) { max = System.Math.Max(max, _plotData.series[i].dataX.Count); } for (int iRow = 0; iRow < max; iRow++) { line = ""; for (int i = 0; i < _plotData.series.Count; i++) { if (_plotData.series[i].dataX.Count <= iRow) { line += Utilities.CSV + Utilities.CSV + Utilities.CSV; } else { line += _plotData.series[i].dataX[iRow] + Utilities.CSV + _plotData.series[i].dataY[iRow] + Utilities.CSV + Utilities.CSV; } } file.WriteLine(line); } file.Close(); }
private plotData getPlotData(string graphName) { plotData _plotData = null; foreach (plotData i in plotInfo) { if (i.name == graphName) _plotData = i; } if (null == _plotData) { _plotData = new plotData(); plotInfo.Add(_plotData); _plotData.name = graphName; } return _plotData; }
/// <summary> /// Export data series directly to CSV file (no graphing). /// </summary> /// <param name="data"> /// An array holding the X and Y coordinate data. /// </param> /// <param name="fileName"> /// The CSV output file name. /// </param> /// <returns> /// None. /// </returns> public static void ExportCSV(Primitive data, Primitive fileName) { plotData _plotData = new plotData(); _plotData.labelX = "X Value"; _plotData.labelY = "Y Value"; _plotData.series.Add(_Engine.createSeries("Data Series", data, "", 0)); _Engine.exportCSV(_plotData, fileName); }