Làm cách nào để thêm văn bản vào bên trong biểu đồ bánh rán bằng Chart.js?


Câu trả lời:


36

Bạn phải sửa đổi mã như: in chart.Doughnut.defaults

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

và sau đó trong chức năng drawPieSegments

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

Xem phần kéo này: https://github.com/nnnick/Chart.js/pull/35

đây là một http://jsfiddle.net/mayankcpdixit/6xV78/ cách triển khai tương tự.


2
Có ai khác không thể tìm thấy hàm drawPieSe mảnh này không?
Yulian

2
Đáng nói là nó không hoạt động với v2. Sử dụng mã jsfiddle đi kèm để dễ sử dụng
Alwin Kesler

1
Làm cách nào để thêm% vào một dòng mới? cái này có được hỗ trợ không?
user7334203

1
Vẫn còn đây là giải pháp?
ACB

@ ArunC.B - cuộn xuống
ashleedawg

176

Không có câu trả lời nào khác thay đổi kích thước văn bản dựa trên số lượng văn bản và kích thước của chiếc bánh rán. Đây là một tập lệnh nhỏ mà bạn có thể sử dụng để đặt động bất kỳ lượng văn bản nào vào giữa và nó sẽ tự động thay đổi kích thước.

Ví dụ: http://jsfiddle.net/kdvuxbtj/

Donut với văn bản động ở giữa

Nó sẽ mất bất kỳ lượng văn bản nào trong chiếc bánh rán có kích thước hoàn hảo cho chiếc bánh rán. Để tránh chạm vào các cạnh, bạn có thể đặt phần đệm bên dưới dạng tỷ lệ phần trăm của đường kính bên trong hình tròn. Nếu bạn không đặt nó, nó sẽ mặc định là 20. Bạn cũng có màu, phông chữ và văn bản. Plugin sẽ lo phần còn lại.

Mã plugin sẽ bắt đầu với kích thước phông chữ cơ bản là 30px. Từ đó, nó sẽ kiểm tra chiều rộng của văn bản và so sánh nó với bán kính của hình tròn và thay đổi kích thước của nó dựa trên tỷ lệ hình tròn / chiều rộng văn bản.

Nó có kích thước phông chữ tối thiểu mặc định là 20px. Nếu văn bản vượt quá giới hạn ở kích thước phông chữ tối thiểu, nó sẽ bao bọc văn bản. Chiều cao dòng mặc định khi gói văn bản là 25px, nhưng bạn có thể thay đổi nó. Nếu bạn đặt kích thước phông chữ tối thiểu mặc định thành false, văn bản sẽ trở nên nhỏ vô hạn và không bao bọc.

Nó cũng có kích thước phông chữ tối đa mặc định là 75px trong trường hợp không có đủ văn bản và chữ sẽ quá lớn.

Đây là mã plugin

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 maxFontSize = centerConfig.maxFontSize || 75;
      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, maxFontSize);
      var minFontSize = centerConfig.minFontSize;
      var lineHeight = centerConfig.lineHeight || 25;
      var wrapText = false;

      if (minFontSize === undefined) {
        minFontSize = 20;
      }

      if (minFontSize && fontSizeToUse < minFontSize) {
        fontSizeToUse = minFontSize;
        wrapText = true;
      }

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

      if (!wrapText) {
        ctx.fillText(txt, centerX, centerY);
        return;
      }

      var words = txt.split(' ');
      var line = '';
      var lines = [];

      // Break words up into multiple lines if necessary
      for (var n = 0; n < words.length; n++) {
        var testLine = line + words[n] + ' ';
        var metrics = ctx.measureText(testLine);
        var testWidth = metrics.width;
        if (testWidth > elementWidth && n > 0) {
          lines.push(line);
          line = words[n] + ' ';
        } else {
          line = testLine;
        }
      }

      // Move the center up depending on line height and number of lines
      centerY -= (lines.length / 2) * lineHeight;

      for (var n = 0; n < lines.length; n++) {
        ctx.fillText(lines[n], centerX, centerY);
        centerY += lineHeight;
      }
      //Draw text in center
      ctx.fillText(line, centerX, centerY);
    }
  }
});

