Chartjs 2.7.2,数据集的堆叠折线图背景颜色重叠

问题描述 投票:0回答:1

堆叠折线图中数据集的背景颜色相互混合,如下所示。

这是我的代码:

var chart = new Chart($('#chart-area'), {
    type: "line",
    data: {
        labels: [],
        datasets: [],
    },
    options: {
        responsive: true,
        maintainAspectRatio: false,
        hover: {
            mode: 'index',
            intersect: false
        },
        scales: {
            yAxes: [{
                stacked: true
            }]
        }
    },
});

我创建了动态数据集:

chart.data.datasets.push({
     label: LABELS,
     borderColor: COLOR1,
     backgroundColor: COLOR2,
     data: []
});

我的颜色示例:

   COLOR1 -> "#000c89",
   COLOR2 -> 'rgba(0, 12, 137, 0.4)'

有什么想法可以让颜色看起来像正常的吗?它们混合在一起(我认为这是因为透明度),我可以在没有透明度的情况下制作它们,但图表变得丑陋。

javascript chart.js
1个回答
0
投票

确实,由于透明度,颜色会混合。我认为不可能避免这种效果,因为

rgba
中存在透明通道的唯一原因是允许“前景”和“背景”颜色的混合。

确实,

rgba
不应该提供比
rgb
更多的颜色。

在 Chart.js 背景中使用

rgba
获得的漂亮颜色是将该颜色的
rgb
部分作为“前景”与通常为白色的图表背景 (
rgb(255, 255, 255)
) 组合的结果。生成的 RGB 混合的分量可以用

计算
rMix = Math.round(r * a + 255 * (1 - a))
gMix = Math.round(g * a + 255 * (1 - a))
bMix = Math.round(b * a + 255 * (1 - a))

这是执行该计算的代码片段

function runColors() {
  const ctxRgba = document.querySelector('#cvs_rgba').getContext('2d'),
    ctxRgb = document.querySelector('#cvs_rgb').getContext('2d'),
    textRgba = document.querySelector('#rgba'),
    textRgb = document.querySelector('#rgb');

  textRgba.innerText = '';
  textRgb.innerText = '';
  ctxRgba.fillStyle = 'rgb(255,255,255)';
  ctxRgba.fillRect(0, 0, 300, 150);
  ctxRgb.fillStyle = 'rgb(255,255,255)';
  ctxRgb.fillRect(0, 0, 300, 150);
  const r = parseInt(document.querySelector('#r').value, 10),
    g = parseInt(document.querySelector('#g').value, 10),
    b = parseInt(document.querySelector('#b').value, 10),
    a = parseFloat(document.querySelector('#a').value);
  if (r < 0 || r > 255 || b < 0 || b > 255 || g < 0 || g > 255 || a < 0 || a > 1) {
    document.querySelector('#error').innerText = 'Invalid data';
    return;
  }
  document.querySelector('#error').innerText = '';
  const sRGBA = `rgba(${r},${g},${b},${a.toFixed(4).replace(/0+$/, '')})`;
  textRgba.innerText = sRGBA;
  const r1 = Math.round(r * a + 255 * (1 - a)),
    b1 = Math.round(b * a + 255 * (1 - a)),
    g1 = Math.round(g * a + 255 * (1 - a));
  const sRGB = `rgb(${r1},${g1},${b1})`;
  textRgb.innerText = sRGB;

  ctxRgba.fillStyle = sRGBA;
  ctxRgba.fillRect(0, 0, 300, 150);

  ctxRgb.fillStyle = sRGB;
  ctxRgb.fillRect(0, 0, 300, 150);
}

runColors();
<body>
  <h3>
    <code>rgb</code> result of mixing an <code>rgba</code> color with a white background
  </h3>
  R:<input type="text" size="3" value="0" id="r" onchange="runColors()"> G:
  <input type="text" size="3" value="12" id="g" onchange="runColors()"> B:
  <input type="text" size="3" value="137" id="b" onchange="runColors()"> A:
  <input type="text" size="5" value="0.4" id="a" onchange="runColors()">
  <div id="error" style="color:red"></div>
  <div style="display: inline-block; border:1px solid black">
    <canvas id="cvs_rgba" style="width: 200px; height: 50px;background-color: rgb(255, 255, 255)"></canvas>
    <br>
    <code id="rgba"></code>
  </div>
  <div style="display: inline-block; border:1px solid black">
    <canvas id="cvs_rgb" style="width: 200px; height: 50px;background-color: rgb(255, 255, 255)"></canvas>
    <br>
    <code id="rgb"></code>
  </div>

也可用作 jsFiddle


附录

注意:我必须添加我理论上所了解的关于广色域颜色主题的知识,因为它与所提出的问题间接相关;然而,这只是抽象信息,因为我从未使用过这些色彩空间,也没有 HDR 显示器。如果您了解更多信息,请为此做出贡献(消息/新答案/编辑/否决)。

就比 rgb(24) 更宽的颜色空间而言,这是一个很大的话题,但值得一提的是(截至 2023 年底发布时)浏览器中已经对其提供了良好的支持。人们可以从简单但很好的介绍开始,比如 this one,或者阅读 css4githb canvas-color-space 页面中的规范。

一项简单的测试表明,如果使用

backgroundColor: "color(display-p3 0 1 0)"
,chart.js 不会抱怨,而是将该颜色传递给画布函数。这意味着我们可以为 Chart.js 编写广域就绪代码。然而,代码中创建画布上下文的方式似乎表明用户当前无法设置颜色空间,即使将
CanvasRenderingContext2d
作为第一个参数传递给
Chart
构造函数也是如此。

© www.soinside.com 2019 - 2024. All rights reserved.