Data Binding

Using this guide, you will begin by learning different approaches to providing data for the dxChart, dxPieChart and dxSparkline widgets. After that, you will discover how to bind data to a widget and specify data-binding settings of that widget. Finally, you will learn how to update data in your widget.

Before you begin, please make sure you have successfully linked the necessary libraries and added the required widget to your page. If not, begin by learning how to do this using the Installation topic.

Provide Data

You can use one of the two approaches to provide data for dxChart, dxPieChart or dxSparkline. The first is declaring an array of plain objects and using it as a data source. For more information on this approach, see the Using an Array of Objects topic. The second is implementing a data source using the data library. With its new level of sophistication, this approach brings you the privileges and flexibility not before seen in primitive arrays. This approach is discussed in greater detail in the Using the Data Library topic.

View Demo

Using an Array of Objects

The simplest way of providing data is using an array of plain objects. Each object in this array specifies series values for a particular argument. dxPieChart and dxSparkline can contain only one series. Therefore, providing data for these widgets requires only one series value to be specified for each argument. The following code snippet shows how to declare an array to be used as a data source for dxPieChart and dxSparkline.

JavaScript
var commonDataSource = [
    { year: 2005, value: 2450 },
    { year: 2006, value: 2156 },
    // ...
    { year: 2014, value: 3650 }
];

This array can be used as a data source in dxChart as well, but in this case, dxChart will display only one series. If you wish to display multiple series in dxChart, specify several values for one argument. For example, the array in the following code snippet provides data for three series named 'aluminum', 'nickel' and 'copper'.

JavaScript
var chartDataSource = [
    { year: 2005, aluminum: 2450, nickel: 1800, copper: 2230 },
    { year: 2006, aluminum: 2156, nickel: 2105, copper: 1990 },
    // ...
    { year: 2014, aluminum: 3650, nickel: 3254, copper: 4052 }
];

In dxChart, the majority of series types requires one value for one argument to define one series point. Data sources for such series are represented above. However, there are series types that require two or more values for one argument to define one point. For example, a range area or range bar series needs two values, while a candle stick or stock series needs four values for one argument. The code snippet below shows how to implement a data source for two series of the range bar type.

JavaScript
var rangeDataSource = [
    { year: 2005, aluminumMin: 2450, aluminumMax: 2750, copperMin: 2230, copperMax: 2600 },
    { year: 2006, aluminumMin: 2156, aluminumMax: 2300, copperMin: 1990, copperMax: 2120 },
    // ...
    { year: 2014, aluminumMin: 3650, aluminumMax: 3850, copperMin: 3500, copperMax: 4300 }
];

After you have implemented a data source, bind it to your widget. To learn how to do this, refer to the Bind Data topic.

Using the Data Library

DevExtreme integrates a data library, which allows you to read and write data. A comprehensive overview of data library features is provided in the Data Layer topic. This data library is comprised of a DataSource and a Store.

A DataSource is a stateful object that keeps sorting, grouping, filtering and data transformation options, and applies them each time data is loaded. It also provides events intended to handle data and state changes. More information on the DataSource object can be found in the Reference section.

A Store is a universal data access interface that is comprised of a number of methods for reading and editing data. You can find a listing of these methods in the What Are Stores topic. There are four types of stores.

  • ArrayStore - provides access to an in-memory array
  • LocalStore - provides access to the HTML5 web storage
  • ODataStore - provides access to a remote OData service
  • CustomStore - allows you to implement your own data access logic

dxChart, dxPieChart and dxSparkline accept a DataSource instance that must have its store field specified. You must assign an object configuring the required store to this field. This rule, however, can be ignored if you use a CustomStore. In this case, specify all store settings directly in the instance object, omitting the use of the store field.

In the following subtopics, you will learn how to configure stores of different types.

Using an ArrayStore

This type of store is great when you need a simple data source with the data lifetime equaling the lifetime of your application. An ArrayStore is created from an array of plain objects. Your widget creates it automatically when such an array is specified for it (see Using an Array of Objects). However, you may need to create an ArrayStore explicitly if you need to handle the events of data loading, updating, etc., in a special way on the store level. The code snippet below illustrates the creating of a DataSource on the base of an ArrayStore. This DataSource can be used to provide data for the dxChart, dxPieChart or dxSparkline widget.