Và bạn sử dụng các tùy chọn sau trong đối tượng biểu đồ của mình

options: {
  elements: {
    center: {
      text: 'Red is 2/3 the total numbers',
      color: '#FF6384', // Default is #000000
      fontStyle: 'Arial', // Default is Arial
      sidePadding: 20, // Default is 20 (as a percentage)
      minFontSize: 20, // Default is 20 (in px), set to false and text will not wrap.
      lineHeight: 25 // Default is 25 (in px), used for when text wraps
    }
  }
}

Ghi có cho @Jenna Sloan để được trợ giúp về phép toán được sử dụng trong giải pháp này.


5
Hoạt động tuyệt vời! Hầu hết các tùy chọn khác bị phá vỡ khi chú giải ở bên phải hoặc bên trái.
louisav

2
Giải pháp tuyệt vời!
JustLooking

3
Tôi cập nhật fiddle của bạn và thêm một cỡ chữ tối đa: jsfiddle.net/nkzyx50o/3059
Felix GEENEN

4
Có thể chia văn bản thành nhiều dòng không? Văn bản của tôi có 6 chữ và tràn của nó giữa bờ cõi của các cutout
Quanda

2
Cảm ơn bạn, điều này cũng hiệu quả với tôi, nhưng làm cách nào để thêm văn bản nhiều dòng?
Ashutosh Shrestha

54

Đây là ví dụ được dọn dẹp và kết hợp của các giải pháp trên - đáp ứng (cố gắng thay đổi kích thước cửa sổ), hỗ trợ hoạt ảnh tự căn chỉnh, hỗ trợ chú giải công cụ

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>

CẬP NHẬT 17.06.16:

Chức năng tương tự nhưng cho chart.js phiên bản 2:

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>


3
Tôi nhận được Uncaught TypeError: Cannot read property 'extend' of undefinedbất kỳ ý tưởng?
Max Rose-Collins

2
Ngoài ra, bạn có thể thay đổi màu văn bản bằng cách sử dụng ctx.fillStyle = 'black';
Adrian Lopez

này vẫn tiếp tục viết trên văn bản một lần nữa và một lần nữa nếu bảng xếp hạng được làm mới bằng cách cung cấp params dữ liệu mới
techie_28

Bạn đã tìm ra giải pháp cho điều đó chưa?
Cmyker

@Cmyker, giải pháp CSS / HTML có thể giúp được nhưng điều đó không xuất văn bản trung tâm khi biểu đồ được xuất dưới dạng PNG. .
techie_28

38

Tôi tránh sửa đổi mã chart.js để thực hiện điều này, vì nó khá dễ dàng với CSS và HTML thông thường. Đây là giải pháp của tôi:

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

Đầu ra trông như thế này:

nhập mô tả hình ảnh ở đây


4
Tại sao không? Chỉ cần thêm @ media-queries vào các lớp của bạn.
Mattias

