Colore diverso per ogni barra in un grafico a barre; ChartJS


94

Sto usando ChartJS in un progetto su cui sto lavorando e ho bisogno di un colore diverso per ogni barra in un grafico a barre.

Ecco un esempio del set di dati del grafico a barre:

var barChartData = {
  labels: ["001", "002", "003", "004", "005", "006", "007"],
  datasets: [{
    label: "My First dataset",
    fillColor: "rgba(220,220,220,0.5)", 
    strokeColor: "rgba(220,220,220,0.8)", 
    highlightFill: "rgba(220,220,220,0.75)",
    highlightStroke: "rgba(220,220,220,1)",
    data: [20, 59, 80, 81, 56, 55, 40]
  }]
};

C'è un modo per dipingere ogni barra in modo diverso?


3
Per risparmiare un po 'di scorrimento, questa risposta menziona che puoi impostare il fillColordi un set di dati come un array e chart.js itererà attraverso l'array selezionando il colore successivo per ogni barra disegnata.
Hartley Brody

Risposte:


74

A partire dalla v2, puoi semplicemente specificare un array di valori per corrispondere a un colore per ciascuna barra tramite la backgroundColorproprietà:

datasets: [{
  label: "My First dataset",
  data: [20, 59, 80, 81, 56, 55, 40],
  backgroundColor: ["red", "blue", "green", "blue", "red", "blue"], 
}],

Ciò è possibile anche per il borderColor, hoverBackgroundColor, hoverBorderColor.

Dalla documentazione sulle proprietà del set di dati del grafico a barre :

Alcune proprietà possono essere specificate come array. Se questi sono impostati su un valore di matrice, il primo valore si applica alla prima barra, il secondo valore alla seconda barra e così via.


66

Soluzione: chiama il metodo di aggiornamento per impostare nuovi valori:

var barChartData = {
    labels: ["January", "February", "March"],
    datasets: [
        {
            label: "My First dataset",
            fillColor: "rgba(220,220,220,0.5)", 
            strokeColor: "rgba(220,220,220,0.8)", 
            highlightFill: "rgba(220,220,220,0.75)",
            highlightStroke: "rgba(220,220,220,1)",
            data: [20, 59, 80]
        }
    ]
};

window.onload = function(){
    var ctx = document.getElementById("mycanvas").getContext("2d");
    window.myObjBar = new Chart(ctx).Bar(barChartData, {
          responsive : true
    });

    //nuevos colores
    myObjBar.datasets[0].bars[0].fillColor = "green"; //bar 1
    myObjBar.datasets[0].bars[1].fillColor = "orange"; //bar 2
    myObjBar.datasets[0].bars[2].fillColor = "red"; //bar 3
    myObjBar.update();
}

1
Questo codice non funzionerà nella sua forma corrente poiché myObjBar è definito in window.onload ma è utilizzato nel flusso di script principale, quindi myObjBar non sarà definito nel momento in cui proveremo a cambiare i colori. Tuttavia ho spostato il codice che cambia colore in basso nello stesso ambito in cui viene generato il mio grafico a barre e questo funziona perfettamente! Non volevo davvero dover modificare chart.js per ottenere qualcosa di così semplice da lavorare, quindi sono molto soddisfatto di questo metodo. EDIT: ho inviato una modifica alla risposta per applicare la mia correzione, devo solo aspettare che venga approvata.
Joshua Walsh

Sfortunatamente, questo non sembra funzionare in Firefox, o IE 10 o 11. Ecco un JSFiddle: jsfiddle.net/3fefqLko/1 . Qualche idea su come farlo funzionare su tutti i browser?
Sam Fen,

Correzione: funziona su tutti i browser. È solo quello che puoi fare fillColor = "#FFFFFF;"in Chrome, ma il punto e virgola finale non dovrebbe essere lì e FF e IE non lo accetteranno.
Sam Fen

5
Aggiornamento: dovrai assegnare "._saved.fillColor" così come ".fillColor" - utilizza il valore _saved per ripristinare dopo il passaggio del mouse (evidenziazione) - es. Ripristina il colore ORIGINALE se non assegni quello nuovo ad esso

