Code:
/**
*
* @author Steve McArthur
* @class HK.chart.TreeMap
* @extends Ext.draw.Component
* Treemaps display hierarchical (tree-structured) data as a set of nested rectangles.
* Each nested rectangle has an area proportional to a specified dimension on the data.
* See: http://en.wikipedia.org/wiki/Treemapping
* By default this class uses the Squarify algorithmn to calculate the tree map. It is
* based on the open source code written by Martin Cowie and found at: http://js-treemap.sourceforge.net/
*
* Example usage:
<pre><code>
Ext.define("Dept", {
extend : 'Ext.data.Model',
fields : ['id', 'Name', 'Title', {
name : 'Cost',
type : 'float'
}],
hasMany : {
model : 'Savings',
name : 'savings'
}
});
var myStore = Ext.create('Ext.data.ArrayStore', {
autoDestroy : true,
model : 'Dept',
data : [[1, "Corporate, Subsidy, Grant & Levies etc", "Corporate, Subsidy, Grant & Levies etc", 556.23], [2, "Health and Community Services", "Health and Community Services", 171.71], [3, "Children and Young People", "Children and\r\n Young People", 51.87], [4, "Finance and Resources", "Finance and Resources", 47.39], [5, "Legal, HR and Regulatory Services", "Legal, HR and\r\n Regulatory Services", 15.74], [6, "Chief Executive", "Chief Executive", 8.24], [7, "Housing", "Housing", 2]]
});
Ext.create('HK.chart.TreeMap', {
chartWidth: 1000,
chartHeight: 530,
chartX: 0,
chartY: 40,
store: myStore,
renderTo: Ext.getBody()
});
</code></pre>
* @xtype treemap
*
*/
Ext.define('HK.chart.TreeMap', {
extend: 'Ext.draw.Component',
alternateClassName: 'TreeMap',
requires: ['HK.chart.Squarify', 'HK.chart.TreeMapSprite'],
type: 'treemap',
store: {},
nodes: [],
sprites: [],
startTotal: 0,
textThreshold: 5,
inheritableStatics: {
TreeMapEngine: {
'squarify': HK.chart.Squarify
}
},
setOpacity: function(cmp, op, speed, callback) {
var duration = speed || 500;
if (!callback) {
callback = Ext.emptyFn;
}
// cmp.stopAnimation();
return cmp.animate({
to: {
opacity: op
},
duration: duration,
callback: callback
});
},
setSpriteOpacity: function(op, cmp, speed, arr) {
var me = this;
var items = arr || me.sprites;
var op2 = op === 1 ? 0 : 1;
me.hoverTitle.setAttributes({
text: cmp.text,
opacity: op2
}, true);
Ext.each(items, function(item, idx, all) {
if (item.id != cmp.id) {
item.stopAnimation();
me.setOpacity(item, op, speed);
if (item.title && !item.title.hidden) {
item.title.stopAnimation();
item.subTitle.stopAnimation();
me.setOpacity(item.title, op, speed);
me.setOpacity(item.subTitle, op, speed);
}
}
});
},
/**
* Creates new TreeMap.
* @param {Object} config Config object.
*/
constructor: function(config) {
var me = this;
me.store = config.store;
var defaults = {
viewBox: false,
autoShow: true,
width: config.chartWidth + 50,
height: config.chartHeight + 70,
x: 0,
y: 0,
renderTo: Ext.get('div1'),
engine: 'squarify'
};
config = Ext.apply(defaults, config);
me.callParent([config]);
var engine = TreeMap.TreeMapEngine[this.engine];
me.nodes = engine.create(me.store, config.chartX, config.chartY, config.chartWidth, config.chartHeight);
me.startTotal = HK.chart.Squarify.getTotal(me.nodes);
TreeMapSprite.surface = me.surface;
me.hoverTitle = Ext.create('Ext.draw.Sprite', {
type: 'text',
"text-anchor": "end",
"text": "hoverTitle",
opacity: 0,
font: 'bold 14px Arial',
fill: '#666666',
x: 950,
y: this.chartY + this.chartHeight + 20
});
me.surface.add(me.hoverTitle).show(true);
},
show: function() {
var me = this;
var l = me.nodes.length;
var nodes = me.nodes;
for (var i = 0; i < l; i++) {
var rec = nodes[i];
var clr = Ext.draw.Color.fromString(rec.col);
//this will be the fade out color
var clr2 = clr.getLighter(0.4);
var width = rec.coords.width;
var height = rec.coords.height;
var txtX = rec.coords.x + 10;
var txtY = rec.coords.y + 20;
var text = "£" + rec.Cost;
text = rec.Cost < 150 ? text + "bn" : text + " billion";
var textSize = "25px";
var hidden = false;
if (rec.Cost < 150 && rec.Cost > 40) {
textSize = "20px";
} else if (rec.Cost < 41) {
textSize = "16px";
}
if (rec.Cost < this.textThreshold) {
hidden = true;
}
var cfg = {
x: rec.coords.x,
y: rec.coords.y,
width: width,
height: height,
startFill: clr2.toString(),
fill: rec.col,
costs: rec.Cost,
text: rec.Title + " " + text,
titleTxt: rec.Title,
itemNo: i,
hidden: false,
opacity: 0,
treeMap: me,
title: Ext.create('Ext.draw.Sprite', {
type: 'text',
"text-anchor": "left",
"text": text,
font: '500 ' + textSize + ' "Times New Roman",Georgia,Serif',
fill: '#FFFFFF',
// surface: this.surface,
hidden: hidden,
x: txtX,
y: txtY,
zIndex: 10
}),
subTitle: Ext.create('Ext.draw.Sprite', {
type: 'text',
"text-anchor": "left",
"text": rec.Name,
font: 'bold 12px Arial',
fill: '#FFFFFF',
hidden: hidden,
// surface: this.surface,
x: txtX,
y: txtY + 20,
zIndex: 10
})
};
var item = Ext.create('HK.chart.TreeMapSprite', cfg);
me.sprites.push(item);
}
Ext.each(me.sprites, function(sp, idx) {
me.surface.add(sp).show(true).animate({
to: {
opacity: 1
},
duration: 1000,
easing: 'easeIn'
});
me.surface.add(sp.title).show(!sp.title.hidden);
me.surface.add(sp.subTitle).show(!sp.subTitle.hidden);
});
me.showBorder();
},
showBorder: function() {
var me = this;
if (!me.chartBorder) {
me.chartBorder = Ext.create('Ext.draw.Sprite', {
type: 'rect',
width: me.chartWidth,
height: me.chartHeight,
x: me.chartX,
y: me.chartY,
stroke: '#000000',
"stroke-opacity": 1,
"stroke-width": 3,
fill: 'none',
opacity: 1,
zIndex: 9999
});
me.surface.add(me.chartBorder);
}
me.chartBorder.show(true);
}
})