雷达图,也称为蜘蛛网图或星形图,是一种展示多变量数据的图表类型。尽管它不如柱状图或折线图那样常见,但雷达图在某些特定场景下非常有用,比如展示不同维度的性能指标或进行多变量比较分析。本文将介绍一个开源库Manufaktura.Controls中的雷达图实现,以及如何在WPF和ASP.NET MVC中使用它。
Manufaktura.Controls是一个开源的.NET库,它提供了音乐符号组件和其他有用的工具和控件。这个库以其音乐符号组件而闻名,但同时也包含了一些跨平台的图表实现,比如雷达图。
Manufaktura.Controls中的雷达图实现遵循了跨平台的设计原则。基础类RadarChartRenderer
负责处理大部分的计算工作,比如坐标轴、样本点等元素的位置。然后,特定平台的类负责在计算出的坐标上进行绘制。
在WPF中,雷达图是通过一个名为WPFRadarChart
的渲染器实现的,它在Canvas
元素上绘制图表。这个渲染器实现了RadarChartRenderer
的抽象方法,包括绘制坐标轴线的方法。
以下是一个绘制坐标轴线的示例代码:
protected override void DrawAxisLine(Primitives.Point start, Primitives.Point end)
{
var line = new Line();
line.SetBinding(Shape.StrokeProperty, new Binding(nameof(RadialChart.AxisStroke)) { Source = Control });
line.SetBinding(Shape.StrokeThicknessProperty, new Binding(nameof(RadialChart.AxisStrokeThickness)) { Source = Control });
line.X1 = start.X;
line.Y1 = start.Y;
line.X2 = end.X;
line.Y2 = end.Y;
Canvas.Children.Add(line);
}
这段代码展示了如何创建一个Line
对象并将其添加到画布上。通过数据绑定机制,用户可以拖动图表上的样本点,并且值的变化会立即反映在模型中。
Manufaktura.Controls的架构允许开发者使用单一代码库快速在其他平台上实现雷达图。作者创建了一个名为HtmlSvgRadarChartRenderer
的类作为架构的证明。这个类将图表渲染为HTML SVG元素。
以下是绘制坐标轴线的示例代码:
protected override void DrawAxisLine(Point start, Point end)
{
var element = new XElement(
"line",
new XAttribute("x1", start.X.ToStringInvariant()),
new XAttribute("y1", start.Y.ToStringInvariant()),
new XAttribute("x2", end.X.ToStringInvariant()),
new XAttribute("y2", end.Y.ToStringInvariant()),
new XAttribute("style", Control.AxisLinePen.ToCss())
);
Canvas.Add(element);
}
此外,还需要编写Razor扩展以便在视图中使用图表:
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification="This is an appropriate nesting of generic types")]
public static MvcHtmlString RadialChartFor(this HtmlHelper htmlHelper, Expression> expression, HtmlRadarChartRendererSettings settings)
{
if (expression == null)
throw new ArgumentNullException(nameof(expression));
if (settings == null)
throw new ArgumentNullException(nameof(settings));
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
RadarChartSample[] samples = metadata.Model == null ? null : metadata.Model as RadarChartSample[];
return RadialChartHelper(htmlHelper, samples, settings);
}
private static MvcHtmlString RadialChartHelper(HtmlHelper helper, RadarChartSample[] samples, HtmlRadarChartRendererSettings settings)
{
var xElement = new XElement("svg");
xElement.Add(new XAttribute("style", $"width:{settings.Width.ToStringInvariant()}px; height:{settings.Height.ToStringInvariant()}px;"));
new HtmlSvgRadarChartRenderer(settings, xElement).RedrawChart(samples);
return MvcHtmlString.Create(xElement.ToString());
}
现在可以将控件添加到视图中:
<div>
@Html.RadialChartFor(x => x.Samples, Model.RadialChartSettings)
</div>