如何使用Chart.js在甜甜圈图中添加文本?

时间:2022-12-04 09:24:54

How to render Text inside the doughnut chart, I am using ChartJs.

如何在甜甜圈图表中显示文本,我正在使用ChartJs。

13 个解决方案

#1


25  

You have to modify the code like: in chart.Doughnut.defaults

您必须修改代码,比如:在chart. doughnu .defaults中

labelFontFamily : "Arial",
labelFontStyle : "normal",
labelFontSize : 24,
labelFontColor : "#666"

and then in function drawPieSegments

然后在函数drawPieSegments中。

ctx.fillText(data[0].value + "%", width/2 - 20, width/2, 200);

ctx.fillText(数据[0]。值+“%”,宽度/2 - 20,宽度/ 2,200);

See this pull: https://github.com/nnnick/Chart.js/pull/35

看到这个拉:https://github.com/nnnick/Chart.js/pull/35

here is a fiddle http://jsfiddle.net/mayankcpdixit/6xV78/ implementing the same.

下面是一个小提琴http://jsfiddle.net/mayankcpdixit/6xV78/实现相同。

#2


64  

None of the other answers resize the text based off the amount of text and the size of the doughnut. Here is a small script you can use to dynamically place any amount of text in the middle, and it will automatically resize it. http://jsfiddle.net/nkzyx50o/

其他答案都不会根据文本的数量和甜甜圈的大小调整文本大小。这里有一个小脚本,您可以使用它来动态地在中间放置任何数量的文本,它将自动调整大小。http://jsfiddle.net/nkzyx50o/

如何使用Chart.js在甜甜圈图中添加文本?

It will take any amount of text in the doughnut sized perfect for the doughnut. To avoid touching the edges you can set a side-padding as a percentage of the diameter of the inside of the circle. If you don't set it, it will default to 20. You also the color, the font, and the text. The plugin takes care of the rest.

它会在甜甜圈大小的甜甜圈中使用任何数量的文字。为了避免接触到边缘,你可以设置一个边距作为圆内径的百分比。如果你不设置它,它将默认为20。还有颜色、字体和文本。插件负责其余部分。

The plugin code will start with a base font size of 30px. From there it will check the width of the text and compare it against the radius of the circle and resize it based off the circle/text width ratio.

插件代码将以30px的基本字体开始。从那里,它将检查文本的宽度,并将它与圆的半径进行比较,并根据圆/文本宽度比调整它的大小。

This is the plugin code

这是插件代码

 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);
    }
  }
});

And you use the following options in your chart object

在图表对象中使用以下选项

options: {
  elements: {
      center: {
      text: 'Desktop',
      color: '#36A2EB', //Default black
      fontStyle: 'Helvetica', //Default Arial
      sidePadding: 15 //Default 20 (as a percentage)
    }
  }
}

#3


39  

Here is cleaned up and combined example of above solutions - responsive (try to resize the window), supports animation self-aligning, supports tooltips

这里是清理和结合的例子上面的解决方案-响应(尝试调整窗口大小),支持动画自对齐,支持工具提示

https://jsfiddle.net/cmyker/u6rr5moq/

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>

UPDATE 17.06.16:

更新17.06.16:

Same functionality but for chart.js version 2:

同样的功能,但是用于图表。js版本2:

https://jsfiddle.net/cmyker/ooxdL2vj/

https://jsfiddle.net/cmyker/ooxdL2vj/

var data = {
  labels: [
    "Red",
    "Blue",
    "Yellow"
  ],
  datasets: [
    {
      data: [300, 50, 100],
      backgroundColor: [
        "#FF6384",
        "#36A2EB",
        "#FFCE56"
      ],
      hoverBackgroundColor: [
        "#FF6384",
        "#36A2EB",
        "#FFCE56"
      ]
    }]
};