4
AGGIORNAMENTO: non funziona con l'ultima versione (2.0 +), ma funziona con 1.0.2
Madan Bhandari

52

Dopo aver esaminato il file Chart.Bar.js sono riuscito a trovare la soluzione. Ho usato questa funzione per generare un colore casuale:

function getRandomColor() {
    var letters = '0123456789ABCDEF'.split('');
    var color = '#';
    for (var i = 0; i < 6; i++ ) {
        color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
}

L'ho aggiunto alla fine del file e ho chiamato questa funzione all'interno di "fillColor:" sotto

helpers.each(dataset.data,function(dataPoint,index){
                    //Add a new point for each piece of data, passing any required data to draw.

quindi ora sembra così:

helpers.each(dataset.data,function(dataPoint,index){
                    //Add a new point for each piece of data, passing any required data to draw.

                    datasetObject.bars.push(new this.BarClass({
                        value : dataPoint,
                        label : data.labels[index],
                        datasetLabel: dataset.label,
                        strokeColor : dataset.strokeColor,
                        fillColor : getRandomColor(),
                        highlightFill : dataset.highlightFill || dataset.fillColor,
                        highlightStroke : dataset.highlightStroke || dataset.strokeColor
                    }));
                },this);

e funziona ottengo colori diversi per ogni barra.


1
Potresti pubblicare la tua soluzione completa (ad esempio con dati e variabili del set di dati, ecc.)? Sto cercando di fare qualcosa di simile e non riesco a replicare la tua soluzione. Grazie
caseklim

hey @casey, questo è il file completo Chart.Bar.js (quello che devi sostituire). pastebin.com/G2Rf0BBn , ho evidenziato la linea che fa la differenza. si noti che in fondo c'è una funzione che restituisce un colore diverso da un array secondo l'indice "i". il set di dati rimane lo stesso (come quello nella domanda). Spero ti abbia aiutato.
BoooYaKa

Questo sicuramente aiuta, grazie! Non mi rendevo conto che stavi modificando il file Chart.js effettivo, piuttosto che il tuo codice.
caseklim

Questa è un'ottima soluzione e non unica per ChartJS.
Crooksey

24

Se dai un'occhiata alla libreria " ChartNew " che si basa su Chart.js puoi farlo passando i valori come un array in questo modo:

var data = {
    labels: ["Batman", "Iron Man", "Captain America", "Robin"],
    datasets: [
        {
            label: "My First dataset",
            fillColor: ["rgba(220,220,220,0.5)", "navy", "red", "orange"],
            strokeColor: "rgba(220,220,220,0.8)",
            highlightFill: "rgba(220,220,220,0.75)",
            highlightStroke: "rgba(220,220,220,1)",
            data: [2000, 1500, 1750, 50]
        }
    ]
};

la tua semplice soluzione ha funzionato per me, grazie e chartNew.js funziona perfettamente bene per me
Pratswinz

come possiamo cambiare ingraphdatashow colore in chartnew js ??
Pratswinz


Molte grazie! Non sapevo che fillColor accettava un array.
Francisco Quintero

18

Puoi chiamare questa funzione che genera colori casuali per ogni barra

var randomColorGenerator = function () { 
    return '#' + (Math.random().toString(16) + '0000000').slice(2, 8); 
};

var barChartData = {
        labels: ["001", "002", "003", "004", "005", "006", "007"],
        datasets: [
            {
                label: "My First dataset",
                fillColor: randomColorGenerator(), 
                strokeColor: randomColorGenerator(), 
                highlightFill: randomColorGenerator(),
                highlightStroke: randomColorGenerator(),
                data: [20, 59, 80, 81, 56, 55, 40]
            }
        ]
    };

2
hey @Sudharshan grazie per la risposta, questo risulterà un colore diverso per ogni grafico ma non per ogni singola barra all'interno del grafico a barre, che è il risultato desiderato. hai qualche idea?
BoooYaKa

1
Grazie per questo codice. Sono stato in grado di usarlo per cambiare il colore delle barre stesse. L'opzione backgroundColor lo consente.
spyke01

Nella versione 2.8, puoi impostare backgroundColor con una funzione backgroundColor: randomColorGenerator,, invece il risultato di una funzione backgroundColor: randomColorGenerator(),. La funzione viene chiamata per ogni elemento anziché una volta per tutti.
negas

14

A partire da agosto 2019, Chart.js ora ha questa funzionalità integrata.

Grafico a barre di successo con diverse barre colorate

Devi semplicemente fornire un array a backgroundColor.

Esempio tratto da https://www.chartjs.org/docs/latest/getting-started/

Prima:

  data: {
        labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
        datasets: [{
            label: 'My First dataset',
            backgroundColor: 'rgb(255, 99, 132)',
            borderColor: 'rgb(255, 99, 132)',
            data: [0, 10, 5, 2, 20, 30, 45]
        }]
    },

Dopo:

  data: {
        labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
        datasets: [{
            label: 'My First dataset',
            backgroundColor: ['rgb(255, 99, 132)','rgb(0, 255, 0)','rgb(255, 99, 132)','rgb(128, 255, 0)','rgb(0, 255, 255)','rgb(255, 255, 0)','rgb(255, 255, 128)'],
            borderColor: 'rgb(255, 99, 132)',
            data: [0, 10, 5, 2, 20, 30, 45]
        }]
    },

Ho appena testato questo metodo e funziona. Ogni barra ha un colore diverso.


13

Qui, ho risolto questo problema creando due funzioni.

1. dynamicColors () per generare colori casuali

function dynamicColors() {
    var r = Math.floor(Math.random() * 255);
    var g = Math.floor(Math.random() * 255);
    var b = Math.floor(Math.random() * 255);
    return "rgba(" + r + "," + g + "," + b + ", 0.5)";
}

2. poolColors () per creare un array di colori

function poolColors(a) {
    var pool = [];
    for(i = 0; i < a; i++) {
        pool.push(dynamicColors());
    }
    return pool;
}

Quindi, passalo

datasets: [{
    data: arrData,
    backgroundColor: poolColors(arrData.length),
    borderColor: poolColors(arrData.length),
    borderWidth: 1
}]

10

Genera colori casuali;

function getRandomColor() {
    var letters = '0123456789ABCDEF'.split('');
    var color = '#';
    for (var i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
}

e chiamalo per ogni record;

function getRandomColorEachEmployee(count) {
    var data =[];
    for (var i = 0; i < count; i++) {
        data.push(getRandomColor());
    }
    return data;
}

finalmente impostare i colori;

var data = {
    labels: jsonData.employees, // your labels
    datasets: [{
        data: jsonData.approvedRatios, // your data
        backgroundColor: getRandomColorEachEmployee(jsonData.employees.length)
    }]
};

4

Ecco un modo per generare colori casuali coerenti usando l' hash dei colori

const colorHash = new ColorHash()

const datasets = [{
  label: 'Balance',
  data: _.values(balances),
  backgroundColor: _.keys(balances).map(name => colorHash.hex(name))
}]

inserisci qui la descrizione dell'immagine


3

ecco come ho gestito: ho spinto un array "colori", con lo stesso numero di voci rispetto al numero di dati. Per questo ho aggiunto una funzione "getRandomColor" alla fine dello script. Spero che sia d'aiuto...

for (var i in arr) {
    customers.push(arr[i].customer);
    nb_cases.push(arr[i].nb_cases);
    colors.push(getRandomColor());
}

window.onload = function() {
    var config = {
        type: 'pie',
        data: {
            labels: customers,
            datasets: [{
                label: "Nomber of cases by customers",
                data: nb_cases,
                fill: true,
                backgroundColor: colors 
            }]
        },
        options: {
            responsive: true,
            title: {
                display: true,
                text: "Cases by customers"
            },
        }
    };

    var ctx = document.getElementById("canvas").getContext("2d");
    window.myLine = new Chart(ctx, config);
};

function getRandomColor() {
    var letters = '0123456789ABCDEF'.split('');
    var color = '#';
    for (var i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
}

2

Se non sei in grado di usare NewChart.js, devi solo cambiare il modo di impostare il colore usando l'array. Trova l'iterazione dell'helper all'interno di Chart.js:

Sostituisci questa riga:

fillColor : dataset.fillColor,

Per questo:

fillColor : dataset.fillColor[index],

Il codice risultante:

//Iterate through each of the datasets, and build this into a property of the chart
  helpers.each(data.datasets,function(dataset,datasetIndex){

    var datasetObject = {
      label : dataset.label || null,
      fillColor : dataset.fillColor,
      strokeColor : dataset.strokeColor,
      bars : []
    };

    this.datasets.push(datasetObject);

    helpers.each(dataset.data,function(dataPoint,index){
      //Add a new point for each piece of data, passing any required data to draw.
      datasetObject.bars.push(new this.BarClass({
        value : dataPoint,
        label : data.labels[index],
        datasetLabel: dataset.label,
        strokeColor : dataset.strokeColor,
        //Replace this -> fillColor : dataset.fillColor,
        // Whith the following:
        fillColor : dataset.fillColor[index],
        highlightFill : dataset.highlightFill || dataset.fillColor,
        highlightStroke : dataset.highlightStroke || dataset.strokeColor
      }));
    },this);

  },this);

E nel tuo js:

datasets: [
                {
                  label: "My First dataset",
                  fillColor: ["rgba(205,64,64,0.5)", "rgba(220,220,220,0.5)", "rgba(24,178,235,0.5)", "rgba(220,220,220,0.5)"],
                  strokeColor: "rgba(220,220,220,0.8)",
                  highlightFill: "rgba(220,220,220,0.75)",
                  highlightStroke: "rgba(220,220,220,1)",
                  data: [2000, 1500, 1750, 50]
                }
              ]

Ho creato una sottoclasse personalizzata del codice del grafico a barre e ho aggiunto un codice simile all'inizializzatore per farlo.
David Reynolds

1

prova questo :

  function getChartJs() {
        **var dynamicColors = function () {
            var r = Math.floor(Math.random() * 255);
            var g = Math.floor(Math.random() * 255);
            var b = Math.floor(Math.random() * 255);
            return "rgb(" + r + "," + g + "," + b + ")";
        }**

        $.ajax({
            type: "POST",
            url: "ADMIN_DEFAULT.aspx/GetChartByJenisKerusakan",
            data: "{}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (r) {
                var labels = r.d[0];
                var series1 = r.d[1];
                var data = {
                    labels: r.d[0],
                    datasets: [
                        {
                            label: "My First dataset",
                            data: series1,
                            strokeColor: "#77a8a8",
                            pointColor: "#eca1a6"
                        }
                    ]
                };

                var ctx = $("#bar_chart").get(0).getContext('2d');
                ctx.canvas.height = 300;
                ctx.canvas.width = 500;
                var lineChart = new Chart(ctx).Bar(data, {
                    bezierCurve: false,
                    title:
                      {
                          display: true,
                          text: "ProductWise Sales Count"
                      },
                    responsive: true,
                    maintainAspectRatio: true
                });

                $.each(r.d, function (key, value) {
                    **lineChart.datasets[0].bars[key].fillColor = dynamicColors();
                    lineChart.datasets[0].bars[key].fillColor = dynamicColors();**
                    lineChart.update();
                });
            },
            failure: function (r) {
                alert(r.d);
            },
            error: function (r) {
                alert(r.d);
            }
        });
    }

1

Questo funziona per me nella versione attuale 2.7.1:

function colorizePercentageChart(myObjBar) {

var bars = myObjBar.data.datasets[0].data;
console.log(myObjBar.data.datasets[0]);
for (i = 0; i < bars.length; i++) {

    var color = "green";

    if(parseFloat(bars[i])  < 95){
        color = "yellow";
    }
    if(parseFloat(bars[i])  < 50){
         color = "red";
    }

    console.log(color);
    myObjBar.data.datasets[0].backgroundColor[i] = color;

}
myObjBar.update(); 

}


1

Prendendo l'altra risposta, ecco una soluzione rapida se vuoi ottenere un elenco con colori casuali per ogni barra:

function getRandomColor(n) {
    var letters = '0123456789ABCDEF'.split('');
    var color = '#';
    var colors = [];
    for(var j = 0; j < n; j++){
        for (var i = 0; i < 6; i++ ) {
            color += letters[Math.floor(Math.random() * 16)];
        }
        colors.push(color);
        color = '#';
    }
    return colors;
}

Ora puoi usare questa funzione nel campo backgroundColor nei dati:

data: {
        labels: count[0],
        datasets: [{
            label: 'Registros en BDs',
            data: count[1],
            backgroundColor: getRandomColor(count[1].length)
        }]
}

1
Questa risposta necessita di lavoro. porta a problemi per me. Ho dovuto riscriverlo come function getRandomColor(n) { var letters = '0123456789ABCDEF'.split(''); var color = '#'; for (var i = 0; i < 6; i++) { color += letters[Math.floor(Math.random() * 16)]; } return color; }.
Sedrick

0

Ho appena ricevuto questo problema di recente ed ecco la mia soluzione

var labels = ["001", "002", "003", "004", "005", "006", "007"];
var data = [20, 59, 80, 81, 56, 55, 40];
for (var i = 0, len = labels.length; i < len; i++) {
   background_colors.push(getRandomColor());// I use @Benjamin method here
}

var barChartData = {
  labels: labels,
  datasets: [{
    label: "My First dataset",
    fillColor: "rgba(220,220,220,0.5)", 
    strokeColor: "rgba(220,220,220,0.8)", 
    highlightFill: "rgba(220,220,220,0.75)",
    highlightStroke: "rgba(220,220,220,1)",
    backgroundColor: background_colors,
    data: data
  }]
};

0

Codice basato sulla seguente richiesta pull :

datapoint.color = 'hsl(' + (360 * index / data.length) + ', 100%, 50%)';

Idea molto utile, molto di più della semplice scelta di colori casuali. Per migliorarlo ulteriormente, quando c'è un gran numero di barre è possibile regolare anche il valore di saturazione, in modo che invece di girare semplicemente intorno alla ruota dei colori, ci si entra a spirale.
Martin CR

0

Se sai quali colori desideri, puoi specificare le proprietà del colore in un array, in questo modo:

    backgroundColor: [
    'rgba(75, 192, 192, 1)',
    ...
    ],
    borderColor: [
    'rgba(75, 192, 192, 1)',
    ...
    ],

-1

quello che ho fatto è creare un generatore di colori casuali come molti qui hanno suggerito

function dynamicColors() {
        var r = Math.floor(Math.random() * 255);
        var g = Math.floor(Math.random() * 255);
        var b = Math.floor(Math.random() * 255);
        return "rgba(" + r + "," + g + "," + b + ", 0.5)";
    }

e poi codificato questo

var chartContext = document.getElementById('line-chart');
    let lineChart = new Chart(chartContext, {
        type: 'bar',
        data : {
            labels: <?php echo json_encode($names); ?>,
            datasets: [{
                data : <?php echo json_encode($salaries); ?>,
                borderWidth: 1,
                backgroundColor: dynamicColors,
            }]
        }
        ,
        options: {
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: true
                    }
                }]
            },
            responsive: true,
            maintainAspectRatio: false,
        }
    });

