Разный цвет для каждого столбца гистограммы; ChartJS


91

Я использую ChartJS в проекте, над которым работаю, и мне нужен разный цвет для каждой полосы на гистограмме.

Вот пример набора данных гистограммы:

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

Есть ли способ раскрасить каждую полосу по-разному?


3
Чтобы избавить вас от прокрутки, в этом ответе упоминается, что вы можете установить fillColorнабор данных как массив, а chart.js будет перебирать массив, выбирая следующий цвет для каждой нарисованной полосы.
Hartley Brody

Ответы:


71

Начиная с версии 2, вы можете просто указать массив значений, соответствующих цвету для каждой полосы, через backgroundColorсвойство:

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

Это также возможно для borderColor, hoverBackgroundColor, hoverBorderColor.

Из документации по свойствам набора данных гистограммы :

Некоторые свойства могут быть указаны в виде массива. Если для них установлено значение массива, первое значение применяется к первому столбцу, второе значение - ко второму столбцу и т. Д.


66

Решение: вызовите метод обновления, чтобы установить новые значения:

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
Этот код не будет работать в его текущей форме, поскольку myObjBar определен в window.onload, но он используется в основном потоке скрипта, поэтому myObjBar не будет определен к тому времени, когда мы попытаемся изменить цвета. Однако я переместил код изменения цвета внизу в ту же область, что и моя гистограмма, и это отлично работает! Мне действительно не хотелось модифицировать chart.js, чтобы заставить что-то работать так просто, поэтому я очень доволен этим методом. РЕДАКТИРОВАТЬ: я отправил редактирование ответа, чтобы применить исправление, просто нужно дождаться его утверждения.
Джошуа Уолш

К сожалению, похоже, что это не работает в Firefox, IE 10 или 11. Вот JSFiddle: jsfiddle.net/3fefqLko/1 . Есть мысли о том, как заставить его работать в браузерах?
Сэм Фен

Исправление: он работает во всех браузерах. Это просто то, что вы можете сделать fillColor = "#FFFFFF;"в Chrome, но последней точки с запятой там быть не должно, и FF и IE ее не примут.
Сэм Фен,

5
Обновление: вам нужно будет назначить "._saved.fillColor", а также ".fillColor" - он использует значение _saved для восстановления после наведения курсора (выделения) - например, он восстанавливает ОРИГИНАЛЬНЫЙ цвет, если вы не назначаете новый на него

4
ОБНОВЛЕНИЕ: это не работает с последней версией (2.0 +), но работает с 1.0.2
Мадан Бхандари

51

Изучив файл Chart.Bar.js, мне удалось найти решение. Я использовал эту функцию для генерации случайного цвета:

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

Я добавил его в конец файла и вызвал эту функцию прямо внутри "fillColor:" под

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

так что теперь это выглядит так:

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

и это работает, я получаю разные цвета для каждой панели.


1
Не могли бы вы опубликовать свое полное решение (например, с данными и переменными набора данных и т. Д.)? Я хочу сделать что-то подобное, и я не могу воспроизвести ваше решение. Спасибо
caseklim

привет @casey, это полный файл Chart.Bar.js (тот, который вам нужно заменить). pastebin.com/G2Rf0BBn , Айв выделил строку, которая делает разницу. обратите внимание, что внизу есть функция, которая возвращает другой цвет из массива в соответствии с индексом «i». набор данных остается тем же (как и в вопросе). Надеюсь, это вам помогло.
BoooYaKa

Это определенно помогает, спасибо! Я не понимал, что вы изменяли фактический файл Chart.js, а не свой собственный код.
caseklim

Это отличное решение, не уникальное для ChartJS.
Crooksey

24

Если вы посмотрите на библиотеку ChartNew, которая построена на Chart.js, вы можете сделать это, передав значения в виде массива, например:

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

Ваше простое решение сработало для меня, спасибо, и chartNew.js отлично работает для меня
Pratswinz

как мы можем изменить цвет ingraphdatashow в chartnew js ??
Pratswinz


