0

我正在绘制一个 WPFToolkit LineSeries 图,除了 ToolTip 之外,它都可以正常工作。我想要一个工具提示来显示鼠标线上任何点的 x 和 y 值。我发现这适用于 DataPoints(在我的情况下相当稀疏):http: //istacee.wordpress.com/2013/03/19/wpf-toolkit-chart-custom-tooltip-on-lineseries- chart/和图表区域上的任何点:使用工具提示 c# 在图表上的任何点上显示系列值

到目前为止,这是我的代码:

<Grid.Resources>
  <ResourceDictionary>
      <ControlTemplate x:Key="CommonLineSeriesDataPointTemplate" TargetType="chartingToolkit:LineDataPoint">
        <Grid x:Name="Root" Opacity="1" />
      </ControlTemplate>

      <Style x:Key="CommonLineSeriesDataPoint" TargetType="chartingToolkit:LineDataPoint">
        <Setter Property="Template" Value="{StaticResource CommonLineSeriesDataPointTemplate}" />
      </Style>

      <Style x:Key="lineSeriesStyle" TargetType="{x:Type chartingToolkit:LineSeries}">
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="DataPointStyle" Value="{StaticResource CommonLineSeriesDataPoint}" />
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="chartingToolkit:LineSeries">
              <Canvas x:Name="PlotArea">
                <Polyline Points="{TemplateBinding Points}" >
                  <Polyline.Stroke>
                    <SolidColorBrush Color="Red"/>
                  </Polyline.Stroke>
                </Polyline>
              </Canvas>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>

      <DataTemplate x:Key="chartTemplate" DataType="{x:Type Views:GraphCurve}">
        <chartingToolkit:LineSeries ItemsSource="{Binding}" 
                                  IndependentValuePath="X" 
                                  DependentValuePath="Y" 
                                  Style="{StaticResource lineSeriesStyle}" />
      </DataTemplate>
  </ResourceDictionary>
</Grid.Resources>

<chartingToolkit:Chart BorderBrush="DarkGray" 
                         SeriesSource="{Binding GraphItems}"
                         SeriesTemplate="{StaticResource chartTemplate}">

  <chartingToolkit:Chart.Axes>
    <chartingToolkit:LinearAxis Orientation="X" />
    <chartingToolkit:LinearAxis Orientation="Y" />
  </chartingToolkit:Chart.Axes>
</chartingToolkit:Chart>

有任何想法吗?

4

1 回答 1

1

您可以尝试使用MouseMove事件,并跟踪鼠标的位置以显示在折线的工具提示中。IRangeAxis提供了一个方法GetValueAtPosition,它接受一个像素坐标并将其转换为轴坐标中的一个值。

首先,将工具提示添加到您的折线:

<Polyline Points="{TemplateBinding Points}" >
    <Polyline.Stroke>
        <SolidColorBrush Color="Red"/>                                      
    </Polyline.Stroke>
    <Polyline.ToolTip>
        <ToolTip>
            <StackPanel>
                <TextBlock Text="{Binding HoverPoint.X}"/>
                <TextBlock Text="{Binding HoverPoint.Y}"/>
            </StackPanel>
        </ToolTip>
    </Polyline.ToolTip>
</Polyline>

在这里,我绑定了这个视图的视图模型的一个属性,称为HoverPoint. 确保在您的视图模型中定义它(我使用的是 ReactiveUI,但您可以使用其他实现的东西INotifyPropertyChanged):

private Point hoverPoint;
public Point HoverPoint
{
    get { return hoverPoint; }
    set { this.RaiseAndSetIfChanged(me => me.HoverPoint, ref hoverPoint, value); }
}

最后,当鼠标在图表区域移动时,我们需要更新这个属性。然后绑定将负责更新工具提示。如果为MouseMove图表上的事件添加处理程序:

<chartingToolkit:Chart MouseMove="Chart_MouseMove" ...

然后像这样填写处理程序:

    private void Chart_MouseMove(object sender, MouseEventArgs e)
    {
        var chart = (Chart)sender;
        var xAxisRange = (IRangeAxis)xAxis;
        var yAxisRange = (IRangeAxis)yAxis;

        var plotArea = FindDescendantWithName(chart, "PlotArea");
        if (plotArea == null)
        {
            return;
        }
        var mousePositionInPixels = e.GetPosition(plotArea);
        var mouseXPositionInChartUnits = (double)xAxisRange.GetValueAtPosition(new UnitValue(mousePositionInPixels.X, Unit.Pixels));
        var mouseYPositionInChartUnits = (double)yAxisRange.GetValueAtPosition(new UnitValue(plotArea.Height - mousePositionInPixels.Y, Unit.Pixels));

        ((MainWindowViewModel)DataContext).HoverPoint = new Point(mouseXPositionInChartUnits, mouseYPositionInChartUnits);
    }

    public static FrameworkElement FindDescendantWithName(DependencyObject root, string name)
    {
        var numChildren = VisualTreeHelper.GetChildrenCount(root);

        for (var i = 0; i < numChildren; i++)
        {
            var child = (FrameworkElement) VisualTreeHelper.GetChild(root, i);
            if (child.Name == name)
            {
                return child;
            }

            var descendantOfChild = FindDescendantWithName(child, name);
            if (descendantOfChild != null)
            {
                return descendantOfChild;
            }
        }

        return null;
    }

xAxis首先,我们获得对图表和轴的引用(我已经yAxis在 XAML 中命名了我的轴)。

然后,我们需要找到PlotArea图表模板的部分,即绘制图表的位(不包括轴等)。可能有更好的方法来解决这个问题,但我使用了一个简单的方法FindDescendantWithName来获取它.

然后,我GetPosition用来获取相对于该图表绘图区域的鼠标位置。最后,GetValueAtPosition轴上的方法为我们提供当前鼠标位置的图表坐标值,我们在HoverPoint属性中设置这些坐标。

唯一的问题是图形线的粗细有限,因此您实际上可以四处移动鼠标并查看相同 X 值的不同 Y 值,反之亦然。但是,扩展它以找到最近的绘图点并不难。然后,您可以将工具提示捕捉到最近的点。或者,如果您找到两个最近的点(一个在鼠标的左侧,一个在鼠标的右侧),您可以自己进行插值并计算出 Y 对应于 X 的当前值。我想这取决于你有多少如果值得这样做,请关心线条的粗细。

于 2013-07-01T09:30:02.160 回答