chartjs是一款非常好用的數(shù)據(jù)可視化工具斋日,對比了echarts牲览、highcharts、c3桑驱、flot竭恬、amchart等各種工具后,現(xiàn)在我的畫圖表工具基本90%都是用chartjs來搞定熬的。
畫面效果、動態(tài)效果都很精致赊级,清爽簡潔押框,基本滿足了一般數(shù)據(jù)展示的需要,現(xiàn)在ppt都懶得做了理逊。
用php結(jié)合chartjs橡伞,效果棒棒盒揉。
上幾張圖,show一下兑徘。
屏幕快照 2018-12-27 下午8.15.37.png
屏幕快照 2018-12-27 下午8.16.00.png
new.png
不過問題也不少刚盈,數(shù)據(jù)不能在圖上顯示,這個很頭疼挂脑,在網(wǎng)上找到的解決方法也只有柱狀圖的藕漱,并沒有圓環(huán)圖、曲線圖崭闲,于是上chartjs的官網(wǎng)上肋联,下載了未壓縮版的chart.js文件,終于找到了解決辦法刁俭,效果如下橄仍。
屏幕快照 2018-12-26 下午8.13.17.png
屏幕快照 2018-12-26 下午8.14.00.png
chartjs
就是用canvas
ctx
畫圖,不嫌麻煩就可以為所欲為了牍戚。
柱狀圖中侮繁,關(guān)鍵在在option
中的animation
,如下:
options: {
animation: {
duration: 1,
onComplete: function() {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillStyle = '#006080';
this.data.datasets.forEach(function(dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function(arc, index) {
var data = dataset.data[index];
var ct=Math.round(arc._model.width*0.35);
if(ct<12){ct=12;}
ctx.font=ct+'px Arial';
ctx.fillText(data, arc._model.x, data>=0?arc._model.y :arc._model.y+15);
});
});
}
},
doughnut圓環(huán)圖如孝,我是這么寫的鼎天。
options: {
animation: {
duration: 1,
onComplete: function() {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
var i, len;
var x = 0;
var y = 0;
var count = 0;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
ctx.textBaseline = 'bottom';
// var total = this.data.total;
this.data.datasets.forEach(function(dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
var arc = meta.data[i];
var objLt10=0;//object less than 5%
var total =eval(dataset.data.join("+"));
meta.data.forEach(function(arc, index) {
var data = dataset.data[index];
var textshift=0;
if(data!=0){
var chartCenterX = arc._model.x;
var chartCenterY = arc._model.y;
var arcCenter = calc(arc._model.startAngle, arc._model.endAngle, arc._model.outerRadius*1.1, arc._model.innerRadius, chartCenterX, chartCenterY);
if(arc._model.circumference<0.314){
ctx.textBaseline = 'bottom';
objLt10++;
ctx.font="14px Arial";
ctx.fillStyle=arc._model.backgroundColor;
if(objLt10<=10) {
ctx.textAlign = 'left';
blockx=10;
cx=60;
cy=chartCenterY+arc._model.outerRadius+20-objLt10*25;
text='██ '+Math.round(data*100/total)+'%' ;
}else{
ctx.textAlign = 'right';
cx=arc._model.x*2-60;
blockx=arc._model.x*2-10;
cy=chartCenterY+arc._model.outerRadius+20-(objLt10-10)*25;
}
ctx.fillText(text, blockx,cy);
ctx.fillStyle='#808080';
ctx.fillText(arc._model.label+' '+data, cx,cy);
}else if(arc._model.circumference<0.628){
var textStart= calc(arc._model.startAngle, arc._model.endAngle, arc._model.outerRadius*1.1, arc._model.outerRadius, chartCenterX, chartCenterY);
var lineStart= calc(arc._model.startAngle, arc._model.endAngle, arc._model.outerRadius, arc._model.outerRadius*0.8, chartCenterX, chartCenterY);
var textCenterX = textStart.x;
var textCenterY = textStart.y;
if(textCenterY>arc._model.y+arc._model.outerRadius-20)
{
textCenterY=arc._model.y+arc._model.outerRadius-20;
textCenterX=textStart.x>arcCenter.x?textStart.x+50+textshift:textStart.x-50-textshift;
textshift=50;
}else if(textCenterY<arc._model.y-arc._model.outerRadius+20)
{
textCenterY=arc._model.y-arc._model.outerRadius+20;
textCenterX=textStart.x>arcCenter.x?textStart.x+50+textshift:textStart.x-50-textshift;
textshift=50;
}else{
textCenterX=textStart.x>arcCenter.x?textCenterX+textshift:textCenterX-textshift;
textshift=0;
};
ctx.strokeStyle=arc._model.backgroundColor;
ctx.beginPath();
ctx.moveTo(lineStart.x,lineStart.y);
ctx.lineTo(textCenterX,textCenterY>chartCenterY?textCenterY+13:textCenterY);
ctx.lineTo(textCenterX+(textStart.x>arcCenter.x?50:-50),textCenterY>chartCenterY?textCenterY+13:textCenterY);
ctx.stroke();
ctx.font="16px Arial";
ctx.textAlign = textStart.x>arcCenter.x?'left':'right';
ctx.textBaseline = 'bottom';
ctx.fillStyle="#006080";
ctx.fillText( arc._model.label+' '+data,
textCenterX, textCenterY>chartCenterY?textCenterY+13:textCenterY);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle=changeColor(arc._model.backgroundColor);
ctx.fillText(Math.round(data*100/total)+'%',
arcCenter.x,arcCenter.y);
}else if(arc._model.circumference>=0.628){
var arcCenterX = arcCenter.x;
var arcCenterY = arcCenter.y;
ctx.font="20px Arial";
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillStyle=changeColor(arc._model.backgroundColor);
ctx.fillText(Math.round(data*100/total)+'%', arcCenterX, arcCenterY<chartCenterY?arcCenterY+15:arcCenterY-5);
ctx.font="16px Arial";
ctx.fillText(arc._model.label+' '+data, arcCenterX, arcCenterY>=chartCenterY?arcCenterY+15:arcCenterY-5);
}
}
});
});
}
},
為了提高顯示效果,針對對于5%暑竟、5% ~ 10%之間斋射、超過10%分開處理。達(dá)到自己覺得還滿意的結(jié)果但荤。
ps:還得帶一個外掛罗岖,計(jì)算圓環(huán)的中心坐標(biāo)。
function calc(startAngle, endAngle, outerRadius, innerRadius ,x,y ) {
var centreAngle = startAngle + ((endAngle - startAngle) / 2);
var rangeFromCentre = (outerRadius - innerRadius) / 2 + innerRadius;
return {
x: x + (Math.cos(centreAngle) * rangeFromCentre),
y: y + (Math.sin(centreAngle) * rangeFromCentre)
}
};
為了讓隨機(jī)得到的顏色上面的字體顯示效果更好腹躁,設(shè)置了一個反差色的函數(shù)changeColor()桑包,這個在下一篇文章里面分享吧。