2
Nó không hoạt động với tôi, tôi đang sử dụng một cách đáp ứng, vì vậy tôi không thể sử dụng các giá trị cố định. :(
Massa

2
@Massa bạn đã thử sử dụng truy vấn phương tiện cho các độ phân giải khác nhau chưa? Hoặc sửa đổi css tôi đã viết để sử dụng% thay vì px?
Mattias

2
@Mattias đây là một giải pháp hay nhưng văn bản trung tâm không được xuất khi biểu đồ được tải xuống dưới dạng PNG.
techie_28

1
@ techie_28 điểm hợp lệ, không tính đến điều đó vì câu hỏi hoàn toàn không đề cập đến việc xuất.
Mattias

20

Điều này cũng đang hoạt động ở cuối của tôi ...

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

nhập mô tả hình ảnh ở đây


4
Tôi đã sử dụng giải pháp của bạn vì nó là giải pháp nhanh nhất và nó thực hiện được công việc của mình. Cảm ơn!
MDT

@Amrik Singh quả thực đây là một giải pháp tốt nhưng văn bản ở giữa sẽ không được xuất nếu biểu đồ được tải xuống dưới dạng hình ảnh PNG.
techie_28

Giải pháp tốt, nó không cần phải bận tâm nhiều.
Shashank

bạn là công tử của tôi! Tôi không thể tìm thấy giải pháp trong anglejs và mặc dù chưa bao giờ làm như thế này. Kinh ngạc.
Nomi Ali

1
đáng yêu, sửa chữa nhanh chóng và sạch sẽ
Khaleel

11

Dựa trên câu trả lời @ rap-2-h, Đây là mã để sử dụng văn bản trên biểu đồ bánh rán trên Chart.js để sử dụng trong trang tổng quan như. Nó có kích thước phông chữ động cho tùy chọn đáp ứng.

HTML:

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

Kịch bản:

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

Đây là mã mẫu. Hãy thử thay đổi kích thước cửa sổ. http://jsbin.com/wapono/13/edit


1
Đây phải là câu trả lời được chấp nhận trong trường hợp cần đáp ứng (trường hợp của tôi).
Greg Blass,

2
Nếu bạn có chú giải công cụ, văn bản sẽ biến mất khi di chuột.
Yulian

Lỗi "jQuery.Deferred ngoại lệ: Chart không được định nghĩa"
Kiquenet

11

Bạn có thể sử dụng css với định vị tương đối / tuyệt đối nếu bạn muốn nó đáp ứng. Thêm vào đó, nó có thể xử lý dễ dàng nhiều dòng.

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>

giải pháp tuyệt đẹp :)
Manza

Người anh em Super Work bạn đã làm cho ngày của tôi
DVP SmartCreators Inc, chúng tôi thực hiện vào

8

Điều này dựa trên bản cập nhật của Cmyker cho Chart.js 2. (được đăng dưới dạng một câu trả lời khác vì tôi chưa thể bình luận)

Tôi gặp sự cố với căn chỉnh văn bản trên Chrome khi chú giải được hiển thị vì chiều cao biểu đồ không bao gồm điều này nên nó không được căn chỉnh chính xác ở giữa. Đã sửa lỗi này bằng cách tính toán điều này trong phép tính fontSize và textY.

