javascript - 在 D3.js 中使用 vanilla JS 选择器
问题描述
我有一个最小的 d3 折线图示例,我想用它替换原版 js 选择器的 d3 选择器。
下面显示了我的尝试,在我的 vanilla js 版本下方注释掉了工作 d3 代码。它确实成功地创建了所有预期的 SVG 元素,但它们没有正确呈现到屏幕上,因此没有图表。
const data = [
{ date: "Wed, 14 Aug 2019 00:00:00 GMT", close: 2.9254177545691844 },
{ date: "Wed, 28 Aug 2019 00:00:00 GMT", close: 2.8956143512450847 },
{ date: "Fri, 30 Aug 2019 00:00:00 GMT", close: 2.8878846468949795 },
{ date: "Mon, 02 Sep 2019 00:00:00 GMT", close: 2.893494826736734 },
];
data.forEach(d => (d.date = new Date(d.date)));
const margin = { top: 30, right: 30, bottom: 50, left: 50 };
const width = 960 - margin.left - margin.right;
const height = 500 - margin.top - margin.bottom;
// set the ranges
const x = d3
.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([0, width]);
const y = d3
.scaleLinear()
.domain(d3.extent(data, d => d.close))
.range([height, 0]);
// create line generator
const valueline = d3
.line()
.x(d => x(d.date))
.y(d => y(d.close));
// add svg and g with vanilla js
const body = document.querySelector("body");
const svg = document.createElement("svg");
svg.setAttribute("width", width + margin.left + margin.right);
svg.setAttribute("height", height + margin.top + margin.bottom);
const g = document.createElement("g");
g.setAttribute("transform", `translate(${margin.left},${margin.top})`);
svg.appendChild(g);
body.appendChild(svg);
// add svg and g with d3
// d3.select("body")
// .append("svg")
// .attr("width", width + margin.left + margin.right)
// .attr("height", height + margin.top + margin.bottom)
// .append("g")
// .attr("transform", `translate(${margin.left},${margin.top})`);
// Add lines
const g2 = d3.select("g");
g2.append("path")
.data([data])
.attr("d", valueline)
.attr("stroke", "red")
.attr("fill", "none");
// Add the Axes
g2.append("g")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(x));
g2.append("g").call(d3.axisLeft(y));
解决方案
您需要指定名称空间,因为 SVG 名称空间与 HTML 不同。我们需要使用document.createElementNS来创建 SVG 元素:
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
如果我们将其放入您的代码块中,我们应该会成功绘制图表:
const data = [
{ date: "Wed, 14 Aug 2019 00:00:00 GMT", close: 2.9254177545691844 },
{ date: "Wed, 28 Aug 2019 00:00:00 GMT", close: 2.8956143512450847 },
{ date: "Fri, 30 Aug 2019 00:00:00 GMT", close: 2.8878846468949795 },
{ date: "Mon, 02 Sep 2019 00:00:00 GMT", close: 2.893494826736734 },
];
data.forEach(d => (d.date = new Date(d.date)));
const margin = { top: 30, right: 30, bottom: 50, left: 50 };
const width = 960 - margin.left - margin.right;
const height = 500 - margin.top - margin.bottom;
// set the ranges
const x = d3
.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([0, width]);
const y = d3
.scaleLinear()
.domain(d3.extent(data, d => d.close))
.range([height, 0]);
// create line generator
const valueline = d3
.line()
.x(d => x(d.date))
.y(d => y(d.close));
// add svg and g with vanilla js
//*
const body = document.querySelector("body");
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute("width", width + margin.left + margin.right);
svg.setAttribute("height", height + margin.top + margin.bottom);
const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
g.setAttribute("transform", `translate(${margin.left},${margin.top})`);
svg.appendChild(g);
body.appendChild(svg);
//*/
// add svg and g with d3
/*
d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
//*/
// Add lines
const g2 = d3.select("g");
g2.append("path")
.data([data])
.attr("d", valueline)
.attr("stroke", "red")
.attr("stroke-width",1)
.attr("fill", "none");
// Add the Axes
g2.append("g")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(x));
g2.append("g").call(d3.axisLeft(y));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
推荐阅读
- docker - 没有密码的用户无法在 Docker 中共享本地驱动器
- xamarin.android - 解决失败:[Lcom/google/android/gms/phenotype/ExperimentTokens,当我点击地点搜索栏时
- c# - 如何从 SpringCM 工作流中获取 Salesforce 字段?
- reactjs - 使用 React.lazy、Suspense 和 react-router-dom 进行代码拆分不起作用
- sql - asp.net rdlc 报告
- javascript - 在大数据上调用 fromCharCode 的有效方法
- javascript - 如何消除不想要的位置间隙:粘性
- r - 升级适用于 Windows 的机器学习服务器的 R 版本
- mysql - 如何使光标工作并填写列表,程序唯一参数的一行中的值
- r-markdown - 将章节编号添加到 r markdown 中的方程式编号