Series data binding in Semi-Bindable Chart

A forum dedicated to WPF version of LightningChart Ultimate.

Moderator: Arction_LasseP

fukasawa
Posts: 18
Joined: Fri Sep 04, 2015 11:13 am

Series data binding in Semi-Bindable Chart

Post by fukasawa » Tue Jun 27, 2017 6:37 am

Hello,

What is best way to change series data from ViewModel?

I modified source code from this topic. Because, It is very beautiful sample.
viewtopic.php?f=16&t=196&hilit=Parallel ... 3D%26gt%3B

I like to use these.
-data binding
-XAML designer
-Semi-Bindable Chart

The Executed result has not changed, but the speed is a bit slow (Within tolerance).

Full Code is attached.
Part is here.

MainWindow.xaml (part)

Code: Select all

<lcusb:ViewXY.IntensityGridSeries>
    <lcusb:IntensityGridSeries
        x:Name="m_heatmap"
        Data="{Binding IntensityPoints}"
        ...
        />
</lcusb:ViewXY.IntensityGridSeries>
MainWindow.xaml.cs (part)

Code: Select all

private void MainWindow_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    var vm = (MainWindowViewModel)this.DataContext;
    vm.UpdateChartInView = UpdateChart;

    //Call VM Method
    vm?.StartInVM();
}

//Call from VM
private void UpdateChart()
{
    m_chart.BeginUpdate();
    m_heatmap.InvalidateValuesDataOnly();
    m_chart.EndUpdate();
}
MainWindowViewModel.cs (part)

Code: Select all

private IntensityPoint[,] intensityPoints = null;
public IntensityPoint[,] IntensityPoints
{
    get { return intensityPoints; }
    set
    {
        intensityPoints = value;
        NotifyPropertyChanged();
    }
}
public Action UpdateChartInView { get; internal set; }
...

void m_timer_Tick(object sender, EventArgs e)
{
    if (m_data == null)
    {
        //Create a data array
       ...
        IntensityPoints = ConvertIntesityPoint(m_data);
    }

    //Set new values to data array
    for (int iCol = 0; iCol < DataColumnCount; iCol++)
    {
        for (int iRow = 0; iRow < DataRowCount; iRow++)
        {
            IntensityPoints[iCol, iRow].Value = (double)m_iRound + 20.0 * Math.Sin((double)iCol * (double)iRow / 5000.0);
        }
    }

    //Call View Method
    UpdateChartInView();
    ...
}
...
In User Manual, WPF (semi-bindable) can't Series data binding.
This code seems to work fine, but is there any problem?
Attachments
HeatmapTest -SemiBind-simple.zip
Full source code
(48.08 KiB) Downloaded 357 times

ArctionKestutis
Posts: 383
Joined: Mon Mar 14, 2016 9:22 am

Re: Series data binding in Semi-Bindable Chart

Post by ArctionKestutis » Tue Jun 27, 2017 12:39 pm

Hello,

Your example is fine, and it woks as it should.
As long as you bind properties Semi-bindable will work just fine. That is, in the example you are replacing two-dimensional array at once. It is equivalent to Series.InvalidateData() call, which notify chart that this series needs a refresh.
However, if you would try binding single element in the 'data' array, that will only work in fully-bindable but not in semi-bindable.

Hope this helps.

All the best.

fukasawa
Posts: 18
Joined: Fri Sep 04, 2015 11:13 am

Re: Series data binding in Semi-Bindable Chart

Post by fukasawa » Wed Jun 28, 2017 2:14 am

Thank you,

In other words, does binding single element mean following?
- Binding Data/Points of Series
- Add or change part of Data/Points in VM

In addition, these are OK?
- Binding SeriesCollection (not Data/Points)
- Add or change part of Data/Points of SeriesCollection in VM

ArctionKestutis
Posts: 383
Joined: Mon Mar 14, 2016 9:22 am

Re: Series data binding in Semi-Bindable Chart

Post by ArctionKestutis » Wed Jun 28, 2017 12:44 pm

Hello,

The Semi-bindable edition of LightningChart will bind OK to Properties (like Data/Points of Series). However, you could not bind to part of Data/Points - for that you need (fully) Binable edition of LightningChart.

The Semi-bindable edition of LightningChart will bind to SeriesCollection without problem.

You can add/change part of Data/Points in ViewModel in Semi-bindable LightningChart, but you could not bind. In this case you required to inform chart about need of refresh: either by Series.InvalidateData() or Chart.BeginUpdate-EndUpdate() call.

Hope this helps.

fukasawa
Posts: 18
Joined: Fri Sep 04, 2015 11:13 am

Re: Series data binding in Semi-Bindable Chart

Post by fukasawa » Fri Jun 30, 2017 2:01 am

Thanks for the info.

I will make it as follows.
When the count of Series as well as Points are changed, I will Bind SeriesCollection.
When the count of Series is fixed and only Points is changed, I will Bind Data/Points.

Now, the VM include "using Arction.Wpf.SemibindableCharting".
Can I avoid any reference to Arction~ in VM?

ArctionKestutis
Posts: 383
Joined: Mon Mar 14, 2016 9:22 am

Re: Series data binding in Semi-Bindable Chart

Post by ArctionKestutis » Fri Jun 30, 2017 6:25 am

If I understood correctly, you want to manipulate LightningChart in VM (e.g. add/change of Data/Points). In that case, I don't see how you could avoid "using Arction.Wpf.SemibindableCharting".

All the best.

fukasawa
Posts: 18
Joined: Fri Sep 04, 2015 11:13 am

Re: Series data binding in Semi-Bindable Chart

Post by fukasawa » Fri Jun 30, 2017 8:29 am

