问题描述
我正在尝试在WPF中创建一个甜甜圈图,并使用此有用的先前答案.
I'm trying to create a doughnut chart in WPF and using this helpful previous answer.
但是,当前StartAngle从3点钟位置开始,例如
However, currently the StartAngle starts from the 3 o'clock position e.g.
如何更改此代码,以便StartAngle从12点钟位置开始,并且角度沿顺时针方向进行测量,例如
How can I change this code so that the StartAngle starts from the 12 o'clock position and the angle measures clockwise e.g.
1] StartAngle = 0,EndAngle = 90 =>覆盖右上角.
1] StartAngle = 0, EndAngle = 90 => covers top right corner.
2] StartAngle = 0,EndAngle = 180 =>覆盖了右半部分.
2] StartAngle = 0, EndAngle = 180 => covers right half.
3] StartAngle = 0,EndAngle = 270 =>覆盖了图表的四分之三.
3] StartAngle = 0, EndAngle = 270 => covers three quarters of the chart.
我尝试将SweepDirection.Counterclockwise
更改为SweepDirection.Clockwise
,但这不起作用.我还尝试在Arc类中添加ScaleTransform
和RotateTransform
,如下所示.
I've tried changing the SweepDirection.Counterclockwise
to SweepDirection.Clockwise
but that doesn't work. I've also tried adding a ScaleTransform
and RotateTransform
in my Arc class as shown below.
WPF代码:
<Viewbox Stretch="Uniform" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid Height="100" Width="200">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle x:Name="divider" Fill="DimGray" Width="2" VerticalAlignment="Stretch" Height="70" Grid.Column="1" Grid.RowSpan="2"/>
<notifications1:Arc
Grid.Column="0"
Stroke="DimGray"
StrokeThickness="5"
StartAngle="0" EndAngle="359.999"
Margin="20"/>
<notifications1:Arc
Grid.Column="0"
Stroke="{Binding DaySalesPercentage, Converter={StaticResource StorePerformanceToColourConverter}}"
StrokeThickness="5"
StartAngle="0" EndAngle="{Binding DaySalesPercentage, Converter={StaticResource StorePerformanceToAngleConverter}}"
Margin="20"/>
<Label Content="sales remaining today"
x:Name="testing"
Foreground="{Binding IsDaySalesPercentageAvailable, Converter={StaticResource UnavailableStorePerformanceToColourConverter}}"
HorizontalContentAlignment="Center"
FontSize="9"
FontWeight="DemiBold"
VerticalAlignment="Top"
Margin="0,0,0,0"
Grid.Column="0"/>
<Label Content="{Binding DaySalesPercentageLabel}"
x:Name="DaySalesPercentageLabel1"
Foreground="{Binding IsDaySalesPercentageAvailable, Converter={StaticResource UnavailableStorePerformanceToColourConverter}}"
HorizontalContentAlignment="Center"
FontSize="20"
FontWeight="DemiBold"
VerticalAlignment="Top"
Margin="0,28,0,0"
Grid.Column="0"/>
<Label Content="-£60"
x:Name="DaySalesPercentageLabel2"
Foreground="{Binding IsDaySalesPercentageAvailable, Converter={StaticResource UnavailableStorePerformanceToColourConverter}}"
HorizontalContentAlignment="Center"
FontSize="10"
FontWeight="DemiBold"
VerticalAlignment="Top"
Margin="0,50,0,0"
Grid.Column="0"/>
</Grid>
</Viewbox>
Arc.cs:
public class Arc : Shape
{
public double StartAngle
{
get { return (double)GetValue(StartAngleProperty); }
set { SetValue(StartAngleProperty, value); }
}
// Using a DependencyProperty as the backing store for StartAngle. This enables animation, styling, binding, etc...
public static readonly DependencyProperty StartAngleProperty =
DependencyProperty.Register("StartAngle", typeof(double), typeof(Arc), new PropertyMetadata(0.0, AnglesChanged));
public double EndAngle
{
get { return (double)GetValue(EndAngleProperty); }
set { SetValue(EndAngleProperty, value); }
}
// Using a DependencyProperty as the backing store for EndAngle. This enables animation, styling, binding, etc...
public static readonly DependencyProperty EndAngleProperty =
DependencyProperty.Register("EndAngle", typeof(double), typeof(Arc), new PropertyMetadata(0.0, AnglesChanged));
protected override Geometry DefiningGeometry
{
get
{
return GetArcGeometry();
}
}
private static void AnglesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var arc = d as Arc;
if (arc != null)
arc.InvalidateVisual();
}
private Geometry GetArcGeometry()
{
Point startPoint = PointAtAngle(Math.Min(StartAngle, EndAngle));
Point endPoint = PointAtAngle(Math.Max(StartAngle, EndAngle));
Size arcSize = new Size(Math.Max(0, (RenderSize.Width - StrokeThickness) / 2),
Math.Max(0, (RenderSize.Height - StrokeThickness) / 2));
bool isLargeArc = Math.Abs(EndAngle - StartAngle) > 180;
StreamGeometry geom = new StreamGeometry();
using (StreamGeometryContext context = geom.Open())
{
context.BeginFigure(startPoint, false, false);
context.ArcTo(endPoint, arcSize, 0, isLargeArc,
SweepDirection.Counterclockwise, true, false);
}
geom.Transform = new TranslateTransform(StrokeThickness / 2, StrokeThickness / 2);
return geom;
}
private Point PointAtAngle(double angle)
{
double radAngle = angle * (Math.PI / 180);
double xRadius = (RenderSize.Width - StrokeThickness) / 2;
double yRadius = (RenderSize.Height - StrokeThickness) / 2;
double x = xRadius + xRadius * Math.Cos(radAngle);
double y = yRadius - yRadius * Math.Sin(radAngle);
return new Point(x, y);
}
}
我尝试添加以下内容:
<notifications1:Arc
Grid.Column="0"
Stroke="{Binding DaySalesPercentage, Converter={StaticResource StorePerformanceToColourConverter}}"
StrokeThickness="5"
StartAngle="0" EndAngle="{Binding DaySalesPercentage, Converter={StaticResource StorePerformanceToAngleConverter}}"
Margin="20">
<notifications1:Arc.RenderTransform>
<TransformGroup>
<!-- Triple the size (scale) of the button in the Y direction. -->
<ScaleTransform ScaleX="-1" ScaleY="1" />
<!-- Rotate the button by 45 degrees. -->
<RotateTransform Angle="90" />
</TransformGroup>
</notifications1:Arc.RenderTransform>
</notifications1:Arc>
像这样旋转和移动圆弧:
Which rotates and moves the arc like this:
推荐答案
您几乎明白了
只需使用LayoutTransform
而不是RenderTransform
这是使用LayoutTransform显示的EndAngle = 120:
here is a display of EndAngle = 120 with LayoutTransform:
这篇关于更改自定义甜甜圈图的起始角度和方向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!