/// <summary> /// Renders the notes to the drawingContext. The notes gets scaled to the available height and width displaying only /// values between minDisplayValueX and maxDisplayValueX, if the x-values are sorted. /// </summary> protected override void OnCreateVisual(DrawingContext drawingContext, double width, double height, DrawingVisual drawingVisual) { if (glyphDrawers == null || fontFamilytracked != chart.FontFamily || fontSizeTracked != chart.FontSize) { fontFamilytracked = chart.FontFamily; fontSizeTracked = chart.FontSize; if (glyphDrawers == null) { glyphDrawers = new GlyphDrawer[fontDefinitions.Length]; } for (int fontDefinitionIndex = 0; fontDefinitionIndex < fontDefinitions.Length; fontDefinitionIndex++) { FontDefinition fontDefinition = fontDefinitions[fontDefinitionIndex]; glyphDrawers[fontDefinitionIndex] = new GlyphDrawer( fontDefinition.FontFamily ?? chart.FontFamily, fontDefinition.FontStyle ?? chart.FontStyle, fontDefinition.FontWeight ?? chart.FontWeight, fontDefinition.FontStretch ?? chart.FontStretch, VisualTreeHelper.GetDpi(drawingVisual).PixelsPerDip); } } double minDisplayValueX = MinDisplayValues[DimensionX]; double maxDisplayValueX = MaxDisplayValues[DimensionX]; double minDisplayValueY = MinDisplayValues[DimensionY]; double maxDisplayValueY = MaxDisplayValues[DimensionY]; int chartNotesLength = chartNotes.Length; for (int chartNotesIndex = 0; chartNotesIndex < chartNotesLength; chartNotesIndex++) { ChartNote chartNote = chartNotes[chartNotesIndex]; double chartNotesX = chartNote.Values[0]; if (chartNotesX < minDisplayValueX) { continue; } double chartNotesY = chartNote.Values[1]; FontDefinition fontDefinition = fontDefinitions[chartNote.FontDefinitionId]; if ((minDisplayValueY <= chartNotesY && chartNotesY <= maxDisplayValueY) || double.IsInfinity(chartNotesY)) { Point chartNotePoint = TranslateValueXYToPoint(chartNotesX, chartNotesY, width, height); if (double.IsPositiveInfinity(chartNotesY)) { //draw at top const double fontOffset = 1.3; //need to move the letters a bit down chartNotePoint.Y = fontOffset * (fontDefinition.FontSize ?? chart.FontSize); } else if (double.IsPositiveInfinity(chartNotesY)) { //draw at bottom chartNotePoint.Y = height; } glyphDrawers[chartNote.FontDefinitionId].Write(drawingContext, chartNotePoint, chartNote.Note, fontDefinition.FontSize ?? chart.FontSize, fontDefinition.FontBrush ?? chart.Foreground); } if (chartNotesX > maxDisplayValueX) { break; } } }
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); }