折线图显示点击点的信息



我正在为一个网页实现一个带有Xamarin Forms的小应用程序,问题是在这个网页中,它是一个包含多个条目的线性图表,如果用户点击某个点,就会显示该点的信息,如图所示:

Web折线图

经过一些工作,我可以使用OxyPlot.Xamarin.Forms插件创建一个或多或少相似的折线图,该插件具有多个显示点的条目

我的应用程序折线图

这是我的代码:

OnPropertyChanged("GraphModel");
var model = new PlotModel
{
LegendPlacement = LegendPlacement.Outside,
LegendPosition = LegendPosition.BottomCenter,
LegendOrientation = LegendOrientation.Horizontal,
LegendBorderThickness = 0
};
model.PlotType = PlotType.XY;
model.InvalidatePlot(false);
Dictionary<string, List<Prices>> values = HistoricData[Selected.ProductId];
int colorIndex = 0;
List<string> x_names = new List<string>();
foreach (var item in values.Keys)
{
if (item.ToUpper() == Selected.ProductName) { SelectedIndex = colorIndex; }
var lineSeries = new LineSeries()
{
Title = item,
MarkerType = MarkerType.Circle,
};
lineSeries.MarkerResolution = 3;
lineSeries.MarkerFill = OxyPlot.OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
lineSeries.MarkerStroke = OxyPlot.OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
lineSeries.MarkerSize = 3;
var points = new List<DataPoint>();

lineSeries.Color = OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
foreach (var price in values[item])
{
points.Add(new DataPoint(price.Week+price.Year, price.Price));
}
if (ButtonsVisibility.Count == 0)
{
lineSeries.IsVisible = (Selected.ProductName == item.ToUpper()) ? true : false;
}
else
{
lineSeries.IsVisible = ButtonsVisibility[colorIndex];
}

lineSeries.ItemsSource = points;
lineSeries.MarkerType = OxyPlot.MarkerType.Circle;
model.Series.Add(lineSeries);
colorIndex++;
}
NumButtons = colorIndex;
LinearAxis yaxis = new LinearAxis();
yaxis.Position = AxisPosition.Left;
yaxis.MajorGridlineStyle = LineStyle.Dot;
model.Axes.Add(yaxis);
LineChart = model;
OnPropertyChanged("GraphModel");
return LineChart;

我的疑问是,我应该使用哪个属性,并至少显示一个具体点的值,我已经看到了OnTouchStarted属性,但它只适用于所有LineSeries,而不适用于单个点。我在一些文章中读到OxyPlot.Xamarin.Forms包含跟踪器。我在代码中添加了这一行:

lineSeries.TrackerFormatString = "X={2},nY={4}";

应该在点击时显示x和y值,但不显示任何内容,有什么建议吗?应该显示这样的东西:点上的跟踪器信息

来自以下示例:跟踪器示例

更新的代码

public PlotModel GetLineChart()
{
OnPropertyChanged("GraphModel");
var model = new PlotModel
{
LegendPlacement = LegendPlacement.Outside,
LegendPosition = LegendPosition.BottomCenter,
LegendOrientation = LegendOrientation.Horizontal,
LegendBorderThickness = 0
};
model.PlotType = PlotType.XY;
model.InvalidatePlot(false);
Dictionary<string, List<Prices>> values = HistoricData[Selected.ProductId];
int colorIndex = 0;
List<string> x_names = new List<string>();
foreach (var item in values.Keys)
{
if (item.ToUpper() == Selected.ProductName) { SelectedIndex = colorIndex; }
var lineSeries = new LineSeries()
{
Title = item,
MarkerType = MarkerType.Circle,
CanTrackerInterpolatePoints = false
};
lineSeries.MarkerResolution = 3;
lineSeries.MarkerFill = OxyPlot.OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
lineSeries.MarkerStroke = OxyPlot.OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
lineSeries.MarkerSize = 3;
var points = new List<DataPoint>();

lineSeries.Color = OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
foreach (var price in values[item])
{
points.Add(new DataPoint(price.Week+price.Year, price.Price)); 
}
if (ButtonsVisibility.Count == 0)
{
lineSeries.IsVisible = (Selected.ProductName == item.ToUpper()) ? true : false;
}
else
{
lineSeries.IsVisible = ButtonsVisibility[colorIndex];
}

lineSeries.ItemsSource = points;
lineSeries.MarkerType = OxyPlot.MarkerType.Circle;
lineSeries.TrackerFormatString = "X={2},nY={4}";
lineSeries.TextColor = OxyPlot.OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
model.Series.Add(lineSeries);
colorIndex++;
}
NumButtons = colorIndex;
LinearAxis yaxis = new LinearAxis();
yaxis.Position = AxisPosition.Left;
//yaxis.StringFormat = "X={2},nY={4}";
yaxis.MajorGridlineStyle = LineStyle.Dot;
model.Axes.Add(yaxis);
LineChart = model;
OnPropertyChanged("GraphModel");
return LineChart;
}

}

protected async override void OnAppearing()
{
await _viewModel.LinearViewModel.GetSubCategoryHistoricWeekPrices(App.ViewModel.LoginViewModel.SesionToken, FROM_DATE, TO_DATE);
Plot.Model = _viewModel.LinearViewModel.GetLineChart();
PlotController controller = new PlotController();
controller.UnbindAll();
controller.BindTouchDown(PlotCommands.PointsOnlyTrackTouch);
Plot.Controller = controller;

AddButtons();

}

绘图视图的Xaml声明:

<oxy:PlotView 
Grid.Row="2"
Grid.RowSpan="2"
Grid.ColumnSpan="4"            
x:Name="Plot" />

您的问题在于以下行。

lineSeries.TrackerKey = "X={2},nY={4}";

使用系列时。TrackerKey,您正在指定您正在使用CustomTracker,而在本例中您不是。如果您需要为模型中的每个系列使用不同的跟踪器,则自定义跟踪器将非常有用。

在这种情况下,您应该删除该行并仅使用TrackerFormatString。

lineSeries.TrackerFormatString = "X={2},nY={4}";

这将使用格式字符串参数显示工具提示,其中{2}表示X值,{4}表示Y。请参阅以下占位符。

{0} = Title of Series
{1} = Title of X-Axis
{2} = X Value
{3} = Title of Y-Axis
{4} = Y Value

如果您需要在工具中包含其他/自定义信息,则您的数据点需要包含该信息。这就是IDataPointProvider接口变得方便的地方。您可以通过实现接口来创建自定义DataPoint,然后也可以在工具提示中包含相同的信息。

根据评论更新

此外,为了包含"触摸",您可以在PlotController中指定TouchDown。您可以通过以下方式在视图模型中定义PlotController来执行此操作。

public PlotController CustomPlotController{get;set;}

可以按如下方式定义特性。

CustomPlotController = new PlotController();
CustomPlotController.UnbindAll();
CustomPlotController.BindTouchDown(PlotCommands.PointsOnlyTrackTouch);

在您的Xaml 中

<oxy:Plot Controller="{Binding CustomPlotController}"......

最新更新