【问题标题】:How to show 3-dimensional data structure but on 2-dimensional graph?如何在二维图上显示 3 维数据结构?
【发布时间】:2013-10-23 15:20:59
【问题描述】:

我有一个MyType { double X, double Y, string Text } 类型的集合。

如何将其显示为带有 X、Y 坐标的点(或标记)以及带有 Text 作为文本的标签?

  • 标签必须经常看到 - 所以没有工具提示。
  • Text 属性因点而异。

【问题讨论】:

  • 你试过什么? SO 不是让其他人为您工作的地方

标签: c# wpf dynamic-data-display


【解决方案1】:

好吧,解决方案是使用文本依赖属性制作自己的标记,然后添加到该属性的映射。它涉及到这样的事情(它看起来有点肮脏,但它说明了主要思想)。它是在每个脉冲开始时带有持续时间标签的脉冲序列:

没有次要属性的自定义标记类(我不是从 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 是一个对象,因此获取其副本可能并非易事。所以我发现最简单的方法是使用this 之类的复制技术。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-04
    • 1970-01-01
    相关资源
    最近更新 更多