javascript - 彩色拦截区
问题描述
如何将d3.js中两条线之间截取的图形区域设置为蓝色。我将 d3.area 用于橙色区域,将 d3.line 用于线条。有 d3 功能吗?
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);
svg.append("path")
.attr("class", "layer")
.style("fill", "orange")
.attr("d", areaData1);
const line = d3.line().x(p => xScale(p.x)).y(p => yScale(p.y));
svg.append("path").attr("class", "line1").attr("stroke", "black").attr("d", line(points[0]));
svg.append("path").attr("class", "line2").attr("stroke", "black").attr("d", line(points[1]));
解决方案
解决了!非常感谢梅赫迪!
现在它起作用了!
下面是使用 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;
推荐阅读
- c# - 在 ASP.NET C# 中将 Label 转换为 int
- mysql - 在 Mysql 中创建动态数据透视表
- c# - stringWithFormat "%.16f" 是什么意思?
- google-apps-script - 调用表单提交可安装触发器时谁是“调用者”?
- java - 在连接 Txt 文件时遇到问题
- python - PyInstaller + Ui 文件
- vba - 用于从 Windows 捕获用户的 VB 代码,用于 Access(2020 版 64 位)
- python - sagemaker.tensorflow.serving 预测失败,出现 502 错误
- linux - Ubuntu 19.10 中的 sssd 配置问题 - 与 Ubuntu <19.04 不同
- ag-grid - 将标题旋转 45 度