Chart.pluginService.register({
  beforeDraw: function(chart) {
    var width = chart.chart.width,
        height = chart.chart.height,
        ctx = chart.chart.ctx;

    ctx.restore();
    var fontSize = (height / 114).toFixed(2);
    ctx.font = fontSize + "em sans-serif";
    ctx.textBaseline = "middle";

    var text = "75%",
        textX = Math.round((width - ctx.measureText(text).width) / 2),
        textY = height / 2;

    ctx.fillText(text, textX, textY);
    ctx.save();
  }
});

var chart = new Chart(document.getElementById('myChart'), {
  type: 'doughnut',
  data: data,
  options: {
  	responsive: true,
    legend: {
      display: false
    }
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.6/Chart.bundle.js"></script>
<canvas id="myChart"></canvas>

#4


25  

I'd avoid modifying the chart.js code to accomplish this, since it's pretty easy with regular CSS and HTML. Here's my solution:

我避免修改图表。js代码可以实现这一点,因为使用常规的CSS和HTML非常容易。这是我的解决方案:

HTML:

HTML:

<canvas id="productChart1" width="170"></canvas>
<div class="donut-inner">
    <h5>47 / 60 st</h5>
    <span>(30 / 25 st)</span>
</div>

CSS:

CSS:

.donut-inner {
   margin-top: -100px;
   margin-bottom: 100px;
}
.donut-inner h5 {
   margin-bottom: 5px;
   margin-top: 0;
}
.donut-inner span {
   font-size: 12px;
}

The output looks like this:

输出如下:

如何使用Chart.js在甜甜圈图中添加文本?

#5


11  

This is also working at my end...

这在我这边也起作用……

<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" />

如何使用Chart.js在甜甜圈图中添加文本?

#6


10  

Base on @rap-2-h answer,Here the code for using text on doughnut chart on Chart.js for using in dashboard like. It has dynamic font-size for responsive option.

基于@ rap2 -h的回答,这里是使用图上的甜甜圈图的代码。用于在仪表板中使用。它有动态字体大小的响应选项。

HTML:

HTML:

<div>text
<canvas id="chart-area" width="300" height="300" style="border:1px solid"/><div>

Script:

脚本:

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);
  }
 });
});

Here the sample code.try to resize the window. http://jsbin.com/wapono/13/edit

这里的示例代码。尝试调整窗口的大小。http://jsbin.com/wapono/13/edit

#7


8  

This is based on Cmyker's update for Chart.js 2. (posted as another answer as I can't comment yet)

这是基于Cmyker更新的图表。js 2。(作为另一个回答,我还不能评论)

I had an issue with the text alignment on Chrome when the legend is displayed as the chart height does not include this so it's not aligned correctly in the middle. Fixed this by accounting for this in the calculation of fontSize and textY.

当图例显示时,我对Chrome上的文本对齐有一个问题,因为图表高度不包含这个,所以它在中间没有正确对齐。修正了这个问题,在计算字体大小和字体的时候。

