直方图,如带有强度色列的柱状图,每个仓位不透明度以显示强度

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

我正在尝试制作一种直方图,每列的颜色都用绿色编码为红色。我想根据数据中存在的该值的计数来更改每个bin的不透明度。

例如:

Data = [ {x:2, y:10},{x:2, y:10},{x:2, y:10},{x:8, y:50},{x:8, y:50},{x:8, y:50} ,{x:8, y:50} ];

{x:2,y:10}的容器的数量为3,因此不透明度为0.2,而bin {x:8,y:50}的容器的数量为4,因此不透明度为1。其他垃圾箱将保留。我已经设法将图表布置到所需的位置,但似乎无法找到一种方法来更改垃圾箱的不透明度。

这里是我到目前为止所做的Fiddle

下图是我要寻找的最终结果。enter image description here

javascript chart.js
1个回答
0
投票

首先,我对您已经取得的成就印象深刻,您的图表看起来很棒!

假设您的数据存在于名为“输入”的array中,我首先使用Array.reduce()计算相同对象的出现次数。

Array.reduce()

使用您提供的数据,const countedData = input.reduce((acc, v) => { const existing = acc.find(o => o.x == v.x && o.y == v.y); if (existing) { existing.count += 1; } else { acc.push({ x: v.x, y: v.y, count: 1 }); } return acc; }, []); 将包含以下对象。

countedData

然后,我需要一个为[ { "x": 2, "y": 10, "count": 3 }, { "x": 8, "y": 50, "count": 4 } ] x的每种组合提供不透明度的函数:

y

剩下的唯一部分是创建使用上述function getOpacity(x, y) { const obj = countedData.find(o => o.x == x && o.y == y); if (obj) { return obj.count < 4 ? 0.7 : 1; } return 0.2; } 函数的backgroundColor数组。

getOpacity

请在下面查看您修改后的可运行代码:

backgroundColor: data.map((v, index) => "rgba("+R+", "+G+", "+B+", " + getOpacity(index + 1, i + 25) + ")"),
const input = [ {x:2, y:10},{x:2, y:10},{x:2, y:10},{x:8, y:50},{x:8, y:50},{x:8, y:50} ,{x:8, y:50} ];
var labels = ["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24"];
var data = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];

const countedData = input.reduce((acc, v) => {
  const existing = acc.find(o => o.x == v.x && o.y == v.y);
  if (existing) {
    existing.count += 1;
  } else {
    acc.push({ x: v.x, y: v.y, count: 1 });
  }
  return acc;
}, []);

function getOpacity(x, y) {
  const obj = countedData.find(o => o.x == x && o.y == y);
  if (obj) {
    return obj.count < 4 ? 0.7 : 1;
  }
  return 0.2;
}

var datasets = [];
var R = 0;
var G = 255;
var B = 2;

for ( var i = 1; i < 26; i ++){
  R += 8;
  G -= 4;
  B += 1;
  datasets.push ({ 
    data: data,
    backgroundColor: data.map((v, index) => "rgba("+R+", "+G+", "+B+", " + getOpacity(index + 1, i) + ")"),
    label: 'Bad Style',
    hoverBackgroundColor: "#7E57C2",
    hoverBorderWidth: 0,
    borderWidth: 1.5,
   });
}

R = 153;
G = 153;
B = 0;
for ( var i = 1; i < 30; i ++) {
  R += 8;
  G -= 5;
  B += 0;
  datasets.push ({ 
    data: data,
    backgroundColor: data.map((v, index) => "rgba("+R+", "+G+", "+B+", " + getOpacity(index + 1, i + 25) + ")"),
    label: 'Bad Style',
    hoverBackgroundColor: "#7E57C2",
    hoverBorderWidth: 0,
    borderWidth: 1.5,
   });
}

var bar_ctx = document.getElementById('bar-chart');
bar_ctx.style.backgroundColor = 'rgba(0,0,0,255)';
var bar_chart = new Chart(bar_ctx, {
    type: 'bar',
    data: {
        labels: labels,
        datasets: datasets
    },
    options: {
     		animation: {
        	duration: 10,
        },
        scales: {
          xAxes: [{ 
          	stacked: true, 
            gridLines: { display: false },
            }],
          yAxes: [{ 
          	stacked: true, 
            gridLines: { display: false },
            }],
        },
        legend: {display: false}
    },
   }
);
© www.soinside.com 2019 - 2024. All rights reserved.