Різний колір для кожного стовпчика на гістограмі; Діаграма JS


90

Я використовую 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 буде перебирати масив, вибираючи наступний колір для кожного намальованого стовпчика.
Хартлі Броді

Відповіді:


69

Починаючи з v2, ви можете просто вказати масив значень, які відповідатимуть кольору для кожного рядка через 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, щоб отримати щось таке просте в роботі, тому я дуже задоволений цим методом. EDIT: Я надіслав редагування відповіді, щоб застосувати моє виправлення, просто потрібно почекати, поки воно буде затверджене.
Джошуа Уолш,

На жаль, це не працює у Firefox, або IE 10 або 11. Ось JSFiddle: jsfiddle.net/3fefqLko/1 . Будь-які думки про те, як змусити його працювати в браузерах?
Сем Фен

Виправлення: воно працює у всіх браузерах. Це просто те, що ви можете робити fillColor = "#FFFFFF;"в Chrome, але останньої крапки з комою там бути не повинно, і FF та IE не приймуть її.
Сем Фен

5
Оновлення: вам потрібно буде призначити "._saved.fillColor", а також ".fillColor" - він використовує значення _saved для відновлення після наведення курсора миші (виділити) - наприклад, він відновлює ORIGINAL колір, якщо ви не призначите новий до нього

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 у мене чудово працює
Пратсвінц,

як ми можемо змінити колір ingraphdatashow у chartnew js ??
Працвінц,


Дуже дякую! Не знав 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(),. Функція викликається для кожного елемента замість одного разу для всіх.
Негас,

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

Я щойно перевірив цей метод, і він працює. Кожен бар має різний колір.


12

Тут я вирішив це питання, зробивши дві функції.

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

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)',
    ...
    ],

0

те, що я зробив, - це створити генератор випадкових кольорів, як багато хто тут пропонував

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

Зверніть увагу, що під час виклику функції немає парантезів. Це дозволяє коду кожного разу викликати функцію, замість того, щоб створювати масив. Це також заважає коду використовувати однаковий колір для всіх стовпців


-8

Ви можете легко генерувати за допомогою діаграм
livegap. Виберіть Mulicolors у меню Bar


(джерело: livegap.com )

** використовується бібліотека діаграм chartnew.js, модифікована версія бібліотеки
chart.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.