【问题标题】:How to set same borderColor and backgroundColor in chartjs javascript如何在chartjs javascript中设置相同的borderColor和backgroundColor
【发布时间】:2023-03-05 08:37:01
【问题描述】:

我已经使用 chartjs 实现了折线图, 每次图表加载时,生成随机颜色,但是如何为backgroundColor and borderColor设置相同颜色

数据集看起来像,

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

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

预期: 边框颜色和背景颜色应该相同

【问题讨论】:

    标签: javascript arrays reactjs object chart.js


    【解决方案1】:

    最简单的方法是将生成的颜色保存到您可以为每个对象引用的变量中(例如,当您映射它时)。

    但如果出于某种原因您不想这样做,那么您可以创建一个对象工厂函数:

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

    然后调用它来生成你的新对象:

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

    现在每个对象都有唯一的颜色,但每个对象的backgroundColorborderColor 将是相同的。

    【讨论】:

    • 在我看来,这是对内存和 CPU 的不必要使用,因为您只需定义 2 个常量。
    • 那就别这样了。我把它作为一个选项给了他,除非列表中有超过 100 万个项目,否则内存差异不会成为问题。
    【解决方案2】:

    您只需要声明一个全局变量并多次使用它。

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

    希望对你有帮助

    【讨论】:

    • 谢谢,但是对于每个标签,borderColor 和 backgroundColor 应该相同但不是所有标签,然后我需要声明其他变量并使用它,还有其他可能吗??
    • 确切地说,您必须为每种唯一颜色声明一个常量。 :)
    【解决方案3】:

    所以问题是每次调用函数时都会得到随机颜色。尝试为数组中的每个元素生成一次颜色。一个简单的想法是:

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

    【讨论】:

      【解决方案4】:

      所以边框颜色和背景颜色不匹配的原因是因为您正在为需要颜色的每个属性调用该函数。函数本身没有任何状态,因此函数本身无法记住函数之前返回的内容。

      我能想到的最好的方法是使用类,它还保留了您布置数据的良好声明方式。

      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)
      

      它比这里提到的其他选项更冗长,但允许您在一个语句中声明所有数据,而不必通过工厂传递它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多