JavaScript
var dataSource = new DevExpress.data.DataSource({
    store: {
        type: 'array',
        data: [
            { year: 2005, value: 2450 },
            { year: 2006, value: 2156 },
            // ...
            { year: 2014, value: 3650 }
        ]
    },
    paginate: false
});
NOTE
We recommend turning pagination off when using a DataSource. This action will prevent your data from partitioning.

In addition, you can specify the store's key option to get a read-write access to data. An ArrayStore has many more options available for configuring. For the full list of them, refer to the ArrayStore reference section.

After you have created a DataSource, you need to bind it to your chart. Refer to the Bind Data section to learn how to do this.

Using a LocalStore

This type of store is helpful when you use an HTML5 Web Storage (also known as window.localStorage) for storing your data. To create a DataSource on the base of a LocalStore, specify the type and name options of the store object as demonstrated below.

JavaScript
var dataSource = new DevExpress.data.DataSource({
    store: {
        type: 'local',
        name: 'MyLocalStore'
    },
    paginate: false
});
NOTE
We recommend turning pagination off when using a DataSource. This action will prevent your data from partitioning.

In addition, you can specify the store's key option to have a read-write access to data.

After that, populate the store (which lays under the DataSource) with data using its insert(values) method.

dataSource.store().insert({ year: 2005, value: 2450 });

A LocalStore has many more options available for configuring. For a full list, refer to the LocalStore reference section.

After you have created a DataSource, you need to bind it to your widget. Refer to the Bind Data section to learn how to do this.

Using an ODataStore

OData is a universal open protocol for consuming data APIs. The DevExtreme data library provides a special type of store to access OData web services, called ODataStore. The following code is sufficient for providing data for a widget using an ODataStore.

JavaScript
var dataSource = new DevExpress.data.DataSource({
    store: {
        type: 'odata',
        url: 'http://url/to/the/source'
    },
    paginate: false
});
NOTE
We recommend turning pagination off when using a DataSource. This action will prevent your data from partitioning.

In some cases, this configuration is not enough for a ODataStore to support proper operation. This may occur due to the same-origin policy restrictions. For more information, read the Note on Same-Origin Policy topic.

In addition, you can specify the store's key option to get a read-write access to data. An ODataStore has many more options available for configuring. For a complete list, refer to the ODataStore reference section.

After you have created a DataSource, you need to bind it to your chart. Refer to the Bind Data section to learn how to do this.

Using a CustomStore

When you have a custom web service with its own data accessing logic, use a CustomStore to operate that data. This type of store requires the implementation of a function for each data access operation. To provide data for dxChart, dxPieChart or dxSparkline, implement the load function at least. As an example of such an implementation, consider the following code snippet.

JavaScript
var dataSource = new DevExpress.data.DataSource({
    load: function (loadOptions) {
        var d = new $.Deferred();
        $.getJSON('http://mydomain.com/MyDataService')
            .done(function (data) {
                // ...
                // process data here
                // ...
                d.resolve(data); 
        });
        return d.promise();
    }
});

To see more examples of CustomStore implementation, refer to the Custom Sources topic. In addition, you can review the full list of CustomStore options in the CustomStore reference section.

After you have created a DataSource, you need to bind it to your chart. Refer to the Bind Data section to learn how to do this.

You can see an example of a chart using a Custom Store in the Use Remote Data for a Chart tutorial.

View Demo

Bind Data

Regardless of the approach you've chosen to provide data, after implementing a data source, bind it to your widget using its dataSource option. The code snippet below demonstrates how to do this for the dxChart widget.

JavaScript
var chartDataSource = // ...

var chartOptions = {
    dataSource: chartDataSource
};

Set an Argument Field

