Inny kolor dla każdego słupka na wykresie słupkowym; ChartJS

90

Używam ChartJS w projekcie, nad którym pracuję i potrzebuję innego koloru dla każdego słupka na wykresie słupkowym.

Oto przykład zestawu danych wykresu słupkowego:

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

Czy istnieje sposób, aby pomalować każdy pasek inaczej?

BoooYaKa
źródło
3
Aby zaoszczędzić trochę przewijania, ta odpowiedź wspomina, że ​​możesz ustawić fillColorzbiór danych jako tablicę, a chart.js będzie iterował przez tablicę, wybierając następny kolor dla każdego narysowanego słupka.
Hartley Brody

Odpowiedzi:

69

Od wersji 2 możesz po prostu określić tablicę wartości odpowiadających kolorowi dla każdego słupka za pomocą backgroundColorwłaściwości:

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

Jest również możliwe, że borderColor, hoverBackgroundColor, hoverBorderColor.

Z dokumentacji dotyczącej właściwości zestawu danych wykresu słupkowego :

Niektóre właściwości można określić jako tablicę. Jeśli są one ustawione na wartość szyku, pierwsza wartość dotyczy pierwszego słupka, druga wartość - drugiego i tak dalej.

dzięki: D
źródło
66

Rozwiązanie: wywołaj metodę aktualizacji, aby ustawić nowe wartości:

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();
}
Nocnik
źródło
1
Ten kod nie będzie działał w swojej obecnej formie, ponieważ myObjBar jest zdefiniowany w window.onload, ale jest używany w głównym przepływie skryptu, więc myObjBar nie zostanie zdefiniowany do czasu, gdy spróbujemy zmienić kolory. Jednak przeniosłem kod zmieniający kolor na dole do tego samego zakresu, w którym generowany jest mój wykres słupkowy i działa to doskonale! Naprawdę nie chciałem modyfikować chart.js, aby uzyskać coś tak prostego w obsłudze, więc jestem bardzo zadowolony z tej metody. EDYCJA: Przesłałem edycję odpowiedzi, aby zastosować moją poprawkę, wystarczy poczekać, aż zostanie zatwierdzona.
Joshua Walsh
Niestety, to nie działa w Firefoksie, IE 10 lub 11. Oto JSFiddle: jsfiddle.net/3fefqLko/1 . Masz jakieś przemyślenia, jak sprawić, by działało w różnych przeglądarkach?
Sam Fen
Poprawka: działa w różnych przeglądarkach. Po prostu możesz to zrobić fillColor = "#FFFFFF;"w Chrome, ale nie powinno tam być ostatniego średnika, a FF i IE tego nie zaakceptują.
Sam Fen
5
Aktualizacja: musisz przypisać "._saved.fillColor" oraz ".fillColor" - używa wartości _saved do przywrócenia po najechaniu kursorem myszy (podświetlenie) - np. Przywraca ORYGINALNY kolor, jeśli nie przypiszesz nowego do niego
4
AKTUALIZACJA: nie działa z najnowszą wersją (2.0 +), ale działa z 1.0.2
Madan Bhandari
51

Po przejrzeniu pliku Chart.Bar.js udało mi się znaleźć rozwiązanie. Użyłem tej funkcji do wygenerowania losowego koloru:

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

Dodałem go na końcu pliku i nazwałem tę funkcję bezpośrednio w polu „fillColor:”

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

więc teraz wygląda to tak:

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

i działa, otrzymuję inny kolor dla każdego paska.

BoooYaKa
źródło
1
Czy mógłbyś opublikować swoje pełne rozwiązanie (np. Ze zmiennymi danych i zbioru danych itp.)? Chcę zrobić coś podobnego i nie mogę powtórzyć twojego rozwiązania. Dzięki
caseklim
hej @casey, to jest pełny plik Chart.Bar.js (ten, który musisz zastąpić). pastebin.com/G2Rf0BBn , podkreśliłem linię, która sprawia, że ​​różnica. zwróć uwagę, że na dole znajduje się funkcja, która zwraca inny kolor z tablicy zgodnie z indeksem „i”. zbiór danych pozostaje taki sam (jak ten w pytaniu). Mam nadzieję, że ci to pomogło.
BoooYaKa
To zdecydowanie pomaga, dziękuję! Nie zdawałem sobie sprawy, że modyfikujesz rzeczywisty plik Chart.js, a nie własny kod.
caseklim
To świetne rozwiązanie, które nie jest unikalne dla ChartJS.
crooksey
24

Jeśli spojrzysz na bibliotekę „ ChartNew ”, która opiera się na Chart.js, możesz to zrobić, przekazując wartości w postaci tablicy, jak na przykład:

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]
        }
    ]
};
Muhammad Mohsin Muneer
źródło
Twoje proste rozwiązanie zadziałało dla mnie, dzięki i chartNew.js działa idealnie dla mnie
Pratswinz
jak możemy zmienić kolor ingraphdatashow w chartnew js ??
Pratswinz
Mam nadzieję że to pomoże! github.com/FVANCOP/ChartNew.js/wiki/100_080_In_Graph_Data
Muhammad Mohsin Muneer
Wielkie dzięki! Nie wiedziałem, że fillColor zaakceptował tablicę.
Francisco Quintero
18

Możesz wywołać tę funkcję, która generuje losowe kolory dla każdego słupka

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]
            }
        ]
    };