I calculated percentage inside the method rather than a set value as I have multiple of these on the page. Assumptions are that your chart only has 2 values (otherwise what is the percentage of? and that the first is the one you want to show the percentage for. I have a bunch of other charts too so I do a check for type = doughnut. I'm only using doughnuts to show percentages so it works for me.

我计算了方法内部的百分比,而不是设置值,因为我在页面上有多个这样的值。假设您的图表只有两个值(否则百分比是多少?第一个是你想要显示的百分比。我还有一些其他的图表所以我检查type = doughnut。我只是用甜甜圈来表示百分比,所以它对我很有用。

Text color seems a bit hit and miss depending on what order things run in etc so I ran into an issue when resizing that the text would change color (between black and the primary color in one case, and secondary color and white in another) so I "save" whatever the existing fill style was, draw the text (in the color of the primary data) then restore the old fill style. (Preserving the old fill style doesn't seem needed but you never know.)

文本颜色似乎有点碰巧取决于订单的事情在等我遇到了一个问题,当调整文本会改变颜色(黑色和原色之间在一个案例中,和次要颜色和白色在另一个)所以我“拯救”不管现有填充风格,画出文本的颜色(主数据)然后恢复旧的风格。(似乎不需要保留原来的填充样式,但您永远不会知道。)

https://jsfiddle.net/g733tj8h/

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="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.6/Chart.bundle.js"></script>
<canvas id="myChart"></canvas>

#8


6  

You can also paste mayankcpdixit's code in onAnimationComplete option :

您还可以在onAnimationComplete选项中粘贴mayankcpdixit的代码:

// ...
var myDoughnutChart = new Chart(ctx).Doughnut(data, {
    onAnimationComplete: function() {
        ctx.fillText(data[0].value + "%", 100 - 20, 100, 200);
    }
});

Text will be shown after animation

文本将在动画之后显示

#9


6  

I create a demo with 7 JQuieryUI Slider and ChartJs (with dinamic text inside)

我用7个JQuieryUI滑动条和ChartJs创建了一个演示程序(其中包含了dinaper文本)

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
});

DEMO IN JSFIDDLE

演示在JSFIDDLE

如何使用Chart.js在甜甜圈图中添加文本?

#10


2  

@rap-2-h and @Ztuons Ch's answer doesn't allow for the showTooltips option to be active, but what you can do is create and layer a second canvas object behind the one rendering the chart.

@rap-2-h和@Ztuons Ch的答案不允许showtooltip选项是活动的,但是您可以做的是创建并在呈现图表的第二个画布对象后面分层第二个画布对象。

The important part is the styling required in the divs and for the canvas object itself so that they render on top of each other.

重要的部分是div中需要的样式,以及画布对象本身的样式,以使它们呈现在彼此之上。

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>

Here's the jsfiddle: https://jsfiddle.net/68vxqyak/1/

这是jsfiddle:https://jsfiddle.net/68vxqyak/1/

#11


1  

@Cmyker, great solution for chart.js v2

@Cmyker,很好的图表解决方案。js v2

One little enhancement: It makes sense to check for the appropriate canvas id, see the modified snippet below. Otherwise the text (i.e. 75%) is also rendered in middle of other chart types within the page.

一个小小的改进:检查适当的画布id是有意义的,请参阅下面修改过的代码片段。否则,文本(例如75%)也会在页面中的其他图表类型中间呈现。

  Chart.pluginService.register({
    beforeDraw: function(chart) {
      if (chart.canvas.id === 'doghnutChart') {
        let width = chart.chart.width,
            height = chart.chart.outerRadius * 2,
            ctx = chart.chart.ctx;

        rewardImg.width = 40;
        rewardImg.height = 40;
        let imageX = Math.round((width - rewardImg.width) / 2),
            imageY = (height - rewardImg.height ) / 2;

        ctx.drawImage(rewardImg, imageX, imageY, 40, 40);
        ctx.save();
      }
    }
  });

Since a legend (see: http://www.chartjs.org/docs/latest/configuration/legend.html) magnifies the chart height, the value for height should be obtained by the radius.

因为一个图例(参见:http://www.chartjs.org/docs/latest/configuration/d.html)放大了图表的高度,所以高度的值应该通过半径来获得。

#12


0  

First of all, kudos on choosing Chart.js! I'm using it on one of my current projects and I absolutely love it - it does the job perfectly.

首先,感谢大家选择Chart.js!我正在我目前的一个项目中使用它,我非常喜欢它——它完美地完成了这项工作。

Although labels/tooltips are not part of the library yet, you may want to take a look at these three pull requests:

虽然标签/工具提示还不是库的一部分,但是您可能想看看这三个拉取请求:

And, as Cracker0dks mentioned, Chart.js uses canvas for rendering so you may as well just implement your own tooltips by interacting with it directly.

正如Cracker0dks提到的,图表。js使用canvas进行渲染,因此您也可以直接与它交互,从而实现自己的工具提示。

Hope this helps.

希望这个有帮助。

#13


0  

You can use css with relative/absolute positioning if you want it responsive. Plus it can handle easily the multi-line.

如果你想要回应,你可以使用相对/绝对定位的css。另外,它可以轻松处理多行。

https://jsfiddle.net/mgyp0jkk/

https://jsfiddle.net/mgyp0jkk/

<div class="relative">
  <canvas id="myChart"></canvas>      
  <div class="absolute-center text-center">
    <p>Some text</p>
    <p>Some text</p>
  </div>
</div>

#1


25  

You have to modify the code like: in chart.Doughnut.defaults

您必须修改代码,比如:在chart. doughnu .defaults中

labelFontFamily : "Arial",
labelFontStyle : "normal",
labelFontSize : 24,
labelFontColor : "#666"

and then in function drawPieSegments

然后在函数drawPieSegments中。

ctx.fillText(data[0].value + "%", width/2 - 20, width/2, 200);

ctx.fillText(数据[0]。值+“%”,宽度/2 - 20,宽度/ 2,200);

See this pull: https://github.com/nnnick/Chart.js/pull/35

看到这个拉:https://github.com/nnnick/Chart.js/pull/35

here is a fiddle http://jsfiddle.net/mayankcpdixit/6xV78/ implementing the same.

下面是一个小提琴http://jsfiddle.net/mayankcpdixit/6xV78/实现相同。

#2


64  

None of the other answers resize the text based off the amount of text and the size of the doughnut. Here is a small script you can use to dynamically place any amount of text in the middle, and it will automatically resize it. http://jsfiddle.net/nkzyx50o/

其他答案都不会根据文本的数量和甜甜圈的大小调整文本大小。这里有一个小脚本,您可以使用它来动态地在中间放置任何数量的文本,它将自动调整大小。http://jsfiddle.net/nkzyx50o/

如何使用Chart.js在甜甜圈图中添加文本?

It will take any amount of text in the doughnut sized perfect for the doughnut. To avoid touching the edges you can set a side-padding as a percentage of the diameter of the inside of the circle. If you don't set it, it will default to 20. You also the color, the font, and the text. The plugin takes care of the rest.

它会在甜甜圈大小的甜甜圈中使用任何数量的文字。为了避免接触到边缘,你可以设置一个边距作为圆内径的百分比。如果你不设置它,它将默认为20。还有颜色、字体和文本。插件负责其余部分。

The plugin code will start with a base font size of 30px. From there it will check the width of the text and compare it against the radius of the circle and resize it based off the circle/text width ratio.

插件代码将以30px的基本字体开始。从那里,它将检查文本的宽度,并将它与圆的半径进行比较,并根据圆/文本宽度比调整它的大小。

This is the plugin code

这是插件代码

 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);
    }
  }
});

