Ext JS 4 Line Chart Themeing

Sometimes using Ext JS 4.1 default chart themeing is not enough, we might want to change the colors, or to have more than the default number which will be repeated once all of them are used.

There are currently 7 default themes defined: "Base, Green, Sky, Red, Purple, Blue, Yellow, Category 1-6", In the Base theme all the attributes are predefined, in the color name themes, the colors are calculated by a base color which get stronger or lighter to create the scheme and in the categories the color scheme is predefined by a complete set of colors.

For example, category1 is defined as:
['#f0a50a', '#c20024', '#2044ba', '#810065', '#7eae29']

In the following example we are going to create a simple chart with: two axes (Date and Numeric), one line series and using a  default theme: 'Category 2', then we will define a new theme and use it instead:

The chart:



Ext.create('Ext.chart.Chart', {
    renderTo: Ext.getBody(),
    width: 1000,
    height: 800,
    animate: true,
    store: store,
    theme: 'Category2',
    axes: [
        {
            type: 'Numeric',
            position: 'left',
            fields: ['value'],
            label: {
                renderer: Ext.util.Format.numberRenderer('0,0')
            },
            title: 'Sample Values',
            grid: true,
            minimum: 0
        },
  {
   type: 'Time',
   position: 'bottom',
   fields: ['timestamp'],
   title: 'Day',
   dateFormat: 'M d',
   adjustEnd : true,
   fromDate: new Date('5/1/12'),
   toDate: new Date('5/20/12'),
   minorTickSteps: 5
  }
    ],
    series: [
        {
            type: 'line',
   fill: false,
            highlight: {
                size: 7,
                radius: 7
            },
            axis: 'left',
            xField: 'timestamp',
            yField: 'value',
            markerConfig: {
                type: 'cross',
                size: 4,
                radius: 4,
                'stroke-width': 0
            }
        }
    ]
});
All themes should extend the theme base class: 'Ext.chart.theme.Base', if you will open the link you will notice there is a red disclaimer on top of the page stating: "This is a private utility class for internal use by the framework. Don't rely on its existence" So we'll need to take this under consideration as this is the only way to define a new theme.

There are 3 ways to define a new theme by extending the base class, after which you will be able to use
theme: 'CustomTheme', 
in the chart creation instead of 'Category2', we'll take a look at them now:

  1. Define the base color only and let Ext JS calculate the scheme itself, we'll get 5 colors: 2 lighter and 2 darker than the base color
    Ext.define('Ext.chart.theme.CustomTheme', {
            extend: 'Ext.chart.theme.Base',
            constructor: function(config) {
                this.callParent([Ext.apply({
       baseColor: '#2f4993'
                }, config)]);
            }
        });
    
  2. Define the colors to be used in the scheme ourselves using an array
    Ext.define('Ext.chart.theme.CustomTheme', {
            extend: 'Ext.chart.theme.Base',
            constructor: function(config) {
                this.callParent([Ext.apply({
       colors: [ "#92EC00", "#0772A1","#FFD200", "#D30068", "#7EB12C", "#225E79", "#BFA630", "#9E2862"]
                }, config)]);
            }
        });
    
  3. Define all the attributes ourselves
        Ext.define('Ext.chart.theme.CustomTheme', {
            extend: 'Ext.chart.theme.Base',
            constructor: function(config) {
                this.callParent([Ext.apply({
                    background: false,
                    axis: {
                        stroke: '#444',
                        'stroke-width': 3
                    },
                    axisLabelTop: {
                        fill: '#444',
                        font: '12px Arial, Helvetica, sans-serif',
                        spacing: 2,
                        padding: 5,
                        renderer: function(v) { return v; }
                    },
                    axisLabelRight: {
                        fill: '#444',
                        font: '12px Arial, Helvetica, sans-serif',
                        spacing: 2,
                        padding: 5,
                        renderer: function(v) { return v; }
                    },
                    axisLabelBottom: {
                        fill: '#444',
                        font: '12px Arial, Helvetica, sans-serif',
                        spacing: 2,
                        padding: 5,
                        renderer: function(v) { return v; }
                    },
                    axisLabelLeft: {
                        fill: '#444',
                        font: '12px Arial, Helvetica, sans-serif',
                        spacing: 2,
                        padding: 5,
                        renderer: function(v) { return v; }
                    },
                    axisTitleTop: {
                        font: 'bold 18px Arial',
                        fill: '#444'
                    },
                    axisTitleRight: {
                        font: 'bold 18px Arial',
                        fill: '#444',
                        rotate: {
                            x:0, y:0,
                            degrees: 270
                        }
                    },
                    axisTitleBottom: {
                        font: 'bold 18px Arial',
                        fill: '#444'
                    },
                    axisTitleLeft: {
                        font: 'bold 18px Arial',
                        fill: '#444',
                        rotate: {
                            x:0, y:0,
                            degrees: 270
                        }
                    },
                    series: {
                        'stroke-width': 0
                    },
                    seriesLabel: {
                        font: '12px Arial',
                        fill: '#333'
                    },
                    marker: {
                        stroke: '#555',
                        fill: '#000',
                        radius: 3,
                        size: 3
                    },
                seriesThemes: [{
                    fill: "#92EC00"
                }, {
                    fill: "#0772A1"
                }, {
                    fill: "#FFD200"
                }, {
                    fill: "#D30068"
                }, {
                    fill: "#7EB12C"
                }, {
                    fill: "#225E79"
                }, {
                    fill: "#BFA630"
                }, {
                    fill: "#9E2862"
                }],
                markerThemes: [{
                    fill: "#115fa6",
                    type: 'plus' 
                }, {
                    fill: "#94ae0a",
                    type: 'cross'
                }, {
                    fill: "#a61120",
                    type: 'plus'
                }]
                }, config)]);
            }
        });
    
After defining this class we can use 'CustomeTheme' in our chart and get the color scheme we wanted.

I hope you found this guide helpful :-)

Comments

  1. Thank you sooooooo much! The comment in the source code is either mis-leading or just plain wrong. Sometimes the finer details of extending ExtJS gets lost on me and this is EXACTLY what I needed!!! +100

    ReplyDelete

Post a Comment

Popular posts from this blog

1. Starting with MongoDB, nodejs and mongoose - part I

HTC One X - Jelly Bean update - quick review

Things you need from time to time I