- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试调整 WPF 4 Unleashed 一书中的饼图 ProgressBar 使其看起来像一个 donut 。我觉得我已经完成了一半,但我不知道如何解决最后一个问题。
这是一张说明我想要什么以及我已经设法实现的图片:
所以我的问题是,我怎样才能让它看起来像我想要的那样?
下面是我正在使用的相关 xaml:
<ControlTemplate x:Key="DonutProgressBar" TargetType="{x:Type ProgressBar}">
<ControlTemplate.Resources>
<conv:ValueMinMaxToIsLargeArcConverter x:Key="ValueMinMaxToIsLargeArcConverter" />
<conv:ValueMinMaxToPointConverter x:Key="ValueMinMaxToPointConverter" />
</ControlTemplate.Resources>
<Grid>
<Viewbox>
<Grid Width="20" Height="20">
<Ellipse x:Name="Background"
Stroke="{TemplateBinding BorderBrush}"
StrokeThickness="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderThickness.Top}"
Width="20"
Height="20"
Fill="{TemplateBinding Background}" />
<Path x:Name="Donut"
Stroke="{TemplateBinding Foreground}"
StrokeThickness="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderThickness.Top}">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="10,0">
<ArcSegment Size="10,10" SweepDirection="Clockwise">
<ArcSegment.Point>
<MultiBinding Converter="{StaticResource ValueMinMaxToPointConverter}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Minimum" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum" />
</MultiBinding>
</ArcSegment.Point>
<ArcSegment.IsLargeArc>
<MultiBinding Converter="{StaticResource ValueMinMaxToIsLargeArcConverter}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Minimum" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum" />
</MultiBinding>
</ArcSegment.IsLargeArc>
</ArcSegment>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</Grid>
</Viewbox>
</Grid>
</ControlTemplate>
...
<ProgressBar Width="70" Height="70" Value="40" Template="{StaticResource DonutProgressBar}" Background="{x:Null}" BorderBrush="#1F000000" BorderThickness="6,6,1,1" />
...和转换器:
public class ValueMinMaxToPointConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
double value = (double)values[0];
double minimum = (double)values[1];
double maximum = (double)values[2];
double current = (value / (maximum - minimum)) * 360;
if (current == 360)
current = 359.999;
current = current - 90;
current = current * (Math.PI / 180.0);
double x = 10 + 10 * Math.Cos(current);
double y = 10 + 10 * Math.Sin(current);
return new Point(x, y);
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
public class ValueMinMaxToIsLargeArcConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
double value = (double)values[0];
double minimum = (double)values[1];
double maximum = (double)values[2];
return ((value * 2) >= (maximum - minimum));
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
最佳答案
这里真正的问题是 WPF 中缺少 Arc
控件。与其试图硬塞现有的框架来满足您的要求,为什么不自己添加呢?网上有许多 WPF Arc 实现,它们看起来都非常相似,只要确保您选择一个在角度 DP 更改时更新视觉效果的实现即可。这应该可以很好地满足您的目的:
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);
}
}
为了维护一个干净的架构,我更喜欢将自定义形状放在一个单独的类库中,并引用 PresentationFramework,这样做还允许您通过在项目中放置以下行来删除命名空间,如 this page 中所述:
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "YourNamespace")]
您现在有一个可重复使用的 Arc 形状,您可以像使用椭圆一样使用它,因此请将您的整个路径 XAML 替换为如下内容:
<Arc
Stroke="{TemplateBinding Foreground}"
StrokeThickness="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderThickness.Top}"
StartAngle="90" EndAngle="-45" />
结果:
显然,我在这里对开始和结束角度进行了硬编码,但是根据您已经完成的工作,我相信您可以轻松编写一个简单的多转换器来计算 value/min 的角度/最大。
关于c# - WPF donut 进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36752183/
我一直致力于使用 highcharts 复制此图表设计。 我一直在玩 jsfiddle 试图获得想要的结果,但问题是我无法设法获得百分比未填充的白色区域,也无法获得条形之间的间隙。 使用 highch
我正在使用 Steema.TeeChart for .Net(用 C# 编码) 有人知道如何在圆环图的饼图内做标签吗? 它应该看起来像: http://www.steema.com/uploads/g
当点击内部 donut 时,我试图将内部和其他 donut 滑出。在下面的链接中,只切掉了内部 donut 。 http://jsfiddle.net/bvL0r6tq/ 我试图通过点选择选择外部切片
我正在尝试将内部 donut 名称设置为 highchart 中外部 donut 工具提示的标题。任何人都可以帮我解决这个问题。在示例中,内部饼图上显示的链接镶边应显示为外部 donut 工具提示中所
我正在使用 jqplot 设置一个具有两个级别的圆环图,但有两个问题,我偷偷怀疑它们是相关的。 当我将设置保留为默认设置时,它会正确显示,但一旦我开始设置直径、内径等。尺寸适用于内部和外部图表,并且它
我想制作一个 donut 风格的饼图,在特定的 donut 扇区带有弯曲的标签,就像这个: 在此模型中,用户单击了“Raphael.js”扇区。现在对于单击的扇区,还应该有一个事件处理程序,负责在饼图
我是编程新手,如果问题很愚蠢,我很抱歉。我正在用 chart.js 做一些图形. 我已经成功地通过 onclick 事件在另一个内部创建了一个 donut ,我遇到的问题是它为每次点击生成一个 don
您好,我想实现一个像这样的 donut 菜单 http://dribbble.com/shots/610433-Wheel-Nav我知道有一种在 css3 中制作 donut 的简单方法。 .doug
我创建了一个带有 highcharts 的饼图,效果很好。现在我想做的是当我悬停一个区域时,我想突出显示它的 parent 和 child ,并在工具提示中显示他们的所有数据。 这是我的图表: htt
我正在尝试增加圆环图的内半径,并且还能够在圆环图内写入。 $scope.donut = new RGraph.Pie('myDonut', $scope.donutData) .
我有一个简单的 SVG donut ,其中使用 stroke-dashoffset="xx"放置了 5 个相等的切片。 donut 本身看起来不错,但是当我尝试为每个切片添加一些悬停更改时,例如,简单
板级: import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.geom.Ellipse2D; import
请帮我修改代码。我使用 D3 v5.7.0 并尝试绘制 donut 。 现场演示 is here. 我的代码在这里: const dataset = [ [ 5, 3 ] ]; const s
我使用 highchart 库开发了一个圆环图。我需要在 donut 的内部添加一个标签。 预期结果: JS: $(function () { $('#container8').highcha
我在 Highcharts 中对 donut 中的馅饼很感兴趣,但我似乎无法显示图例或共享工具提示。工作正常with non-shared tooltips : tooltip: {
我创建了一个圆环图,如下所示: 我生成的 donut chart 应采用以下方式: 我的问题是,我怎样才能用图像实现线条(它们在第二个屏幕截图中四舍五入) 供引用,这是我编写的代码: public c
我有一个 2D map ,它在边缘处环绕。因此,如果您离开右边缘,您将重新出现在 map 的左侧。其他三个边也是如此。 这是我用来在点范围内查找元素的 KDTree 的可继承问题。通常,您会检查超球体
我正在使用 Plotly 来绘制 Donut Plot。下面你可以看到我的数据 df1% plot_ly(labels = ~manuf, values = ~count) fig % add_pie
我正在尝试为圆圈内的点生成一个分布,其中有更多的点朝向中心,但对于 donut 形状 我可以制作一个均匀分布的 donut 形状 (1),或者一个有更多点朝向中心的圆圈 (2),但不能制作一个有这么多
http://www.mediafire.com/view/z8ad4pedqr7twbl/donut.png 我想像那个图像一样绘制这个 donut 。我已经使用 raphaeljs 来绘制它。但是
我是一名优秀的程序员,十分优秀!