如何使用Chart.js在圆环图中添加文本?
如何在甜甜圈图表内呈现文本,我正在使用ChartJs 。
您必须修改代码,如: chart.Doughnut.defaults
labelFontFamily : "Arial", labelFontStyle : "normal", labelFontSize : 24, labelFontColor : "#666"
然后在函数drawPieSegments
ctx.fillText(data[0].value + "%", width/2 - 20, width/2, 200);
看到这个拉: https : //github.com/nnnick/Chart.js/pull/35
这里清理并结合以上解决scheme的例子 – 响应式(尝试调整窗口大小),支持animation自动alignment,支持工具提示
https://jsfiddle.net/cmyker/u6rr5moq/
Chart.types.Doughnut.extend({ name: "DoughnutTextInside", showTooltip: function() { this.chart.ctx.save(); Chart.types.Doughnut.prototype.showTooltip.apply(this, arguments); this.chart.ctx.restore(); }, draw: function() { Chart.types.Doughnut.prototype.draw.apply(this, arguments); var width = this.chart.width, height = this.chart.height; var fontSize = (height / 114).toFixed(2); this.chart.ctx.font = fontSize + "em Verdana"; this.chart.ctx.textBaseline = "middle"; var text = "82%", textX = Math.round((width - this.chart.ctx.measureText(text).width) / 2), textY = height / 2; this.chart.ctx.fillText(text, textX, textY); } }); var data = [{ value: 30, color: "#F7464A" }, { value: 50, color: "#E2EAE9" }, { value: 100, color: "#D4CCC5" }, { value: 40, color: "#949FB1" }, { value: 120, color: "#4D5360" }]; var DoughnutTextInsideChart = new Chart($('#myChart')[0].getContext('2d')).DoughnutTextInside(data, { responsive: true });
<html> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script> <body> <canvas id="myChart"></canvas> </body> </html>
没有其他的答案根据文本的数量和甜甜圈的大小调整文本的大小。 这里有一个小脚本可以用来dynamic地放置任何数量的文本,它会自动resize。 http://jsfiddle.net/nkzyx50o/
它将采取任何数量的文字在甜甜圈大小完美的甜甜圈。 为了避免碰到边缘,可以将边填充设置为圆内部直径的百分比。 如果你没有设置,它将默认为20.你也是颜色,字体和文本。 该插件照顾其余的。
插件代码将以30px的基础字体大小开始。 从那里它将检查文本的宽度,并将其与圆的半径进行比较,然后根据圆/文本宽度比调整它的大小。
这是插件代码
Chart.pluginService.register({ beforeDraw: function (chart) { if (chart.config.options.elements.center) { //Get ctx from string var ctx = chart.chart.ctx; //Get options from the center object in options var centerConfig = chart.config.options.elements.center; var fontStyle = centerConfig.fontStyle || 'Arial'; var txt = centerConfig.text; var color = centerConfig.color || '#000'; var sidePadding = centerConfig.sidePadding || 20; var sidePaddingCalculated = (sidePadding/100) * (chart.innerRadius * 2) //Start with a base font of 30px ctx.font = "30px " + fontStyle; //Get the width of the string and also the width of the element minus 10 to give it 5px side padding var stringWidth = ctx.measureText(txt).width; var elementWidth = (chart.innerRadius * 2) - sidePaddingCalculated; // Find out how much the font can grow in width. var widthRatio = elementWidth / stringWidth; var newFontSize = Math.floor(30 * widthRatio); var elementHeight = (chart.innerRadius * 2); // Pick a new font size so it will not be larger than the height of label. var fontSizeToUse = Math.min(newFontSize, elementHeight); //Set font settings to draw it correctly. ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; var centerX = ((chart.chartArea.left + chart.chartArea.right) / 2); var centerY = ((chart.chartArea.top + chart.chartArea.bottom) / 2); ctx.font = fontSizeToUse+"px " + fontStyle; ctx.fillStyle = color; //Draw text in center ctx.fillText(txt, centerX, centerY); } } });
在图表对象中使用以下选项
options: { elements: { center: { text: 'Desktop', color: '#36A2EB', //Default black fontStyle: 'Helvetica', //Default Arial sidePadding: 15 //Default 20 (as a percentage) } } }
我会避免修改chart.js代码来实现这一点,因为使用常规的CSS和HTML很容易。 这是我的解决scheme:
HTML:
<canvas id="productChart1" width="170"></canvas> <div class="donut-inner"> <h5>47 / 60 st</h5> <span>(30 / 25 st)</span> </div>
CSS:
.donut-inner { margin-top: -100px; margin-bottom: 100px; } .donut-inner h5 { margin-bottom: 5px; margin-top: 0; } .donut-inner span { font-size: 12px; }
输出如下所示:
基于@ rap-2-h答案,这里是在Chart.js的圆环图上使用文本的代码,以便在仪表板中使用。 它具有响应选项的dynamic字体大小。
HTML:
<div>text <canvas id="chart-area" width="300" height="300" style="border:1px solid"/><div>
脚本:
var doughnutData = [ { value: 100, color:"#F7464A", highlight: "#FF5A5E", label: "Red" }, { value: 50, color: "#CCCCCC", highlight: "#5AD3D1", label: "Green" } ]; $(document).ready(function(){ var ctx = $('#chart-area').get(0).getContext("2d"); var myDoughnut = new Chart(ctx).Doughnut(doughnutData,{ animation:true, responsive: true, showTooltips: false, percentageInnerCutout : 70, segmentShowStroke : false, onAnimationComplete: function() { var canvasWidthvar = $('#chart-area').width(); var canvasHeight = $('#chart-area').height(); //this constant base on canvasHeight / 2.8em var constant = 114; var fontsize = (canvasHeight/constant).toFixed(2); ctx.font=fontsize +"em Verdana"; ctx.textBaseline="middle"; var total = 0; $.each(doughnutData,function() { total += parseInt(this.value,10); }); var tpercentage = ((doughnutData[0].value/total)*100).toFixed(2)+"%"; var textWidth = ctx.measureText(tpercentage).width; var txtPosx = Math.round((canvasWidthvar - textWidth)/2); ctx.fillText(tpercentage, txtPosx, canvasHeight/2); } }); });
这里的示例code.try来调整窗口的大小。 http://jsbin.com/wapono/13/edit
这也是我的最后…
<div style="width: 100px; height: 100px; float: left; position: relative;"> <div style="width: 100%; height: 40px; position: absolute; top: 50%; left: 0; margin-top: -20px; line-height:19px; text-align: center; z-index: 999999999999999"> 99%<Br /> Total </div> <canvas id="chart-area" width="100" height="100" />
这是基于Cmyker对Chart.js 2的更新(张贴为另一个答案,因为我还不能评论)
当显示图例时,由于图表高度没有包含此图标,所以在Chrome中的文本alignment方式出现问题,因此在中间没有正确alignment。 通过计算fontSize和textY来解决这个问题。
我计算方法内的百分比,而不是一个设定值,因为我有多个这样的网页。 假设是你的图表只有2个值(否则它的百分比是多less?第一个是你想显示的百分比)我还有一堆其他的图表,所以我做了一个types=甜甜圈的检查。我只使用甜甜圈来显示百分比,所以它适用于我。
文本颜色似乎有点击中和取决于什么顺序的事情运行等等,所以我遇到了一个问题,当resize,文本会改变颜色(黑色和原色之间的一种情况下,二级颜色和白色在另一个)如此无论现有的填充样式是什么,我都会“保存”,绘制文本(以主数据的颜色),然后恢复旧的填充样式。 (保留旧的填充样式似乎并不需要,但你永远不知道。)
https://jsfiddle.net/g733tj8h/
Chart.pluginService.register({ beforeDraw: function(chart) { var width = chart.chart.width, height = chart.chart.height, ctx = chart.chart.ctx, type = chart.config.type; if (type == 'doughnut') { var percent = Math.round((chart.config.data.datasets[0].data[0] * 100) / (chart.config.data.datasets[0].data[0] + chart.config.data.datasets[0].data[1])); var oldFill = ctx.fillStyle; var fontSize = ((height - chart.chartArea.top) / 100).toFixed(2); ctx.restore(); ctx.font = fontSize + "em sans-serif"; ctx.textBaseline = "middle" var text = percent + "%", textX = Math.round((width - ctx.measureText(text).width) / 2), textY = (height + chart.chartArea.top) / 2; ctx.fillStyle = chart.config.data.datasets[0].backgroundColor[0]; ctx.fillText(text, textX, textY); ctx.fillStyle = oldFill; ctx.save(); } } });
var data = { labels: ["Red","Blue"], datasets: [ { data: [300, 50], backgroundColor: ["#FF6384","#36A2EB"], }] }; Chart.pluginService.register({ beforeDraw: function(chart) { var width = chart.chart.width, height = chart.chart.height, ctx = chart.chart.ctx, type = chart.config.type; if (type == 'doughnut') { var percent = Math.round((chart.config.data.datasets[0].data[0] * 100) / (chart.config.data.datasets[0].data[0] + chart.config.data.datasets[0].data[1])); var oldFill = ctx.fillStyle; var fontSize = ((height - chart.chartArea.top) / 100).toFixed(2); ctx.restore(); ctx.font = fontSize + "em sans-serif"; ctx.textBaseline = "middle" var text = percent + "%", textX = Math.round((width - ctx.measureText(text).width) / 2), textY = (height + chart.chartArea.top) / 2; ctx.fillStyle = chart.config.data.datasets[0].backgroundColor[0]; ctx.fillText(text, textX, textY); ctx.fillStyle = oldFill; ctx.save(); } } }); var myChart = new Chart(document.getElementById('myChart'), { type: 'doughnut', data: data, options: { responsive: true, legend: { display: true } } });
<script src="ajax/libs/Chart.js/2.1.6/Chart.bundle.js"></script> <canvas id="myChart"></canvas>
你也可以在onAnimationComplete
选项中粘贴mayankcpdixit的代码:
// ... var myDoughnutChart = new Chart(ctx).Doughnut(data, { onAnimationComplete: function() { ctx.fillText(data[0].value + "%", 100 - 20, 100, 200); } });
文字将在animation之后显示
我用7个JQuieryUI Slider和ChartJs创build了一个演示(里面有dynamic文本)
Chart.types.Doughnut.extend({ name: "DoughnutTextInside", showTooltip: function() { this.chart.ctx.save(); Chart.types.Doughnut.prototype.showTooltip.apply(this, arguments); this.chart.ctx.restore(); }, draw: function() { Chart.types.Doughnut.prototype.draw.apply(this, arguments); var width = this.chart.width, height = this.chart.height; var fontSize = (height / 140).toFixed(2); this.chart.ctx.font = fontSize + "em Verdana"; this.chart.ctx.textBaseline = "middle"; var red = $( "#red" ).slider( "value" ), green = $( "#green" ).slider( "value" ), blue = $( "#blue" ).slider( "value" ), yellow = $( "#yellow" ).slider( "value" ), sienna = $( "#sienna" ).slider( "value" ), gold = $( "#gold" ).slider( "value" ), violet = $( "#violet" ).slider( "value" ); var text = (red+green+blue+yellow+sienna+gold+violet) + " minutes"; var textX = Math.round((width - this.chart.ctx.measureText(text).width) / 2); var textY = height / 2; this.chart.ctx.fillStyle = '#000000'; this.chart.ctx.fillText(text, textX, textY); } }); var ctx = $("#myChart").get(0).getContext("2d"); var myDoughnutChart = new Chart(ctx).DoughnutTextInside(data, { responsive: false });
在JSFIDDLE中进行演示
@ rap-2-h和@Ztuons Ch的答案不允许showTooltips
选项处于活动状态,但是您可以做的是在呈现图表的一个背景之后创build第二个canvas
对象。
重要的部分是在div和canvas对象本身所需的样式,以便它们呈现在彼此之上。
var data = [ {value : 100, color : 'rgba(226,151,093,1)', highlight : 'rgba(226,151,093,0.75)', label : "Sector 1"}, {value : 100, color : 'rgba(214,113,088,1)', highlight : 'rgba(214,113,088,0.75)', label : "Sector 2"}, {value : 100, color : 'rgba(202,097,096,1)', highlight : 'rgba(202,097,096,0.75)', label : "Sector 3"} ] var options = { showTooltips : true }; var total = 0; for (i = 0; i < data.length; i++) { total = total + data[i].value; } var chartCtx = $("#canvas").get(0).getContext("2d"); var chart = new Chart(chartCtx).Doughnut(data, options); var textCtx = $("#text").get(0).getContext("2d"); textCtx.textAlign = "center"; textCtx.textBaseline = "middle"; textCtx.font = "30px sans-serif"; textCtx.fillText(total, 150, 150);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script> <html> <body> <div style="position: relative; width:300px; height:300px;"> <canvas id="text" style="z-index: 1; position: absolute; left: 0px; top: 0px;" height="300" width="300"></canvas> <canvas id="canvas" style="z-index: 2; position: absolute; left: 0px; top: 0px;" height="300" width="300"></canvas> </div> </body> </html>
首先,selectChart.js的赞誉! 我正在使用它在我目前的项目之一,我绝对喜欢它 – 它完美的工作。
尽pipe标签/工具提示不是库的一部分,但您可能需要查看以下三个请求:
- 提示
- 将标签添加到饼图
- 向饼图添加基本标签
而且,正如Cracker0dks提到的那样,Chart.js使用canvas
进行渲染,因此您可以直接通过与之交互来实现自己的工具提示。
希望这可以帮助。