我想向用户展示可供选择的可用系列列表(也许直接通过单击图例?)该图将仅显示所选系列
实现这一目标的最佳方法是什么?
我建议您使用代表这些系列的复选框。当用户选中复选框时,您可以将新的 LineSeries 或任何其他系列添加到 PlotModel/PlotView。
checkbox1 代表系列 1。checkbox2 代表 series2。ETC..
前任:
Plotview pv = new PlotView(); // you can also use plotmodel instead of plotview.
pv.Width = 480.0;
pv.Height = 272.0;
pv.Title = graphname;
private void checkbox4_Checked(object sender, RoutedEventArgs e)
{
var LineChart = new LineSeries();
pv.Series.Add(LineChart);
LineChart.DataFieldX = "X";
LineChart.DataFieldY = "Y";
List<Vector> coords = new List<Vector>();
//Add X and Y values to this list. Or you can use any other way you want.
LineChart.ItemsSource = coords; //Feed it to itemsource
LineChart.Title = name;
}
这是我与同事一起找到的 MVVM 解决方案,允许用户选择要显示的系列:
首先,我们在 xaml 中创建一个 PlotView,并在 PlotModel.Series 上绑定一个 ItemsControl:
<oxy:PlotView Background="Transparent" Model="{Binding PlotModelCompareChart}" x:Name="CompareChart"/>
<Border Grid.Column="1" Margin="0,150,0,0" BorderBrush="Gray" BorderThickness="1" Height="80">
<ItemsControl ItemsSource="{Binding PlotModelCompareChart.Series}" Margin="5" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel IsItemsHost="True">
</StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type oxy:Series}">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="True" Tag="{Binding ElementName=CompareChart}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding ElementName=userControl, Path=DataContext.ManageCheckBoxCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=CheckBox}}" ></i:InvokeCommandAction>
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding ElementName=userControl, Path=DataContext.ManageCheckBoxCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=CheckBox}}"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
<Rectangle Width="15" Height="3.5" Margin="5,0,0,0" Fill="{Binding Color, Converter={StaticResource OxyColorToSolidColorBrushConverter}}"/>
<TextBlock Text="{Binding Title}" Margin="5,0,0,0" ></TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
将收到的 OxyColor 转换为填充矩形的转换器(您必须设置系列的颜色,如果让 Oxyplot 选择颜色,它不起作用):
public class OxyColorToSolidColorBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (null == value)
{
return null;
}
if (value is OxyColor)
{
var color = (SolidColorBrush)new BrushConverter().ConvertFrom(value.ToString());
return color;
}
Type type = value.GetType();
throw new InvalidOperationException("Unsupported type [" + type.Name + "]");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
现在 ViewModel 中的代码:
--绘图模型创建--
public PlotModel PlotModelCompareChart => CreatePlotModelForCompareChart(DataPoints);
public PlotModel CreatePlotModelForCompareChart(StripLengthReferentialDataPointCollection points)
{
var plotModel= new PlotModel();
plotModel.IsLegendVisible = false;
var linearAxis = new LinearAxis
{
Position = AxisPosition.Bottom,
MajorGridlineStyle = LineStyle.Solid,
Title = LabelsAndMessagesRes.StripLengthReferentialChart_Legend_HeadPosition,
Unit = PhysicalQuantityManager.Instance.LengthAcronym
};
var linearAxis2 = new LinearAxis
{
Position = AxisPosition.Left,
Title = LabelsAndMessagesRes.Lexicon_Temperature,
Unit = PhysicalQuantityManager.Instance.TemperatureAcronym
};
var linearAxis3 = new LinearAxis
{
Position = AxisPosition.Right,
Maximum = 70,
Key = "ValveAxis"
};
plotModel.Axes.Add(linearAxis);
plotModel.Axes.Add(linearAxis2);
plotModel.Axes.Add(linearAxis3);
var lineSeries = new LineSeries();
lineSeries.Title = LabelsAndMessagesRes.StripLengthReferentialChart_Legend_MeasuredCoilingTemperature;
lineSeries.DataFieldX = "HeadPosition";
lineSeries.DataFieldY = "MeasuredCoilingTemperature";
lineSeries.ItemsSource = points;
lineSeries.Color = OxyColors.Green;
var lineSeries2 = new LineSeries();
lineSeries2.Title = "All valves count";
lineSeries2.DataFieldX = "HeadPosition";
lineSeries2.DataFieldY = "AllValvesCount";
lineSeries2.YAxisKey = "ValveAxis";
lineSeries2.ItemsSource = points;
lineSeries2.Color = OxyColors.LightSeaGreen;
plotModel.Series.Add(lineSeries);
plotModel.Series.Add(lineSeries2);
return plotModel;
}
-- Checkbox事件的命令和方法(Unchecked和Checked)
public ICommand ManageCheckBoxCommand { get; private set; }
在克托尔:
ManageCheckBoxCommand = new GalaSoft.MvvmLight.CommandWpf.RelayCommand<object>(ManageCheckBoxMethod);
方法 :
private void ManageCheckBoxMethod(object obj)
{
if(obj != null)
{
var checkbox = obj as CheckBox;
var datacontext = checkbox.DataContext as Series;
datacontext.IsVisible = checkbox.IsChecked.Value;
var plotView = checkbox.Tag as OxyPlot.Wpf.PlotView;
plotView.Model = null;
plotView.Model = datacontext.PlotModel;
}
}
现在结果:已 检查选项
希望能帮助到你 !
上面找到了对卢卡斯答案的更新。我假设 OxyPlot 自去年以来以两种方式更改或破坏了界面:1)因为 Color 的绑定现在失败了,所以我绑定了 ActualColor 属性并且这有效。2)但是,对于具有大量“系列”(例如 LineSeries)的图,OxyPlot 会分配 12 种不同的纯色,然后接下来的 12 种是虚线颜色,然后接下来的 12 种是虚线颜色到“系列”的整体集合" 所以你需要使用 ActualLineStyle,但不幸的是 OxyPlot 将其标记为“受保护”。所以 XAML 调整替换了卢卡斯回答中的矩形:
<Line Stroke="{Binding ActualColor, Converter={StaticResource OxyColorToSolidColorBrushConverter}}"
StrokeThickness="3" SnapsToDevicePixels="True"
StrokeDashArray="{Binding MyActualLineStyle, Converter={StaticResource LineStyleToDashArrayConverter}}"
Height="3" Width="30" X1="0" Y1="0" X2="30" Y2="0"/>
新的转换器是:
public class LineStyleToDashArrayConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return null;
}
double[] array = LineStyleHelper.GetDashArray((LineStyle)value);
return array == null ? null : new DoubleCollection(array); // switches double array to double collection
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
OxyPlot 的 LineSeries 的新子类将公开 ActualLineStyle 属性(假设您的系列是线条):
public class MyLineSeries : LineSeries
{
public LineStyle MyActualLineStyle => ActualLineStyle;
}
因此,您创建了这个新 LineSeries 子类的实例,而不是 LineSeries:
MyLineSeries ls = new MyLineSeries() { Title = sq };
ls.Points.AddRange(_points); // a line consisting of multiple points
MyPlotModel.Series.Add(ls); // a line for each onto the overall plot model