Sudharshan
źródło
2
hej @Sudharshan dzięki za odpowiedź, da to inny kolor dla każdego wykresu, ale nie dla każdego pojedynczego słupka wewnątrz wykresu słupkowego, co jest moim pożądanym wynikiem. masz jakiś pomysł?
BoooYaKa
1
Dzięki za ten kod. Udało mi się go użyć do zmiany koloru samych pasków. Umożliwia to opcja backgroundColor.
spyke01
W wersji 2.8 można ustawić backgroundColor za pomocą funkcji backgroundColor: randomColorGenerator,zamiast wyniku funkcji backgroundColor: randomColorGenerator(),. Funkcja jest wywoływana dla każdego elementu zamiast jednego razu dla wszystkich.
negas
13

Tutaj rozwiązałem ten problem, wykonując dwie funkcje.

1. dynamicColors () do generowania losowego koloru

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 () do tworzenia tablicy kolorów

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

Następnie po prostu go przekaż

datasets: [{
    data: arrData,
    backgroundColor: poolColors(arrData.length),
    borderColor: poolColors(arrData.length),
    borderWidth: 1
}]
Abdul Hameed
źródło
13

Od sierpnia 2019 r. Chart.js ma teraz wbudowaną tę funkcję.

Udany wykres słupkowy z różnymi kolorowymi słupkami

Wystarczy podać tablicę dla backgroundColor.

Przykład zaczerpnięty z https://www.chartjs.org/docs/latest/getting-started/

Przed:

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

Po:

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

Właśnie przetestowałem tę metodę i działa. Każdy pasek ma inny kolor.

legobloki
źródło
10

Generuj losowe kolory;

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

i nazwij to dla każdego rekordu;

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

wreszcie ustalono kolory;

var data = {
    labels: jsonData.employees, // your labels
    datasets: [{
        data: jsonData.approvedRatios, // your data
        backgroundColor: getRandomColorEachEmployee(jsonData.employees.length)
    }]
};
Martin Schneider
źródło
4

Oto sposób na generowanie spójnych losowych kolorów za pomocą skrótu kolorów

const colorHash = new ColorHash()

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

wprowadź opis obrazu tutaj

TeNNoX
źródło
3

oto jak sobie poradziłem: wrzuciłem tablicę "kolory" z taką samą liczbą wpisów jak liczba danych. W tym celu dodałem na końcu skryptu funkcję „getRandomColor”. Mam nadzieję, że to pomoże...

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;
}
Jean-François Rullier
źródło
2

Jeśli nie możesz użyć NewChart.js, wystarczy zmienić sposób ustawiania koloru za pomocą tablicy. Znajdź iterację pomocnika w Chart.js:

Zastąp tę linię:

fillColor : dataset.fillColor,

Dla tego:

fillColor : dataset.fillColor[index],

Wynikowy kod:

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

A w twoim 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]
                }
              ]
Armando Reyna
źródło
Utworzyłem niestandardową podklasę kodu kreskowego i dodałem podobny kod do inicjatora, aby to zrobić.
David Reynolds
1

Spróbuj tego :

  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);
            }
        });
    }
FannyKaunang
źródło
1

To działa dla mnie w aktualnej wersji 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(); 

}

Damian
źródło
1

Biorąc drugą odpowiedź, oto szybkie rozwiązanie, jeśli chcesz uzyskać listę z losowymi kolorami dla każdego paska:

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

Teraz możesz użyć tej funkcji w polu backgroundColor w danych:

data: {
        labels: count[0],
        datasets: [{
            label: 'Registros en BDs',
            data: count[1],
            backgroundColor: getRandomColor(count[1].length)
        }]
}
Eduardo Luis Santos
źródło
1
Ta odpowiedź wymaga pracy. prowadzi to do problemów. Musiałem przepisać to jako 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

Niedawno otrzymałem ten problem i oto moje rozwiązanie

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
  }]
};
Feiyu Chen
źródło
0

Kod oparty na następującym żądaniu ściągnięcia :

datapoint.color = 'hsl(' + (360 * index / data.length) + ', 100%, 50%)';
voho
źródło
Bardzo przydatny pomysł - znacznie więcej niż tylko wybór przypadkowych kolorów. Aby to jeszcze bardziej poprawić, gdy jest duża liczba słupków, możesz również dostosować wartość nasycenia, tak aby zamiast po prostu krążyć po kole kolorów, wkręcałeś się po nim spiralnie.
Martin CR
0

Jeśli wiesz, jakie kolory chcesz, możesz określić właściwości kolorów w tablicy, na przykład:

    backgroundColor: [
    'rgba(75, 192, 192, 1)',
    ...
    ],
    borderColor: [
    'rgba(75, 192, 192, 1)',
    ...
    ],
frostbyyte
źródło
-1

co zrobiłem, to utworzenie losowego generatora kolorów, jak sugerowało wielu tutaj

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

a następnie zakodował to

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

Zauważ, że przy wywołaniu funkcji nie ma parantez To umożliwia kodowi wywoływanie funkcji za każdym razem zamiast tworzenia tablicy Zapobiega to również używaniu przez kod tego samego koloru dla wszystkich słupków

Kapil
źródło
-9

Możesz łatwo generować za pomocą wykresów Livegap
Wybierz Mulicolors z menu Bar


(źródło: livegap.com )

** Biblioteka wykres wykorzystywany jest chartnew.js zmodyfikowana wersja chart.js biblioteki
z kodem chartnew.js będzie coś takiego

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]
            }
        ]
    };
Omar Sedki
źródło
3
Komentowanie „porzuć swoją bibliotekę i użyj tej drugiej” całkowicie mija się z celem pytania.
jlh
chartnew.js to zmodyfikowana wersja pliku chart.js. w tym czasie multikolor nie był obsługiwany w chart.js, ale dostępny w chartnew.js
Omar Sedki