private void Update() { if (!IsChartInitialized) { return; } Func <double, string> defFormatter = x => x.ToString(CultureInfo.InvariantCulture); var completed = (Value - From) / (To - From); var t = 0d; if (double.IsNaN(completed) || double.IsInfinity(completed)) { completed = 0; } completed = completed > 1 ? 1 : (completed < 0 ? 0 : completed); var angle = Uses360Mode ? 360 : 180; if (!_isCallBack && Uses360Mode) { Grid.SetRow(Min, 0); Grid.SetRow(Max, 0); Grid.SetRow(LeftLabel, 1); Grid.SetRow(RightLabel, 1); //LeftLabel.UpdateLayout(); //RightLabel.UpdateLayout(); GridLeft.Children.Remove(GridLeftBoarder); GridLeftBoarder = new Border { BorderThickness = new Thickness(1, 0, 0, 0), BorderBrush = _titleColor }; GridLeft.Children.Add(GridLeftBoarder); Grid.SetRow(GridLeftBoarder, 1); GridRight.Children.Remove(GridRightBoarder); Panel.SetZIndex(GridLeftBoarder, 1); Canvas.SetLeft(GridLeftBoarder, ActualWidth / 2); _isCallBack = true; } if (!Uses360Mode) { LeftLabel.Text = (LabelFormatter ?? defFormatter)(From); RightLabel.Text = (LabelFormatter ?? defFormatter)(To); LeftLabel.UpdateLayout(); RightLabel.UpdateLayout(); //LeftLabel.Visibility = LabelsVisibility; GridLeft.Visibility = LabelsVisibility; //RightLabel.Visibility = LabelsVisibility; GridRight.Visibility = LabelsVisibility; t = LeftLabel.ActualHeight; if (Icon != null) { Icon.Visibility = Visibility.Hidden; } } else { LeftLabel.Text = (LabelFormatter ?? defFormatter)(From); RightLabel.Text = (LabelFormatter ?? defFormatter)(To); LeftLabel.UpdateLayout(); RightLabel.UpdateLayout(); GridLeft.Visibility = LabelsVisibility; GridRight.Visibility = LabelsVisibility; //LeftLabel.Visibility = Visibility.Hidden; //RightLabel.Visibility = Visibility.Hidden; // t = GridLeft.ActualHeight; if (Icon != null) { Icon.Visibility = Visibility.Visible; } } double r, top; if (Uses360Mode) { //r = ActualWidth > ActualHeight ? ActualHeight : ActualWidth; //r = r / 2 - t; //r / 2 - 2 * t; r = ActualWidth > ActualHeight ? ActualHeight / 2 - t : ActualWidth / 2; top = ActualHeight / 2; } else { r = ActualWidth; if (ActualWidth > ActualHeight * 2) { r = ActualHeight * 2; } else { t = 0; } //r = r / 2 - 2 * t; r = r / 2; top = ActualHeight / 2 + r / 2; } if (r < 0) { r = 1; } PieBack.Radius = r; PieBack.InnerRadius = InnerRadius ?? r * .8; PieBack.RotationAngle = 270; PieBack.WedgeAngle = angle; Pie.Radius = PieBack.Radius * 0.96; Pie.InnerRadius = PieBack.InnerRadius * 1.06; Pie.RotationAngle = PieBack.RotationAngle; Canvas.SetLeft(PieBack, ActualWidth / 2); Canvas.SetTop(PieBack, top); Canvas.SetLeft(Pie, ActualWidth / 2); Canvas.SetTop(Pie, top); //Canvas.SetTop(LeftLabel, top); //Canvas.SetTop(RightLabel, top); //Canvas.SetRight(LeftLabel, ActualWidth / 2 + ( r + PieBack.InnerRadius ) / 2 - LeftLabel.ActualWidth / 2); //Canvas.SetRight(RightLabel, ActualWidth / 2 - ( r + PieBack.InnerRadius ) / 2 - RightLabel.ActualWidth / 2); MeasureTextBlock.FontSize = HighFontSize ?? Pie.InnerRadius * .4; if (Uses360Mode) { MeasureTextBlock.FontSize = Pie.InnerRadius * .6; } MeasureTextBlock.Text = (LabelFormatter ?? defFormatter)(Value); if (FontColor != null) { MeasureTextBlock.Foreground = FontColor; } MeasureTextBlock.UpdateLayout(); double ratio = Uses360Mode ? .3 : .4; MeasureTextBlockUnit.Text = (Uses360Mode ? "" : " ") + GaugeUnit; MeasureTextBlockUnit.FontSize = MeasureTextBlock.FontSize * ratio; MeasureTextBlockUnit.UpdateLayout(); Title.Text = GaugeTitle; Title.FontSize = MeasureTextBlock.FontSize * ratio; Title.UpdateLayout(); //LeftLabel.FontSize = MeasureTextBlock.FontSize * ratio; //RightLabel.FontSize = MeasureTextBlock.FontSize * ratio; //LeftLabel.UpdateLayout(); //RightLabel.UpdateLayout(); if (Uses360Mode) { double top360 = top - r - GridLeft.ActualHeight; //top - Gridleft.ActualHeight + ( r + PieBack.InnerRadius ) / 2; Canvas.SetTop(GridLeft, top360); Canvas.SetTop(GridRight, top360); Canvas.SetLeft(GridRight, (ActualWidth / 2) - GridRight.ActualWidth); Canvas.SetLeft(GridLeft, ActualWidth / 2); if (IconSource != null) { if (Icon == null) { Icon = new Image { Source = IconSource }; Icon.UpdateLayout(); Canvas.Children.Add(Icon); } Icon.Width = Icon.Height = Pie.InnerRadius * .5; Canvas.SetTop(Icon, top - PieBack.InnerRadius * 0.9); Canvas.SetLeft(Icon, (ActualWidth - Icon.Width) / 2); Icon.UpdateLayout(); } } else { LeftLabel.FontSize = Min.FontSize = MeasureTextBlock.FontSize * ratio * 0.6; Min.UpdateLayout(); LeftLabel.UpdateLayout(); Canvas.SetTop(GridLeft, top - GridLeft.ActualHeight); Canvas.SetLeft(GridLeft, ActualWidth / 2 - PieBack.InnerRadius); RightLabel.FontSize = Max.FontSize = MeasureTextBlock.FontSize * ratio * 0.6; Max.UpdateLayout(); RightLabel.UpdateLayout(); Canvas.SetTop(GridRight, top - GridRight.ActualHeight); Canvas.SetLeft(GridRight, ActualWidth / 2 + PieBack.InnerRadius - GridRight.ActualWidth); } GridLeft.UpdateLayout(); GridRight.UpdateLayout(); //August Lee if (Uses360Mode) { Canvas.SetTop(MeasureTextBlock, top - MeasureTextBlock.ActualHeight * .5); Canvas.SetLeft(MeasureTextBlock, ActualWidth / 2 - MeasureTextBlock.ActualWidth / 2); Canvas.SetTop(MeasureTextBlockUnit, top + (MeasureTextBlock.ActualHeight) * .5); Canvas.SetLeft(MeasureTextBlockUnit, ActualWidth / 2 - MeasureTextBlockUnit.ActualWidth / 2); Canvas.SetTop(Title, top + Title.ActualHeight + MeasureTextBlock.ActualHeight / 2); Canvas.SetLeft(Title, ActualWidth / 2 - Title.ActualWidth / 2); } else { Canvas.SetTop(MeasureTextBlock, top - (MeasureTextBlock.ActualHeight * 1.5)); Canvas.SetLeft(MeasureTextBlock, ActualWidth / 2 - MeasureTextBlock.ActualWidth / 2 - MeasureTextBlockUnit.ActualWidth / 2); Canvas.SetTop(MeasureTextBlockUnit, top - (MeasureTextBlock.ActualHeight * 0.5 + MeasureTextBlockUnit.ActualHeight * 1.2)); Canvas.SetLeft(MeasureTextBlockUnit, ActualWidth / 2 + MeasureTextBlock.ActualWidth / 2 - MeasureTextBlockUnit.ActualWidth / 2); Canvas.SetTop(Title, top - Title.ActualHeight); Canvas.SetLeft(Title, ActualWidth / 2 - Title.ActualWidth / 2); } var interpolatedColor = new Color { R = LinearInterpolation(FromColor.R, ToColor.R), G = LinearInterpolation(FromColor.G, ToColor.G), B = LinearInterpolation(FromColor.B, ToColor.B), A = LinearInterpolation(FromColor.A, ToColor.A) }; if (IsNew) { Pie.Fill = new SolidColorBrush(FromColor); Pie.WedgeAngle = 0; } if (DisableAnimations) { Pie.WedgeAngle = completed * angle; } else { Pie.BeginAnimation(PieSlice.WedgeAngleProperty, new DoubleAnimation(completed * angle, AnimationsSpeed)); } if (GaugeActiveFill == null) { ((SolidColorBrush)Pie.Fill).BeginAnimation(SolidColorBrush.ColorProperty, new ColorAnimation(interpolatedColor, AnimationsSpeed)); } else { Pie.Fill = GaugeActiveFill; } IsNew = false; }
private void Update() { if (!IsChartInitialized) { return; } Func <double, string> defFormatter = x => x.ToString(CultureInfo.InvariantCulture); var completed = (Value - From) / (To - From); var t = 0d; if (double.IsNaN(completed) || double.IsInfinity(completed)) { completed = 0; } completed = completed > 1 ? 1 : (completed < 0 ? 0 : completed); var angle = Wedge > 360 ? 360 : (Wedge < 0 ? 0 : Wedge); var fromAlpha = (360 - Wedge) * .5; var toAlpha = 360 - fromAlpha; LeftLabel.Visibility = Visibility.Hidden; RightLabel.Visibility = Visibility.Hidden; double r, top; r = ActualWidth > ActualHeight ? ActualHeight : ActualWidth; r = r / 2 - 2 * t; top = ActualHeight / 2; if (r < 0) { r = 1; } PieBack.Radius = r; PieBack.InnerRadius = InnerRadius ?? r * .6; PieBack.RotationAngle = 270; PieBack.WedgeAngle = angle; Pie.Radius = PieBack.Radius; Pie.InnerRadius = PieBack.InnerRadius; Pie.RotationAngle = PieBack.RotationAngle; Canvas.SetLeft(PieBack, ActualWidth / 2); Canvas.SetTop(PieBack, top); Canvas.SetLeft(Pie, ActualWidth / 2); Canvas.SetTop(Pie, top); Canvas.SetTop(LeftLabel, top); Canvas.SetTop(RightLabel, top); Canvas.SetRight(LeftLabel, ActualWidth / 2 + (r + PieBack.InnerRadius) / 2 - LeftLabel.ActualWidth / 2); Canvas.SetRight(RightLabel, ActualWidth / 2 - (r + PieBack.InnerRadius) / 2 - RightLabel.ActualWidth / 2); MeasureTextBlock.FontSize = HighFontSize ?? Pie.InnerRadius * .4; MeasureTextBlock.Text = (Value / 100).ToString("P"); MeasureTextBlock.SetCurrentValue(ForegroundProperty, GaugeActiveFill); MeasureTextBlock.UpdateLayout(); Canvas.SetTop(MeasureTextBlock, top * 2 - MeasureTextBlock.ActualHeight * 1.3); Canvas.SetLeft(MeasureTextBlock, ActualWidth / 2 - MeasureTextBlock.ActualWidth / 2); var interpolatedColor = new Color { R = LinearInterpolation(FromColor.R, ToColor.R), G = LinearInterpolation(FromColor.G, ToColor.G), B = LinearInterpolation(FromColor.B, ToColor.B), A = LinearInterpolation(FromColor.A, ToColor.A) }; if (IsNew) { Pie.Fill = new SolidColorBrush(FromColor); Pie.WedgeAngle = 0; } if (DisableAnimations) { Pie.WedgeAngle = completed * angle; } else { Pie.BeginAnimation(PieSlice.WedgeAngleProperty, new DoubleAnimation(completed * angle, AnimationsSpeed)); } var d = ActualWidth < ActualHeight ? ActualWidth : ActualHeight; Stick.Height = d * .5 * .8; Stick.Width = Stick.Height * .2; Canvas.SetLeft(Stick, ActualWidth * .5 - Stick.Width * .5); Canvas.SetTop(Stick, ActualHeight * .5 - Stick.Height * .9); var ticksHi = d * .35; var ticksHj = d * .3; var labelsHj = d * .3; #region 画Tick刻度 var ts = double.IsNaN(TicksStep) ? DecideInterval((To - From) / 5) : TicksStep; if (ts / (From - To) > 300) { throw new InvalidOperationException("TicksStep property is too small compared with the range in " + "the gauge, to avoid performance issues, please increase it."); } for (var i = From; i <= To; i += ts) { var alpha = LinearInterpolation(fromAlpha, toAlpha, From, To, i) + 90; var tick = new Line { X1 = ActualWidth * .5 + ticksHi * Math.Cos(alpha * Math.PI / 180), X2 = ActualWidth * .5 + ticksHj * Math.Cos(alpha * Math.PI / 180), Y1 = ActualHeight * .5 + ticksHi * Math.Sin(alpha * Math.PI / 180), Y2 = ActualHeight * .5 + ticksHj * Math.Sin(alpha * Math.PI / 180) }; Canvas.Children.Add(tick); tick.SetBinding(Shape.StrokeProperty, new Binding { Path = new PropertyPath(TicksForegroundProperty), Source = this }); tick.SetBinding(Shape.StrokeThicknessProperty, new Binding { Path = new PropertyPath(TicksStrokeThicknessProperty), Source = this }); } #endregion #region 画Lable刻度 var ls = double.IsNaN(LabelsStep) ? DecideInterval((To - From) / 5) : LabelsStep; if (ls / (From - To) > 300) { throw new InvalidOperationException("LabelsStep property is too small compared with the range in " + "the gauge, to avoid performance issues, please increase it."); } for (var i = From; i <= To; i += ls) { var alpha = LinearInterpolation(fromAlpha, toAlpha, From, To, i) + 90; var tick = new Line { X1 = ActualWidth * .5 + ticksHi * Math.Cos(alpha * Math.PI / 180), X2 = ActualWidth * .5 + labelsHj * Math.Cos(alpha * Math.PI / 180), Y1 = ActualHeight * .5 + ticksHi * Math.Sin(alpha * Math.PI / 180), Y2 = ActualHeight * .5 + labelsHj * Math.Sin(alpha * Math.PI / 180) }; Canvas.Children.Add(tick); var label = new TextBlock { Text = (LabelFormatter ?? defFormatter)(i) }; Canvas.Children.Add(label); label.UpdateLayout(); Canvas.SetLeft(label, alpha < 270 ? tick.X2 : (Math.Abs(alpha - 270) < 4 ? tick.X2 - label.ActualWidth * .5 : tick.X2 - label.ActualWidth)); Canvas.SetTop(label, tick.Y2); tick.SetBinding(Shape.StrokeProperty, new Binding { Path = new PropertyPath(TicksForegroundProperty), Source = this }); tick.SetBinding(Shape.StrokeThicknessProperty, new Binding { Path = new PropertyPath(TicksStrokeThicknessProperty), Source = this }); } #endregion MoveStick(); if (GaugeActiveFill == null) { ((SolidColorBrush)Pie.Fill).BeginAnimation(SolidColorBrush.ColorProperty, new ColorAnimation(interpolatedColor, AnimationsSpeed)); } else { Pie.Fill = GaugeActiveFill; } IsNew = false; }
private void Update() { if (!IsChartInitialized) { return; } Func <double, string> defFormatter = x => x.ToString(CultureInfo.InvariantCulture); var completed = (Value - From) / (To - From); var t = 0d; if (double.IsNaN(completed) || double.IsInfinity(completed)) { completed = 0; } completed = completed > 1 ? 1 : (completed < 0 ? 0 : completed); var angle = Uses360Mode ? 360 : 180; if (!Uses360Mode) { LeftLabel.Text = (LabelFormatter ?? defFormatter)(From); RightLabel.Text = (LabelFormatter ?? defFormatter)(To); LeftLabel.UpdateLayout(); RightLabel.UpdateLayout(); LeftLabel.Visibility = LabelsVisibility; RightLabel.Visibility = LabelsVisibility; t = LeftLabel.ActualHeight; } else { LeftLabel.Visibility = Visibility.Hidden; RightLabel.Visibility = Visibility.Hidden; } double r, top; if (Uses360Mode) { r = ActualWidth > ActualHeight ? ActualHeight : ActualWidth; r = r / 2 - 2 * t; top = ActualHeight / 2; } else { r = ActualWidth; if (ActualWidth > ActualHeight * 2) { r = ActualHeight * 2; } else { t = 0; } r = r / 2 - 2 * t; top = ActualHeight / 2 + r / 2; } if (r < 0) { r = 1; } PieBack.Radius = r; PieBack.InnerRadius = InnerRadius ?? r * .6; PieBack.RotationAngle = 270; PieBack.WedgeAngle = angle; Pie.Radius = PieBack.Radius; Pie.InnerRadius = PieBack.InnerRadius; Pie.RotationAngle = PieBack.RotationAngle; Canvas.SetLeft(PieBack, ActualWidth / 2); Canvas.SetTop(PieBack, top); Canvas.SetLeft(Pie, ActualWidth / 2); Canvas.SetTop(Pie, top); Canvas.SetTop(LeftLabel, top); Canvas.SetTop(RightLabel, top); Canvas.SetRight(LeftLabel, ActualWidth / 2 + (r + PieBack.InnerRadius) / 2 - LeftLabel.ActualWidth / 2); Canvas.SetRight(RightLabel, ActualWidth / 2 - (r + PieBack.InnerRadius) / 2 - RightLabel.ActualWidth / 2); MeasureTextBlock.FontSize = HighFontSize ?? Pie.InnerRadius * .4; MeasureTextBlock.Text = (LabelFormatter ?? defFormatter)(Value); MeasureTextBlock.UpdateLayout(); Canvas.SetTop(MeasureTextBlock, top - MeasureTextBlock.ActualHeight * (Uses360Mode ? .5 : 1)); Canvas.SetLeft(MeasureTextBlock, ActualWidth / 2 - MeasureTextBlock.ActualWidth / 2); var interpolatedColor = new Color { R = LinearInterpolation(FromColor.R, ToColor.R), G = LinearInterpolation(FromColor.G, ToColor.G), B = LinearInterpolation(FromColor.B, ToColor.B), A = LinearInterpolation(FromColor.A, ToColor.A) }; if (IsNew) { Pie.Fill = new SolidColorBrush(FromColor); Pie.WedgeAngle = 0; } if (DisableAnimations) { Pie.WedgeAngle = completed * angle; } else { Pie.BeginAnimation(PieSlice.WedgeAngleProperty, new DoubleAnimation(completed * angle, AnimationsSpeed)); } if (GaugeActiveFill == null) { ((SolidColorBrush)Pie.Fill).BeginAnimation(SolidColorBrush.ColorProperty, new ColorAnimation(interpolatedColor, AnimationsSpeed)); } else { Pie.Fill = GaugeActiveFill; } IsNew = false; }
private void Update() { if (!IsChartInitialized) { return; } var ms = new Size(double.PositiveInfinity, double.PositiveInfinity); Measure(ms); Canvas.Width = Width; Canvas.Height = Height; Func <double, string> defFormatter = x => x.ToString(CultureInfo.InvariantCulture); var completed = (Value - From) / (To - From); var t = 0d; if (double.IsNaN(completed) || double.IsInfinity(completed)) { completed = 0; } completed = completed > 1 ? 1 : (completed < 0 ? 0 : completed); var angle = Uses360Mode ? 360 : 180; if (!Uses360Mode) { LeftLabel.Text = (LabelFormatter ?? defFormatter)(From); RightLabel.Text = (LabelFormatter ?? defFormatter)(To); LeftLabel.Visibility = LabelsVisibility; RightLabel.Visibility = LabelsVisibility; t = LeftLabel.ActualHeight; } else { LeftLabel.Visibility = Visibility.Collapsed; RightLabel.Visibility = Visibility.Collapsed; } double r, top; if (Uses360Mode) { r = ActualWidth > ActualHeight ? ActualHeight: ActualWidth; r = r / 2 - 2 * t; top = ActualHeight / 2; } else { r = ActualWidth; if (ActualWidth > ActualHeight * 2) { r = ActualHeight * 2; } else { t = 0; } r = r / 2 - 2 * t; top = ActualHeight / 2 + r / 2; } if (r < 0) { r = 1; } PieBack.Height = Canvas.ActualHeight; PieBack.Width = Canvas.ActualWidth; Pie.Height = Canvas.ActualHeight; Pie.Width = Canvas.ActualWidth; PieBack.Radius = r; PieBack.InnerRadius = double.IsNaN(InnerRadius) ? r * .6 : InnerRadius; PieBack.RotationAngle = 270; PieBack.WedgeAngle = angle; Pie.Radius = PieBack.Radius; Pie.InnerRadius = PieBack.InnerRadius; Pie.RotationAngle = PieBack.RotationAngle; Pie.YOffset = top - ActualHeight / 2; PieBack.YOffset = top - ActualHeight / 2; Canvas.SetTop(LeftLabel, top); Canvas.SetTop(RightLabel, top); LeftLabel.Measure(ms); RightLabel.Measure(ms); Canvas.SetLeft(LeftLabel, Canvas.ActualWidth * .5 - (Pie.InnerRadius + (Pie.Radius - Pie.InnerRadius) * .5 + LeftLabel.DesiredSize.Width * .5)); Canvas.SetLeft(RightLabel, Canvas.ActualWidth * .5 + (Pie.InnerRadius + (Pie.Radius - Pie.InnerRadius) * .5 - RightLabel.DesiredSize.Width * .5)); MeasureTextBlock.FontSize = double.IsNaN(HighFontSize) ? Pie.InnerRadius * .4 : HighFontSize; MeasureTextBlock.Text = (LabelFormatter ?? defFormatter)(Value); MeasureTextBlock.Measure(ms); Canvas.SetTop(MeasureTextBlock, top - MeasureTextBlock.DesiredSize.Height * (Uses360Mode ? .5 : 1)); Canvas.SetLeft(MeasureTextBlock, ActualWidth / 2 - MeasureTextBlock.DesiredSize.Width / 2); var interpolatedColor = new Color { R = LinearInterpolation(FromColor.R, ToColor.R), G = LinearInterpolation(FromColor.G, ToColor.G), B = LinearInterpolation(FromColor.B, ToColor.B), A = LinearInterpolation(FromColor.A, ToColor.A) }; if (IsNew) { Pie.Fill = new SolidColorBrush(FromColor); Pie.WedgeAngle = 0; } Pie.BeginDoubleAnimation(nameof(PieSlice.WedgeAngle), completed * angle, AnimationsSpeed); if (GaugeActiveFill == null) { ((SolidColorBrush)Pie.Fill).BeginColorAnimation(nameof(SolidColorBrush.Color), interpolatedColor, AnimationsSpeed); } else { Pie.Fill = GaugeActiveFill; } IsNew = false; }