Как построить разделенную тепловую карту - PullRequest
2 голосов
/ 21 марта 2020

Используя D3, я хочу взять тип визуализации данных классической тепловой карты ...

enter image description here

.. на разделенную версию нескольких Heatmap группирует данные чертежа из одного источника данных.

enter image description here

Технически это должен быть один элемент тепловой карты, извлекающий свои данные из одного источника - разделение и, следовательно, кластеризация / группировка должна происходить посредством сортировки данных в файле * .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

Я изо всех сил пытаюсь расширить эту базовую c структуру для создания нескольких групп, как описано выше. Расширение цветовая схема, попытка построить несколько дополнительных осей X и Y, которые охватывают различные диапазоны, приводит к полному разрыву элемента D3 , что делает карту невозможной для отображения вообще.

Может кто-то указать мне в правильном направлении о том, как создать несколько групп тепловой карты, не нарушая тепловую карту?

1 Ответ

0 голосов
/ 10 апреля 2020

Я смог решить разделение, используя процедуру, основанную на строках и столбцах для построения разделов:

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