Диаграммы в Ext JS

Есть три типа диаграмм: cartesian, polar и spacefilling.

Ext.chart.CartesianChart (xtype: cartesian or chart)
У графика в прямоугольной системе координат (cartesian) есть два направления: X и Y. Диаграммы которые используют прямоугольную систему координат: column, bar, area, line и scatter.

Ext.chart.PolarChart (xtype: polar)
Эти диаграммы имеют две оси: angular и radial.
Диаграммы, которые используют полярные координаты: pie и radar.

Ext.chart.SpaceFillingChart (xtype: spacefilling)
Эти диаграммы заполняют всю область отведенную под диаграмму.

Столбчатая диаграмма


Для начала создадим древовидное хранилище данных:

Ext.define('MyApp.model.Population', {
    extend: 'Ext.data.Model',
    fields: ['year', 'population']
});
Ext.define('MyApp.store.Population', {
    extend: 'Ext.data.Store',
    storeId: 'population',
    model: 'MyApp.model.Population',
    data: [{
        "year": "1610",
        "population": 350
    }, {
        "year": "1650",
        "population": 50368
    }, {
        "year": "1700",
        "population": 250888
    }, {
        "year": "1750",
        "population": 1170760
    }, {
        "year": "1800",
        "population": 5308483
    }, {
        "year": "1900",
        "population": 76212168
    }, {
        "year": "1950",
        "population": 151325798
    }, {
        "year": "2000",
        "population": 281421906
    }, {
        "year": "2010",
        "population": 308745538
    }, ]
});
var store = Ext.create("MyApp.store.Population");

Теперь используя Ext.chart.CartesianChart (xtype: cartesian or chart ) создадим диаграмму:

Ext.create('Ext.Container', {
    renderTo: Ext.getBody(),
    width: 500,
    height: 500,
    layout: 'fit',
    items: [{
        xtype: 'chart',
        insetPadding: {
            top: 60,
            bottom: 20,
            left: 20,
            right: 40
        },
        store: store,
        axes: [{
            type: 'numeric',
            position: 'left',
            grid: true,
            title: {
                text: 'Population in Millions',
                fontSize: 16
            },
        }, {
            type: 'category',
            title: {
                text: 'Year',
                fontSize: 16
            },
            position: 'bottom',
        }],
        series: [{
            type: 'bar',
            xField: 'year',
            yField: ['population']
        }],
        sprites: {
            type: 'text',
            text: 'United States Population',
            font: '25px Helvetica',
            width: 120,
            height: 35,
            x: 100,
            y: 40
        }
    }]
});

Оси (axes) могут быть одного из трех типов: numeric, time или category.

В series установлен тип bar. В Ext JS чтобы визуализировать column или bar chart нужно указывать тип bar. Но если вам нужен bar chart, то нужно еще установить flipXY в true.

Опция grid может указывать для обеих осей.

Если не указывать insetPadding, то заголовок и другая информация могут перекрываться.

Линейчатая диаграмма



Ext.create('Ext.Container', {
    renderTo: Ext.getBody(),
    width: 500,
    height: 500,
    layout: 'fit',
    items: [{
        xtype: 'chart',
        flipXY: true,
        insetPadding: {
            top: 60,
            bottom: 20,
            left: 20,
            right: 40
        },
        store: store,
        axes: [{
            type: 'numeric',
            position: 'bottom',
            grid: true,
            title: {
                text: 'Population in Millions',
                fontSize: 16
            },
        }, {
            type: 'category',
            title: {
                text: 'Year',
                fontSize: 16
            },
            position: 'left',
        }],
        series: [{
            type: 'bar',
            xField: 'year',
            yField: ['population']
        }],
        sprites: {
            type: 'text',
            text: 'United States Population',
            font: '25px Helvetica',
            width: 120,
            height: 35,
            x: 100,
            y: 40
        }
    }]
});

Stacked chart

Что если в столбчатой диаграмме нам нужно отображать два значения в категории. Вы можете отобразить их стопкой или иметь по два столбца в каждой категории.

Отображение стопкой:




Ext.define('MyApp.model.Population', {
    extend: 'Ext.data.Model',
    fields: ['year', 'total', 'slaves']
});
Ext.define('MyApp.store.Population', {
    extend: 'Ext.data.Store',
    storeId: 'population',
    model: 'MyApp.model.Population',
    data: [{
        "year": "1790",
        "total": 3.9,
        "slaves": 0.7
    }, {
        "year": "1800",
        "total": 5.3,
        "slaves": 0.9
    }, {
        "year": "1810",
        "total": 7.2,
        "slaves": 1.2
    }, {
        "year": "1820",
        "total": 9.6,
        "slaves": 1.5
    }, {
        "year": "1830",
        "total": 12.9,
        "slaves": 2
    }, {
        "year": "1840",
        "total": 17,
        "slaves": 2.5
    }, {
        "year": "1850",
        "total": 23.2,
        "slaves": 3.2
    }, {
        "year": "1860",
        "total": 31.4,
        "slaves": 4
    }, ]
});
var store = Ext.create("MyApp.store.Population");
Ext.create('Ext.Container', {
    renderTo: Ext.getBody(),
    width: 500,
    height: 500,
    layout: 'fit',
    items: [{
        xtype: 'cartesian',
        store: store,
        insetPadding: {
            top: 60,
            bottom: 20,
            left: 20,
            right: 40
        },
        axes: [{
            type: 'numeric',
            position: 'left',
            grid: true,
            title: {
                text: 'Population in Millions',
                fontSize: 16
            },
        }, {
            type: 'category',
            title: {
                text: 'Year',
                fontSize: 16
            },
            position: 'bottom',
        }],
        series: [{
            type: 'bar',
            xField: 'year',
            yField: ['total', 'slaves']
        }],
        sprites: {
            type: 'text',
            text: 'United States Slaves Distribution 1790 to 1860',
            font: '20px Helvetica',
            width: 120,
            height: 35,
            x: 60,
            y: 40
        }
    }]
});

