Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 彩色交叉区_Javascript_Reactjs_D3.js_Frontend - Fatal编程技术网

Javascript 彩色交叉区

Javascript 彩色交叉区,javascript,reactjs,d3.js,frontend,Javascript,Reactjs,D3.js,Frontend,我怎样才能为区域设置蓝色​​在d3.js中的两行之间截取的图形。 我用d3.area表示橙色区域,用d3.line表示线条。有d3功能吗 问题解决了! 非常感谢你,Mehdi 现在它工作了 下面是使用React JS的完整源代码: import React, { useEffect, useRef, useState } from "react"; import { select, axisBottom, min, max, scaleLinear, axisLeft,

我怎样才能为区域设置蓝色​​在d3.js中的两行之间截取的图形。 我用d3.area表示橙色区域,用d3.line表示线条。有d3功能吗

问题解决了! 非常感谢你,Mehdi

现在它工作了

下面是使用React JS的完整源代码:

import React, { useEffect, useRef, useState } from "react";
import {
  select,
  axisBottom,
  min,
  max,
  scaleLinear,
  axisLeft,
  area,
  line,
  curveMonotoneX,
} from "d3";
import useResizeObserver from "./useResizeObserver";

const data = [
  { x: 0, low: 100, high: 245 },
  { x: 3, low: 97, high: 244 },
  { x: 5, low: 94, high: 243 },
  { x: 8, low: 92, high: 242 },
  { x: 10, low: 90, high: 240 },
  { x: 13, low: 88, high: 237 },
  { x: 16, low: 85, high: 234 },
  { x: 18, low: 83, high: 232 },
  { x: 20, low: 80, high: 230 },
  { x: 22, low: 79, high: 225 },
  { x: 25, low: 69, high: 220 },
  { x: 28, low: 49, high: 215 },
  { x: 30, low: 0, high: 210 },
  { x: 40, low: 0, high: 120 },
  { x: 49, low: 0, high: 0 },
];

const points = [
  [
    { x: 0, y: 0 },
    { x: 10, y: 70 },
    { x: 20, y: 150 },
    { x: 25, y: 180 },
    { x: 30, y: 245 },
  ],
  [
    { x: 14, y: 0 },
    { x: 27, y: 100 },
    { x: 30, y: 150 },
    { x: 38, y: 245 },
  ],
];

function StackedBarChart() {
  const svgRef = useRef();
  const wrapperRef = useRef();
  const dimensions = useResizeObserver(wrapperRef);
  const [init, setInit] = useState(false);

  useEffect(() => {
    if (data.length && points.length && !init) {
      setInit(true);
      const svg = select(svgRef.current);
      const { width, height } =
        dimensions || wrapperRef.current.getBoundingClientRect();

      const xScale = scaleLinear()
        .domain([min(data, (d) => d.x), max(data, (d) => d.x)])
        .range([0, width]);

      const yScale = scaleLinear()
        .domain([0, max(data, (d) => d.high)])
        .range([height, 0]);

      const xAxis = axisBottom(xScale);
      svg.append("g").attr("transform", `translate(0, ${height})`).call(xAxis);

      const yAxis = axisLeft(yScale);
      svg.append("g").call(yAxis);

      const areaGenerator = area()
        .defined((d) => true)
        .x((d) => xScale(d.x))
        .y0((d) => yScale(d.low))
        .y1((d) => yScale(d.high))
        .curve(curveMonotoneX);

      const areaData1 = areaGenerator(data);

      const lineGenerator = line()
        .x((p) => xScale(p.x))
        .y((p) => yScale(p.y));

      const polygon1 = points.map((point) =>
        point.map((item) => [item.x, item.y])
      );
      const arrPolygons = [...polygon1[0].reverse(), ...polygon1[1]];

      const clip = svg.append("g").append("clipPath").attr("id", "clip");
      clip
        .selectAll("#pol1")
        .data([arrPolygons])
        .enter()
        .append("polygon")
        .attr("id", "pol1")
        .attr("points", (d) => {
          return d.map((i) => [xScale(i[0]), yScale(i[1])]).join(" ");
        });

      const areaChart1 = svg
        .append("path")
        .attr("id", "area1")
        .attr("class", "layer1")
        .style("fill", "orange")
        .attr("d", areaData1);

      const areaChart = svg
        .append("path")
        .attr("id", "area")
        .attr("class", "layer")
        .attr("clip-path", "url(#clip)")
        .style("fill", "blue")
        .attr("d", areaData1);

      svg
        .append("path")
        .attr("class", "line1")
        .attr("d", lineGenerator(points[0]));
      svg
        .append("path")
        .attr("class", "line2")
        .attr("d", lineGenerator(points[1]));
    }
  }, [data, dimensions, init, points]);

  return (
    <>
      <div ref={wrapperRef} style={{ marginBottom: "2rem" }}>
        <svg ref={svgRef} />
      </div>
    </>
  );
}

export default StackedBarChart;

是的,当然。我很抱歉。我会的。谢谢谢谢但这个例子并非如此,这使得提供解决方案更加困难。未定义数据,语法无效,例如scaleLinear而不是d3.scaleLinear。可以使用覆盖两条线之间区域的多边形定义clipPath。然后,剪裁路径的副本,并用蓝色填充。参考文献:。
import React, { useEffect, useRef, useState } from "react";
import {
  select,
  axisBottom,
  min,
  max,
  scaleLinear,
  axisLeft,
  area,
  line,
  curveMonotoneX,
} from "d3";
import useResizeObserver from "./useResizeObserver";

const data = [
  { x: 0, low: 100, high: 245 },
  { x: 3, low: 97, high: 244 },
  { x: 5, low: 94, high: 243 },
  { x: 8, low: 92, high: 242 },
  { x: 10, low: 90, high: 240 },
  { x: 13, low: 88, high: 237 },
  { x: 16, low: 85, high: 234 },
  { x: 18, low: 83, high: 232 },
  { x: 20, low: 80, high: 230 },
  { x: 22, low: 79, high: 225 },
  { x: 25, low: 69, high: 220 },
  { x: 28, low: 49, high: 215 },
  { x: 30, low: 0, high: 210 },
  { x: 40, low: 0, high: 120 },
  { x: 49, low: 0, high: 0 },
];

const points = [
  [
    { x: 0, y: 0 },
    { x: 10, y: 70 },
    { x: 20, y: 150 },
    { x: 25, y: 180 },
    { x: 30, y: 245 },
  ],
  [
    { x: 14, y: 0 },
    { x: 27, y: 100 },
    { x: 30, y: 150 },
    { x: 38, y: 245 },
  ],
];

function StackedBarChart() {
  const svgRef = useRef();
  const wrapperRef = useRef();
  const dimensions = useResizeObserver(wrapperRef);
  const [init, setInit] = useState(false);

  useEffect(() => {
    if (data.length && points.length && !init) {
      setInit(true);
      const svg = select(svgRef.current);
      const { width, height } =
        dimensions || wrapperRef.current.getBoundingClientRect();

      const xScale = scaleLinear()
        .domain([min(data, (d) => d.x), max(data, (d) => d.x)])
        .range([0, width]);

      const yScale = scaleLinear()
        .domain([0, max(data, (d) => d.high)])
        .range([height, 0]);

      const xAxis = axisBottom(xScale);
      svg.append("g").attr("transform", `translate(0, ${height})`).call(xAxis);

      const yAxis = axisLeft(yScale);
      svg.append("g").call(yAxis);

      const areaGenerator = area()
        .defined((d) => true)
        .x((d) => xScale(d.x))
        .y0((d) => yScale(d.low))
        .y1((d) => yScale(d.high))
        .curve(curveMonotoneX);

      const areaData1 = areaGenerator(data);

      const lineGenerator = line()
        .x((p) => xScale(p.x))
        .y((p) => yScale(p.y));

      const polygon1 = points.map((point) =>
        point.map((item) => [item.x, item.y])
      );
      const arrPolygons = [...polygon1[0].reverse(), ...polygon1[1]];

      const clip = svg.append("g").append("clipPath").attr("id", "clip");
      clip
        .selectAll("#pol1")
        .data([arrPolygons])
        .enter()
        .append("polygon")
        .attr("id", "pol1")
        .attr("points", (d) => {
          return d.map((i) => [xScale(i[0]), yScale(i[1])]).join(" ");
        });

      const areaChart1 = svg
        .append("path")
        .attr("id", "area1")
        .attr("class", "layer1")
        .style("fill", "orange")
        .attr("d", areaData1);

      const areaChart = svg
        .append("path")
        .attr("id", "area")
        .attr("class", "layer")
        .attr("clip-path", "url(#clip)")
        .style("fill", "blue")
        .attr("d", areaData1);

      svg
        .append("path")
        .attr("class", "line1")
        .attr("d", lineGenerator(points[0]));
      svg
        .append("path")
        .attr("class", "line2")
        .attr("d", lineGenerator(points[1]));
    }
  }, [data, dimensions, init, points]);

  return (
    <>
      <div ref={wrapperRef} style={{ marginBottom: "2rem" }}>
        <svg ref={svgRef} />
      </div>
    </>
  );
}

export default StackedBarChart;