首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我无法从绘图中删除路径

我无法从绘图中删除路径
EN

Stack Overflow用户
提问于 2020-11-09 23:41:56
回答 1查看 27关注 0票数 0

我正在制作一个复合图。在要实现的功能中,有可能使绘图动态地出现和消失。

对于圆形和线条,我对下面的代码没有问题:

代码语言:javascript
复制
svg.selectAll('circle').remove();
svg.selectAll('line').remove();

但是我不能从显示的项目中删除路径。

我已经进行了几次尝试,这些尝试出现在useEffect钩子的lambda中,但它们都不起作用。

代码语言:javascript
复制
const useState = React.useState;
const useRef = React.useRef;
const useEffect = React.useEffect;
const Fragment = React.Fragment;

const select = d3.select;
const scaleLinear = d3.scaleLinear;
const axisBottom = d3.axisBottom;
const axisLeft = d3.axisLeft;
const line = d3.line;
const curveCardinal = d3.curveCardinal;

const PathPlot = () => {

  const [xAxisData] = useState({
    min: 100,
    max: 700
  });

  const [yAxisData] = useState({
    min: 200,
    max: 500
  });

  const [meta] = useState({
    xWidth: 600,
    yWidth: 300,
  });

  const [visible, setVisible] = useState(true);

  const handleRemove = () => {
    setVisible(false);
  }

  const [plot] = useState({
    color: 'red',
    width: '5px',
    line: [{
      x: '120',
      y: '210'
    }, {
      x: '220',
      y: '230'
    }, {
      x: '320',
      y: '250'
    }, {
      x: '380',
      y: '270'
    }, {
      x: '450',
      y: '290'
    }]

  });

  const svgRef = useRef();

  useEffect(() => {

    if (svgRef.current) {

      const svg = select(svgRef.current);

      // X-AXIS
      const xScale = scaleLinear()
        .domain([xAxisData.min, xAxisData.max])
        .range([0, meta.xWidth]);

      const xAxis = axisBottom(xScale);

      svg
        .select(".x-axis")
        .style("transform", `translateY(${meta.yWidth}px)`)
        .call(xAxis);

      // Y-AXIS
      const yScale = scaleLinear()
        .domain([yAxisData.min, yAxisData.max])
        .range([meta.yWidth, 0]);

      const yAxis = axisLeft(yScale);

      svg
        .select(".y-axis")
        .call(yAxis);

      // line plot
      if (visible) {
        const myLine = line()
          .x(value => xScale(value.x))
          .y(value => yScale(value.y))
          .curve(curveCardinal);

        svg
          .select(".line-plot")
          .data([plot.line])
          .join("path")
          .attr("d", value => myLine(value))
          .attr("fill", "transparent")
          .attr("stroke", () => plot.color)
          .attr("stroke-width", () => plot.width);
      }


    }
    return () => {
      if (svgRef.current !== undefined) {
        const svg = select(svgRef.current);
        svg
          .selectAll('.line-plot')
          .attr('d', '')
          .attr("fill", 'trasparent')
          .attr("stroke", 'transparent')
          .attr("stroke-width", '0px')
          .attr("opacity", '0');
      }
    }
  }, [xAxisData, yAxisData, meta, line]);

  return ( <
    Fragment >
    <
    svg viewBox = {
      `0 0 ${meta.xWidth} ${meta.yWidth}`
    }
    ref = {
      svgRef
    } >
    <
    g className = "x-axis" / >
    <
    g className = "y-axis" / >
    <
    path className = "line-plot" / >
    <
    /svg> <
    div onClick = {
      handleRemove
    } > REMOVE < /div> <
    /Fragment>

  );
}

ReactDOM.render( < PathPlot / > , document.querySelector("body"));
代码语言:javascript
复制
svg {
  width: 80%;
  height: auto;
  background: #eee;
  overflow: visible;
  margin: 5%;
}
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-10 05:06:28

下面就是一个例子。我将visible添加到useEffect的依赖项列表中,并始终与之划清界限。如果visible为false,我只给它0不透明度,否则给1。

代码语言:javascript
复制
const useState = React.useState;
const useRef = React.useRef;
const useEffect = React.useEffect;
const Fragment = React.Fragment;

const select = d3.select;
const scaleLinear = d3.scaleLinear;
const axisBottom = d3.axisBottom;
const axisLeft = d3.axisLeft;
const line = d3.line;
const curveCardinal = d3.curveCardinal;

const PathPlot = () => {

  const [xAxisData] = useState({
    min: 100,
    max: 700
  });

  const [yAxisData] = useState({
    min: 200,
    max: 500
  });

  const [meta] = useState({
    xWidth: 600,
    yWidth: 300,
  });

  const [visible, setVisible] = useState(true);

  const handleRemove = () => {
    setVisible(false);
  }

  const [plot] = useState({
    color: 'red',
    width: '5px',
    line: [{
      x: '120',
      y: '210'
    }, {
      x: '220',
      y: '230'
    }, {
      x: '320',
      y: '250'
    }, {
      x: '380',
      y: '270'
    }, {
      x: '450',
      y: '290'
    }]

  });

  const svgRef = useRef();

  useEffect(() => {

    console.log("hi");
    if (svgRef.current) {

      const svg = select(svgRef.current);

      // X-AXIS
      const xScale = scaleLinear()
        .domain([xAxisData.min, xAxisData.max])
        .range([0, meta.xWidth]);

      const xAxis = axisBottom(xScale);

      svg
        .select(".x-axis")
        .style("transform", `translateY(${meta.yWidth}px)`)
        .call(xAxis);

      // Y-AXIS
      const yScale = scaleLinear()
        .domain([yAxisData.min, yAxisData.max])
        .range([meta.yWidth, 0]);

      const yAxis = axisLeft(yScale);

      svg
        .select(".y-axis")
        .call(yAxis);

      // line plot
      if (visible) {
        const myLine = line()
          .x(value => xScale(value.x))
          .y(value => yScale(value.y))
          .curve(curveCardinal);

        svg
          .select(".line-plot")
          .data([plot.line])
          .join("path")
          .attr("d", value => myLine(value))
          .attr("fill", "transparent")
          .attr("stroke", () => plot.color)
          .attr("stroke-width", () => plot.width);
      }


    }
    return () => {
      if (svgRef.current !== undefined) {
        const svg = select(svgRef.current);
        svg
          .selectAll('.line-plot')
          .attr('d', '')
          .attr("fill", 'trasparent')
          .attr("stroke", 'transparent')
          .attr("stroke-width", '0px')
          .attr("opacity", '0');
      }
    }
  }, [xAxisData, yAxisData, meta, line, visible]);

  return ( <
    Fragment >
    <
    svg viewBox = {
      `0 0 ${meta.xWidth} ${meta.yWidth}`
    }
    ref = {
      svgRef
    } >
    <
    g className = "x-axis" / >
    <
    g className = "y-axis" / >
    <
    path className = "line-plot" / >
    <
    /svg> <
    div onClick = {
      handleRemove
    } > REMOVE < /div> <
    /Fragment>

  );
}

ReactDOM.render( < PathPlot / > , document.querySelector("body"));
代码语言:javascript
复制
svg {
  width: 80%;
  height: auto;
  background: #eee;
  overflow: visible;
  margin: 5%;
}
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64754730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档