Разный цвет для каждого столбца гистограммы; 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]
  }]
};

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

BoooYaKa
источник
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);

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

BoooYaKa
источник
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
Надеюсь это поможет! github.com/FVANCOP/ChartNew.js/wiki/100_080_In_Graph_Data
Muhammad Mohsin Muneer
Большое спасибо! Не знал, что 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))
}]

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

TeNNoX
источник
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
Омар Седки