skip to Main Content

I’m aware that in Chart.js, you can pass an array of colours to the backgroundColor option, but is it possible to use the current dataset item to choose the colour? Ideally, I’d want to do something like:

new Chart(ctx, {
  type: "pie",
  data: {
    datasets: [{
      data: scores,
      backgroundColor: (context) => {
         // This is the key bit. Can I somehow access the current
         // dataset item here from the context?
        return context.item.colour
      }
    }]
  }
})

Below is a working example where backgroundColor is an array but I’d want to change it to use a callback function that sets the background based on the current dataset item:

const ctx = document.getElementById('chart')

const dataSet = [
  { name: 'John', score: 10, colour: 'orange' },
  { name: 'Bob', score: 5, colour: 'yellow', },
  { name: 'Alice', score: 20, color: 'pink' }
]

const scores = dataSet.map(data => data.score)

new Chart(ctx, {
  type: "pie",
  data: {
    datasets: [{
      data: scores,
      backgroundColor: ['red', 'green', 'blue'] // Is there a way I can choose the colour based on the dataset item. Ideally, I'd want to access the array item from dataSet and read the `colour` property from there.
    }]
  }
})
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="chart"></canvas>

2

Answers


  1. You could use map() to generate an array of colors base on dataSet:

    backgroundColor: dataSet.map(({ colour }) => colour)
    

    But you could also use reduce() to re-work your dataSet variable to the format CharJS expects. Then you don’t need the map() for the score :

    const ctx = document.getElementById('chart')
    
    const dataSet = [
      { name: 'John', score: 10, colour: 'orange' },
      { name: 'Bob', score: 5, colour: 'yellow', },
      { name: 'Alice', score: 20, color: 'pink' }
    ]
    
    const mappedDataSet = dataSet.reduce((p, { score, colour }) => { 
        p.data.push(score);
        p.backgroundColor.push(colour);
        return p;
    }, { data: [], backgroundColor: [] });
    
    new Chart(ctx, {
      type: "pie",
      data: {
        datasets: [ mappedDataSet ]
      }
    })
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <canvas id="chart"></canvas>
    Login or Signup to reply.
  2. You have 2 options.

    Option 1

    First is to use a scriptable option to read it from your dataset array like so:

    const ctx = document.getElementById('chart')
    
    const dataSet = [{
        name: 'John',
        score: 10,
        colour: 'orange'
      },
      {
        name: 'Bob',
        score: 5,
        colour: 'yellow',
      },
      {
        name: 'Alice',
        score: 20,
        colour: 'pink'
      }
    ]
    
    const scores = dataSet.map(data => data.score)
    
    new Chart(ctx, {
      type: "pie",
      data: {
        datasets: [{
          data: scores,
          backgroundColor: (c) => dataSet[c.dataIndex].colour,
        }]
      }
    })
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <canvas id="chart"></canvas>

    Option 2:

    You can also pass the entire dataset to the data field and set the parsing in the options to let chart.js know where to look for the data. With this you have access to this array in the scriptable options and can read it from there:

    const ctx = document.getElementById('chart')
    
    const dataSet = [{
        name: 'John',
        score: 10,
        colour: 'orange'
      },
      {
        name: 'Bob',
        score: 5,
        colour: 'yellow',
      },
      {
        name: 'Alice',
        score: 20,
        colour: 'pink'
      }
    ]
    
    new Chart(ctx, {
      type: "pie",
      data: {
        datasets: [{
          data: dataSet,
          backgroundColor: (c) => c.raw.colour,
        }]
      },
      options: {
        parsing: {
          key: 'score'
        }
      }
    })
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <canvas id="chart"></canvas>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search