我正在使用Xamarin Forms为网页实现一个小应用程序,问题是在该网络中是具有多个条目的线性图表,并且如果用户单击该行的某个点,则会显示有关该点的信息,例如您可以在图片中看到:
完成一些工作后,我可以使用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值,但什么也没显示,没有任何建议吗? 应该显示以下内容:Tracker info on point
从以下示例中:Tracker Example
更新代码
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" />
答案 0 :(得分:1)
您的问题在于以下几行。
lineSeries.TrackerKey = "X={2},\nY={4}";
在使用series.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接口变得很方便。您可以通过实现界面来创建Custom DataPoint,然后在工具提示中也包含相同的信息。
基于评论进行更新
此外,要包含“ Touch”,可以在PlotController中指定TouchDown。您可以通过在viewModel中定义如下的PlotController来实现。
public PlotController CustomPlotController{get;set;}
您可以如下定义属性。
CustomPlotController = new PlotController();
CustomPlotController.UnbindAll();
CustomPlotController.BindTouchDown(PlotCommands.PointsOnlyTrackTouch);
在您的Xaml中
<oxy:Plot Controller="{Binding CustomPlotController}"......