2013-10-23 46 views
-2

我有一個MyType { double X, double Y, string Text }類型的集合。如何在二維圖上顯示三維數據結構?

如何使用X,Y座標以及文本爲文本的標籤將它顯示爲點(或標記)?

  • 標籤必須經常看到 - 所以沒有工具提示。
  • Text屬性因點而異。
+1

你有什麼嘗試? SO不是讓別人爲你做這項工作的地方 –

回答

1

好了,解決的辦法是使文本依賴屬性自己的標記,然後添加映射到該屬性。它涉及到這樣的事情(它看起來有點gr,,但它說明了主要想法)。它是在每個脈衝的開始與持續時間標籤的脈衝序列:

自定義標記類無次要屬性(我獲得不是來自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,添加映射源和標記模板這個圖,並在最後的這個圖形添加到繪圖儀(對不起,我的英語 - 我不是englishspeaker :)):

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