Yes, if I bind LightningChart control (e.g. SeriesCollection) directory, I can't avoid.
I want to separate VM from View if possible.

Already, I tried Converter.
I defined MySeriesClass in VM and Converter in View. The Converter convert MySeriesClass to LightningChart.SeriesCollection.
During I set data at once this strategy was going well. But, if I change data of MySeriesClass, it broken.

There are any other ideas?

ArctionKestutis
Posts: 383
Joined: Mon Mar 14, 2016 9:22 am

Re: Series data binding in Semi-Bindable Chart

Post by ArctionKestutis » Fri Jun 30, 2017 2:59 pm

Could you send updated or new application to Arction's support account or here in forum. That way we would be 'on the same page' and it will easier to imagine what is broken.

All the best.

fukasawa
Posts: 18
Joined: Fri Sep 04, 2015 11:13 am

Re: Series data binding in Semi-Bindable Chart

Post by fukasawa » Wed Jul 05, 2017 9:43 am

Sorry, late

Here is changed history.
1. Change direct reference to EventTrigger and Behaviors (MainWindow, MainWindowViewModel, MyDelegateCommand).
2. Change bind IntensityPoint to IntensityGridSeriesCollection (MainWindow and MainWindowViewModel).
--- Everything worked yet :D ---
3. Change bind IntensityGridSeriesCollection to List<MySeries> (MainWindow, MainWindowViewModel, MySeries and MySe~Converter).
--- Update didn't reflect in View :oops: ---
Attachments
HeatmapTest -SemiBind-5 - Simple.zip
(45.17 KiB) Downloaded 327 times

ArctionKestutis
Posts: 383
Joined: Mon Mar 14, 2016 9:22 am

Re: Series data binding in Semi-Bindable Chart

Post by ArctionKestutis » Fri Jul 07, 2017 11:59 am

Hello,

Thank you for the application. Indeed we see the problem: _chart.ViewXY.IntensityGridSeries.Data is updated only during initialization and never again. What is wrong with this Binding-Converter pattern we are still investigating. It may take for a while as our main 'binding specialists' currently on holidays.
We will update issue whenever we find something substantial.

Sorry for inconvenience.

All the best.

fukasawa
Posts: 18
Joined: Fri Sep 04, 2015 11:13 am

Re: Series data binding in Semi-Bindable Chart

Post by fukasawa » Mon Jul 10, 2017 6:16 am

OK, I look forward to hearing from you.

User avatar
ArctionLasse
Posts: 26
Joined: Fri Mar 27, 2015 11:23 am

Re: Series data binding in Semi-Bindable Chart

Post by ArctionLasse » Tue Jul 18, 2017 12:21 pm

Hi,

the problem on the application is that the bound series is given it's data only once - when it's created by converter - and when the source data changes it does not affect the bound series data in any way as the data is not shared or linked in any way.

In more detail, the bound series is created by the converter when the source data collection changes. After that the source data is modified, but the collection itself is not, and thus the binding does not try to deliver the information again to the chart, and the converter does nothing. One could set the collection again, causing the converter to create new series and set them to chart. That however would probably be quite slow and thus I do not recommend it.

I see three main ways this could be implemented so that it works.
1) When the series converter creates new series, give it a reference to the source data or some other way of receiving information that the source data has changed, so that when the source data changes, the created series data is changed as well.
2) Same as 1. but do the update of the created serie data through binding. Meaning that instead of setting the series data when the converter creates the serie, insert binding to it, pointing to the source data.
3) Don't bind the series, just the data, through converter as you have now done with the series. I modified your demo for this purpose, as this seemed like the easiest option.

Hope you understand this explanation, it's a bit short, but I figured that it would be clarified by inspecting the code.
Attachments
HeatmapTest -SemiBind-5 - Simple.rar
Modified version of the demo that binds IntensityPoints through converter.
(12.87 KiB) Downloaded 343 times
LightningChart Support Team, LV

fukasawa
Posts: 18
Joined: Fri Sep 04, 2015 11:13 am

Re: Series data binding in Semi-Bindable Chart

Post by fukasawa » Thu Jul 20, 2017 5:19 am

Thank 'binding specialists' !
It's a Great solution :D .

Everything works fine.
VM is abstracted and separated from ViewObject.
In case of count of Series is fixed and only Points is changed, this solution will be used.

In addition, for case of count of Series as well as Points are changed, I modified your demo.
I revived binding of IntensityGridSeriesCollection and using MySeriesToIntensityGridSeriesCollectionConverter.
MySeries.Data is bind to IntensityGridSeries.Data with DoubleToIntensityPointConverter in MySeriesToIntensityGridSeriesCollectionConverter.

Full Code is attached.
Part is here.

in MySeriesToIntensityGridSeriesCollectionConverter

Code: Select all

var binding = new Binding(nameof(MySeries.Data))
{
    Source = mSe,
    Mode = BindingMode.OneWay,
    Converter = new DoubleToIntensityPointConverter(),
};
BindingOperations.SetBinding(iSe, IntensityGridSeries.DataProperty, binding);
This code seems to work fine, but is there any problem?
Attachments
HeatmapTest -SemiBind-7-simple.zip
(28.6 KiB) Downloaded 347 times

User avatar
ArctionLasse
Posts: 26
Joined: Fri Mar 27, 2015 11:23 am

Re: Series data binding in Semi-Bindable Chart

Post by ArctionLasse » Fri Jul 21, 2017 6:18 am

Hi,

Great to hear that you got your app working!
On a quick glance I see no problems with your implementation. It's pretty much what a meant with the option 2.
It might not be the optimal solution though, so if it's performance critical system there might be lots of things you can do to make it faster.
LightningChart Support Team, LV