What is the best way to insert an image into the center of a Donut Chart using Chart.js?

Currently, I am utilizing Chart.js to visualize my data as shown in the following image:

https://i.sstatic.net/5sEHW.png

My goal is to incorporate an image in the center of the chart.

https://i.sstatic.net/YDlOd.png

Is there a way to insert an image in the middle of the Donut Chart?

Here is the JavaScript code I have been working with:
$.ajax({
    type: "POST",
    url: "/Plant/SunChart",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (jsonData) {
        var items = jsonData[0];
        var countOfItems = jsonData[1];
        var ctx = document.getElementById("sunPieChart");
        var myPieChart = new Chart(ctx, {
            type: 'doughnut',
            data: {
                labels: items,
                datasets: [{
                    data: countOfItems,
                    backgroundColor: ['#ffff00', '#ffffa4', '#ced5df'],
                    hoverBackgroundColor: ['#ffff00', '#ffffa4', '#ced5df'],
                    hoverBorderColor: "rgba(234, 236, 244, 1)",
                }],
            },
            options: {
                maintainAspectRatio: false,
                tooltips: {
                    backgroundColor: "rgb(255,255,255)",
                    bodyFontColor: "#858796",
                    borderColor: '#dddfeb',
                    borderWidth: 1,
                    xPadding: 15,
                    yPadding: 15,
                    displayColors: false,
                    caretPadding: 10,
                },
                legend: {
                    display: false
                },
                cutoutPercentage: 80,
            },
        });
    }
});

Answer №1

The Plugin Core API provides various hooks for implementing custom code. The afterDraw hook can be used to directly draw images on the canvas using

CanvasRenderingContext2D.drawImage()
.

Take a look at the updated code below.

