//int[] Groups; /// <summary> /// Updates graphic with new data series /// </summary> public virtual void FillData <TRecord>(IEnumerable <TRecord> newRecords, SerieSetting <TRecord>[] newSerieSettings) { DataSeries = new double[newSerieSettings.Length][, ]; serieStyle = new SerieStyleEnum[newSerieSettings.Length]; //Groups = new int[newSerieSettings.Length]; int recordsCount = newRecords.Count(); double[] firstDataPoint = newSerieSettings[0].Getter(newRecords.First()); int dimensionCount = firstDataPoint.Length; for (int dataSeriesIndex = 0; dataSeriesIndex < DataSeries.Length; dataSeriesIndex++) { DataSeries[dataSeriesIndex] = new double[recordsCount, dimensionCount]; serieStyle[dataSeriesIndex] = newSerieSettings[dataSeriesIndex].SerieStyle; //Groups[dataSeriesIndex] = newSerieSettings[dataSeriesIndex].Group; } int recordIndex = 0; foreach (TRecord record in newRecords) { for (int dataSerieIndex = 0; dataSerieIndex < newSerieSettings.Length; dataSerieIndex++) { SerieSetting <TRecord> serieSetting = newSerieSettings[dataSerieIndex]; double[] dataPoint = serieSetting.Getter(record); //double[] dataPoint; //try{ // dataPoint = serieSetting.Getter(record); //} catch (Exception ex) { System.Diagnostics.Debugger.Break(); } for (int dimensionIndex = 0; dimensionIndex < dataPoint.Length; dimensionIndex++) { DataSeries[dataSerieIndex][recordIndex, dimensionIndex] = dataPoint[dimensionIndex]; } } recordIndex++; } InvalidateMeasure(); //It seems InvalidateVisual() does not force Measure() InvalidateVisual(); IsEnabled = true; }
/// <summary> /// returns a new renderer based on serieSetting /// </summary> protected Renderer?CreateGraphRenderer <TRecord>(int serieIndex, SerieSetting <TRecord> serieSetting) { if (isArea2Expected && serieSetting.SerieStyle != SerieStyleEnum.area2) { throw new Exception(string.Format("SerieStyle[{0}] '{1}, {2}' should be area2 because the previous data series had style aera1.", serieIndex, serieSetting.SerieStyle, (int)serieSetting.SerieStyle)); } //get stroke brush or default brush Brush strokeBrush; if (serieSetting.StrokeBrush != null) { strokeBrush = serieSetting.StrokeBrush; } else { //use default brushes if (serieIndex == 0) { strokeBrush = Brushes.LightGreen; } else if (serieIndex == 1) { strokeBrush = Brushes.LightBlue; } else if (serieIndex == 2) { strokeBrush = Brushes.LightGray; } else if (serieIndex == 3) { strokeBrush = Brushes.LightGray; } else if (serieIndex == 4) { strokeBrush = Brushes.Black; } else { strokeBrush = Brushes.Red; } } //get fill brush or use transparent version of stroke brush Brush?fillBrush = null; if (serieSetting.SerieStyle == SerieStyleEnum.line) { fillBrush = serieSetting.FillBrush; } else if (serieSetting.SerieStyle == SerieStyleEnum.area1) { if (serieSetting.FillBrush == null) { if (!(strokeBrush is SolidColorBrush strokeSolidColorBrush)) { fillBrush = new SolidColorBrush(Color.FromArgb(128, 240, 240, 240)); } else { Color strokeColor = strokeSolidColorBrush.Color; fillBrush = new SolidColorBrush(Color.FromArgb(128, strokeColor.R, strokeColor.G, strokeColor.B)); } } else { fillBrush = serieSetting.FillBrush; } }
/// <summary> /// whenever a setup parameter changes, regenerate the test data and refresh /// </summary> private void updateParameters() { DateTime time = startDateDatePicker.SelectedDate.Value; double minutes = timeNumberScrollBar.Value; int stepsCount = (int)stepsNumberScrollBar.Value; var dataRecords = new DataRecord[stepsCount]; //count selected series and prepare values for data calculation var serieValues = new double[seriesCountDraw]; var increments = new double[seriesCountDraw]; int selectSeriesCount = 0; for (int seriesUIIndex = 0; seriesUIIndex < seriesCountUI; seriesUIIndex++) { if (serieCheckBoxes[seriesUIIndex].IsChecked.Value) { serieValues[selectSeriesCount] = minNumberScrollBars[seriesUIIndex].Value; increments[selectSeriesCount] = (maxNumberScrollBars[seriesUIIndex].Value - serieValues[selectSeriesCount]) / (stepsCount - 1); selectSeriesCount++; if (seriesUIIndex == areaLineIndex) { //areaLine needs 2 series for drawing serieValues[selectSeriesCount] = minNumberScrollBars[seriesUIIndex].Value * 0.8; increments[selectSeriesCount] = (maxNumberScrollBars[seriesUIIndex].Value * 0.9 - serieValues[selectSeriesCount]) / (stepsCount - 1); selectSeriesCount++; } } } //setup line settings var seriesSettings = new SerieSetting <DataRecord> [selectSeriesCount]; var seriesBrushes = new Brush[] { Brushes.Green, Brushes.Blue, Brushes.Gray, /*area2*/ null }; int seriesSettingsIndex = 0; for (int seriesUIIndex = 0; seriesUIIndex < seriesCountUI; seriesUIIndex++) { if (serieCheckBoxes[seriesUIIndex].IsChecked.Value) { int lambdaIndex = seriesSettingsIndex; //we need to create a new instance within the loop, otherwise the lambda expression will use the latest value of seriesSettingsIndex (i.e. max(seriesSettingsIndex)), see C# reference "Outer Variables" if (seriesUIIndex == areaLineIndex) { seriesSettings[seriesSettingsIndex] = new SerieSetting <DataRecord>(record => new double[] { record.Date.ToDouble(), record.Values[lambdaIndex] }, SerieStyleEnum.area1, seriesBrushes[seriesUIIndex], 1, null); seriesSettingsIndex++; int lambdaIndex2 = lambdaIndex + 1; seriesSettings[seriesSettingsIndex] = new SerieSetting <DataRecord>(record => new double[] { record.Date.ToDouble(), record.Values[lambdaIndex2] }, SerieStyleEnum.area2, seriesBrushes[seriesUIIndex], 1, null); seriesSettingsIndex++; } else { seriesSettings[seriesSettingsIndex] = new SerieSetting <DataRecord>(record => new double[] { record.Date.ToDouble(), record.Values[lambdaIndex] }, SerieStyleEnum.line, seriesBrushes[seriesUIIndex], 2, null); seriesSettingsIndex++; } } } //fill serie values into records for (int stepIndex = 0; stepIndex < stepsCount; stepIndex++) { var recordValues = new double[selectSeriesCount]; for (int selectSeriesIndex = 0; selectSeriesIndex < selectSeriesCount; selectSeriesIndex++) { recordValues[selectSeriesIndex] = serieValues[selectSeriesIndex]; serieValues[selectSeriesIndex] += increments[selectSeriesIndex]; } var dataRecord = new DataRecord(time, recordValues); dataRecords[stepIndex] = dataRecord; time = time.AddMinutes(minutes); } chart1Plot1X1YLegendTraced.FillData <DataRecord>(dataRecords, seriesSettings); }
private void fillDataSeries() { DateTime startTime = DateTime.Now.Date.AddYears(-1); DateTime time = startTime; double minutes = 60 * 24; int stepsCount = 365; var dataRecords = new DataRecord[stepsCount]; //count selected series and prepare values for data calculation var serieValues = new double[seriesCountDraw]; var increments = new double[seriesCountDraw]; int selectSeriesCount = 0; for (int seriesUIIndex = 0; seriesUIIndex < seriesCountUI; seriesUIIndex++) { serieValues[selectSeriesCount] = minNumbers[seriesUIIndex]; increments[selectSeriesCount] = (maxNumbers[seriesUIIndex] - serieValues[selectSeriesCount]) / (stepsCount - 1); selectSeriesCount++; if (seriesUIIndex == areaLineIndex) { //areaLine needs 2 series for drawing serieValues[selectSeriesCount] = minNumbers[seriesUIIndex] * 0.8; increments[selectSeriesCount] = (maxNumbers[seriesUIIndex] * 0.9 - serieValues[selectSeriesCount]) / (stepsCount - 1); selectSeriesCount++; } } //setup line settings var seriesSettings = new SerieSetting <DataRecord> [selectSeriesCount]; var seriesBrushes = new Brush[] { Brushes.Green, Brushes.Blue, Brushes.Gray, /*area2*/ null }; int seriesSettingsIndex = 0; for (int seriesUIIndex = 0; seriesUIIndex < seriesCountUI; seriesUIIndex++) { int lambdaIndex = seriesSettingsIndex; //we need to create a new instance within the loop, otherwise the lambda expression will use the latest value of seriesSettingsIndex (i.e. max(seriesSettingsIndex)), see C# reference "Outer Variables" if (seriesUIIndex == areaLineIndex) { seriesSettings[seriesSettingsIndex] = new SerieSetting <DataRecord>(record => new double[] { record.Date.ToDouble(), record.DataPoint[lambdaIndex] }, SerieStyleEnum.area1, 0, seriesBrushes[seriesUIIndex], 1, null); seriesSettingsIndex++; int lambdaIndex2 = lambdaIndex + 1; seriesSettings[seriesSettingsIndex] = new SerieSetting <DataRecord>(record => new double[] { record.Date.ToDouble(), record.DataPoint[lambdaIndex2] }, SerieStyleEnum.area2, 0, seriesBrushes[seriesUIIndex], 1, null); seriesSettingsIndex++; } else { int group; Brush fillBrush; if (seriesUIIndex == lowerGraphLineIndex) { group = 1; Color fillColor = Colors.LightSkyBlue; fillColor.A = 128; fillBrush = new SolidColorBrush(fillColor); } else { group = 0; fillBrush = null; } seriesSettings[seriesSettingsIndex] = new SerieSetting <DataRecord>(record => new double[] { record.Date.ToDouble(), record.DataPoint[lambdaIndex] }, SerieStyleEnum.line, group, seriesBrushes[seriesUIIndex], 2, fillBrush); seriesSettingsIndex++; } } //fill serie values into records for (int stepIndex = 0; stepIndex < stepsCount; stepIndex++) { var recordValues = new double[selectSeriesCount]; for (int selectSeriesIndex = 0; selectSeriesIndex < selectSeriesCount; selectSeriesIndex++) { recordValues[selectSeriesIndex] = serieValues[selectSeriesIndex]; serieValues[selectSeriesIndex] += increments[selectSeriesIndex]; } var dataRecord = new DataRecord(time, recordValues); dataRecords[stepIndex] = dataRecord; time = time.AddMinutes(minutes); } TestChart2Plots1X2YLegendsTraced.FillData <DataRecord>(dataRecords, seriesSettings); FontDefinition[] fontDefinitions = new FontDefinition[] { new FontDefinition(Brushes.DarkBlue, FontFamily, null, null, null, FontWeights.Bold), new FontDefinition(Brushes.DarkRed, null, 18, null, FontStyles.Italic, FontWeights.Bold), new FontDefinition(Brushes.DarkOrange, null, 32, FontStretches.Condensed, null, FontWeights.Normal), }; ChartNote[] chartNotes = new ChartNote[stepsCount / 20]; time = startTime; for (int chartNoteIndex = 0; chartNoteIndex < chartNotes.Length; chartNoteIndex++) { if (chartNoteIndex < 3) { chartNotes[chartNoteIndex] = new ChartNote(new double[] { time.ToDouble(), double.PositiveInfinity }, chartNoteIndex.ToString(), chartNoteIndex % 3); } else { chartNotes[chartNoteIndex] = new ChartNote(new double[] { time.ToDouble(), chartNoteIndex *10 }, chartNoteIndex.ToString(), chartNoteIndex % 3); } time = time.AddMinutes(20 * minutes); } TestChart2Plots1X2YLegendsTraced.AddNotes(chartNotes, fontDefinitions, true); }
private void fillDataSeries() { DateTime startTime = DateTime.Now.Date.AddYears(-1); DateTime time = startTime; double minutes = 60 * 24; int stepsCount = 365; var dataRecords = new DataRecord[stepsCount]; var serieValues = new double[seriesCount]; var random = new Random(); //prepare values for data calculation var serieIndex = 0; var seriesSettings = new SerieSetting <DataRecord> [seriesCount]; var seriesBrushes = new Brush[] { new SolidColorBrush(Color.FromRgb(0x00, 0x00, 0x00)) }; var seriesFillBrushes = new Brush[] { Brushes.Green, Brushes.Blue, Brushes.Gray }; for (var groupIndex = 0; groupIndex < groupCount; groupIndex++) { var lambdaIndex = serieIndex; //A new instance within the loop is needed, otherwise the lambda expression will use the latest value of serieIndex (i.e. 12), see C# reference "Outer Variables" seriesSettings[serieIndex] = new SerieSetting <DataRecord>(record => new double[] { record.Date.ToDouble(), record.DataPoint[lambdaIndex] }, SerieStyleEnum.line, groupIndex, new SolidColorBrush(Color.FromRgb(0xA0, 0xA0, 0xA0)), 2, new SolidColorBrush(Color.FromArgb(0x30, 0xA0, 0xA0, 0xA0))); serieValues[serieIndex++] = random.NextDouble() * 100; var lambdaIndex1 = serieIndex; seriesSettings[serieIndex] = new SerieSetting <DataRecord>(record => new double[] { record.Date.ToDouble(), record.DataPoint[lambdaIndex1] }, SerieStyleEnum.line, groupIndex, new SolidColorBrush(Color.FromRgb(0x80, 0x80, 0x80)), 2, new SolidColorBrush(Color.FromArgb(0x30, 0x80, 0x80, 0x80))); serieValues[serieIndex++] = random.NextDouble() * 100; var lambdaIndex2 = serieIndex; seriesSettings[serieIndex] = new SerieSetting <DataRecord>(record => new double[] { record.Date.ToDouble(), record.DataPoint[lambdaIndex2] }, SerieStyleEnum.line, groupIndex, new SolidColorBrush(Color.FromRgb(0x00, 0x00, 0x00)), 2, new SolidColorBrush(Color.FromArgb(0x30, 0x00, 0x00, 0x00))); serieValues[serieIndex] = serieValues[serieIndex - 1] + serieValues[serieIndex - 2]; serieIndex++; } //fill serie values into records for (var stepIndex = 0; stepIndex < stepsCount; stepIndex++) { var recordValues = new double[seriesCount]; serieIndex = 0; for (var groupIndex = 0; groupIndex < groupCount; groupIndex++) { recordValues[serieIndex] = serieValues[serieIndex]; serieValues[serieIndex++] += random.NextDouble() * 10 - 5; recordValues[serieIndex] = serieValues[serieIndex]; serieValues[serieIndex++] += random.NextDouble() * 10 - 5; recordValues[serieIndex] = serieValues[serieIndex - 1] + serieValues[serieIndex - 2]; serieIndex++; } var dataRecord = new DataRecord(time, recordValues); dataRecords[stepIndex] = dataRecord; time = time.AddMinutes(minutes); } TestChart4Plots1X4YLegendsTraced.FillData <DataRecord>(dataRecords, seriesSettings); FontDefinition[] fontDefinitions = new FontDefinition[] { new FontDefinition(Brushes.DarkBlue, FontFamily, null, null, null, FontWeights.Bold), new FontDefinition(Brushes.DarkRed, null, 18, null, FontStyles.Italic, FontWeights.Bold), new FontDefinition(Brushes.DarkOrange, null, 32, FontStretches.Condensed, null, FontWeights.Normal), }; ChartNote[] chartNotes = new ChartNote[stepsCount / 20]; time = startTime; for (int chartNoteIndex = 0; chartNoteIndex < chartNotes.Length; chartNoteIndex++) { if (chartNoteIndex < 3) { chartNotes[chartNoteIndex] = new ChartNote(new double[] { time.ToDouble(), double.PositiveInfinity }, chartNoteIndex.ToString(), chartNoteIndex % 3); } else { chartNotes[chartNoteIndex] = new ChartNote(new double[] { time.ToDouble(), chartNoteIndex *10 }, chartNoteIndex.ToString(), chartNoteIndex % 3); } time = time.AddMinutes(20 * minutes); } TestChart4Plots1X4YLegendsTraced.AddNotes(chartNotes, fontDefinitions, 0); }