After you have bound data to your widget, you need to specify which fields of a data source object must be used to provide arguments and values for chart points. To specify the argument field name, assign it to the argumentField option. This option can be specified differently depending on the widget you use.

  • dxChart
    Usually, dxChart contains several series that have the same argument field. You can specify the argument field for all these series at once within the commonSeriesSettings object.

    JavaScript
    var chartOptions = {
        //...
        commonSeriesSettings: {
            argumentField: 'year'
        }
    };

    Similarly, you can specify the argumentField option within the series object in case you have only one series in your chart.

    JavaScript
    var chartOptions = {
        //...
        series: {
            argumentField: 'year',
            // ...
        }
    };

    In rare cases, you may need different argument fields for different series. Then, assign an array to the series option and specify the argumentField option in each object of this array.

    JavaScript
    var chartOptions = {
        //...
        series: [{
            argumentField: 'year1990',
            // ...
        }, {
            argumentField: 'year2000'
            // ...
        }]
    };
  • dxPieChart
    To specify an argument field for a series in the dxPieChart widget, set the argumentField option within the series object.

    JavaScript
    $("#pieChartContainer").dxPieChart({
        //...
        series: {
            argumentField: 'year',
            // ...
        }
    };
  • dxSparkline
    The argumentField option for the dxSparkline widget must be specified in the root configuration object.

    JavaScript
    $("#sparklineContainer").dxSparkline({
        //...
        argumentField: 'year'
    };

To finish setting up the minimal configuration for you widget, specify one or several value fields for your series. To learn how to do this, refer to the next topic.

Set a Value Field

To set the value field name, assign it to the valueField option. Similarly to the argumentField option, valueField is set differently depending on the widget in use.

  • dxChart
    If you have only one series in your chart, specify the valueField option within the series object.

    JavaScript
    var chartOptions = {
        //...
        series: {
            valueField: 'year',
            // ...
        }
    };

    If you have several series in your chart, assign an array of objects to the series option and specify an individual value field for each object of this array.

    JavaScript
    var chartOptions = {
        //...
        series: [{
            valueField: 'copper',
            // ...
        }, {
            valueField: 'nickel'.
            // ...
        }]
    };

    Certain series types require several value fields to be specified for one series. In these instances, data source fields must be set using options particular to a specific series type. For example, the following code snippet shows how to specify value fields for a Range Area and Range Bar series.

    JavaScript
    var rangeDataSource = [
        { month: 'January', min1: 36, max1: 43.29, min2:  42.12, max2: 49.91 },
        //...
    ];
    var chartOptions = {
        //...
        dataSource: rangeDataSource,
        commonSeriesSettings: {
            type: 'rangebar' // type: 'rangearea',
        },
        series: [
            { rangeValue1Field: 'min1', rangeValue2Field: 'max1' },
            { rangeValue1Field: 'min2', rangeValue2Field: 'max2' }
        ]
    };

    The following code demonstrates how to set value fields for the Candle Stick and Stock series types.

    JavaScript
    var stockDataSource = [
        { date: new Date(1994,2,1), lowPrice: 24.00, highPrice: 25.00, openPrice: 25.00, closePrice: 24.875 },
        //...
    ];
    var chartOptions = {
        //...
        dataSource: stockDataSource,
        commonSeriesSettings: {
            type: 'stock' // type: 'candlestick',
        },
        series: {         
             openValueField: 'openPrice',
             closeValueField: 'closePrice',
             lowValueField: 'lowPrice',
             highValueField: 'highPrice'
        }
    };

    Series of the Bubble type slightly differ from other series. Along with the value field, they require the size field to be specified. The code below illustrates how to specify the value and size fields for the bubble series.

    JavaScript
    var dataSource = [
        { month: 'January', val1: 24, size1: 25, val2: 14, size2: 31  },
        //...
    ];
    var chartOptions = {
        //...
        dataSource: dataSource,
        commonSeriesSettings: {
            type: 'bubble'
        },
        series: [
            { valueField: 'val1', sizeField: 'size1' },
            { valueField: 'val2', sizeField: 'size2' }
        ]
    });
  • dxPieChart
    To specify the value field for a series in the dxPieChart widget, set the valueField option within the series object.

    JavaScript
    $("#pieChartContainer").dxPieChart({
        //...
        series: {
            valueField: 'copper',
            // ...
        }
    });
  • dxSparkline
    The valueField option for the dxSparkline widget must be specified in the root configuration object.

    JavaScript
    $("#sparklineContainer").dxSparkline({
        //...
        valueField: 'year'
    });

At this point, you have created a data source and configured data-binding settings of your widget. If your data source is supposed to be invariable, these actions are sufficient to support a correct operation of your widget. But you may have a scenario that requires a data source to be changed dynamically, and these changes must be reflected in your widget. Refer to the next topic to learn the approaches you can use for updating data in that case.

Update Data

When a data source assigned to the dxChart, dxPieChart or dxSparkline widget is changed, the widget must be updated in order to reflect the current state of the data source. Subtopics in this section provide an overview of approaches you can use to support the dynamic widget update. Before you begin, please make sure that you know the basics of configuring a data visualization widget using the jQuery, Knockout or AngularJS approach.

See Also

Using jQuery

When using jQuery, rebind the data source to your widget in order to update data in this widget. To do this, obtain its instance at first. The following code snippet demonstrates how this can be done for a pie chart.

JavaScript
var pieChart = $("#pieChartContainer").dxPieChart("instance");

After that, call the option() method of this instance. Pass an object with the specified dataSource field to this method.

JavaScript
pieChart.option({ dataSource: updatedDataSource });

Alternatively, you can call the option() method with two arguments: the name of the option that must be changed and a new value for this option.

JavaScript
pieChart.option('dataSource', updatedDataSource);

After the option is changed, your widget will be refreshed automatically.

Show Example:
jQuery

This example shows how data in the dxChart and dxPieChart widget can be updated. Here, these widgets have the same data source. When you click one of the buttons located below the widgets, this data source is updated. To make the widgets reflect changes made in the data source, the data source must be rebound to the widgets. This is performed using the option() method of the widget instance.


                                    

                                    

Using Knockout

The dataSource option, like any other option from the first level of the widget's configuration object, can be declared as an observable variable. Any changes in the option value will be detected and the widget will be refreshed automatically.

HTML
<div id="chartContainer" style="height:400px; width: 600px" data-bind="dxChart: {
    dataSource: observableChartDataSource
    ...
}"></div>
JavaScript
var myViewModel = {
    observableChartDataSource: ko.observableArray(data),
    //...
};
ko.applyBindings(myViewModel);
Show Example:
jQuery