new Chart('myChart', {
  type: 'doughnut',
  plugins: [{
    afterDraw: chart => {
      var ctx = chart.chart.ctx;
      ctx.save();
      var image = new Image();      
      image.src = 'https://i.sstatic.net/S7tJH.png';      
      imageSize = 40;
      ctx.drawImage(image, chart.chart.width / 2 - imageSize / 2, chart.chart.height / 2 - imageSize / 2, imageSize, imageSize);
      ctx.restore();
    }
  }],
  data: {
    labels: ['A', 'B', 'C'],
    datasets: [{
      data: [50, 25, 25],
      backgroundColor: ['#ffff00', '#ffffa4', '#ced5df'],
      hoverBackgroundColor: ['#ffff00', '#ffffa4', '#ced5df'],
      hoverBorderColor: "rgba(234, 236, 244, 1)",
    }],
  },
  options: {
    maintainAspectRatio: false,
    tooltips: {
      backgroundColor: "rgb(255,255,255)",
      bodyFontColor: "#858796",
      borderColor: '#dddfeb',
      borderWidth: 1,
      xPadding: 15,
      yPadding: 15,
      displayColors: false,
      caretPadding: 10,
    },
    legend: {
      display: false
    },
    cutoutPercentage: 80,
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="180"></canvas>

Answer №2

Uminder's solution was really useful. Expanding on that to position the image in the center, here is an updated code snippet.

afterDraw: chart => {
  var ctx = chart.chart.ctx;
  ctx.save();
  var image = new Image();      
  image.src = 'https://i.sstatic.net/S7tJH.png';      
  imageSize = 40;
  const {top, left, width, height} = chart.chartArea;
  const x = left + width / 2 - imageSize / 2;
  const y = top + height / 2 - imageSize / 2;
  ctx.drawImage(image, x , y, imageSize, imageSize);
  ctx.restore();
}

Check out the official documentation. I hope this can be of help to someone.

Answer №3

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js" type="text/javascript"></script>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>

credit to How to add image inside the doughnut chart using chart.js? and and http://jsfiddle.net/jimrhoskins/Sv87G/

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can enemies in Javascript's EaselJS library execute the same functions simultaneously?

Hey everyone! I've been working on creating a dodge game using JavaScript. I have a question about how to ensure that each of the 3 enemies I create will have unique functions. Right now, they all move in the same direction determined by enemyrandom ...

Having trouble accessing the latest props within a setInterval in a React functional component

I'm facing an issue where I can't seem to access the updated prop within setInterval inside Component1; instead, it keeps showing me the old value. Here's the code snippet I'm working with: import { useState, useEffect } from "reac ...

Keep running PHP code following an Ajax request

I am dealing with a block of HTML code that needs to be replaced by an Ajax call. Here is the initial HTML code: <div class="box-body" id="mcontent"> <?php if (isset($_POST["id"])){ $id = $_POST["id" ...

Comparison of WebAPI Response Codes: Understanding the Difference Between 401 and

As a part of my learning project, I am developing a WebAPI and striving to implement best practices. The initial focus is on creating an authentication API that accepts an authentication object in JSON format: { username: myusername, password: mypa ...

Sort through an array of objects using a different array

I am looking to showcase projects based on specific skills. For instance, if I choose "HTML", I want to see all projects that have "HTML" listed in their array of skills. If I select multiple skills, then only display projects that have those exact skills. ...

What is the correct way to properly enter a Svelte component instance variable?

Currently, I am delving into learning Svelte and specifically exploring how to bind to a component instance as demonstrated in this tutorial: As I progress through the tutorial, I am attempting to convert it to Typescript. However, I have encountered an ...

Arranging a JSON Object Array in JavaScript by its alphanumeric key attribute order

I need assistance sorting this JSON array by unitId var array = [ { id: 10, unitId: 'unit17' }, { id: 11, unitId: 'unit19' }, { id: 13, unitId: 'unit27' }, { id: 12, unitId: 'unit2' }, { id: 13, unitId: 'unit ...

Combining SlateJS with Redux

I need to store the value of a SlateJS editor in redux instead of state, but when I modify the hasLinks method, I encounter an immediate crash with the error message: TypeError: Cannot read property 'inlines' of undefined Modified Editor&apos ...

Unable to show additional tooltip information on the price history chart

In an attempt to enhance the tooltip of a price-history chart (stockChart), I am trying to display extra data. Here is a jsfiddle example: http://jsfiddle.net/z10dLcj8/1/ $(function(){ var priceHistoryObjArray = [ [1379883600000,47.19,'extra ...

Update the available choices in one select field based on the choice made in another

I am working on a feature where users can select their country, either USA or Canada. Currently, I have all the American states listed in one dropdown menu. However, I want this dropdown to change to display Canadian provinces when users select Canada. Bel ...

Tips for optimizing caching of API responses and assets using service workers in Vue CLI 3

import { register } from 'register-service-worker' import pwa from '@vue/cli-plugin-pwa' if (process.env.NODE_ENV === 'development') { // if (process.env.NODE_ENV === 'production') { console.log(pwa) register(`${pro ...

Managing numerous inquiries from a single customer within a succession of brief intervals

After creating a web application with a dashboard to showcase different reports and graphs based on user selections, I encountered an issue. Users can interact with the reports using checkboxes and radio buttons. Every time a checkbox or radio button is s ...

Leverage JsonConvert for Serializing Objects with different arguments

Hi there! I am working on a project where I need to return Json data to Ajax in order to update some HTML on my page. The C# code I'm using looks like this: public JsonResult AddToCart(int id, int sizeid, int sizeVal, int catID) { Cake C = db.Cak ...

Storm, the crooning guitarist, and real-time alerts

After conducting research on various platforms, I have only found information on using Tornado as an HTTP server. My current dilemma is how to initiate push notifications within this system? To provide some background... The database I am dealing with ...

Wait for the playwright to detect a specific and exact change in the inner text

There is a specific innerText that transitions from Loading to Play after 2-3 seconds. I want to wait for this change to happen before proceeding. Currently, I am using the following code snippet: let attempt = 0; let maxRetries = 4; let payerButtonStatus ...

Removing an object from a JSON data structure using AngularJS

Currently facing a minor issue here. I have a nested JSON object that is embedded within ng-repeat and is sortable by using AngularJS UI Sortable (based on JQuery UI Sortable): $scope.rootItem = { id: '1', type: 'course&apo ...

Using socket.io in a Django template without the need for the node.js service or socket.io.js file

I am working on a Django app that requires real-time push to clients. I have decided to use node.js and socket.io as it is considered the easiest platform for achieving this functionality. To implement this, I have included the socket.io framework code in ...

Unable to capture HTML form input in $_POST[]

I've encountered an unusual issue while transferring data from an email form (HTML5) to ajax/JSON and receiving false in order to prevent redirection to the php script after pressing the submit button. When I include commas between each data paramete ...

Extract Individual Textures from a Single Texture File

Currently, I am working on developing a 2D tile-based computer game using JavaScript and jQuery. The game utilizes the Canvas element for rendering. One challenge I am facing is how to handle an image file containing multiple textures within a single file. ...

Error encountered when attempting to retrieve JSON data in JavaScript due to being undefined

A snippet of code that reads and writes JSON data is presented below: var info; $(function () { $.getJSON("data.json", function (d) { info = d; }); $('.btn').click(function () { info['c-type'] = $('#c- ...