Chartjs-How to set same borderColor and backgroundColor in chartjs javascript

0👍

The easiest way is to just save the generated color to a variable you can reference for each object (for eample when you map over it).

But if for some reason you don’t want to do that then you could create an object factory function:

const buildObj = obj => {
    const color = generateColor();
    const o = { ...obj, backgroundColor: color, borderColor: color };
    return o;
}

And then call it to generate your new objects:

const mappedData = data.map(o => buildObj(o))

Now every object will have a unique color, but the backgroundColor and borderColor of each object will be the same.

0👍

You just have to declare a global variable and use it multiple of times.

const globalColor = this.generateColor();
var data = [{
      label: "records",
      data: [2, 4 ,20,10],
      fill: false,
      backgroundColor: globalColor ,
      borderColor: globalColor ,
      borderWidth: 1
    },{
      label: "amount",
      data: [100, 200, 500,50],
      fill: false,
      backgroundColor: globalColor ,
      borderColor: globalColor ,
      borderWidth: 1
    }

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

Hope it helps

0👍

So the problem is that you’re getting a random color each time you’re calling the function. Try generating a color once per element in your array. A simple idea is:

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

var data = [{
      label: "records",
      data: [2, 4 ,20,10],
      fill: false,
      borderWidth: 1
    },{
      label: "amount",
      data: [100, 200, 500,50],
      fill: false,
      borderWidth: 1
    }].map(v => {
                var color = generateColor(); 
                return {...v, backgroundColor: color, borderColor: color}
           })

0👍

so the reason the border color and the background color are not matching up is because you are calling the function for each property where you need a color. functions alone do not have any kind of state, so there is no way for a function itself to remember what the function returned previously.

The best way I could think of doing this, that also retains the nice declarative way you layed-out your data was by the use of a class.

class GenerateColorPairs {
    constructor(numOfColorPairs) {
        this.tickCycle = 2
        this.currentTick = 0
        this.colorSetIndex = 0

        this.colorSet = []

        const letters = '0123456789ABCDEF';
        for (let i = 0; i < numOfColorPairs; i++) {
            let color = '#';
            for (let j = 0; j < 6; j++) {
                color += letters[Math.floor(Math.random() * 16)];
            }
            debugger;
            this.colorSet.push(color)
        }
    }

    tick() {
        if (this.currentTick < this.tickCycle) {

            this.currentTick += 1

        } else if (this.currentTick === this.tickCycle) {

            if (this.colorSetIndex === this.numOfColorPairs) {
                throw new Error(`
            function has been called more times than 
            the 'numOfColorPairs' x2\n To be able to use this 
            function more than ${this.numOfColorPairs} times, 
            pass a higher value when instanciating to the class 
            constructor
          `)
            }

            this.colorSetIndex += 1
            this.currentTick = 0

        }
    }

    generateColor() {
        this.tick()
        return this.colorSet[this.colorSetIndex];
    }

}

var colors = new GenerateColorPairs(2)

var data = [{
    label: "records",
    data: [2, 4, 20, 10],
    fill: false,
    backgroundColor: colors.generateColor(),
    borderColor: colors.generateColor(),
    borderWidth: 1
}, {
    label: "amount",
    data: [100, 200, 500, 50],
    fill: false,
    backgroundColor: colors.generateColor(),
    borderColor: colors.generateColor(),
    borderWidth: 1
}];

console.log(data)

Its a lot verbose than the other options mentioned here, but allows you to declare all your data in one statement and not have to pass it through a factory.

Leave a comment