~/overview/1.4.automatic updates.md

Automatic updates Updates

LiveCharts is listening for any change in your data, the library is be able to update automatically, every time you change a property or you add, remove, replace, insert or clear your data collection you will see that change immediately in the user interface, for most cases automatic updates should not impact performance significantly.

LiveCharts changes detection is based on INotifyPropertyChanged and INotifyCollectionChanged interfaces, both provided by the .Net framework, every time a property or a collection changes and the object implements any of these interfaces, the chart throttles an update, this means that the library will not update every time a change happens, it will only update once every 10 ms (by default).

LiveCharts changes detection is handled by the CollectionDeepObserver class, this objects makes it easy for the library to listen and stop listening to changes in all the objects that must fire an update in the library. Listeners must be removed automatically by the library, if not, then it is a bug, you can call the CollectionDeepObserver.Dispose method if you are facing memory leaks, but it is not the intention, the library should handle that automatically.

The CollectionDeepObserver class subscribes and unsubscribes a handler to INotifyCollectionChanged.CollectionChanged event, this means that any time you add, remove, replace, insert or clear the collection, the library will be able to update. Also if any item in the collection implements INotifyPropertyChanged, the library will also subscribe a handler to the PropertyChanged event for each item that implements the interface, this means that any time a property changes LiveCharts will be able to update. The library should remove the subscriptions to both events once they are no longer necessary, for example when you remove an item from the collection, the library should also unsubscribe the handler to that item that was just removed.

All the objects provided by LiveCharts, when necessary implement INotifyCollectionChanged or INotifyPropertyChanged, so normally after changing any property in your plot, you will see that immediately in the user interface, but there are special cases where it is up to the developer whether the chart will update or not, since the implementation of these interfaces depends on the data your provide to the library, this is specially important to understand for the Chart.Series and Series.Values properties.

Enable automatic updates for the Series.Values and Chart.Series properties

Automatic updates for most cases should not impact performance significantly, so feel free to do it, LiveCharts will be able to detect a change in your data only when these interfaces are implemented.

INotifyCollectionChanged

The INotifyCollectionChanged interface is provided by the .Net framework and it is widely used all over the framework, there are some classes that already implement the interface such as the ObservableCollection class, this class notifies the subscriber when you add, remove, insert, replace or clear the collection.

// since valuesCollection is of type ObservableCollection 
// LiveCharts will update when you add, remove, replace or clear the collection
var valuesCollection = new ObservableCollection<double>();

var lineSeries = new LineSeries<double>();
lineSeries.Values = valuesCollection;

valuesCollection.Add(4);
valuesCollection.Add(6);
valuesCollection.Add(2);
// you should see the values in the user interface.


// but in the following series, you will not see the change in the user interface.
var valuesCollection2 = new List<double>();

var lineSeries = new LineSeries<double>();
lineSeries.Values = valuesCollection2;

valuesCollection2.Add(4);
valuesCollection2.Add(6);
valuesCollection2.Add(2);
// the UI will not update automatically.


// it works the same for the Chart.Series property
// the library will be able to reflect when you add a new series
// to your plot, only if the collection implements INotifyCollectionChanged
var seriesCollection = new ObservableCollection<ISeries>();
myChartControl.Series = seriesCollection; 
seriesCollection.Add(new LineSeries{ Values = new [] { 1, 2, 3 } });

// the previous block updated the chart when the Add method was called
// but the following will not:
var seriesCollection = new List<ISeries>();
myChartControl.Series = seriesCollection; 
seriesCollection.Add(new LineSeries{ Values = new [] { 1, 2, 3 } });

INotifyPropertyChanged

You are probably already familiar with the INotifyPropertyChanged interface, it is normally used to reflect the changes of an object in the user interface, LiveCharts also uses this interface to detect when a property on your data changed, but it is up to you to implement the interface.

The library already provides objects that implement the interface, you can use them to enable automatic property changed updates.

// The LiveChartsCore.Defaults.ObservableValue class is ready
// to update the user interface every time the Value property changes
var valuesCollection = new ObservableCollection<ObservableValue>();
valuesCollection.Add(new ObservableValue { Value = 1 });
valuesCollection.Add(new ObservableValue { Value = 2 });
valuesCollection.Add(new ObservableValue { Value = 3 });

// every time you update the Value property, you will also
// see that change in the user interface
valuesCollection[0].Value = 5;


// notice that valuesCollection is of type ObservableCollection
// this means that it is listening for add, remove, replace or clear changes
// in the collection, but in this case, the property changed update
// would have also worked if it was just a List<> or any other collection
var valuesCollection = new List<ObservableValue>();
valuesCollection.Add(new ObservableValue { Value = 1 });
valuesCollection.Add(new ObservableValue { Value = 2 });
valuesCollection.Add(new ObservableValue { Value = 3 });
// it also updates! but is not listening to add, remove, insert, replace and clear changes.
valuesCollection[0].Value = 5;

Finally you can also plot an object defined in you application (see Mappers), and the logic is the same, the library will be able to reflect the changes in the user interface just when your object implements INotifyPropertyChanged, lets take the following City class as an example.

public class City
{
    public double Population { get; set; }
}

// now in our chart we will plot objects of type City
var valuesCollection = new List<City>();

valuesCollection.Add(new City { Population = 100 });
valuesCollection.Add(new City { Population = 200 });
valuesCollection.Add(new City { Population = 300 });

// this will not update the user interface, since the City class does not
// implement INotifyPropertyChanged
valuesCollection[0].Population = 500;



// Lets now change the City class definition to implement INotifyPropertyChanged
// so our chart can update once the Population property changes
using System.ComponentModel;
using System.Runtime.CompilerServices;

public class City : INotifyPropertyChanged
{
    private double population;

    public double Population { get => population; set { population = value; OnPropertyChanged(); } }

    public event PropertyChangedEventHandler? PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(propertyName, new PropertyChangedEventArgs(propertyName));
    }
}

// after this implementation the chart will update once the Population property changes