Color diferente para cada barra en un gráfico de barras; ChartJS


90

Estoy usando ChartJS en un proyecto en el que estoy trabajando y necesito un color diferente para cada barra en un gráfico de barras.

A continuación, se muestra un ejemplo del conjunto de datos del gráfico de barras:

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

¿Hay alguna forma de pintar cada barra de forma diferente?


3
Para ahorrarle algo de desplazamiento, esta respuesta menciona que puede configurar el fillColorde un conjunto de datos para que sea una matriz, y chart.js iterará a través de la matriz eligiendo el siguiente color para cada barra dibujada.
Hartley Brody

Respuestas:


69

A partir de la v2, simplemente puede especificar una matriz de valores para que corresponda con un color para cada barra a través de la backgroundColorpropiedad:

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

Esto también es posible que el borderColor, hoverBackgroundColor, hoverBorderColor.

De la documentación sobre las propiedades del conjunto de datos del gráfico de barras :

Algunas propiedades se pueden especificar como una matriz. Si se establecen en un valor de matriz, el primer valor se aplica a la primera barra, el segundo valor a la segunda barra, y así sucesivamente.


66

Solución: llame al método de actualización para establecer nuevos valores:

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
Este código no funcionará en su forma actual ya que myObjBar está definido en window.onload pero se usa en el flujo de secuencia de comandos principal, por lo que myObjBar no estará definido para cuando intentemos cambiar los colores. Sin embargo, moví el código de cambio de color en la parte inferior al mismo alcance donde se genera mi gráfico de barras y esto funciona perfectamente. Realmente no quería tener que modificar chart.js para que algo tan simple funcionara, así que estoy muy contento con este método. EDITAR: Envié una edición a la respuesta para aplicar mi corrección, solo necesito esperar a que se apruebe.
Joshua Walsh

Desafortunadamente, esto no parece funcionar en Firefox, o IE 10 o 11. Aquí hay un JSFiddle: jsfiddle.net/3fefqLko/1 . ¿Alguna idea sobre cómo hacer que funcione en todos los navegadores?
Sam Fen

Corrección: funciona en todos los navegadores. Es solo que puede hacer fillColor = "#FFFFFF;"en Chrome, pero el punto y coma final no debería estar allí y FF e IE no lo aceptarán.
Sam Fen

5
Actualización: deberá asignar "._saved.fillColor" así como ".fillColor" - usa el valor _saved para restaurar después del mouseover (resaltado) - por ejemplo, restaura el color ORIGINAL si no asigna el nuevo a él

4
ACTUALIZACIÓN: esto no funciona con la última versión (2.0 +), pero funciona con 1.0.2
Madan Bhandari

51

Después de buscar en el archivo Chart.Bar.js, logré encontrar la solución. He usado esta función para generar un color aleatorio:

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

Lo agregué al final del archivo y llamé a esta función dentro de "fillColor:" debajo

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

así que ahora se ve así:

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

y funciona, obtengo un color diferente para cada barra.


1
¿Podría publicar su solución completa (por ejemplo, con datos y variables de conjuntos de datos, etc.)? Estoy buscando hacer algo similar y parece que no puedo replicar su solución. Gracias
caseklim

Hola @casey, este es el archivo completo Chart.Bar.js (el que necesitas reemplazar). pastebin.com/G2Rf0BBn , he resaltado la línea que marca la diferencia. tenga en cuenta que en el botón hay una función que devuelve un color diferente de una matriz según el índice "i". el conjunto de datos sigue siendo el mismo (como el de la pregunta). Espero que te haya ayudado.
BoooYaKa

Eso definitivamente ayuda, ¡gracias! No me di cuenta de que estaba modificando el archivo Chart.js real, en lugar de su propio código.
caseklim

Esta es una gran solución y no es exclusiva de ChartJS.
crooksey

24

Si echa un vistazo a la biblioteca " ChartNew " que se basa en Chart.js, puede hacer esto pasando los valores como una matriz así:

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

su solución simple funcionó para mí, gracias y chartNew.js funciona perfectamente bien para mí
Pratswinz

