2016-11-30 68 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);