private double staticAxisMargin = 1; // px private void CreateCommonLabels(double[] screenTicksX) { Size renderSize = RenderSize; commonLabelsCanvas.Children.Clear(); UIElement[] labels = this.labels.ToArray(); double minCoordUnsorted = ToScreen(range.Min); double maxCoordUnsorted = ToScreen(range.Max); double minCoord = Math.Min(minCoordUnsorted, maxCoordUnsorted); double maxCoord = Math.Max(minCoordUnsorted, maxCoordUnsorted); double maxCoordDiff = (maxCoord - minCoord) / labels.Length / 2.0; double minCoordToAdd = minCoord - maxCoordDiff; double maxCoordToAdd = maxCoord + maxCoordDiff; for (int i = 0; i < ticks.Length; i++) { UIElement tickLabel = labels[i]; if (tickLabel == null) { continue; } // getting real size of label tickLabel.Measure(renderSize); Size tickLabelSize = tickLabel.DesiredSize; double screenX = screenTicksX[i]; double coord = screenX - getSize(tickLabelSize) / 2; if (isStaticAxis) { if (Math.Abs(screenX - minCoord) < maxCoordDiff) { coord = screenX + staticAxisMargin; } else if (Math.Abs(screenX - maxCoord) < maxCoordDiff) { coord = screenX - getSize(tickLabelSize) - staticAxisMargin; } } if (coord < minCoordToAdd || coord > maxCoordToAdd) { continue; } if (coord.IsNaN()) { continue; } StackCanvas.SetCoordinate(tickLabel, coord); commonLabelsCanvas.Children.Add(tickLabel); } }
private void DoDrawMayorLabels() { additionalLabelsCanvas.Children.Clear(); ITicksProvider <T> mayorTicksProvider = ticksProvider.MayorProvider; if (mayorTicksProvider != null && MayorLabelProvider != null) { Size renderSize = RenderSize; var mayorTicks = mayorTicksProvider.GetTicks(range, DefaultTicksProvider.DefaultTicksCount); double[] screenCoords = mayorTicks.Ticks.Select(tick => createDataPoint(convertToDouble(tick))). Select(p => p.DataToScreen(transform)).Select(p => getCoordinate(p)).ToArray(); // todo this is not the best decision - when displaying, for example, // milliseconds, it causes to create hundreds and thousands of textBlocks. double rangesRatio = GetRangesRatio(mayorTicks.Ticks.GetPairs().ToArray()[0], range); object info = mayorTicks.Info; MayorLabelsInfo newInfo = new MayorLabelsInfo { Info = info, MayorLabelsCount = (int)Math.Ceiling(rangesRatio) }; var newMayorTicks = new TicksInfo <T> { Info = newInfo, Ticks = mayorTicks.Ticks, TickSizes = mayorTicks.TickSizes }; UIElement[] additionalLabels = MayorLabelProvider.CreateLabels(newMayorTicks); for (int i = 0; i < additionalLabels.Length; i++) { if (screenCoords[i].IsNaN()) { continue; } UIElement tickLabel = additionalLabels[i]; tickLabel.Measure(renderSize); StackCanvas.SetCoordinate(tickLabel, screenCoords[i]); StackCanvas.SetEndCoordinate(tickLabel, screenCoords[i + 1]); if (tickLabel is FrameworkElement) { ((FrameworkElement)tickLabel).LayoutTransform = additionalLabelTransform; } additionalLabelsCanvas.Children.Add(tickLabel); } } }
private static void OnCoordinateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { UIElement reference = d as UIElement; if (reference != null) { StackCanvas parent = VisualTreeHelper.GetParent(reference) as StackCanvas; if (parent != null) { parent.InvalidateArrange(); } } }
private void DoDrawMayorLabels() { AdditionalLabelsCanvas.Children.Clear(); ITicksProvider <T> mayorTicksProvider = ticksProvider.MayorProvider; if (mayorTicksProvider != null && MayorLabelProvider != null) { Size renderSize = RenderSize; //if (renderSize.Width == 0 || renderSize.Height == 0) return; var mayorTicks = mayorTicksProvider.GetTicks(range, DefaultTicksProvider.DefaultTicksCount); double[] screenCoords = mayorTicks.Ticks.Select(tick => createDataPoint(convertToDouble(tick))). Select(p => p.DataToScreen(transform)).Select(p => getCoordinate(p)).ToArray(); int expectedMayorLabelsCount = mayorTicks.Ticks.Length; // todo this is not the best decision - when displaying, for example, // milliseconds, it causes to create hundreds and thousands of textBlocks. double rangesRatio = GetRangesRatio(mayorTicks.Ticks.GetPairs().ToArray()[0], range); object info = mayorTicks.Info; MayorLabelsInfo newInfo = new MayorLabelsInfo { Info = info, MayorLabelsCount = (int)Math.Ceiling(rangesRatio) }; var newMayorTicks = new TicksInfo <T> { Info = newInfo, Ticks = mayorTicks.Ticks, TickSizes = mayorTicks.TickSizes }; IEnumerable <FrameworkElement> additionalLabels = MayorLabelProvider.CreateLabels(newMayorTicks); int i = 0; foreach (FrameworkElement fe in additionalLabels) { fe.Measure(renderSize); StackCanvas.SetCoordinate(fe, screenCoords[i]); if (i + 1 < screenCoords.Length) { StackCanvas.SetEndCoordinate(fe, screenCoords[i + 1]); } AdditionalLabelsCanvas.Children.Add(fe); i++; } } }
/*protected override void OnRender(DrawingContext dc) * { * base.OnRender(dc); * * if (!rendered) * { * UpdateUIRepresentation(); * } * rendered = true; * }*/ private void InitializeComponent() { LayoutRoot = new Grid(); LayoutRoot.Background = new SolidColorBrush(Colors.White); TicksPath = new Path(); TicksPath.Stroke = new SolidColorBrush(Colors.Black); CommonLabelsCanvas = new StackCanvas(); AdditionalLabelsCanvas = new StackCanvas(); AdditionalAxisTranslate = new TranslateTransform(); LayoutRoot.Children.Add(TicksPath); LayoutRoot.Children.Add(CommonLabelsCanvas); LayoutRoot.Children.Add(AdditionalLabelsCanvas); this.Content = LayoutRoot; }
private void CreateCommonLabels(double[] screenTicksX) { Size renderSize = RenderSize; CommonLabelsCanvas.Children.Clear(); List <FrameworkElement> .Enumerator labelsEnumerator = labels.GetEnumerator(); //IEnumerator<UIElement> canvasEnumerator= CommonLabelsCanvas.Children.GetEnumerator(); for (int i = 0; i < labels.Count; i++) { FrameworkElement tickLabel = labels[i]; Size tickLabelSize = new Size(tickLabel.ActualWidth, tickLabel.ActualHeight); StackCanvas.SetCoordinate(tickLabel, screenTicksX[i] - getSize(tickLabelSize) / 2); CommonLabelsCanvas.Children.Add(tickLabel); } }
private void CreateCommonLabels(double[] screenTicksX) { Size renderSize = RenderSize; CommonLabelsCanvas.Children.Clear(); List <FrameworkElement> .Enumerator labelsEnumerator = labels.GetEnumerator(); //IEnumerator<UIElement> canvasEnumerator= CommonLabelsCanvas.Children.GetEnumerator(); for (int i = 0; i < labels.Count; i++) { FrameworkElement tickLabel = labels[i]; Size tickLabelSize = new Size(tickLabel.ActualWidth, tickLabel.ActualHeight); StackCanvas.SetCoordinate(tickLabel, screenTicksX[i] - getSize(tickLabelSize) / 2); CommonLabelsCanvas.Children.Add(tickLabel); //if (i >= allocatedLabels) //{ // CommonLabelsCanvas.Children.Add(tickLabel); //} //else //{ // labelsEnumerator.MoveNext(); // i = CommonLabelsCanvas.Children.IndexOf(labelsEnumerator.Current); // //labelsEnumerator.Current = tickLabel; // //CommonLabelsCanvas.Children. // CommonLabelsCanvas.Children[i] = tickLabel; //} } //for (int j = allocatedLabels-1; j >= ticks.Length; j--) { // CommonLabelsCanvas.Children.RemoveAt(j); //} //allocatedLabels = CommonLabelsCanvas.Children.Count; }
private double staticAxisMargin = 1; // px private void DoDrawCommonLabels(double[] screenTicksX) { Size renderSize = RenderSize; commonLabelsCanvas.Children.Clear(); #if DEBUG if (labels != null) { foreach (FrameworkElement item in labels) { if (item != null) { Debug.Assert(item.Parent == null); } } } #endif double minCoordUnsorted = ToScreen(range.Min); double maxCoordUnsorted = ToScreen(range.Max); double minCoord = Math.Min(minCoordUnsorted, maxCoordUnsorted); double maxCoord = Math.Max(minCoordUnsorted, maxCoordUnsorted); double maxCoordDiff = (maxCoord - minCoord) / labels.Length / 2.0; double minCoordToAdd = minCoord - maxCoordDiff; double maxCoordToAdd = maxCoord + maxCoordDiff; for (int i = 0; i < ticks.Length; i++) { FrameworkElement tickLabel = (FrameworkElement)labels[i]; if (tickLabel == null) { continue; } Debug.Assert(((FrameworkElement)tickLabel).Parent == null); tickLabel.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); double screenX = screenTicksX[i]; double coord = screenX; tickLabel.HorizontalAlignment = HorizontalAlignment.Center; tickLabel.VerticalAlignment = VerticalAlignment.Center; if (isStaticAxis) { // getting real size of label tickLabel.Measure(renderSize); Size tickLabelSize = tickLabel.DesiredSize; if (Math.Abs(screenX - minCoord) < maxCoordDiff) { coord = minCoord + staticAxisMargin; if (placement.IsBottomOrTop()) { tickLabel.HorizontalAlignment = HorizontalAlignment.Left; } else { tickLabel.VerticalAlignment = VerticalAlignment.Top; } } else if (Math.Abs(screenX - maxCoord) < maxCoordDiff) { coord = maxCoord - getSize(tickLabelSize) / 2 - staticAxisMargin; if (!placement.IsBottomOrTop()) { tickLabel.VerticalAlignment = VerticalAlignment.Bottom; coord = maxCoord - staticAxisMargin; } } } // label is out of visible area if (coord < minCoord || coord > maxCoord) { continue; } if (coord.IsNaN()) { continue; } StackCanvas.SetCoordinate(tickLabel, coord); commonLabelsCanvas.Children.Add(tickLabel); } }
private double staticAxisMargin = 1; // px private void DrawCommonLabels(double[] screenTicksX) { Size renderSize = RenderSize; commonLabelsCanvas.Children.Clear(); #if DEBUG if (labels != null) { foreach (FrameworkElement item in labels) { Debug.Assert(item.Parent == null); } } #endif double minCoordUnsorted = ToScreen(range.Min); double maxCoordUnsorted = ToScreen(range.Max); double minCoord = Math.Min(minCoordUnsorted, maxCoordUnsorted); double maxCoord = Math.Max(minCoordUnsorted, maxCoordUnsorted); double maxCoordDiff = (maxCoord - minCoord) / labels.Length / 2.0; double minCoordToAdd = minCoord - maxCoordDiff; double maxCoordToAdd = maxCoord + maxCoordDiff; for (int i = 0; i < ticks.Length; i++) { UIElement tickLabel = labels[i]; Debug.Assert(((FrameworkElement)tickLabel).Parent == null); if (tickLabel == null) { continue; } // getting real size of label tickLabel.Measure(renderSize); Size tickLabelSize = tickLabel.DesiredSize; double screenX = screenTicksX[i]; double coord = screenX; if (isStaticAxis) { if (Math.Abs(screenX - minCoord) < maxCoordDiff) { coord = screenX + staticAxisMargin; } else if (Math.Abs(screenX - maxCoord) < maxCoordDiff) { coord = screenX - getSize(tickLabelSize) - staticAxisMargin; } } if (coord < minCoordToAdd || coord > maxCoordToAdd) { continue; } if (coord.IsNaN()) { continue; } StackCanvas.SetCoordinate(tickLabel, coord); commonLabelsCanvas.Children.Add(tickLabel); } }
internal void UpdateUI() { if (range.IsEmpty) { return; } if (transform == null) { return; } if (independent) { InitTransform(RenderSize); } bool isHorizontal = Placement == AxisPlacement.Bottom || Placement == AxisPlacement.Top; if (transform.ScreenRect.Width == 0 && isHorizontal || transform.ScreenRect.Height == 0 && !isHorizontal) { return; } if (!IsMeasureValid) { InvalidateMeasure(); } Range <double> currentDoubleRange = new Range <double>(convertToDouble(range.Min), convertToDouble(range.Max)); bool sameLength = Math.Abs(cachedPartLength - currentDoubleRange.GetLength()) / cachedPartLength < 0.01 || cachedPartLength == 0; if (UseSmoothPanning && sameLength) { Debug.WriteLine(Placement + " " + range + " " + axisLongRange); // current range is included into axisLongRange if (currentDoubleRange < axisLongRange) { var axisContent = (FrameworkElement)mainGrid.Children[0]; double leftScreen; if (placement.IsBottomOrTop()) { leftScreen = ((axisLongRange.Min - currentDoubleRange.Min) / currentDoubleRange.GetLength() + 1) * getSize(transform.ScreenRect.Size); } else { leftScreen = -((axisLongRange.Min - currentDoubleRange.Min) / currentDoubleRange.GetLength() + 1) * getSize(transform.ScreenRect.Size); } StackCanvas.SetCoordinate(axisContent, leftScreen); // this call should be commented // double rightScreen = ((axisLongRange.Max - currentDoubleRange.Max) / currentDoubleRange.GetLength() + 1) * getSize(transform.ScreenRect.Size); // StackCanvas.SetEndCoordinate(axisContent, rightScreen); } else { double length = currentDoubleRange.GetLength(); cachedPartLength = length; // cached axis part is three times longer double min = currentDoubleRange.Min - length; double max = currentDoubleRange.Max + length; Range <T> widerRange = new Range <T>(convertFromDouble(min), convertFromDouble(max)); axisLongRange = new Range <double>(min, max); // rebuild entire ticks FillParts(widerRange); Debug.WriteLine("не шире " + Placement + " " + widerRange); originalScreenTicks = screenTicks.ToArray(); } // updating screen ticks (for axis grid) // 3 is a ratio of cached area to visible area double shift = (currentDoubleRange.Min - (axisLongRange.Min + axisLongRange.GetLength() / 3)) * getSize(transform.ScreenRect.Size); if (!placement.IsBottomOrTop()) { shift *= -1; } screenTicks = originalScreenTicks.ToArray(); for (int i = 0; i < originalScreenTicks.Length; i++) { screenTicks[i] -= shift; } } else { FillParts(range); } ScreenTicksChanged.Raise(this); }