Как мне ввести свои данные в эту пузырьковую диаграмму d3 в React?

поэтому в React я копирую и вставляю элемент пузырьковой диаграммы d3, не зная слишком много о реакции. Я ввожу данные в пузырьковую диаграмму со своими собственными данными json. Когда я запускаю его, он выдает «не могу читать из неопределенного» из-за d.data.Name.substring (0, d.r / 3). Мне кажется, что я неправильно определяю свой объект json (d3.hierachy и некоторые функции, похоже, запрашивают детей или что-то в этом роде), вот мои коды:

RoadmapList.json:

    [
  {
    "Name": "Computer Science",
    "Count": 4156
  },

  {
    "Name": "Home Economics",
    "Count": 689
  },
  {
    "Name": "Venture Capital Investment",
    "Count": 890
  },
  {
    "Name": "Fabric design",
    "Count": 167
  },
  {
    "Name": "Deep Learning Researchers",
    "Count": 812
  }
]

А в Bubble.js, моем компоненте пузырьковой диаграммы, кстати, когда я использую состояния, он работает, но поскольку мне нужно динамическое обновление, я использую this.props.roadmapdata

Bubble.js:

import React, { Component } from "react";
import * as d3 from "d3";

class Bubble extends Component {
  constructor(props) {
    super(props);
  }

  componentWillReceiveProps(nextProps) {
    d3.select("nodes").remove("nodes");
    var diameter = 600;

    var color = d3.scaleOrdinal(d3.schemeCategory10);

    var bubble = d3
      .pack(this.props.RoadmapData)
      .size([diameter, diameter])
      .padding(1.5);

    var svg = d3
      .select("body")
      .append("svg")
      .attr("width", diameter)
      .attr("height", diameter)
      .attr("class", "bubble");

    var node = svg
      .selectAll(".node")
      .data(this.props.RoadmapData)
      .enter()
      .filter(function(d) {
        return !d.children;
      })
      .append("g")
      .attr("class", "node")
      .attr("transform", function(d) {
        return "translate(" + d.x + "," + d.y + ")";
      });
    node.append("title").text(function(d) {
      return d.Name + ": " + d.Count;
    });

    node
      .append("circle")
      .attr("r", function(d) {
        return d.r;
      })
      .style("fill", function(d, i) {
        return color(i);
      });

    node
      .append("text")
      .attr("dy", ".2em")
      .style("text-anchor", "middle")
      .text(function(d) {
        return d.data.Name.substring(0, d.r / 3);
      })
      .attr("font-family", "sans-serif")
      .attr("font-size", function(d) {
        return d.r / 5;
      })
      .attr("fill", "white");

    node
      .append("text")
      .attr("dy", "1.3em")
      .style("text-anchor", "middle")
      .text(function(d) {
        return d.data.Count;
      })
      .attr("font-family", "Gill Sans", "Gill Sans MT")
      .attr("font-size", function(d) {
        return d.r / 5;
      })
      .attr("fill", "white");
  }

  render() {
    return <div>{this.node}</div>;
  }
}

export default Bubble;

Благодарность!

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
446
1

Ответы 1

Вот пример использования пузырьковой диаграммы и реакции с использованием d3.packSiblings.

Элемент <svg> имеет ссылка, поэтому, когда компонент смонтирован, вы можете использовать d3 для создания / обновления / удаления элементов.

Примечание:

dataForPacking - это просто карта для создания атрибутов, требуемых для упаковки d3, таких как, r, x, z, затем имя ваших данных, количество.

Есть поле ввода, чтобы проиллюстрировать, как setState обновляет исходные данные реквизита новыми данными и повторно отображает пузырек. Есть много способов сделать это лучше, но это хорошее начало.

const dataJSON = [
  {
    Name: "Computer Science",
    Count: 4156
  },

  {
    Name: "Home Economics",
    Count: 689
  },
  {
    Name: "Venture Capital Investment",
    Count: 890
  },
  {
    Name: "Fabric design",
    Count: 167
  },
  {
    Name: "Deep Learning Researchers",
    Count: 812
  }
];

const dataForPacking = (data) => {
    return {
      r: data.Count,
      x: 0,
      y: 0,
      Count: data.Count,
      Name: data.Name
    };
};

class Bubble extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      width: this.props.size[0],
      height: this.props.size[1],
      data: this.props.data
    };
    this.svgRef = React.createRef();
    this.drawBubble = this.drawBubble.bind(this);
  }
  componentDidMount() {
    this.drawBubble()
  }
  componentDidUpdate() {
    this.drawBubble()
  }
  drawBubble = () => {
    const svg = d3.select(this.svgRef.current);
    svg.select("g").remove();
    const diameter = 600;

    const color = d3.scaleOrdinal(d3.schemeCategory10);

    const circles = svg
      .append("g")
      .attr("class", "circles")
      .attr(
        "transform",
        `translate(${this.state.width / 2},
          ${this.state.height / 2})scale(0.02)`
      );

    const node = circles
      .selectAll(".node")
      .data(d3.packSiblings(this.state.data))
      .enter()
      .append("g")
      .attr("class", "node")
      .attr("transform", function(d) {
        return "translate(" + d.x + "," + d.y + ")";
      });

    node.append("title").text(function(d) {
      return d.Name + ": " + d.Count;
    });

    node
      .append("circle")
      .attr("r", function(d) {
        return d.r;
      })
      .style("fill", function(d, i) {
        return color(i);
      });

    node
      .append("text")
      .attr("dy", ".2em")
      .style("text-anchor", "middle")
      .text(function(d) {
        return d.Name.substring(0, d.r / 3);
      })
      .attr("font-family", "sans-serif")
      .attr("font-size", function(d) {
        return d.r / 5;
      })
      .attr("fill", "white");

    node
      .append("text")
      .attr("dy", "1.3em")
      .style("text-anchor", "middle")
      .text(function(d) {
        return d.Count;
      })
      .attr("font-family", "Gill Sans", "Gill Sans MT")
      .attr("font-size", function(d) {
        return d.r / 5;
      })
      .attr("fill", "white");
  };
  keyPress = event => {
    if (event.key === "Enter") {
      const newDataArray = event.currentTarget.value.split(",");
      if (!newDataArray[1] || isNaN(newDataArray[1])){
        return; 
      }
      const newData = {
        Name: newDataArray[0],
        Count: Number(newDataArray[1])
      };
      this.setState(prevState => ({
        data: [...prevState.data, dataForPacking(newData)]
      }))
      event.currentTarget.value = "";
    }
  };
  reset = () => {
      this.setState(prevState => ({
        data: this.props.data.map(e => dataForPacking(e))
      }))
  };
  render() {
    return (
      <div>
        <span>Name, Count </span>
        <input type = "text" onKeyPress = {this.keyPress} />
        <button onClick = {this.reset}>reset</button>
        <svg
          ref = {this.svgRef}
          width = {this.props.size[0]}
          height = {this.props.size[1]}
        />
      </div>
    );
  }
}
ReactDOM.render(
  <Bubble data = {dataJSON.map(e=> dataForPacking(e))} size = {[600, 200]} />,
  document.getElementById("app")
);
<script src = "https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.7.0/umd/react.production.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.7.0/umd/react-dom.production.min.js"></script>
<div id = "app"><div>

Спасибо, cal_br_mar, сегодня днем ​​реализую это решение!

Acy 11.01.2019 20:29

Другие вопросы по теме