Большое спасибо! Не знал, что fillColor принял массив.
Франсиско Кинтеро

18

Вы можете вызвать эту функцию, которая генерирует случайные цвета для каждой полосы.

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
Привет, @Sudharshan, спасибо за ответ, это приведет к разному цвету для каждой диаграммы, но не для каждой отдельной полосы внутри гистограммы, что является моим желаемым результатом. есть идеи?
BoooYaKa

1
Спасибо за этот код. Я смог использовать его, чтобы изменить цвет самих полос. Опция backgroundColor позволяет это сделать.
spyke01

В версии 2.8 вы можете установить backgroundColor с помощью функции backgroundColor: randomColorGenerator,вместо результата функции backgroundColor: randomColorGenerator(),. Функция вызывается для каждого элемента, а не один раз для всех.
negas

13

Здесь я решил эту проблему, выполнив две функции.

1. dynamicColors () для генерации случайного цвета

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 () для создания массива цветов

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

Тогда просто передай это

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

13

По состоянию на август 2019 года Chart.js теперь имеет встроенную функцию.

Успешная гистограмма с полосами разного цвета

Вам просто нужно предоставить массив для backgroundColor.

Пример взят из https://www.chartjs.org/docs/latest/getting-started/

Перед:

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

После:

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

Я только что протестировал этот метод, и он работает. Каждая полоса имеет свой цвет.


10

Создавать случайные цвета;

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

и вызывать его для каждой записи;

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

окончательно установить цвета;

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

4

Вот способ генерировать последовательные случайные цвета с помощью цветового хеша

const colorHash = new ColorHash()

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

введите описание изображения здесь


3

вот как я поступил: я нажал на массив «цветов» с тем же количеством записей, что и количество данных. Для этого я добавил в конец скрипта функцию getRandomColor. Надеюсь, это поможет...

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

Если вы не можете использовать NewChart.js, вам просто нужно изменить способ установки цвета, используя вместо этого массив. Найдите вспомогательную итерацию внутри Chart.js:

Замените эту строку:

fillColor : dataset.fillColor,

Для этого:

fillColor : dataset.fillColor[index],

Полученный код:

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

И в вашем 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]
                }
              ]

Я создал собственный подкласс кода штриховой диаграммы и для этого добавил аналогичный код в инициализатор.
Дэвид Рейнольдс

1

попробуй это :

  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

У меня это работает в текущей версии 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

Принимая другой ответ, вот быстрое исправление, если вы хотите получить список со случайными цветами для каждой панели:

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

Теперь вы можете использовать эту функцию в поле backgroundColor в данных:

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

1
Этот ответ требует доработки. это приводит к проблемам для меня. Пришлось переписать как 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; }.
Седрик

0

У меня недавно возникла эта проблема, и вот мое решение

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

Код, основанный на следующем запросе на вытягивание :

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

Очень полезная идея - гораздо больше, чем просто выбор случайных цветов. Чтобы еще больше улучшить это, при большом количестве полосок вы также можете настроить значение насыщенности, чтобы вместо того, чтобы просто кружить на цветовом круге, вы вращались по нему.
Martin CR

0

Если вы знаете, какие цвета вам нужны, вы можете указать свойства цвета в массиве, например:

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

-1

что я сделал, так это создал генератор случайных цветов, как многие здесь предложили

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

а затем закодировал это

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

Обратите внимание, что при вызове функции нет скобок. Это позволяет коду вызывать функцию каждый раз, а не создавать массив. Это также предотвращает использование кода одного цвета для всех полос.


-9

Вы можете легко создавать с помощью графиков livegap
Выберите Mulicolors в меню панели.


(источник: livegap.com )

** используемая библиотека диаграмм представляет собой модифицированную версию библиотеки
chart.js chartnew.js с кодом chartnew.js примерно так

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
Комментируя «выбросьте свою библиотеку и используйте эту другую» полностью упускает из виду суть вопроса.
jlh

chartnew.js - это модифицированная версия chart.js. в то время многоцветный режим не поддерживался в chart.js, но был доступен в chartnew.js
Омар Седки
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.