javascript - 如何构建分区热图
问题描述
使用D3,我想采用经典热图的数据可视化类型......
.. 到从单个数据源绘制数据的几个热图组的分隔版本上。
从技术上讲,这应该是一个热图元素从单一来源提取其数据 - 分离并因此聚类/分组应该通过对 *.csv 文件(第一组、第二组、第三组..)和 D3 中的数据进行排序来发生*.JS 文件处理样式。
生成单个地图时:
// Build X scales and axis:
const x = d3.scaleBand()
.range([0, width])
.domain(myGroups)
.padding(0.00);
svg.append('g')
.attr('transform', `translate(0,${height})`)
.call(d3.axisBottom(x));
// Build Y scales and axis:
const y = d3.scaleBand()
.range([height, 0])
.domain(myVars)
.padding(0.00);
svg.append('g')
.call(d3.axisLeft(y));
分配颜色:
// Assign color scale
const myColor = d3.scaleLinear()
.range(['red', '#750606'])
.domain([1, 100]);
并获取(样本)数据:
// Read the data
d3.csv('https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/heatmap_data.csv', (data) => {
data.sort(function(a, b) {
return myVars.indexOf(b.variable) - myVars.indexOf(a.variable) || myGroups.indexOf(a.group) - myGroups.indexOf(b.group)
});
一直像魅力一样工作: CodePen
如上所述,我正在努力将这个基本结构扩展到生成多个组。扩展配色方案,尝试构建多个覆盖不同范围的额外 X 和 Y 轴,导致 D3 元素完全中断,导致地图根本无法显示。
有人可以指出我如何在不破坏热图的情况下生成多个热图组的正确方向吗?
解决方案
我能够使用基于行和列的过程来构造隔间来解决隔间化问题:
// Dimensions
const numCategoryCols = 4;
const numCategoryRows = Math.ceil(grouped.length / numCategoryCols);
const numEntryCols = 3;
const numEntryRows = Math.ceil(grouped[0].values.length / numEntryCols);
const gridSize = 20;
const width = gridSize * numCategoryCols * numEntryCols;
const height = gridSize * numCategoryRows * numEntryRows;
const tooltipArrowSize = 8;
// Containers
const container = d3
.select("#" + containerId)
.classed("heatmap-grid", true)
.style("position", "relative");
const svg = container
.append("svg")
.style("display", "block")
.style("width", "100%")
.attr("viewBox", [0, 0, width, height])
.style("opacity", 0);
svg.transition()
.duration(3000)
.delay((d,i) => i*200)
.style("opacity", 1)
// Heatmap
const gCategory = svg
.selectAll(".category-g")
.data(grouped, (d) => d.key)
.join("g")
.attr("class", "category-g")
.attr("fill", (d) => color(d.key))
.attr("transform", (_, i) => {
const y = Math.floor(i / numCategoryCols);
const x = i % numCategoryCols;
return `translate(${gridSize * numEntryCols * x},${
gridSize * numEntryRows * y
})`;
});
const gEntry = gCategory
.selectAll(".entry-g")
.data((d) => d.values)
.join("g")
.attr("class", "entry-g")
.attr("transform", (_, i) => {
const y = Math.floor(i / numEntryCols);
const x = i % numEntryCols;
return `translate(${gridSize * x},${gridSize * y})`;
});
const entry = gEntry
.append("rect")
.attr("width", gridSize)
.attr("height", gridSize)
.attr("fill-opacity", (d) => d.Severity / 100)
.on("mouseenter", showTooltip)
.on("mouseleave", hideTooltip);
推荐阅读
- android - 刷新令牌时如何发送到服务器?
- ansible - 迭代库存时,Ansible如何将寄存器的输出存储在列表中
- google-apps-script - Google Sheets API - 展开或折叠组会触发事件吗?
- java - 如何让一个Android应用更安全,安全问题。
- google-maps - 官方谷歌地图绘制路线
- python-3.x - error while executing a REST api script in Python : TypeError:'dict' object is not callable
- mysql - connecting jenkins hosted on kubernetes to MySQL on Google Cloud Platform
- testing - 使用多个标签在空手道选项中运行
- node.js - How to resolve a proxy error in a reactjs/ express app?
- apache-spark - How to stream 100GB of data in Kafka topic?