2012-11-16 68 views
2

在動態數據顯示中,有一個名爲MarkerPointsGraph的類。這源於FrameWorkElement(通過一系列其他類,最直接的父級是PointsGraphBase)並重寫OnRenderMethod以在圖表上繪製一組標記。查找懸停上的元素 - WPF - C# - 動態數據顯示

它通過爲屏幕上呈現的每個點調用適當的標記類型(比如Triangle,Circle等)的渲染方法一次。我需要找到一種方法來識別鼠標懸停在這些標記之一上,以便我可以設置該標記的工具提示。

我有一套方法,允許我將一個點從屏幕位置轉換到視口位置和數據位置並返回。即將屏幕值轉換爲相應的數據值或視口值,反之亦然。

我也有這個框架元素的工具提示打開事件和每個這些標記的像素大小。只要用戶懸停在特定標記上,我需要確定他徘徊在哪個點上,並讓markerpointsgraph設置工具提示值。

但是,用於轉換值的轉換和方法似乎不能正常工作,尤其是在x方向。你的方向似乎很好。

下面是一些示例代碼,將解釋的想法:

    double selectedPointX = 0; 
        double selectedPointY = 0; 

        CoordinateTransform transformLocal = this.primaryPlotter.Transform; 

        if (series.SeriesDescription.YAxisAffinity == AxisAffinity_Y.Y1) 
        { 
         selectedPointX = Mouse.GetPosition(this.primaryPlotter).ScreenToViewport(transformLocal).X; //Getting the mouse positions 
         selectedPointY = Mouse.GetPosition(this.primaryPlotter).ScreenToViewport(transformLocal).Y; 
        } 
        else if (series.SeriesDescription.YAxisAffinity == AxisAffinity_Y.Y2 && injSecondaryAxis != null) 
        { 
         transformLocal = injSecondaryAxis.Transform; 

         selectedPointX = Mouse.GetPosition(this.injSecondaryAxis).ScreenToViewport(transformLocal).X; 
         selectedPointY = Mouse.GetPosition(this.injSecondaryAxis).ScreenToViewport(transformLocal).Y; 
        } 
        else if (series.SeriesDescription.YAxisAffinity == AxisAffinity_Y.Y3 && injTertiaryAxis != null) 
        { 
         transformLocal = injTertiaryAxis.Transform; 

         selectedPointX = Mouse.GetPosition(this.injTertiaryAxis).ScreenToViewport(transformLocal).X; 
         selectedPointY = Mouse.GetPosition(this.injTertiaryAxis).ScreenToViewport(transformLocal).Y; 
        } 

        foreach (var item in SeriesList) 
        { 
         if (item.Key == GraphKey) 
         { 
          for (int i = 0; i < item.Value.Collection.Count; i++) 
          { 
//Calculate the size of the marker on the screen and allow for some level of inaccuracy in identifying the marker i.e anywhere within the marker is allowed. 
           double xlowerBound = item.Value.Collection[i].DataToViewport(transformLocal).X - series.MarkerSize; 
           double xUpperBound = item.Value.Collection[i].DataToViewport(transformLocal).X + series.MarkerSize; 
           double ylowerBound = item.Value.Collection[i].DataToViewport(transformLocal).Y - series.MarkerSize; 
           double yUpperBound = item.Value.Collection[i].DataToViewport(transformLocal).Y + series.MarkerSize; 

           //If point is within bounds 
           if (!(selectedPointX < xlowerBound || selectedPointX > xUpperBound || selectedPointY < ylowerBound || selectedPointY > yUpperBound)) 
           { 
            strToolTip = item.Value.Collection[i].X + ", " + item.Value.Collection[i].Y; //This point is set as the tooltip 
            break; 
           } 
          } 

          break; 
         } 
        } 

這裏,injSecondary和injTertiary兩個注入提供兩個垂直Y軸繪圖儀。他們的行爲與主要海圖繪圖儀非常相似。

這裏有什麼問題嗎?出於某種原因,在實際點擊點之前的點數正在傳遞緩衝區子句。

回答

2

嗯,看起來你正在對這個錯誤的方式對我。如果您深入瞭解D3的源代碼,您可以打開其中一個標記類,然後直接在其中編輯工具提示。每個System.Windows.Shapes元素都有一個Tooltip屬性,您可以在標記類中正確指定它。您所需要做的就是決定工具提示所持有的數據。

例子 - CircleElementPointMarker類:​​

using System; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Shapes; 

namespace Microsoft.Research.DynamicDataDisplay.PointMarkers 
{ 
/// <summary>Adds Circle element at every point of graph</summary> 
public class CircleElementPointMarker : ShapeElementPointMarker { 

    public override UIElement CreateMarker() 
    { 
     Ellipse result = new Ellipse(); 
     result.Width = Size; 
     result.Height = Size; 
     result.Stroke = Brush; 
     result.Fill = Fill; 
     if (!String.IsNullOrEmpty(ToolTipText)) 
     { 
      ToolTip tt = new ToolTip(); 
      tt.Content = ToolTipText; 
      result.ToolTip = tt; 
     } 
     return result; 
    } 

    public override void SetMarkerProperties(UIElement marker) 
    { 
     Ellipse ellipse = (Ellipse)marker; 

     ellipse.Width = Size; 
     ellipse.Height = Size; 
     ellipse.Stroke = Brush; 
     ellipse.Fill = Fill; 

     if (!String.IsNullOrEmpty(ToolTipText)) 
     { 
      ToolTip tt = new ToolTip(); 
      tt.Content = ToolTipText; 
      ellipse.ToolTip = tt; 
     } 
    } 

    public override void SetPosition(UIElement marker, Point screenPoint) 
    { 
     Canvas.SetLeft(marker, screenPoint.X - Size/2); 
     Canvas.SetTop(marker, screenPoint.Y - Size/2); 
    } 
} 
} 

你可以在這個課堂上我們有內置的代碼來處理提示看。 ToolTipText是一個從父類 - ShapeElementPointMarker派生的屬性。您只需爲該屬性分配需要顯示的數據即可。

+0

是的。已經嘗試過這一點,它工作正常。也看起來比MarkerPointsGraph更加出色。 :) – Harsha

0

在繪圖儀上使用cursorcoordinategraph來代替Mouse.GetPosition來獲取正確的屏幕位置並避免ScreenToViewport轉換。另外,在創建邊界時使用DataToScreen。