And you use the following options in your chart object

在图表对象中使用以下选项

options: {
  elements: {
      center: {
      text: 'Desktop',
      color: '#36A2EB', //Default black
      fontStyle: 'Helvetica', //Default Arial
      sidePadding: 15 //Default 20 (as a percentage)
    }
  }
}

#3


39  

Here is cleaned up and combined example of above solutions - responsive (try to resize the window), supports animation self-aligning, supports tooltips

这里是清理和结合的例子上面的解决方案-响应(尝试调整窗口大小),支持动画自对齐,支持工具提示

https://jsfiddle.net/cmyker/u6rr5moq/

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>

UPDATE 17.06.16:

更新17.06.16:

Same functionality but for chart.js version 2:

同样的功能,但是用于图表。js版本2:

https://jsfiddle.net/cmyker/ooxdL2vj/

https://jsfiddle.net/cmyker/ooxdL2vj/

var data = {
  labels: [
    "Red",
    "Blue",
    "Yellow"
  ],
  datasets: [
    {
      data: [300, 50, 100],
      backgroundColor: [
        "#FF6384",
        "#36A2EB",
        "#FFCE56"
      ],
      hoverBackgroundColor: [
        "#FF6384",
        "#36A2EB",
        "#FFCE56"
      ]
    }]
};

Chart.pluginService.register({
  beforeDraw: function(chart) {
    var width = chart.chart.width,
        height = chart.chart.height,
        ctx = chart.chart.ctx;

    ctx.restore();
    var fontSize = (height / 114).toFixed(2);
    ctx.font = fontSize + "em sans-serif";
    ctx.textBaseline = "middle";

    var text = "75%",
        textX = Math.round((width - ctx.measureText(text).width) / 2),
        textY = height / 2;

    ctx.fillText(text, textX, textY);
    ctx.save();
  }
});