This example illustrates the capability of the dxSparkline widget to refresh itself when its data source is updated. This data source is declared as an observable array. Each time a new entry is added to the data source using the addPoint function, the dxSparkline widget is refreshed automatically.


                                    

                                    

Using AngularJS

In order to update data in your widget when using AngularJS, provide two-way binding between the dataSource option and the corresponding field of the $scope object. For this purpose, add the bindingOptions field to the widget configuration object. This field is assigned an object containing options that require two-way binding. In your case, the dataSource is such an option. In the following code snippet, the dataSource $scope field is used to provide data for dxChart.

HTML
<div ng-controller="myController">
    <div dx-chart="{
        ...
        bindingOptions: {
            dataSource: 'dataSource'
        }
    }"></div>
</div>
JavaScript
var myApp = angular.module('myApp', ['dx']);
myApp.controller('myController', function ($scope) {
    $scope.dataSource = dataArray;
});
NOTE
When specifying options within the bindingOptions object, you must use the name of the corresponding $scope object field instead of the field itself.

In order to keep data in your widget up-to-date after the data source is changed, you need to wrap actions that modify the data source in the following construction.

JavaScript
$scope.$apply(function () {
    // perform actions on the data source here
});

Obviously, this code must be used inside the controller constructor. The resulting implementation of a dynamically updating data source for an abstract application is given below. With this code, your widget will be refreshed automatically after the data source is changed.

JavaScript
var myApp = angular.module('myApp', ['dx']);
myApp.controller('myController', function ($scope) {
    $scope.dataSource = dataArray;
    $scope.dataChangingFunction = function () {
        $scope.$apply(function () {
            // perform actions on the data source here
        });
    }
});

Using the Data Library

For a read-write access to data, use a Store directly. To obtain a store instance from a DataSource, call its store() method.

JavaScript
var store = dataSource.store();

To update a data item specified by a key, use the update(key, values) method of a store instance.

JavaScript
store.update(1, { value: "new value" })
    .done(function(values) {
        // handle successful updating
    })
    .fail(function(error) {
        // handle an error
    });

Note that the second argument of the update(key, values) method contains only the options whose values should be changed in the data item, but not the entire item, because it will be merged with the original item object. Before updating, you may need to obtain the required item using the byKey(key) method of a store instance.

After a store has been updated, call the load() method of the DataSource object to update data in your widget as well.

JavaScript
dataSource.load();

For details on data modification in the Data Library, refer to the Data Modification topic.

Show Example:
jQuery

This example shows how data in the dxChart and dxPieChart widgets can be updated using the Data Library. Here, these widgets are bound to a DataSource object. When you click one of the buttons located below the widgets, an ArrayStore that lies under the DataSource object is updated. The load() method of the DataSource object must be called in order for widgets reflect changes made in the ArrayStore.