2016-11-30 86 views
6

我有一个使用Chart.js的网页。在这个页面中,我呈现了三个圆环图。在每张图表的中间,我想显示已填充的甜甜圈的百分比。目前,我有以下代码,可以在Fiddle中看到。Chart.js - 定位甜甜圈标签

function setupChart(chartId, progress) { 
    var canvas = document.getElementById(chartId); 
    var context = canvas.getContext('2d'); 

    var remaining = 100 - progress; 
    var data = { 
    labels: [ 'Progress', '', ], 
    datasets: [{ 
     data: [progress, remaining], 
     backgroundColor: [ 
     '#8FF400', 
     '#FFFFFF' 
     ], 
     borderColor: [ 
     '#8FF400', 
     '#408A00' 
     ], 
     hoverBackgroundColor: [ 
     '#8FF400', 
     '#FFFFFF' 
     ] 
    }] 
    }; 

    var options = { 
    responsive: true, 
    maintainAspectRatio: false, 
    scaleShowVerticalLines: false, 

    cutoutPercentage: 80, 
    legend: { 
     display: false 
    }, 
    animation: { 
     onComplete: function() { 
     var xCenter = (canvas.width/2) - 20; 
     var yCenter = canvas.height/2 - 40; 

     context.textAlign = 'center'; 
     context.textBaseline = 'middle'; 

     var progressLabel = data.datasets[0].data[0] + '%'; 
     context.font = '20px Helvetica'; 
     context.fillStyle = 'black'; 
     context.fillText(progressLabel, xCenter, yCenter); 
     } 
    } 
    }; 

    Chart.defaults.global.tooltips.enabled = false; 
    var chart = new Chart(context, { 
    type: 'doughnut', 
    data: data, 
    options: options 
    }); 
} 

图表“运行”。但问题出在标签的渲染上。标签不是在甜甜圈中间的垂直和水平中心。标签的位置也根据屏幕分辨率而改变。您可以通过在Fiddle范围内调整图表的框架大小来查看标签更改位置。

我的问题是,我如何始终如一地将比例定位在甜甜圈中间?我的网页是一个快速响应的页面,因此具有一致的定位非常重要。但是,我不确定还有什么要做。我觉得textAligntextBaseline属性不起作用,或者我误解了它们的用法。

谢谢!

+0

你更喜欢使用你有你的小提琴的chart.js之版本,或你会考虑使用V2.1吗? –

回答

2

看到这个http://jsfiddle.net/uha5tseb/2/

它可以通过引用

onComplete: function (event) { 
    console.log(this.chart.height); 
    var xCenter = this.chart.width/2; 
    var yCenter = this.chart.height/2; 

    context.textAlign = 'center'; 
    context.textBaseline = 'middle'; 

    var progressLabel = data.datasets[0].data[0] + '%'; 
    context.font = '20px Helvetica'; 
    context.fillStyle = 'black'; 
    context.fillText(progressLabel, xCenter, yCenter); 
    } 

希望让每个图表的宽度/高度来处理问题得以解决!

+0

我很好奇,当你将鼠标悬停在图表的一部分上时,我注意到了闪烁的百分比。有什么办法消除闪烁?换句话说,当你悬停在甜甜圈的一部分上时,让标签留下来? – user687554

+0

@ user687554是的,可以通过悬停模式“false”看到这个http://jsfiddle.net/uha5tseb/7/希望这解决了所有为你:) –

2

当您获取xCenter和yCenter时,您可能会错误地设置变量。目前他们没有得到画布的中间。

您有:

var xCenter = (canvas.width/2) - 20; 
var yCenter = canvas.height/2 - 40; 

它应该是:

var xCenter = (canvas.width/2); 
var yCenter = (canvas.height/2); 
0

林不熟悉chart.js之,但据我从文档的理解,他们提供generateLegend的方法你的目的。它会返回legendCallback的数据,您可以在画布之外的页面上显示该数据。

图例文本的容器可以相对于画布的包装对齐。

HTML:

<div class="chart" data-legend=""> 
    <canvas id="standChart"></canvas> 
</div> 

JS:解决这个

var container = canvas.parentElement; 
... 
container.setAttribute('data-legend', chart.generateLegend()); 

Fiddle

0

一种方式是通过在画布的顶部添加绝对定位的元素。

您可以将每个canvas元素后添加div元素,然后设置其风格:

.precentage { 
    font-family: tahoma; 
    font-size: 28px; 
    left: 50%; 
    position: absolute; 
    top: 50%; 
    transform: translate(-50%, -50%); 
} 

下面是一个完整JSFiddle

-1
We Give Size of the Chart Can be with in the Chart And Align to center on the Give the hight width based on the Chart Hight and Width.. 
i will make simple change in Your Jsfiddle 
.. 
xcenter and y center with the half distence for chart.. 

[http://jsfiddle.net/uha5tseb/10/][1] 
4

根据this answer,你可以在一个更高版本的插件中做到这一点。我不知道你是否注意到了,但如果你增加宽度并在你的小提琴上反复减少它,那么画布的高度会越来越大(图表越来越向下)。

您正在使用的版本,你可以扩展doughnut控制器是这样的:

http://jsfiddle.net/ivanchaer/cutkqkuz/1/

Chart.defaults.DoughnutTextInside = Chart.helpers.clone(Chart.defaults.doughnut); 
Chart.controllers.DoughnutTextInside = Chart.controllers.doughnut.extend({ 
    draw: function(ease) { 

     var ctx = this.chart.chart.ctx; 
     var data = this.getDataset(); 

     var easingDecimal = ease || 1; 
     Chart.helpers.each(this.getDataset().metaData, function(arc, index) { 
      arc.transition(easingDecimal).draw(); 

      var vm = arc._view; 
      var radius = (vm.outerRadius + vm.innerRadius)/2; 
      var thickness = (vm.outerRadius - vm.innerRadius)/2; 
      var angle = Math.PI - vm.endAngle - Math.PI/2; 

      ctx.save(); 
      ctx.fillStyle = vm.backgroundColor; 

      ctx.font = "20px Verdana"; 
      ctx.textAlign = 'center'; 
      ctx.textBaseline = "middle"; 

      var text = data.data[0] + '%'; 
      ctx.fillStyle = '#000'; 
      ctx.fillText(text, $(ctx.canvas).width()/2, $(ctx.canvas).height()/2); 
     }); 
     ctx.fillStyle = '#fff'; 
     ctx.fill(); 
     ctx.restore(); 

    } 

}); 


function setupChart(chartId, progress) { 
    var canvas = document.getElementById(chartId); 
    var context = canvas.getContext('2d'); 
    var remaining = 100 - progress; 

    var deliveredData = { 
     labels: [ 
      "Value" 
     ], 
     datasets: [{ 
      data: [progress, remaining], 
      backgroundColor: [ 
       '#8FF400', 
       '#FFFFFF' 
      ], 
      borderColor: [ 
       '#8FF400', 
       '#408A00' 
      ], 
      hoverBackgroundColor: [ 
       '#8FF400', 
       '#FFFFFF' 
      ] 
     }] 
    }; 

    var deliveredOpt = { 
     cutoutPercentage: 88, 

     animation: false, 
     legend: { 
      display: false 
     }, 
     tooltips: { 
      enabled: false 
     } 
    }; 

    var chart = new Chart(canvas, { 
     type: 'DoughnutTextInside', 
     data: deliveredData, 
     options: deliveredOpt 
    }); 

} 

setupChart('standChart', 33); 
setupChart('moveChart', 66); 
setupChart('exerciseChart', 99);