¿Cómo podemos cambiar el color ingraphdatashow en chartnew js?
Pratswinz


¡Muchas gracias! No sabía que fillColor aceptaba una matriz.
Francisco Quintero

18

Puede llamar a esta función que genera colores aleatorios para cada 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
Hola @Sudharshan, gracias por la respuesta, esto resultará en un color diferente para cada gráfico, pero no para cada barra dentro del gráfico de barras, que es mi resultado deseado. tienes alguna idea?
BoooYaKa

1
Gracias por este código. Pude usarlo para cambiar el color de las barras. La opción backgroundColor permite esto.
spyke01

En la versión 2.8, puede establecer backgroundColor con una función backgroundColor: randomColorGenerator,, en lugar del resultado de una función backgroundColor: randomColorGenerator(),. La función se llama para cada elemento en lugar de una vez para todos.
negas

13

Aquí, resolví este problema haciendo dos funciones.

1. dynamicColors () para generar colores aleatorios

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 () para crear una variedad de colores

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

Entonces, solo pásalo

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

13

A partir de agosto de 2019, Chart.js ahora tiene esta funcionalidad incorporada.

Gráfico de barras exitoso con barras de diferentes colores

Simplemente necesita proporcionar una matriz a backgroundColor.

Ejemplo tomado de https://www.chartjs.org/docs/latest/getting-started/

Antes de:

  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]
        }]
    },

Después:

  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]
        }]
    },

Acabo de probar este método y funciona. Cada barra tiene un color diferente.


10

Genera colores aleatorios;

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

y llámelo para cada registro;

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

finalmente establecer colores;

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

4

Aquí hay una forma de generar colores aleatorios consistentes usando color-hash

const colorHash = new ColorHash()

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

ingrese la descripción de la imagen aquí


3

así es como lo hice: presioné una matriz de "colores", con el mismo número de entradas que el número de datos. Para esto agregué una función "getRandomColor" al final del script. Espero eso ayude...

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

Si no puede usar NewChart.js, solo necesita cambiar la forma de establecer el color usando la matriz en su lugar. Encuentre la iteración auxiliar dentro de Chart.js:

Reemplazar esta línea:

fillColor : dataset.fillColor,

Para este:

fillColor : dataset.fillColor[index],

El código resultante:

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

Y en tu 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]
                }
              ]

Creé una subclase personalizada del código del gráfico de barras y agregué un código similar al inicializador para hacer esto.
David Reynolds

1

prueba esto :

  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

Esto me funciona en la versión actual 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

Tomando la otra respuesta, aquí hay una solución rápida si desea obtener una lista con colores aleatorios para cada 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;
}

Ahora puede usar esta función en el campo backgroundColor en los datos:

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

1
Esta respuesta necesita trabajo. me genera problemas. Tuve que reescribirlo como 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

Acabo de tener este problema recientemente y esta es mi solución

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

Código basado en la siguiente solicitud de extracción :

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

Idea muy útil, mucho más que simplemente elegir colores aleatorios. Para mejorar esto aún más, cuando hay una gran cantidad de barras, también puede ajustar el valor de saturación, de modo que en lugar de simplemente dar vueltas en la rueda de colores, se mueva en espiral.
Martin CR

0

Si sabe qué colores desea, puede especificar las propiedades de color en una matriz, así:

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

-1

lo que he hecho es crear un generador de color aleatorio como muchos aquí han sugerido

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

y luego codificó esto

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

Observe que no hay paréntesis en la llamada de la función Esto permite que el código llame a la función cada vez, en lugar de hacer una matriz Esto también evita que el código use el mismo color para todas las barras


-9

Puede generar fácilmente con gráficos
livegap Seleccione Mulicolors en el menú Bar


(fuente: livegap.com )

** biblioteca gráfico utilizado es chartnew.js versión de biblioteca chart.js modificados
con código chartnew.js será algo como esto

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
Al comentar "deshazte de tu biblioteca y usa esta otra" se pierde completamente el sentido de la pregunta.
jlh

chartnew.js es una versión modificada de chart.js. en este momento, el multicolor no era compatible con chart.js pero estaba disponible en chartnew.js
Omar Sedki
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.