Tôi đã tính toán tỷ lệ phần trăm bên trong phương pháp chứ không phải một giá trị đặt vì tôi có nhiều giá trị này trên trang. Các giả định là biểu đồ của bạn chỉ có 2 giá trị (nếu không thì tỷ lệ phần trăm là bao nhiêu? Và giá trị đầu tiên là giá trị bạn muốn hiển thị phần trăm. Tôi cũng có rất nhiều biểu đồ khác nên tôi kiểm tra type = donut. Tôi chỉ sử dụng bánh rán để hiển thị tỷ lệ phần trăm để nó phù hợp với tôi.

Màu văn bản có vẻ hơi bị nhấn và bị thiếu tùy thuộc vào thứ tự mọi thứ chạy theo thứ tự nào, v.v. vì vậy tôi đã gặp phải vấn đề khi thay đổi kích thước rằng văn bản sẽ thay đổi màu sắc (giữa màu đen và màu chính trong một trường hợp và màu phụ và màu trắng trong một trường hợp khác) vì vậy Tôi "lưu" bất kỳ kiểu tô hiện có nào, vẽ văn bản (bằng màu của dữ liệu chính) sau đó khôi phục kiểu tô cũ. (Giữ nguyên kiểu tô cũ có vẻ không cần thiết nhưng bạn không bao giờ biết.)

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


7

Bạn cũng có thể dán mã của mayankcpdixit trong onAnimationCompletetùy chọn:

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

Văn bản sẽ được hiển thị sau hoạt ảnh


6
Tốt nhưng các văn bản biến mất trên di chuột
rnaud

1
Chính xác, văn bản biến mất khi di chuột ... :( Sẽ thật tuyệt nếu văn bản không biến mất, bất kỳ ý tưởng nào để làm điều này? Cảm ơn
MDT

@MDT @maud có thể bằng cách sử dụng các savephương pháp
techie_28

7

Tôi tạo bản demo với 7 jQueryUI Slider và ChartJs (với văn bản động bên trong)

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 TRONG JSFIDDLE

nhập mô tả hình ảnh ở đây


3

Câu trả lời của @ rap-2-h và @Ztuons Ch không cho phép showTooltipstùy chọn hoạt động, nhưng những gì bạn có thể làm là tạo và xếp lớp canvasđối tượng thứ hai phía sau đối tượng hiển thị biểu đồ.

Phần quan trọng là kiểu dáng được yêu cầu trong các div và cho chính đối tượng canvas để chúng hiển thị chồng lên nhau.

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>

Đây là jsfiddle: https://jsfiddle.net/68vxqyak/1/


1

@Cmyker, giải pháp tuyệt vời cho chart.js v2

Một chút cải tiến: Nên kiểm tra id canvas phù hợp, hãy xem đoạn mã đã sửa đổi bên dưới. Nếu không, văn bản (tức là 75%) cũng được hiển thị ở giữa các loại biểu đồ khác trong trang.

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

Vì chú giải (xem: http://www.chartjs.org/docs/latest/configuration/legend.html ) phóng đại chiều cao biểu đồ, nên giá trị cho chiều cao sẽ được tính bằng bán kính.


0

Trước hết, xin chúc mừng khi chọn Chart.js! Tôi đang sử dụng nó cho một trong những dự án hiện tại của mình và tôi hoàn toàn thích nó - nó thực hiện công việc một cách hoàn hảo.

Mặc dù nhãn / chú giải công cụ chưa phải là một phần của thư viện, bạn có thể muốn xem ba yêu cầu kéo sau:

Và, như Cracker0dks đã đề cập, Chart.js sử dụng canvasđể hiển thị, vì vậy bạn cũng có thể triển khai các chú giải công cụ của riêng mình bằng cách tương tác trực tiếp với nó.

Hi vọng điêu nay co ich.


0

Nói chung, giải pháp của Alesana hoạt động rất tốt đối với tôi, nhưng giống như những giải pháp khác, tôi muốn có thể chỉ định nơi xảy ra ngắt dòng. Tôi đã thực hiện một số sửa đổi đơn giản để bọc các dòng ở ký tự '\ n', miễn là văn bản đã được bao bọc. Một giải pháp hoàn chỉnh hơn sẽ buộc phải gói nếu có bất kỳ ký tự '\ n' nào trong văn bản, nhưng tôi không có thời gian để làm điều đó hoạt động với định cỡ phông chữ. Sự thay đổi cũng căn giữa tốt hơn một chút theo chiều ngang khi gói (tránh khoảng trống ở cuối). Đoạn mã bên dưới (Tôi chưa thể đăng nhận xét).

Sẽ thật tuyệt nếu ai đó đưa plugin này lên GitHub ...

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 maxFontSize = centerConfig.maxFontSize || 75;
      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, maxFontSize);
      var minFontSize = centerConfig.minFontSize;
      var lineHeight = centerConfig.lineHeight || 25;
      var wrapText = false;

      if (minFontSize === undefined) {
        minFontSize = 20;
      }

      if (minFontSize && fontSizeToUse < minFontSize) {
        fontSizeToUse = minFontSize;
        wrapText = true;
      }

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

      if (!wrapText) {
        ctx.fillText(txt, centerX, centerY);
        return;
      }

      var lines = [];
      var chunks = txt.split('\n');
      for (var m = 0; m < chunks.length; m++) {
        var words = chunks[m].split(' ');
        var line;

        // Break words up into multiple lines if necessary
        for (var n = 0; n < words.length; n++) {
          var testLine = (n == 0) ? words[n] : line + ' ' + words[n];
          var metrics = ctx.measureText(testLine);
          var testWidth = metrics.width;
          if (testWidth > elementWidth && n > 0) {
            lines.push(line);
            line = words[n];
          } else {
            line = testLine;
          }
        }
        lines.push(line);
      }

      // Move the center up depending on line height and number of lines
      centerY -= ((lines.length-1) / 2) * lineHeight;

      // All but last line
      for (var n = 0; n < lines.length; n++) {
        ctx.fillText(lines[n], centerX, centerY);
        centerY += lineHeight;
      }
    }
  }
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.