Hello.
In my project, I am trying to display four SciChartSurfaces with a single legend. Furthermore, I want the Visibility changes of each series in the legend checkbox to be reflected in all SciChartSurfaces.
The following code achieves this, but I am not confident that it is the best solution. Is there a more Smart way to accomplish this?
MainWindow.xaml
<Window x:Class="SurveyFleetVisionChartLegend.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SurveyFleetVisionChartLegend"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
Title="MainWindow"
Width="800"
Height="550"
d:DataContext="{d:DesignInstance {x:Type local:MainWindowViewModel}}"
mc:Ignorable="d">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<s:SciChartSurface Grid.Row="0"
Margin="5"
VerticalAlignment="Stretch"
Background="WhiteSmoke"
CacheMode="{x:Null}"
ChartTitle="SciChartSurface1"
RenderableSeries="{s:SeriesBinding GraphSeriess1.Value,
Mode=OneWay,
UpdateSourceTrigger=PropertyChanged}">
<s:SciChartSurface.XAxis>
<s:NumericAxis DrawLabels="False"
GrowBy="0.1, 0.1" />
</s:SciChartSurface.XAxis>
<s:SciChartSurface.YAxis>
<s:NumericAxis HorizontalContentAlignment="Left"
DrawLabels="False"
GrowBy="0.1, 0.1" />
</s:SciChartSurface.YAxis>
<s:SciChartSurface.ChartModifier>
<s:ModifierGroup>
<s:LegendModifier x:Name="TrendChartLegendModifier"
ShowLegend="False"
Visibility="Visible" />
</s:ModifierGroup>
</s:SciChartSurface.ChartModifier>
</s:SciChartSurface>
<s:SciChartSurface Grid.Row="1"
Margin="5"
VerticalAlignment="Stretch"
Background="WhiteSmoke"
ChartTitle="SciChartSurface2"
RenderableSeries="{s:SeriesBinding GraphSeriess2.Value,
UpdateSourceTrigger=PropertyChanged}">
<s:SciChartSurface.XAxis>
<s:NumericAxis DrawLabels="False"
GrowBy="0.1, 0.1" />
</s:SciChartSurface.XAxis>
<s:SciChartSurface.YAxis>
<s:NumericAxis HorizontalContentAlignment="Left"
DrawLabels="False"
GrowBy="0.1, 0.1" />
</s:SciChartSurface.YAxis>
</s:SciChartSurface>
<s:SciChartSurface Grid.Row="2"
Margin="5"
VerticalAlignment="Stretch"
Background="WhiteSmoke"
ChartTitle="SciChartSurface3"
RenderableSeries="{s:SeriesBinding GraphSeriess3.Value}">
<s:SciChartSurface.XAxis>
<s:NumericAxis DrawLabels="False"
GrowBy="0.1, 0.1" />
</s:SciChartSurface.XAxis>
<s:SciChartSurface.YAxis>
<s:NumericAxis HorizontalContentAlignment="Left"
DrawLabels="False"
GrowBy="0.1, 0.1" />
</s:SciChartSurface.YAxis>
</s:SciChartSurface>
<s:SciChartSurface Grid.Row="3"
Margin="5"
VerticalAlignment="Stretch"
Background="WhiteSmoke"
ChartTitle="SciChartSurface4"
RenderableSeries="{s:SeriesBinding GraphSeriess4.Value}">
<s:SciChartSurface.XAxis>
<s:NumericAxis DrawLabels="False"
GrowBy="0.1, 0.1"
VisibleRangeLimitMode="MinMax" />
</s:SciChartSurface.XAxis>
<s:SciChartSurface.YAxis>
<s:NumericAxis HorizontalContentAlignment="Left"
DrawLabels="False"
GrowBy="0.1, 0.1" />
</s:SciChartSurface.YAxis>
</s:SciChartSurface>
<!-- Display the legend for Chart1. -->
<!-- Synchronization of Visiblity of each series of each SciChartSurface is performed on the ViwModel side. -->
<s:SciChartLegend Grid.Row="4"
Grid.Column="1"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
LegendData="{Binding LegendData,
ElementName=TrendChartLegendModifier}"
Orientation="Vertical"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ShowVisibilityCheckboxes="True" />
</Grid>
</Window>
MainWindowViewModel.cs
using Reactive.Bindings;
using Reactive.Bindings.Extensions;
using SciChart.Charting.Common.Extensions;
using SciChart.Charting.Model.ChartData;
using SciChart.Charting.Model.ChartSeries;
using SciChart.Charting.Model.DataSeries;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Xml.Linq;
namespace SurveyFleetVisionChartLegend
{
public class MainWindowViewModel
{
public ReactivePropertySlim<List<IRenderableSeriesViewModel>> GraphSeriess1 { get; set; } = new ReactivePropertySlim<List<IRenderableSeriesViewModel>>();
public ReactivePropertySlim<List<IRenderableSeriesViewModel>> GraphSeriess2 { get; set; } = new ReactivePropertySlim<List<IRenderableSeriesViewModel>>();
public ReactivePropertySlim<List<IRenderableSeriesViewModel>> GraphSeriess3 { get; set; } = new ReactivePropertySlim<List<IRenderableSeriesViewModel>>();
public ReactivePropertySlim<List<IRenderableSeriesViewModel>> GraphSeriess4 { get; set; } = new ReactivePropertySlim<List<IRenderableSeriesViewModel>>();
public ReactiveCommand RecreateCommand { get; set; }
private List<string> chartNames;
private Dictionary<string, bool> seriesVisibles { get; set; }
private Random random = new Random();
public MainWindowViewModel()
{
chartNames = new List<string>() { "Chart1", "Chart2", "Chart3" };
seriesVisibles = new Dictionary<string, bool>();
chartNames.ForEach(a => seriesVisibles.Add(a, true));
GraphSeriess1.Value = createGraphSeriess("Chart");
GraphSeriess2.Value = createGraphSeriess("Chart");
GraphSeriess3.Value = createGraphSeriess("Chart");
GraphSeriess4.Value = createGraphSeriess("Chart");
// If the legend changes the Visibility of each series in GraphSeriess1,
// Vary the Visibility of each series in other GraphSeriess.
GraphSeriess1.Subscribe(s=> {
if(s != null)
s.ForEach(a =>
{
a.ObserveProperty(b => b.IsVisible).Subscribe(_ =>
{
if (GraphSeriess2.Value != null)
GraphSeriess2.Value.First(c => c.DataSeries.SeriesName == a.DataSeries.SeriesName).IsVisible = a.IsVisible;
if (GraphSeriess3.Value != null)
GraphSeriess3.Value.First(c => c.DataSeries.SeriesName == a.DataSeries.SeriesName).IsVisible = a.IsVisible;
if (GraphSeriess4.Value != null)
GraphSeriess4.Value.First(c => c.DataSeries.SeriesName == a.DataSeries.SeriesName).IsVisible = a.IsVisible;
seriesVisibles[a.DataSeries.SeriesName] = a.IsVisible;
});
});
});
}
private List<IRenderableSeriesViewModel> createGraphSeriess(string name)
{
return chartNames.Select((x,a) => createGraphSeries(x, a)).ToList();
}
private IRenderableSeriesViewModel createGraphSeries(string name, int index)
{
var dataSeries = new XyDataSeries<double>() { SeriesName = name};
for (var i = 0; i < 5; i++)
{
dataSeries.Append(i, random.Next(100));
}
return new LineRenderableSeriesViewModel()
{
DataSeries = dataSeries,
IsVisible = seriesVisibles[dataSeries.SeriesName],
Stroke = Color.FromRgb((byte)(index * 200), (byte)(index * 100), (byte)(index * 100))
};
}
}
}
That is all. Best regards.
- Kouki Takeda asked 10 months ago
- last edited 10 months ago
- You must login to post comments
Please login first to submit.