public void AddErrorFromCSVFile(PlotParameters plotParams, string path) { object data = new object(); if (plotParams.drawSettings.type != PlotType.bar_grouped) { using (StreamReader file = new StreamReader(path)) { string[] raw = file.ReadToEnd().Split(new char[] { ',', '\n' }); List <double> serialData = raw.Where(m => double.TryParse(m, out _)).Select(m => double.Parse(m)).ToList(); if (plotParams.drawSettings.type == PlotType.scatter) { double[] xs = new double[serialData.Count / 2]; double[] ys = new double[serialData.Count / 2]; for (int i = 0; i < serialData.Count; i++) { int row = i / 2; int col = i % 2; if (col == 0) { xs[row] = serialData[i]; } else { ys[row] = serialData[i]; } data = new double[][] { xs, ys }; } } else if (plotParams.drawSettings.type == PlotType.bar) { data = serialData.ToArray(); } } } else { string[] paths = path.Split(','); data = new double[paths.Length][]; for (int i = 0; i < paths.Length; i++) { using (StreamReader file = new StreamReader(paths[i])) { string[] raw = file.ReadToEnd().Split(new char[] { ',', '\n' }); ((double[][])data)[i] = raw.Where(m => double.TryParse(m, out _)).Select(m => double.Parse(m)).ToArray(); } } } plotParams.errorData = data; plotParams.hasErrorData = true; ((MainWindow)this.MainWindow).RenderPlot(); }
public PlotParameters AddSeriesFromString(string[] raw, DrawSettings drawSettings, Dictionary <string, object> metadata) { object data = new object(); if (drawSettings.type == PlotType.bar_grouped) { double[][] dataList = new double[raw.Length][]; for (int i = 0; i < raw.Length; i++) { string[] temp = raw[i].Split(',', '\n'); dataList[i] = new double[temp.Length]; for (int j = 0; j < temp.Length; j++) { double parseOut; if (double.TryParse(temp[j], out parseOut)) { dataList[i][j] = (parseOut); } } } data = dataList; } else { throw new NotImplementedException(); } if (!metadata.ContainsKey("group_names")) { metadata.Add("group_names", Enumerable.Range(1, ((double[][])data)[0].Count()).Select(i => i + "").ToArray()); } if (!metadata.ContainsKey("series_names")) { metadata.Add("series_names", Enumerable.Range(1, ((double[][])data).Count()).Select(i => char.ConvertFromUtf32(64 + i)).ToArray()); } PlotParameters plotParams = new PlotParameters { data = data, drawSettings = drawSettings, metaData = metadata }; series.Add(plotParams); ((MainWindow)this.MainWindow).RenderPlot(); return(plotParams); }
private async void FunctionPlot_Click(object sender, RoutedEventArgs e) { var dlg = new FunctionPlotDialog(); dlg.Owner = App.Current.MainWindow; if (dlg.ShowDialog() == true) { string expression = dlg.expressionTextBox.Text; Func <double, double?> f_unsafe; try { f_unsafe = await CSharpScript.EvaluateAsync <Func <double, double?> >("x=>" + expression, ScriptOptions.Default.WithImports("System.Math")); } catch (CompilationErrorException error) { DialogUtilities.ShowSpecificPlotError("Compilation Error", error, false, "Make sure your expression is valid C#. Note that ternary operators that may return null are not supported by C# in this context. Returning double.NaN will work fine."); return; } double?f_temp(double x) { try { double?y = f_unsafe(x); if (y.HasValue && !double.IsFinite(y.Value)) {// Make sure it ain't infinity, negative infinity, NaN, etc return(null); } return(f_unsafe(x)); } catch (Exception e) { return(null); } } Func <double, double?> f = x => f_temp(x); PlotParameters plotParams = new PlotParameters() { data = f, drawSettings = new DrawSettings() { type = PlotType.function, label = "y = " + expression, } }; try { ((App)App.Current).AddSeries(plotParams); } catch { DialogUtilities.ShowGenericPlotNotAddedError(); return; } } }
private void LineSpan_Click(object sender, RoutedEventArgs e) { string plotType = ((MenuItem)e.OriginalSource).Header.ToString().ToUpperInvariant(); PlotType type = new PlotType(); switch (plotType) { case "VERTICAL LINE": type = PlotType.vertical_line; break; case "HORIZONTAL LINE": type = PlotType.horizontal_line; break; case "VERTICAL SPAN": type = PlotType.vertical_span; break; case "HORIZONTAL SPAN": type = PlotType.horizontal_span; break; } SettingsDialog settingsDialog = new SettingsDialog(type); settingsDialog.Owner = App.Current.MainWindow; DrawSettings drawSettings; drawSettings = FetchSettingsFromDialog(settingsDialog, type); if (!drawSettings.valid) { return; } PlotParameters plotParams = new PlotParameters(); plotParams.drawSettings = drawSettings; if (type == PlotType.horizontal_line || type == PlotType.vertical_line) { LineSettingsDialog lineDialog = new LineSettingsDialog(); lineDialog.Owner = App.Current.MainWindow; if (lineDialog.ShowDialog() != true) { return; } double value = 0; DateTime date = new DateTime(); if (DateTime.TryParse(lineDialog.value.Text, out date)) { plotParams.data = date.ToOADate(); } else if (double.TryParse(lineDialog.value.Text, out value)) { plotParams.data = value; } else { DialogUtilities.ShowCouldNotParseValueError("Value", lineDialog.value.Text); return; } } else { SpanSettingsDialog spanDialog = new SpanSettingsDialog(); spanDialog.Owner = App.Current.MainWindow; if (spanDialog.ShowDialog() != true) { return; } double minValue = 0; double maxValue = 0; DateTime dateMin = new DateTime(); DateTime dateMax = new DateTime(); if (DateTime.TryParse(spanDialog.minValue.Text, out dateMin)) { minValue = dateMin.ToOADate(); } else if (!double.TryParse(spanDialog.minValue.Text, out minValue)) { DialogUtilities.ShowCouldNotParseValueError("Min Value", spanDialog.minValue.Text); return; } if (DateTime.TryParse(spanDialog.maxValue.Text, out dateMax)) { maxValue = dateMax.ToOADate(); } else if (!double.TryParse(spanDialog.maxValue.Text, out maxValue)) { DialogUtilities.ShowCouldNotParseValueError("Max Value", spanDialog.maxValue.Text); return; } plotParams.data = (minValue, maxValue); } try { ((App)App.Current).AddSeries(plotParams); } catch { DialogUtilities.ShowGenericPlotNotAddedError(); return; } }
private void LoadCSVSeries_Click(object sender, RoutedEventArgs e) { string plotType = ((MenuItem)e.OriginalSource).Header.ToString().ToUpperInvariant(); PlotType type = new PlotType(); switch (plotType) { case "SCATTER PLOT": type = PlotType.scatter; break; case "SIGNAL": type = PlotType.signal; break; case "BAR PLOT": type = PlotType.bar; break; case "HISTOGRAM": type = PlotType.histogram; break; case "BOX AND WHISKER": type = PlotType.box_whisker; break; case "GROUPED BAR PLOT": type = PlotType.bar_grouped; break; } SettingsDialog settingsDialog = new SettingsDialog(type); settingsDialog.Owner = App.Current.MainWindow; DrawSettings drawSettings; drawSettings = FetchSettingsFromDialog(settingsDialog, type); if (!drawSettings.valid) { return; } Dictionary <string, object> metadata = new Dictionary <string, object>(); if (type == PlotType.signal) { SignalFrequencyDialog dlg = new SignalFrequencyDialog(); dlg.Owner = App.Current.MainWindow; if (dlg.ShowDialog() != true) { //Nullable return; } double sampleRate; if (!double.TryParse(dlg.frequency, out sampleRate)) { DialogUtilities.ShowCouldNotParseNumberError("Sample Rate", dlg.frequency); return; } double xOffset; if (double.TryParse(dlg.xOffsetTextBox.Text, out xOffset)) { DialogUtilities.ShowCouldNotParseNumberError("X-Offset", dlg.xOffsetTextBox.Text); return; } metadata.Add("sampleRate", sampleRate); metadata.Add("xOffset", xOffset); } else if (type == PlotType.bar_grouped) { GroupedPlotDialog dlg = new GroupedPlotDialog(); dlg.Owner = App.Current.MainWindow; if (dlg.ShowDialog() != true) { //Nullable return; } if (dlg.groupNamesTextBox.Text != "") { metadata.Add("group_names", dlg.groupNamesTextBox.Text.Split(',')); } if (dlg.seriesNamesTextBox.Text != "") { metadata.Add("series_names", dlg.seriesNamesTextBox.Text.Split(',')); } } FilePickerDialog filePickerDialog = new FilePickerDialog(drawSettings.type == PlotType.bar_grouped); filePickerDialog.Owner = App.Current.MainWindow; try { if (filePickerDialog.ShowDialog() == true) { PlotParameters plotParams = new PlotParameters(); plotParams = (App.Current as App).AddSeriesFromCSVFile(filePickerDialog.filepath, drawSettings, metadata); if (settingsDialog.errorDataCSV != null) { ((App)App.Current).AddErrorFromCSVFile(plotParams, settingsDialog.errorDataCSV); } statusMessage.Text = $"{filePickerDialog.filepath} loaded"; } } catch { DialogUtilities.ShowGenericPlotNotAddedError(); return; } }
public PlotParameters AddSeriesFromString(string dataString, DrawSettings drawSettings, Dictionary <string, object> metadata) { object data = new object(); string[] raw = dataString.Split(new char[] { ',', '\n' }); if (!drawSettings.dateXAxis) { List <double> serialData = raw.Where(m => double.TryParse(m, out _)).Select(m => double.Parse(m)).ToList(); if (drawSettings.type == PlotType.scatter || drawSettings.type == PlotType.bar) { double[] xs = new double[serialData.Count / 2]; double[] ys = new double[serialData.Count / 2]; for (int i = 0; i < serialData.Count; i++) { int row = i / 2; int col = i % 2; if (col == 0) { xs[row] = serialData[i]; } else { ys[row] = serialData[i]; } data = new double[][] { xs, ys }; } } else if (drawSettings.type == PlotType.signal || drawSettings.type == PlotType.histogram) { data = serialData.ToArray(); } else if (drawSettings.type == PlotType.box_whisker) { ScottPlot.Statistics.Population dataPopulation = new ScottPlot.Statistics.Population(serialData.ToArray()); data = dataPopulation; } if (drawSettings.type == PlotType.scatter && drawSettings.polarCoordinates) { (((double[][])data)[0], ((double[][])data)[1]) = ScottPlot.Tools.ConvertPolarCoordinates(((double[][])data)[0], ((double[][])data)[1]); } } else { if (drawSettings.type == PlotType.scatter || drawSettings.type == PlotType.bar) { List <DateTime> dataX = new List <DateTime>(); List <double> dataY = new List <double>(); int successfullyParsed = 0; for (int i = 0; i < raw.Length; i++) { if (successfullyParsed % 2 == 0) { DateTime temp; if (DateTime.TryParse(raw[i], out temp)) { dataX.Add(temp); successfullyParsed++; } } else { double temp; if (double.TryParse(raw[i], out temp)) { dataY.Add(temp); successfullyParsed++; } } } long totalDistanceTicks = 0; for (int i = 0; i < dataX.Count; i++) { if (i == dataX.Count - 1) { break; } totalDistanceTicks += Math.Abs(dataX[i].Ticks - dataX[i + 1].Ticks); } long averageTickDistance = totalDistanceTicks / (dataX.Count - dataX.Count % 2); //The fact that this is rounded doesn't matter, bc ticks are so obsenely small long averageSecondsDistance = averageTickDistance / 10_000_000; metadata["numTimeUnits"] = 1; if (averageSecondsDistance > 0.75 * 86400 * 365) { metadata["timeUnit"] = ScottPlot.Config.DateTimeUnit.Year; } else if (averageSecondsDistance > 0.75 * 86400 * 30) { metadata["timeUnit"] = ScottPlot.Config.DateTimeUnit.Month; } else if (averageSecondsDistance > 0.75 * 86400) { metadata["timeUnit"] = ScottPlot.Config.DateTimeUnit.Day; } else if (averageSecondsDistance > 0.75 * 3600) { metadata["timeUnit"] = ScottPlot.Config.DateTimeUnit.Hour; } else if (averageSecondsDistance > 0.75 * 60) { metadata["timeUnit"] = ScottPlot.Config.DateTimeUnit.Minute; } else { metadata["timeUnit"] = ScottPlot.Config.DateTimeUnit.Second; } metadata["startDate"] = dataX[0]; metadata["numTimeUnits"] = (dataX.Count / 30) + 1; double[] dataXDouble = dataX.Select((dt, i) => dt.ToOADate()).ToArray(); data = new double[][] { dataXDouble, dataY.ToArray() }; } } PlotParameters plotParams = new PlotParameters { data = data, drawSettings = drawSettings, metaData = metadata }; series.Add(plotParams); ((MainWindow)this.MainWindow).RenderPlot(); return(plotParams); }
public void AddSeries(PlotParameters plotParams) { series.Add(plotParams); ((MainWindow)this.MainWindow).RenderPlot(); }