jaklar
jaklar

Reputation: 33

Multipe doughnut charts on one page with text in center using Chart.js

I am displaying one doughnut chart on a web page with chart.js with some text in the center of the doughnut. The problems is when adding multiple dounghnut charts on the same page. The center text is overlapped on all charts.

Result looks like this doughnut chart with overlapping text

Here is a fiddle : https://jsfiddle.net/jaklar/ng1y18yo/1/

HTML code:

`

<table>
    <tr>
            <td><canvas id="myChart1" width="150" height="150"></canvas></td>
            <td><canvas id="myChart2" width="150" height="150"></canvas></td>
        </tr>
  <table>

`

javascript

'

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

var promisedDeliveryChart = new Chart(document.getElementById('myChart1'), {
  type: 'doughnut',
  data: data,
  options: {
    responsive: true,
    cutoutPercentage: 75,
    legend: {
      display: false
    }
  }
});

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 = "100%",
        textX = Math.round((width - ctx.measureText(text).width) / 2),
        textY = height / 2;

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

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

var promisedDeliveryChart = new Chart(document.getElementById('myChart2'), {
  type: 'doughnut',
  data: data,
  options: {
    responsive: true,
    cutoutPercentage: 75,
    legend: {
      display: false
    }
  }
});

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 = "9%",
        textX = Math.round((width - ctx.measureText(text).width) / 2),
        textY = height / 2;

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

'

Upvotes: 3

Views: 8607

Answers (2)

Ajit Bhatt
Ajit Bhatt

Reputation: 31

Line : 98 replace with below: Actually the text is proper but X and Y cordinate are same so it is overlapping. I have increase Y axis here so it comes down(if you want to keep upper side do decrease value of Y axis) and X make same so both start from same position.

ctx.fillText(text, textX, textY + 25);

Upvotes: 0

ɢʀᴜɴᴛ
ɢʀᴜɴᴛ

Reputation: 32869

There is no need to register separate plugin for different charts. This could be achieved by registering just a single plugin for both the charts.

also, your chart plugin has some flaws to it. here is the corrected version of the plugin ...

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 = chart.config.options.elements.center.text,
            textX = Math.round((width - ctx.measureText(text).width) / 2),
            textY = height / 2;
        ctx.fillText(text, textX, textY);
        ctx.save();
    }
});

you would also need to set the following option for both the charts ...

elements: {
    center: {
        text: '50%' //set as you wish
    }
}

ᴅᴇᴍᴏ

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 = chart.config.options.elements.center.text,
            textX = Math.round((width - ctx.measureText(text).width) / 2),
            textY = height / 2;
        ctx.fillText(text, textX, textY);
        ctx.save();
    }
});

// chart1
var data = {
    labels: ["Red", "Blue"],
    datasets: [{
        data: [50, 50],
        backgroundColor: ["#FF6384", "#36A2EB"],
        hoverBackgroundColor: ["#FF6384", "#36A2EB"]
    }]
};
var promisedDeliveryChart = new Chart(document.getElementById('myChart1'), {
    type: 'doughnut',
    data: data,
    options: {
        elements: {
            center: {
                text: '50%'  //set as you wish
            }
        },
        cutoutPercentage: 75,
        legend: {
            display: false
        }
    }
});

// chart2
var data = {
    labels: ["Red", "Blue"],
    datasets: [{
        data: [75, 25],
        backgroundColor: ["#FF6384", "#36A2EB"],
        hoverBackgroundColor: ["#FF6384", "#36A2EB"]
    }]
};
var promisedDeliveryChart = new Chart(document.getElementById('myChart2'), {
    type: 'doughnut',
    data: data,
    options: {
        elements: {
            center: {
                text: '75%'  //set as you wish
            }
        },
        cutoutPercentage: 75,
        legend: {
            display: false
        }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<table>
    <tr>
        <td><canvas id="myChart1" width="150" height="150"></canvas></td>
        <td><canvas id="myChart2" width="150" height="150"></canvas></td>
    </tr>
<table>

Upvotes: 8

Related Questions