【问题标题】:How to use observablehq D3 graph in React project?如何在 React 项目中使用 observablehq D3 图?
【发布时间】:2020-05-20 13:47:21
【问题描述】:

在 react 项目中,我想使用一个纠结的树形图,比如 - tangled-tree-visualization-ii

我该如何使用它?既然D3是开源库,那么上面的示例代码也是开源使用的吗?

我是 D3 的初学者。至今, 1.用npm install d3 --save安装D3库 2. 创建 D3 基本条形图以检查 d3 是否正常工作

想要使用上面共享的 tangled-tree-visualization 而不是条形图。但它似乎使用 observablehq 生成的缩小的 runtime.js。

BarChart.js

import React from 'react';
import * as d3 from 'd3';

import { Runtime, Inspector } from "@observablehq/runtime";
import define from "@nitaku/tangled-tree-visualization-ii";

class BarChart extends React.Component {
    componentDidMount() {
        this.drawChart();
    }

    drawChart() {
        const data = this.props.data;
        const svg = d3.select("body").append("svg")
            .attr("width", this.props.width)
            .attr("height", this.props.height);

        const h = this.props.height;

        svg.selectAll("rect")
            .data(data)
            .enter()
            .append("rect")
            .attr("x", (d, i) => i * 70)
            .attr("y", (d, i) => h - 10 * d)
            .attr("width", 65)
            .attr("height", (d, i) => d * 10)
            .attr("fill", "green")

        svg.selectAll("text")
            .data(data)
            .enter()
            .append("text")
            .text((d) => d)
            .attr("x", (d, i) => i * 70)
            .attr("y", (d, i) => h - (10 * d) - 3)

        //selection.attr(“property”, (d, i) => {})
    }

    render() {
        return <div id={"#" + this.props.id}></div>
    }

}

export default BarChart;

App.js

import React from 'react';
import BarChart from './BarChart.js';
import './App.css';

class App extends React.Component {

  state = {
    data: [12, 5, 6, 6, 9, 10],
    width: 700,
    height: 500,
    id: "root"
  }

  render() {
    return (
      <div className="App">
        <BarChart data={this.state.data} width={this.state.width} height={this.state.height} />
      </div>
    );
  }
}

export default App;

【问题讨论】:

  • 嗨,您可能想查看他们的教程,了解如何将其嵌入到反应应用程序中。 observablehq.com/@observablehq/… 因为有一个运行时编译他们的 javascript,你必须使用它来安装你的 react 应用程序。
  • @cal_br_mar - 感谢您对此有所了解。
  • 您好,我添加了一个完整的响应示例,因为让它在 stackoverflow 中工作很有趣,希望这很有用。

标签: javascript reactjs d3.js observablehq


【解决方案1】:

这是一个在他们的guideline 之后使用反应钩子的例子。

当组件被挂载时,你必须实例化运行时,指定要挂载的单元格和 html 节点,在这种情况下使用ref 指向div 元素

  useEffect(() => {
    const runtime = new Runtime();
    runtime.module(notebook, name => {
      if (name === "animation") {
        return new Inspector(animationRef.current);
      }
       if (name === "mutable speed") {
        return {fulfilled: (value) => {
          animationSpeed.current = value;
        }};
      }
    });
  },[]);

animationSpeed 是对可观察笔记本中的mutable speed 单元格的引用。当反应输入范围有更新时,您 useEffect 在笔记本内更新,使用 animationSpeed 参考

useEffect(() => {
  if(animationSpeed.current){
    animationSpeed.current.value = speed;
    }
  },[speed]);

这是功能示例。

ps。在stackoverflow代码sn-ps中加载模块有一点技巧

const {
  useState,
  useEffect,
  useRef,
} = React;

const App = () => {
  const [speed, setSpeed] = useState(1);
  const animationRef = useRef();
  const animationSpeed = useRef();
  
  useEffect(() => {
    const runtime = new Runtime();
    runtime.module(notebook, name => {
      if (name === "animation") {
        return new Inspector(animationRef.current);
      }
       if (name === "mutable speed") {
        return {fulfilled: (value) => {
          animationSpeed.current = value;
        }};
      }
    });
  },[]);
  
  useEffect(() => {
  if(animationSpeed.current){
    animationSpeed.current.value = speed;
    }
  },[speed]);

  return (
  <div className="App">
    <small>Speed: {speed}</small>
    <input type="range"
            min="0"
            max="5"
            step="0.1"
            value={speed}
            onChange={(event)=> setSpeed(event.target.valueAsNumber)} />
     <div ref={animationRef}></div>

  </div>
  );
};

// Render
ReactDOM.render( <App / > ,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
<script type="module">
  import {Runtime, Inspector} from "https://cdn.jsdelivr.net/npm/@observablehq/runtime@4/dist/runtime.js"; import notebook from "https://api.observablehq.com/@observablehq/how-to-embed-a-notebook-in-a-react-app.js?v=3";
  // hack to make module packages global, so the babel transpile code can see it
  window.Runtime = Runtime;
  window.Inspector = Inspector;
  window.notebook = notebook;
</script>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-30
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    • 2018-12-31
    相关资源
    最近更新 更多