Extjs chart Legend (Legend) branch and Column Display

Source: Internet
Author: User

Legend of Chart in Extjs.

Legend.

What exactly does Extjs Chart represent? Take a look at this figure:


The red area on the right is Legend.

In the definition of Extjs Chart, you can configure the configuration value (configs) of legend to set the position and style of the Legend display:

Position: The displayed position can be set to "top", "bottom", "left", "right", or "float ".

For more information, see Ext. chart. Legend.

The specific settings are as follows:




How Legend is divided or divided into branches-History

The default display method of Extjs Legend is single row or column. (Based on location configuration differences)

All the configurations, attributes, and methods in the reference document of Legend cannot be found. How can we display Legend by branch or by column.

The updatePosition ([relativeTo]) method is found in the reference document of legendItem.

Legend is the entire Legend, and LegendItem should be each Legend in it.

Therefore, a solution is generated:

1. Can I set the location of legendItem when appropriate?

First, what is the right time? In the afterRender event,

However, the actual test shows that the legend is not produced in the afterRender of the Chart. This Form and Grid mechanisms look different.

No way. You can only set one button and click to see if this solution is feasible.

1) obtain the legend of the Chart.

var chart = Ext.getCmp("testChart");var legend = chart.legend;
My Chart Id is testChart.

2) Get ChartItems

var legendItems = legend.items;

3) loop through the preceding array and set the positions of each Item. The positions are calculated by yourself (x, y coordinates)

legendItem.updatePosition({x:xPos,y:yPos});
The location is indeed changed.


At this point, the problem is not over,

The Item on the legend can be clicked, and after clicking it, the corresponding graph can be displayed and hidden.

Using the above method, after clicking it, It is restored to its original state.

So I came up with another idea,

2. Can I add a click event to LegendItem? Re-calculate the location in the click and update/

legendItem.on("click",function(){legendItem.updatePosition({x:xPos,y:yPos});});

If this method is complex or not, you will find a problem:

That is, legendItem must have more than two points to trigger the above function.

Dubug found that Legend item has two click events, one being native and the other being added later.

This method will certainly have problems.

Therefore, the above method can only be declared as failure.


Legend breakdown or branch

It seems that we can only consider the source code level of Extjs.

The underlying technology of Extjs Chart is nothing more than SVG and VML.

For more information, see:

[One of the Web Chart series] comparison of SVG, VML, and HTML5 Canvas technologies for drawing Web Images

The Extjs Chart is based on the raphael framework. For details about raphael, refer to the official website:

Http://raphaeljs.com/

The thought process is omitted, and the conclusion is: rewrite the updatePosition method of Ext. chart. LegendItem and Ext. chart. Legend:

  New Document 
 <script></script>
 Insert title here<script type="text/javascript" src="../ext-all-debug.js"></script>
 <script>Ext.chart.LegendItem.override({    updateSpecPosition: function(positionTo) {        var me = this,                   items = me.items,            ln = items.length,            i = 0,            item; var posX = positionTo.x;var posY = positionTo.y;        for (; i < ln; i++) {            item = items[i];            switch (item.type) {                case 'text':                    item.setAttributes({                        x: 20 + posX,                        y: posY                    }, true);                    break;                case 'rect':                    item.setAttributes({                        translate: {                            x: posX,                            y: posY - 6                        }                    }, true);                    break;                default:                    item.setAttributes({                        translate: {                            x: posX,                            y: posY                        }                    }, true);            }        }    }});Ext.chart.Legend.override({ updatePosition: function() {        var me = this,            items = me.items,            pos, i, l, bbox;        if (me.isDisplayed()) {                        pos = me.calcPosition();                        me.x = pos.x;            me.y = pos.y;            //items[i].updatePosition({x:100,y:100});                        var posX = me.x;            var posY = me.y;            for (i = 0, l = items.length; i < l; i++) {            posX = me.x;            posY = me.y;            //items[i].updatePosition();                           if(i%2>0)            {            posX += 80;            }                            posY += parseInt(i/2)*30;                        items[i].updateSpecPosition({x:posX,y:posY});            }            bbox = me.getBBox();                                                                        if (isNaN(bbox.width) || isNaN(bbox.height)) {                if (me.boxSprite) {                    me.boxSprite.hide(true);                }            }            else {                if (!me.boxSprite) {                    me.createBox();                }                                                me.boxSprite.setAttributes(bbox, true);                me.boxSprite.show(true);            }        }    }});</script><script>Ext.onReady(function(){var store = Ext.create('Ext.data.JsonStore', {        fields: ['year', 'comedy', 'action', 'drama', 'thriller'],        data: [                {year: 2005, comedy: 34000000, action: 23890000, drama: 18450000, thriller: 20060000},                {year: 2006, comedy: 56703000, action: 38900000, drama: 12650000, thriller: 21000000},                {year: 2007, comedy: 42100000, action: 50410000, drama: 25780000, thriller: 23040000},                {year: 2008, comedy: 38910000, action: 56070000, drama: 24810000, thriller: 26940000}              ]    });    var chart = Ext.create('Ext.chart.Chart',{            id:'testChart',    animate: true,            shadow: true,            store: store,            legend: {                //position: 'right',                //position:'float',                position: 'bottom',                boxStroke: '#FFF',                legendCol:2,                update:false            },            axes: [{                type: 'Numeric',                position: 'bottom',                fields: ['comedy', 'action', 'drama', 'thriller'],                title: false,                grid: true,                label: {                    renderer: function(v) {                        return String(v).replace(/(.)00000$/, '.$1M');                    }                }            }, {                type: 'Category',                position: 'left',                fields: ['year'],                title: false            }],            series: [{                type: 'bar',                axis: 'bottom',                gutter: 80,                xField: 'year',                yField: ['comedy', 'action', 'drama', 'thriller'],                stacked: true,                tips: {                    trackMouse: true,                    width: 65,                    height: 28,                    renderer: function(storeItem, item) {                        this.setTitle(String(item.value[1] / 1000000) + 'M');                    }                }            }]        });    var panel1 = Ext.create('widget.panel', {        width: 800,        height: 400,        title: 'Stacked Bar Chart - Movies by Genre',        renderTo: Ext.getBody(),        layout: 'fit',        tbar: [{            text: 'Save Chart',            handler: function() {                Ext.MessageBox.confirm('Confirm Download', 'Would you like to download the chart as an image?', function(choice){                    if(choice == 'yes'){                        chart.save({                            type: 'image/png'                        });                    }                });            }        }],        items: chart    });});</script>

Note:

1. The above is not a complete and perfect code. It just shows the POC code that can be implemented in this way.

2. Do you need to calculate the position of the arrangement by yourself, multiple rows or multiple columns?




Results and summary

Finally, let's look at the implementation results.


Of course, if LegendItem is relatively small, it does not make sense to split the branch and column.

Applicable scenarios: Many legenditems, more than 20 or 30, greatly affecting the page senses.

However, in actual development, this situation should be relatively small.

If there is such a situation, we need to carefully consider it from the beginning, and try to avoid such a demand, because even if the development, for so many Series, the speed will naturally not be faster.



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.