Ext JSの中でもトップレベルのダサさを誇るPieチャートコンポーネントをどうにかしてあげよう ;)
チャートコンポーネントを弄くるのが少し楽しくなってきたこの頃
どうも tnker です :)
前回チャートのテーマ作成と設定の仕方をやりましたね :)
これで皆さんもチャートの見た目弄り倒してテーマを作成してみましょう!
前回
そして今回は、Ext JSチャートコンポーネントの中でもトップレベルのダサさであるPieチャートの見た目をカスタマイズしてみます。
標準で用意されているPieチャートは次の通り
誰がどう見ても絶望的ですね。
今回はこれをシャレオツにしていきましょう。
設定項目は以外と少ない
Pieチャートの場合設定項目は以外と少なかったです。
Ext.define('App.view.charts.D', {
extend: 'Ext.chart.Chart',
xtype : 'chart-d',
width : 200,
height : 200,
animate : true,
store : 'LineStore',
shadow : false,
series: [{
type : 'pie',
angleField : 'data1',
donut : 90,
colorSet : ['#33BFDB', '#79D1B0', '#5EBABA', '#93B8CA'],
style : {
'stroke-width': 2,
'stroke': '#FFF'
}
}]
});
- shadow: false
- チープな影は消しちゃいましょう
- donut: 90
- 円グラフの真ん中に空白を入れて良い感じに
- colorSet: ['#33BFDB', '#79D1B0', '#5EBABA', '#93B8CA']
- ダサさの元凶である色の組み合わせを良い感じに変更しましょう
- style
- stroke-width: 2
- stroke: '#FFF'
- これは設定しなくても良いかもですが、設定している色によってはPieチャートの各フィールドの境目が分かりにくくなるかもしてないので、境界線を入れて分かりやすくします
これを表示してみると
こんな感じのクールなPieチャートに変身します!
Theme側にRendererを実装して更にシャレオツ度を上げる
これだけでも綺麗っちゃ綺麗なんですけど、Ext JSのチャートコンポーネントで用意されているTipやRendererの機能を使うことで、Chart.jsなんかに負けないチャートを作成することが出来ますよ!
今回はThemeクラスにRendererの処理を実装して、Pieチャート側に設定してみました。
Ext.define('App.view.charts.D', {
extend: 'Ext.chart.Chart',
requires: [
'App.chart.theme.FlatPie'
],
xtype : 'chart-d',
width : 200,
height : 200,
animate : true,
store : 'LineStore',
theme : 'FlatPie',
shadow : false,
initComponent: function() {
var me = this;
Ext.applyIf(me, {
series: [{
type : 'pie',
angleField : 'data1',
donut : 90,
renderer : App.chart.theme.FlatPie.total,
total: {
store: me.getStore(),
format: '0.00'
}
}]
});
me.callParent(arguments);
},
constructor: function() {
App.chart.theme.FlatPie.configure();
this.callParent(arguments);
}
});
FlatPieというようなThemeクラスを定義して、そっちにThemeの設定とRendererを実装し設定しています。 これだけの設定をするだけで、チャートの表示をしてみると
シャレオツ度が上がりましたね!
肝心のThemeクラスのコードは次の通りです。
FlatPieクラス
Ext.define('App.chart.theme.FlatPie', {
singleton: true,
configure: function() {
Ext.chart.theme.FlatPie = Ext.extend(Ext.chart.theme.Base, {
constructor: function(config) {
Ext.chart.theme.Base.prototype.constructor.call(this, Ext.apply({
colors: [
'#33BFDB',
'#79D1B0',
'#5EBABA',
'#93B8CA'
],
series: {
'stroke-width': 2
},
seriesThemes: [{
'stroke': '#FFF'
}]
}, config));
}
});
},
total: function(draw, record, style, index) {
var me = this,
pk = Ext.Array.pluck,
offset = 3,
sprite, values, total, temp;
me.total = me.total || {};
if (index === 0) {
if (!Ext.isEmpty(me.total.store)) {
if (Ext.isString(me.total.store)) {
me.total.store = Ext.getStore(me.total.store);
}
if (me.total.store.isStore) {
temp = pk(me.total.store.data.items, 'data');
temp = pk(temp, me.angleField);
total = Ext.Array.sum(temp);
if (!Ext.isEmpty(me.total.format)) {
total = Ext.util.Format.number(total, me.total.format);
}
}
}
sprite = Ext.create('Ext.draw.Sprite', {
type: 'text',
text: me.total.labelText || 'Total',
fill: me.total.labelFill || '#333',
surface: draw.surface,
font: me.total.labelFont || '24px HelveticaNeue-UltraLight'
});
values = Ext.create('Ext.draw.Sprite', {
type: 'text',
text: total || '999,999',
fill: me.total.labelFill || '#333',
surface: draw.surface,
font: me.total.totalFont || '36px HelveticaNeue-Bold'
});
sprite.show(true);
values.show(true);
sprite.setAttributes({
translate: {
x: ( draw.surface.width / 2 ) - ( sprite.el.dom.clientWidth / 2 ),
y: ( draw.surface.height / 2 ) + ( values.el.dom.clientHeight / 2 ) + offset
}
}, true);
values.setAttributes({
translate: {
x: ( draw.surface.width / 2 ) - ( values.el.dom.clientWidth / 2 ),
y: ( draw.surface.height / 2 ) - ( sprite.el.dom.clientHeight / 2 ) + offset
}
}, true);
}
}
});
やっていることはRendererの処理内で、チャートにバインドされているStoreとseriesに設定されているフィールドの合計値を描画しているだけです。
Theme側でtotalプロパティを参照して、各設定を行っています。
設定可能なプロパティは以下
total: {
store: xxx,
format: xxx,
labelFont: xxx,
labelFill: xxx,
labelText: xxx,
totalFont: xxx,
totalFill: xxx
}
- store
- チャートにバインドされているものと同じStoreを定義します(Storeのインスタンスもしくはクラス名を文字列指定)
- format
- 合計値を表示する際にフォーマットを行う場合は指定
- 指定出来るフォーマットについては Ext.util.Format.number 参照
- 合計値を表示する際にフォーマットを行う場合は指定
- labelFont
- ラベル部分のフォント情報を指定
- デフォルト値:'24px HelveticaNeue-UltraLight'
- ラベル部分のフォント情報を指定
- labelFill
- ラベル部分の文字色を指定
- デフォルト値:'#333'
- ラベル部分の文字色を指定
- labelText
- ラベルに表示する文字列を指定
- デフォルト値:'Total'
- ラベルに表示する文字列を指定
- totalFont
- 数値部分のフォント情報を指定
- デフォルト値:'36px HelveticaNeue-UltraLight'
- 数値部分のフォント情報を指定
- totalFill
- 数値部分の文字色を指定
- デフォルト値:'#333'
- 数値部分の文字色を指定
デフォルト値とかに関しては、思いっきり個人的な値が入っているので勝手に変えてください :(
ダサすぎなPieチャートもこれで中々のシャレオツコンポーネントになりましたね!:)