d3.js - 如何将 ObservableHq 简单算法解释为可重用的代码片段?
问题描述
D3js 解决方案的主要来源是observableHq.com
,但似乎不可能(?)通过复制/粘贴重用算法......是吗?即使检查这样的教程,也没有简单的方法(使用更少的插件或程序员的时间消耗!)来检查和重用.
示例:我需要一个新的 2020 D3js v5算法用于缩进树可视化,并且有一个很好的解决方案:observableHq.com/@d3/indented-tree。
下载没有用,因为是基于复杂的 运行时类...
但是,似乎是一个简单的图表生成算法,
chart = { // the indented-tree algorithm
const nodes = root.descendants();
const svg = d3.create("svg")// ...
// ...
return svg.node();
}
我是否可以通过简单的人工逐步将其转换为简单的 HTML,无需复杂的改编,以不使用Runtime 类<script src="https://d3js.org/d3.v5.min.js"></script>
开始和结束?
更多细节作为例子
想象一下我对引用的 indented-tree algorithm的逐步说明,我无法精通并需要您的帮助:
假设从一个干净的 HTML5 模板开始。例如:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Indented Tree</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
function onLOAD() {
console.log("Hello onLoad!")
// all copy-paste and adaptations HERE.
console.log("!Bye!")
} // \onLOAD
</script>
</head>
<body onload="onLOAD()">
<script>
console.log("Hello!")
// global INITIALIZATIONS HERE.
</script>
</body>
</html>
准备全局变量,似乎
root
,,nodeSize=17
和width
准备数据... JSON数据很丑
./files/e6537420...
,我用它的真实名称移动到项目的根目录,flare-2.json
.读取 JSON 数据的简单而经典的 D3js 方法:
d3.json("./flare-2.json").then( data=> console.log(data) );
必须测试并检查无 CORS 错误等。准备数据作为
root
变量。全部进入data => {}
块以避免同步问题......
似乎root
基于function(d3,data) { let i = 0; return d3.hierarchy(data).eachBefore(d => d.index = i++); }
.chart =
上面引用的复制粘贴,在root
用数据初始化之后。...
常问问题
评论问题和答案:
@Mehdi - 你能解释一下在代码中包含 D3 脚本标签和使用运行时库的问题吗?
当原始的 ObservableHq 算法很简单时,我需要另一种方法,一种简单的方法来重用它,通过复制/粘贴和最小的调整。
@Mehdi - 你读过下载和嵌入笔记本教程吗?
是的,那里没有消息:没有关于如何重用代码的“人工指令”......只有“安装它”和“安装那个”。没有关于我上面解释过的“复制/粘贴和最小调整”的说明。
(@nobody) - 你需要什么作为答案?
正如我在上面展示的,一个简单的人类可读的逐步转换过程......理想情况下,最终结果可以通过测试,证明它可以在例如 JSFiddle 上工作,并带有复制/粘贴代码等等适应线来表明你的观点。
解决方案
2020年11月编辑
Observable 现在有一个embed
特性,详情在这个页面。
原帖
这是将链接的可观察图表移植到自托管网页的分步过程,方法是复制粘贴代码,而无需使用可观察runtime
库。
从 HTML 页面和 HTML 页面中引用的 JavaScript 文件开始。假设 Web 服务器正在运行并且配置合适。
- 获取数据。
- 如果您想使用自己的数据而不是笔记本中使用的数据,请在您的 Web 服务器上的目录中提供数据文件。
- 否则,请使用每个单元格菜单中的
Download JSON
链接下载连接到笔记本的每个输入数据集。data
- 使用加载页面中的每个数据集
d3-fetch
d3.json("/path/to/data.json").then(function(data) {
console.log(data); // [{"Hello": "world"}, …]
});
获取笔记本中每个包含变量或函数的单元格的内容,然后将其放入
.then
上一步的函数中。此笔记本可视化工具有助于识别相关单元格。适当地调整刚刚复制的函数的语法。例如,以下笔记本单元格:
root = { let i = 0; return d3.hierarchy(data).eachBefore(d => d.index = i++); }
可以转化为:
function getRoot(){
let i = 0;
return d3.hierarchy(data).eachBefore(d => d.index = i++);
}
root = getRoot()
如果笔记本中的某些功能需要,请定义一个变量
width
,并使用所需的值对其进行初始化。调整 DOM 操作代码以便将元素附加到 DOM,而不是依赖于可观察运行时的隐式执行。
下面截图中的演示:
d3.json("https://rawcdn.githack.com/d3/d3-hierarchy/46f9e8bf1a5a55e94c40158c23025f405adf0be5/test/data/flare.json").then(function(data) {
const width = 800
, nodeSize = 17
, format = d3.format(",")
, getRoot = function(){
let i = 0;
return d3.hierarchy(data).eachBefore(d => d.index = i++);
}
, columns = [
{
label: "Size",
value: d => d.value,
format,
x: 280
},
{
label: "Count",
value: d => d.children ? 0 : 1,
format: (value, d) => d.children ? format(value) : "-",
x: 340
}
]
, root = getRoot()
, chart = function() {
const nodes = root.descendants();
const svg = d3.select('#chart')
.attr("viewBox", [-nodeSize / 2, -nodeSize * 3 / 2, width, (nodes.length + 1) * nodeSize])
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.style("overflow", "visible");
const link = svg.append("g")
.attr("fill", "none")
.attr("stroke", "#999")
.selectAll("path")
.data(root.links())
.join("path")
.attr("d", d => `
M${d.source.depth * nodeSize},${d.source.index * nodeSize}
V${d.target.index * nodeSize}
h${nodeSize}
`);
const node = svg.append("g")
.selectAll("g")
.data(nodes)
.join("g")
.attr("transform", d => `translate(0,${d.index * nodeSize})`);
node.append("circle")
.attr("cx", d => d.depth * nodeSize)
.attr("r", 2.5)
.attr("fill", d => d.children ? null : "#999");
node.append("text")
.attr("dy", "0.32em")
.attr("x", d => d.depth * nodeSize + 6)
.text(d => d.data.name);
node.append("title")
.text(d => d.ancestors().reverse().map(d => d.data.name).join("/"));
for (const {label, value, format, x} of columns) {
svg.append("text")
.attr("dy", "0.32em")
.attr("y", -nodeSize)
.attr("x", x)
.attr("text-anchor", "end")
.attr("font-weight", "bold")
.text(label);
node.append("text")
.attr("dy", "0.32em")
.attr("x", x)
.attr("text-anchor", "end")
.attr("fill", d => d.children ? null : "#555")
.data(root.copy().sum(value).descendants())
.text(d => format(d.value, d));
}
}
chart()
}).catch(function(err) {
console.log('error processing data', err)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.8.0/d3.min.js"></script>
<svg id = 'chart'></svg>
推荐阅读
- c# - EF:如何在同一个解决方案中跨多个项目使用数据库?
- openstreetmap - 确定是十字路口还是三向路口
- python - Accuracy_score 出现错误
- java - 使用spark检索elasticsearch数据时出错
- python - 如何从巨大的 tar.gz 文件中下载文件夹?
- powershell - Powershell读取大量文本文件,过滤信息并作为一行写入其他文本文件
- sql - 使用游标执行sql查询并将其值存储在表中
- python - 从熊猫数据框文本列中获取数组的有效方法
- c# - 我想要用户的 ax value(double)。但是当试图输入 string.program 时崩溃。我该如何解决
- python - 生成趋势特定数据