Nota che non ci sono parentesi alla chiamata della funzione Ciò abilita il codice a chiamare la funzione ogni volta, invece di creare un array Questo impedisce anche al codice di usare lo stesso colore per tutte le barre


-9

Puoi generare facilmente con i grafici livegap
Seleziona Mulicolors dal menu Bar


(fonte: livegap.com )

** biblioteca grafico utilizzato è chartnew.js versione della libreria chart.js modificati
con il codice di chartnew.js sarà qualcosa di simile

var barChartData = {
        labels: ["001", "002", "003", "004", "005", "006", "007"],
        datasets: [
            {
                label: "My First dataset",
                fillColor: ["rgba(0,10,220,0.5)","rgba(220,0,10,0.5)","rgba(220,0,0,0.5)","rgba(120,250,120,0.5)" ],
                strokeColor: "rgba(220,220,220,0.8)", 
                highlightFill: "rgba(220,220,220,0.75)",
                highlightStroke: "rgba(220,220,220,1)",
                data: [20, 59, 80, 81, 56, 55, 40]
            }
        ]
    };

3
Commentando "lascia la tua libreria e usa quest'altra" manca completamente il punto della domanda.
jlh

chartnew.js è una versione modificata di chart.js. in questo periodo il multi colore non era supportato in chart.js ma disponibile in chartnew.js
Omar Sedki
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.