var chart = new Chart(document.getElementById('myChart'), {
  type: 'doughnut',
  data: data,
  options: {
  	responsive: true,
    legend: {
      display: false
    }
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.6/Chart.bundle.js"></script>
<canvas id="myChart"></canvas>

#4


25  

I'd avoid modifying the chart.js code to accomplish this, since it's pretty easy with regular CSS and HTML. Here's my solution:

我避免修改图表。js代码可以实现这一点,因为使用常规的CSS和HTML非常容易。这是我的解决方案:

HTML:

HTML:

<canvas id="productChart1" width="170"></canvas>
<div class="donut-inner">
    <h5>47 / 60 st</h5>
    <span>(30 / 25 st)</span>
</div>

CSS:

CSS:

.donut-inner {
   margin-top: -100px;
   margin-bottom: 100px;
}
.donut-inner h5 {
   margin-bottom: 5px;
   margin-top: 0;
}
.donut-inner span {
   font-size: 12px;
}

The output looks like this:

输出如下:

如何使用Chart.js在甜甜圈图中添加文本?

#5


11  

This is also working at my end...

这在我这边也起作用……

<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" />

如何使用Chart.js在甜甜圈图中添加文本?

#6


10  

Base on @rap-2-h answer,Here the code for using text on doughnut chart on Chart.js for using in dashboard like. It has dynamic font-size for responsive option.

基于@ rap2 -h的回答,这里是使用图上的甜甜圈图的代码。用于在仪表板中使用。它有动态字体大小的响应选项。

HTML:

HTML:

<div>text
<canvas id="chart-area" width="300" height="300" style="border:1px solid"/><div>

Script:

脚本:

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);
  }
 });
});

Here the sample code.try to resize the window. http://jsbin.com/wapono/13/edit

这里的示例代码。尝试调整窗口的大小。http://jsbin.com/wapono/13/edit

#7


8  

This is based on Cmyker's update for Chart.js 2. (posted as another answer as I can't comment yet)

这是基于Cmyker更新的图表。js 2。(作为另一个回答,我还不能评论)

I had an issue with the text alignment on Chrome when the legend is displayed as the chart height does not include this so it's not aligned correctly in the middle. Fixed this by accounting for this in the calculation of fontSize and textY.

当图例显示时,我对Chrome上的文本对齐有一个问题,因为图表高度不包含这个,所以它在中间没有正确对齐。修正了这个问题,在计算字体大小和字体的时候。

