当数据加载D3时获取多个SVG元素

发布于 2025-02-06 18:28:03 字数 2058 浏览 3 评论 0原文

我试图在包装器SVG Div中制作一个矩形SVG,但不知何故,我得到了两个或有时是多个SVG包装师。我猜想当数据加载时使用效果刷新组件时,当数据不可用时会创建一个,但我可能错了。我不知道为什么会发生这种愚蠢的错误或合乎逻辑的错误,我在学习D3方面是新手,所以请原谅我并指导我。 请帮忙。 以下是代码。 谢谢

import React, { useState, useEffect } from 'react';
import * as d3 from 'd3';

const LineChart = () => {
  const weatherDataUrl =
    'https://gist.githubusercontent.com/anujshaanmydash/17687a309a87105ab8991a3dcfd8c7e3/raw/weatherData.json';

  const [data, setData] = useState(null);

  useEffect(() => {
    d3.json(weatherDataUrl).then(setData);
  }, []);

  if (!data) {
    return <pre>Loading....</pre>;
  }
  console.log(data);

  const yAccessor = (d) => d.temperatureMax;
  const dateParser = d3.timeParse('%Y-%m-%d');
  const xAccessor = (d) => dateParser(d.date);

  let dimensions = {
    width: 1200,
    height: 500,
    margins: {
      top: 15,
      right: 15,
      bottom: 30,
      left: 50,
    },
  };
  dimensions.boundedWidth =
    dimensions.width - dimensions.margins.left - dimensions.margins.right;
  dimensions.boundedHeight =
    dimensions.height - dimensions.margins.top - dimensions.margins.bottom;

  const wrapper = d3
    .select('#Wrapper')
    .append('svg')
    .attr('width', dimensions.width)
    .attr('height', dimensions.height);

  const bounds = wrapper
    .append('g')
    .style(
      'transform',
      `translate(${dimensions.margins.left}px,${dimensions.margins.top}px)`
    );

  //Create Scales
  const yScale = d3
    .scaleLinear()
    .domain(d3.extent(data, yAccessor))
    .range([dimensions.boundedHeight, 0]);

  const freezingTempArea = yScale(32);
  const freezingTemp = bounds
    .append('rect')
    .attr('x', 0)
    .attr('width', dimensions.boundedWidth)
    .attr('y', freezingTempArea)
    .attr('height', dimensions.boundedHeight - freezingTempArea)
    .attr('fill', '#e0f3f3');

  const xScale = d3
    .scaleTime()
    .domain(d3.extent(data, xAccessor))
    .range(0, dimensions.boundedWidth);

  return <div id='Wrapper'></div>;
};

export default LineChart;

I am trying to make a rectangle svg inside a wrapper svg div but somehow I am getting two or sometimes multiple svg wrapper div. I am guessing that one is created when data isn't available and another when useEffect refresh component when data loads but I might be wrong. I don't know why its happening there might be a silly mistake or logical mistake I am new in learning D3 so forgive me and guide me.
Please help.
below is the code.
Thank You

import React, { useState, useEffect } from 'react';
import * as d3 from 'd3';

const LineChart = () => {
  const weatherDataUrl =
    'https://gist.githubusercontent.com/anujshaanmydash/17687a309a87105ab8991a3dcfd8c7e3/raw/weatherData.json';

  const [data, setData] = useState(null);

  useEffect(() => {
    d3.json(weatherDataUrl).then(setData);
  }, []);

  if (!data) {
    return <pre>Loading....</pre>;
  }
  console.log(data);

  const yAccessor = (d) => d.temperatureMax;
  const dateParser = d3.timeParse('%Y-%m-%d');
  const xAccessor = (d) => dateParser(d.date);

  let dimensions = {
    width: 1200,
    height: 500,
    margins: {
      top: 15,
      right: 15,
      bottom: 30,
      left: 50,
    },
  };
  dimensions.boundedWidth =
    dimensions.width - dimensions.margins.left - dimensions.margins.right;
  dimensions.boundedHeight =
    dimensions.height - dimensions.margins.top - dimensions.margins.bottom;

  const wrapper = d3
    .select('#Wrapper')
    .append('svg')
    .attr('width', dimensions.width)
    .attr('height', dimensions.height);

  const bounds = wrapper
    .append('g')
    .style(
      'transform',
      `translate(${dimensions.margins.left}px,${dimensions.margins.top}px)`
    );

  //Create Scales
  const yScale = d3
    .scaleLinear()
    .domain(d3.extent(data, yAccessor))
    .range([dimensions.boundedHeight, 0]);

  const freezingTempArea = yScale(32);
  const freezingTemp = bounds
    .append('rect')
    .attr('x', 0)
    .attr('width', dimensions.boundedWidth)
    .attr('y', freezingTempArea)
    .attr('height', dimensions.boundedHeight - freezingTempArea)
    .attr('fill', '#e0f3f3');

  const xScale = d3
    .scaleTime()
    .domain(d3.extent(data, xAccessor))
    .range(0, dimensions.boundedWidth);

  return <div id='Wrapper'></div>;
};

export default LineChart;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

以可爱出名 2025-02-13 18:28:03

最有可能是A &lt; strictmode&gt; essue(index.js)。某些功能(例如useeffect)在开发模式下进行了双重驱动。

您可以看到,因此,在控制台上将数据记录在两次。

如何避免这种情况? @dan abramov

useEffect(() => {
  let ignore = false;
  fetchStuff().then(res => {
    if (!ignore) setResult(res)
  })
  return () => { ignore = true }
}, [])

在这里阅读更多信息 - https://github.com/github.com/face/face/face/react/react/react/24502/24502

Most probably its a <StrictMode> issue (index.js). Some functions like useEffect are double-invoked in development mode.

You can see that data is logged twice on console due to this.

How to avoid this? @Dan Abramov

useEffect(() => {
  let ignore = false;
  fetchStuff().then(res => {
    if (!ignore) setResult(res)
  })
  return () => { ignore = true }
}, [])

Read more here - https://github.com/facebook/react/issues/24502

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文