Если вы хотите отображать два значений в категории без stacking-а то можете просто установить свойство stacked у series в false и получите следующее:



Ext.create('Ext.Container', {
    renderTo: Ext.getBody(),
    width: 500,
    height: 500,
    layout: 'fit',
    items: [{
        xtype: 'chart',
        legend: {
            docked: 'bottom'
        },
        insetPadding: {
            top: 60,
            bottom: 20,
            left: 20,
            right: 40
        },
        store: store,
        axes: [{
            type: 'numeric',
            position: 'left',
            grid: true,
            title: {
                text: 'Population in Millions',
                fontSize: 16
            },
            minimum: 0,
        }, {
            type: 'category',
            title: {
                text: 'Year',
                fontSize: 16
            },
            position: 'bottom',
        }],
        series: [{
            type: 'bar',
            xField: 'year',
            stacked: false,
            title: ['Total', 'Slaves'],
            yField: ['total', 'slaves'],
            tooltip: {
                trackMouse: true,
                style: 'background: #fff',
                renderer: function(storeItem, item) {
                    this.setHtml('In ' + storeItem.get('year') + ' ' + item.
                    field + ' population was ' + storeItem.get(item.field) + ' m');
                }
            }],
        sprites: [{
            type: 'text',
            text: 'United States Slaves Distribution 1790 to 1860',
            font: '20px Helvetica',
            width: 120,
            height: 35,
            x: 60,
            y: 40
        }, {
            type: 'text',
            text: 'Source: http://www.wikipedia.org',
            fontSize: 10,
            x: 12,
            y: 440
        }]
        }]
    });


3D bar chart

Если просто изменить тип серий на 3D bar вместо bar, то можно получить 3D column chart.


Диаграмма с областями (area chart) и линейный график (line chart)

Чтобы отобразить комбинированную двумерную диаграмму просто замените серии в предыдущем примере на:

series: [{
    type: 'area',
    xField: 'year',
    stacked: false,
    title: ['Total', 'slaves'],
    yField: ['total', 'slaves'],
    style: {
        stroke: "#94ae0a",
        fillOpacity: 0.6,
    }
}]


Подобно stacked column chart можно сделать stacked area chart также устанавливая свойство stacked в true для серий.


Для линейного графика используйте следующие серии:

series: [{
    type: 'line',
    xField: 'year',
    title: ['Total'],
    yField: ['total']

}, {
    type: 'line',
    xField: 'year',
    title: ['Slaves'],
    yField: ['slaves']
}],


Круговая диаграмма (pie chart)

Для отображения круговой диаграммы используется Ext.chart.PolarChart (xtype: polar).



Ext.define('MyApp.store.Expense', {
    extend: 'Ext.data.Store',
    alias: 'store.expense',
    fields: ['cat', 'spent'],
    data: [{
        "cat": "Restaurant",
        "spent": 100
    }, {
        "cat": "Travel",
        "spent": 150
    }, {
        "cat": "Insurance",
        "spent": 500
    }, {
        "cat": "Rent",
        "spent": 1000
    }, {
        "cat": "Groceries",
        "spent": 400
    }, {
        "cat": "Utilities",
        "spent": 300
    }, ]
});

var store = Ext.create("MyApp.store.Expense");
Ext.create('Ext.Container', {
    renderTo: Ext.getBody(),
    width: 600,
    height: 500,
    layout: 'fit',
    items: [{
        xtype: 'polar',
        legend: {
            docked: 'bottom'
        },
        insetPadding: {
            top: 100,
            bottom: 20,
            left: 20,
            right: 40
        },
        store: store,
        series: [{
            type: 'pie',
            angleField: 'spent',
            label: {
                field: 'cat',
            },
            tooltip: {
                trackMouse: true,
                renderer: function(storeItem, item) {
                    var value = ((parseFloat(storeItem.get('spent') / storeItem.store.sum('spent')) * 100.0).toFixed(2));
                    this.setHtml(storeItem.get('cat') + ': ' + value + '%');
                }
            }
        }]
    }]
});


Кольцевая диаграмма (donut chart)

Если у серий установить свойство donut на 40 в предыдущем примере, то получится следующее:

3D pie chart



Ext.create('Ext.Container', {
    renderTo: Ext.getBody(),
    width: 600,
    height: 500,
    layout: 'fit',
    items: [{
        xtype: 'polar',
        legend: {
            docked: 'bottom'
        },
        insetPadding: {
            top: 100,
            bottom: 20,
            left: 80,
            right: 80
        },
        store: store,
        series: [{
            type: 'pie3d',
            donut: 50,
            thickness: 70,
            distortion: 0.5,
            angleField: 'spent',
            label: {
                field: 'cat'
            },
            tooltip: {
                trackMouse: true,
                renderer: function(storeItem, item) {
                    var value = ((parseFloat(storeItem.get('spent') / storeItem.store.sum('spent')) * 100.0).toFixed(2));
                    this.setHtml(storeItem.get('cat') + ': ' + value + '%');
                }
            }
        }]
    }]
});