public void SetGlyphDrawer(GlyphDrawer glyphDrawer, double fontSize) { if (this.glyphDrawer == glyphDrawer && this.fontSize == fontSize) { return; } this.glyphDrawer = glyphDrawer; this.fontSize = fontSize; if (timeSpanUnitConfigs == null) { timeSpanUnitConfigs = new TimeSpanUnitConfig[(int)TimeSpanUnitEnum.max + 1]; } maxFollowLabelWidth = double.MinValue; for (TimeSpanUnitEnum timeSpanUnitIndex = TimeSpanUnitEnum.none + 1; timeSpanUnitIndex <= TimeSpanUnitEnum.max; timeSpanUnitIndex++) { TimeSpanUnitMask mask = timeSpanUnitIndex.GetMask(); double firstLabelWidth = glyphDrawer.GetLength(mask.FirstLabelMask !, fontSize); double followLabelWidth = glyphDrawer.GetLength(mask.FollowLabelMask !, fontSize); maxFollowLabelWidth = Math.Max(followLabelWidth, maxFollowLabelWidth); timeSpanUnitConfigs[(int)timeSpanUnitIndex] = new TimeSpanUnitConfig(timeSpanUnitIndex, firstLabelWidth, followLabelWidth); } }
protected override void OnRecalculate(ref double[]?labelValues, ref string?[]?labelStrings, ref Point[]?labelPoints) { //choose time unit (seconds to years) TimeSpanUnitEnum newTimeSpanUnit = timeSpanUnitFormatter.GetDefaultTimeSpanUnit(DisplayDateRange, RenderWidthTracked); //check if even more labels can be displayed TimeSpan step = TimeSpan.MinValue; DateTime firstLabelDate = DateTime.MinValue; int labelsCount = int.MinValue; double spaceBetweenLabels = LegendGlyphDrawer.GetLength(" ", FontSize); while (true) { calculate(newTimeSpanUnit, out var newStep, out var newFirstLabelDate, out var newLabelsCount); TimeSpanUnitConfig timeSpanUnitConfig = timeSpanUnitFormatter.GetWidths(newTimeSpanUnit); double totalWidth = timeSpanUnitConfig.FirstLabelWidth; if (newLabelsCount > 1) { totalWidth += (newLabelsCount - 1) * (timeSpanUnitConfig.FollowLabelWidth + spaceBetweenLabels) * 1.1; } if (totalWidth > RenderWidthTracked || newTimeSpanUnit < 0) { if (labelsCount == int.MinValue) { //seems even the first estimated step is already too big. Just use the values step = newStep; firstLabelDate = newFirstLabelDate; labelsCount = newLabelsCount; } else { //take previous TimeSpanUnit newTimeSpanUnit += 1; } break; } step = newStep; firstLabelDate = newFirstLabelDate; labelsCount = newLabelsCount; newTimeSpanUnit -= 1; } TimeSpanUnit = newTimeSpanUnit; if (labelValues == null || labelValues.Length != labelsCount) { labelValues = new double[labelsCount]; labelStrings = new string[labelsCount]; labelPoints = new Point[labelsCount]; } //calculate labels double pixelPerValue = RenderWidthTracked / DisplayValueRange; TimeSpanUnitMask mask = newTimeSpanUnit.GetMask(); double firstLabelWidth = double.MinValue; DateTime labelDate = firstLabelDate; for (int labelIndex = 0; labelIndex < labelsCount; labelIndex++) { //write label value labelValues[labelIndex] = labelDate.ToDouble(); //calculate position double xPosition = (labelValues[labelIndex] - DisplayValue) * pixelPerValue; #if DEBUG if (xPosition > RenderWidthTracked && labelsCount > 1) { if (xPosition - RenderWidthTracked > 0.0001)//filter rounding problems //should not happen { System.Diagnostics.Debugger.Break(); throw new Exception(); } } #endif labelPoints ![labelIndex] = new Point(xPosition, 0);