在反应中向 Nivo 热图添加 D3 缩放功能

时间:2021-04-13 10:15:03

标签: reactjs svg d3.js zooming nivo-react

我有一个使用 Nivo 响应式热图的 React 应用程序。我无法从 d3 实现缩放功能。我试过以下示例 Example1Example2。据我所知,Nivo 生成了一个 SVG,但是当我在 SVG 上单击/鼠标滚动时,缩放功能甚至没有运行。 有什么我做错了吗? 希望得到任何建议。

results.js: 第 33 行 -50

import HeatMap from "../components/results/heatmap"
import * as d3 from "d3"

const zoomed = () => {
  svg.attr(
    "transform",
    "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"
  )

  console.log("inside zoomed")
}

// zoom base element
let svg = d3.select("svg")


// zoom behaviour
let zoom = d3.zoom().on("zoom", zoomed)

// call behaviour on base element
svg.call(zoom)

第 393 -396 行



return(
<div className="mt-8">
            <div className="heat-map-wrapper">
              <HeatMap dateMap={plateMapState} />
            </div>

            <hr />
          </div>
)

heatmap.js:第 272-396 行

import { ResponsiveHeatMap } from "@nivo/heatmap"

return (
    <div className="mb-48">
      <div className="h-128">
        <ResponsiveHeatMap
          padding={1}
          data={data}
          keys={keys}
          cellShape={CustomCell}
          indexBy="country"
          margin={{ top: 100, right: 60, bottom: 60, left: 90 }}
          forceSquare={true}
          axisTop={{
            orient: "top",
            tickSize: 5,
            tickPadding: 5,
            tickRotation: -90,
            legend: "",
            legendOffset: 36,
          }}
          axisRight={null}
          axisBottom={null}
          axisLeft={{
            orient: "left",
            tickSize: 5,
            tickPadding: 5,
            tickRotation: 0,
            legend: false,
          }}
          tooltip={tt => {
            if (!tt) return null
            let { xKey, yKey, color } = tt
            let value = tt.value ? tt.value : ""
            let message = `No data is available for ${xKey} on ${yKey}`
            let spanMess = ""

            if (!isNaN(value)) {
              return `Total: ${value}`
            }

            if (value) {
              switch (value) {
                case "POS_TEST":
                  message = `On ${yKey}, ${xKey} tested `
                  spanMess = "Positive"
                  color = dataMap["POS_TEST"].color
                  break
                case "NEG_TEST":
                  message = `On ${yKey}, ${xKey} tested `
                  spanMess = "Negative"
                  color = dataMap["NEG_TEST"].color
                  break
                case "POS_TEST_POOL":
                  message = `On ${yKey}, ${xKey} tested `
                  spanMess = "Positive"
                  color = dataMap["POS_TEST"].color
                  break
                case "NEG_TEST_POOL":
                  message = `On ${yKey}, ${xKey} tested `
                  spanMess = "Negative"
                  color = dataMap["NEG_TEST"].color
                  break
                default:
                  message = dataMap[value].message
                  spanMess = dataMap[value].spanMess
                  color = dataMap[value].color
              }
            }

            return (
              <strong>
                {message}
                <span style={{ color }}>{spanMess}</span>
              </strong>
            )
          }}
          cellOpacity={1}
          cellBorderColor={{ from: "color", modifiers: [["darker", 0.4]] }}
          labelTextColor={{ from: "color", modifiers: [["darker", 1.8]] }}
          defs={[
            {
              id: "lines",
              type: "patternLines",
              background: "inherit",
              color: "rgba(0, 0, 0, 0.1)",
              rotation: -45,
              lineWidth: 4,
              spacing: 7,
            },
          ]}
          animate={false}
          colors="RdYlGn"
          motionStiffness={80}
          motionDamping={9}
          hoverTarget="cell"
          cellHoverOthersOpacity={0.25}
        />
      </div>
      <div className="h-64">
        <div className="flex-col">
          {Object.values(dataMap).map((d, i) => {
            if (!d.legend) return null
            return (
              <div className="w-64 flex" key={`legend-item-${i}`}>
                <div className="relative w-10 h-10 p-2 text-center ">
                  <div
                    className="opacity-50 absolute top-0 left-0 w-full h-full"
                    style={{ backgroundColor: d.bg }}
                  ></div>
                  <div
                    style={{ color: d.color }}
                    className="absolute top-0 left-0 w-full h-full mt-2 font-bold"
                  >
                    {d.short}
                  </div>
                </div>
                <p className="mt-2 ml-4 font-semibold text-sm text-gray-900">
                  - {d.legend}
                </p>
              </div>
            )
          })}
        </div>
      </div>
    </div>
  )

0 个答案:

没有答案
相关问题