首页 > 解决方案 > 如何构建分区热图

问题描述

使用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 元素完全中断,导致地图根本无法显示。

有人可以指出我如何在不破坏热图的情况下生成多个热图组的正确方向吗?

标签: javascripthtmld3.jsdata-visualization

解决方案


我能够使用基于行和列的过程来构造隔间来解决隔间化问题:

    // 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);

推荐阅读