2016-11-30 3 views
6

Chart.js를 사용하는 웹 페이지가 있습니다. 이 페이지에서는 3 개의 도넛 형 차트를 렌더링하고 있습니다. 각 도표의 중간에 채워진 도넛의 비율을 보여주고 싶습니다. 현재 다음 코드를 가지고 있는데이 코드는 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의 버전을 사용하는 것을 선호합니까, 또는 :

사용중인 버전에

,이 같은 doughnut 컨트롤러를 확장 할 수 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 방법을 제공하지 너의 목적. 캔버스 외부 페이지에 표시 할 수있는 범례 콜백의 데이터를 반환합니다.

범례 텍스트의 컨테이너는 캔버스의 래퍼에 상대적으로 정렬 될 수 있습니다.

HTML :

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

JS :이 문제를 해결하기

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

Fiddle

0

한가지 방법은 캔버스 위쪽에 절대 위치 요소를 추가하는 것이다.

는 각 캔버스 요소 다음에 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에 따르면, 당신은 더 버전의 플러그인을 함께 할 수 있습니다. 당신이 알아 차렸는지 모르겠지만 너비를 늘리고 그것을 바이올린에서 반복해서 줄이면 캔버스의 높이가 점점 커집니다 (차트는 더 멀리 내려갑니다).

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); 
관련 문제