I calculated percentage inside the method rather than a set value as I have multiple of these on the page. Assumptions are that your chart only has 2 values (otherwise what is the percentage of? and that the first is the one you want to show the percentage for. I have a bunch of other charts too so I do a check for type = doughnut. I'm only using doughnuts to show percentages so it works for me.

我计算了方法内部的百分比,而不是设置值,因为我在页面上有多个这样的值。假设您的图表只有两个值(否则百分比是多少?第一个是你想要显示的百分比。我还有一些其他的图表所以我检查type = doughnut。我只是用甜甜圈来表示百分比,所以它对我很有用。

Text color seems a bit hit and miss depending on what order things run in etc so I ran into an issue when resizing that the text would change color (between black and the primary color in one case, and secondary color and white in another) so I "save" whatever the existing fill style was, draw the text (in the color of the primary data) then restore the old fill style. (Preserving the old fill style doesn't seem needed but you never know.)

文本颜色似乎有点碰巧取决于订单的事情在等我遇到了一个问题,当调整文本会改变颜色(黑色和原色之间在一个案例中,和次要颜色和白色在另一个)所以我“拯救”不管现有填充风格,画出文本的颜色(主数据)然后恢复旧的风格。(似乎不需要保留原来的填充样式,但您永远不会知道。)

https://jsfiddle.net/g733tj8h/

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="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.6/Chart.bundle.js"></script>
<canvas id="myChart"></canvas>

#8


6  

You can also paste mayankcpdixit's code in onAnimationComplete option :

您还可以在onAnimationComplete选项中粘贴mayankcpdixit的代码:

// ...
var myDoughnutChart = new Chart(ctx).Doughnut(data, {
    onAnimationComplete: function() {
        ctx.fillText(data[0].value + "%", 100 - 20, 100, 200);
    }
});

Text will be shown after animation

文本将在动画之后显示

#9


6  

I create a demo with 7 JQuieryUI Slider and ChartJs (with dinamic text inside)

我用7个JQuieryUI滑动条和ChartJs创建了一个演示程序(其中包含了dinaper文本)

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
});

DEMO IN JSFIDDLE

演示在JSFIDDLE

如何使用Chart.js在甜甜圈图中添加文本?

#10


2  

@rap-2-h and @Ztuons Ch's answer doesn't allow for the showTooltips option to be active, but what you can do is create and layer a second canvas object behind the one rendering the chart.

@rap-2-h和@Ztuons Ch的答案不允许showtooltip选项是活动的,但是您可以做的是创建并在呈现图表的第二个画布对象后面分层第二个画布对象。

The important part is the styling required in the divs and for the canvas object itself so that they render on top of each other.

重要的部分是div中需要的样式,以及画布对象本身的样式,以使它们呈现在彼此之上。

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>

Here's the jsfiddle: https://jsfiddle.net/68vxqyak/1/

这是jsfiddle:https://jsfiddle.net/68vxqyak/1/

#11


1  

@Cmyker, great solution for chart.js v2

@Cmyker,很好的图表解决方案。js v2

One little enhancement: It makes sense to check for the appropriate canvas id, see the modified snippet below. Otherwise the text (i.e. 75%) is also rendered in middle of other chart types within the page.

一个小小的改进:检查适当的画布id是有意义的,请参阅下面修改过的代码片段。否则,文本(例如75%)也会在页面中的其他图表类型中间呈现。

  Chart.pluginService.register({
    beforeDraw: function(chart) {
      if (chart.canvas.id === 'doghnutChart') {
        let width = chart.chart.width,
            height = chart.chart.outerRadius * 2,
            ctx = chart.chart.ctx;

        rewardImg.width = 40;
        rewardImg.height = 40;
        let imageX = Math.round((width - rewardImg.width) / 2),
            imageY = (height - rewardImg.height ) / 2;

        ctx.drawImage(rewardImg, imageX, imageY, 40, 40);
        ctx.save();
      }
    }
  });

Since a legend (see: http://www.chartjs.org/docs/latest/configuration/legend.html) magnifies the chart height, the value for height should be obtained by the radius.

因为一个图例(参见:http://www.chartjs.org/docs/latest/configuration/d.html)放大了图表的高度,所以高度的值应该通过半径来获得。

#12


0  

First of all, kudos on choosing Chart.js! I'm using it on one of my current projects and I absolutely love it - it does the job perfectly.

首先,感谢大家选择Chart.js!我正在我目前的一个项目中使用它,我非常喜欢它——它完美地完成了这项工作。

Although labels/tooltips are not part of the library yet, you may want to take a look at these three pull requests:

虽然标签/工具提示还不是库的一部分,但是您可能想看看这三个拉取请求:

And, as Cracker0dks mentioned, Chart.js uses canvas for rendering so you may as well just implement your own tooltips by interacting with it directly.

正如Cracker0dks提到的,图表。js使用canvas进行渲染,因此您也可以直接与它交互,从而实现自己的工具提示。

Hope this helps.

希望这个有帮助。

#13


0  

You can use css with relative/absolute positioning if you want it responsive. Plus it can handle easily the multi-line.

如果你想要回应,你可以使用相对/绝对定位的css。另外,它可以轻松处理多行。

https://jsfiddle.net/mgyp0jkk/

https://jsfiddle.net/mgyp0jkk/

<div class="relative">
  <canvas id="myChart"></canvas>      
  <div class="absolute-center text-center">
    <p>Some text</p>
    <p>Some text</p>
  </div>
</div>