我有一个类型的集合MyType { double X, double Y, string Text }
。
如何将其显示为带有 X、Y 坐标的点(或标记)以及带有 Text 作为文本的标签?
- 标签必须经常看到 - 所以没有工具提示。
- Text 属性因点而异。
我有一个类型的集合MyType { double X, double Y, string Text }
。
如何将其显示为带有 X、Y 坐标的点(或标记)以及带有 Text 作为文本的标签?
好吧,解决方案是使用文本依赖属性制作自己的标记,然后将映射添加到该属性。它涉及到这样的事情(它看起来有点肮脏,但它说明了主要思想)。它是带有标签的脉冲序列,每个脉冲开始时都有持续时间:
没有次要属性的自定义标记类(我不是从 ShapeElementPointMarker 派生的,因为最后一个对我来说有不受欢迎的属性):
public class LabeledPointMarker : ElementPointMarker
{
#region TextProperty
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(
"Text",
typeof(string),
typeof(LabeledPointMarker));
public string Text
{
get { return (string)this.GetValue(LabeledPointMarker.TextProperty); }
set { this.SetValue(LabeledPointMarker.TextProperty, value); }
}
#endregion TextProperty
// ...
// Another dependency properties in the same manner.
// ...
public override UIElement CreateMarker()
{
TextBlock tb = new TextBlock()
{
Text = this.Text,
Foreground = this.TextBrush
};
Border b = new Border()
{
BorderBrush = this.BorderBrush,
BorderThickness = this.BorderThickness,
Background = this.BorderBackground,
Child = tb
};
return b;
}
public override void SetPosition(UIElement marker, Point screenPoint)
{
Canvas.SetLeft(marker, screenPoint.X - marker.DesiredSize.Width / 2);
Canvas.SetTop(marker, screenPoint.Y - marker.DesiredSize.Height / 2);
}
}
现在您可以创建一个“N 维集合”(简单来说),它是一个复杂类型的一维集合。对我来说,我只使用元组:
var data =
results.Data
.Select(d =>
new Tuple<double, double, string>(
d.StartIndex,
0,
d.DurationTime.ToString("######.####")))
.ToList();
然后创建数据源,设置映射(另一个键 - AddMapping 方法),创建标记模板(并在模板中设置未在映射中设置的属性),创建 ElementMarkerPointsGraph,将地图源和标记模板添加到此图,最后将此图添加到绘图仪(对不起我的英语 - 我不是英语使用者:)):
EnumerableDataSource<Tuple<double, double, string>> dataSource =
new EnumerableDataSource<Tuple<double, double, string>>(data);
dataSource.SetXMapping(x => x.Item1);
dataSource.SetYMapping(y => y.Item2);
dataSource.AddMapping(LabeledPointMarker.TextProperty, t => t.Item3);
ElementMarkerPointsGraph empg = new ElementMarkerPointsGraph();
empg.DataSource = dataSource;
empg.Marker = new LabeledPointMarker()
{
TextBrush = Brushes.Black,
BorderBackground = Brushes.Red,
BorderBrush = Brushes.Purple,
BorderThickness = new Thickness(2)
};
chartPlotter.Children.Add(empg);
此外,它可能需要返回的不是 CreateMarker 中相同的 UIElement,而是它的副本。否则它可能会因为映射到同一个 UIElement(上面代码的“dataSource.AddMapping”部分)而引发异常。由于 UIElement 是一个对象,因此获取其副本可能并非易事。所以我发现最简单的方法是使用这样的复制技术。