我编写了以下用于显示d3js树布局的代码,但在尝试根据其宽高比调整生成的svg时遇到了一些困难。我能够(在附带的演示中)让svg按照我想要的方式进行扩展,但是我编写的代码受到const ASPECT_RATIO
的约束,如下所示:
canvas.attr("viewBox", " 0 0 " + window.innerWidth + " " + (window.innerWidth * ASPECT_RATIO));
再次向下,在这里:
layout.size([(window.innerWidth * ASPECT_RATIO), window.innerWidth - 128]);
有没有办法规避这个?我希望每次svg的宽高比改变时(即,每次添加新内容时)都不需要手动更改此值。
此致
布赖恩
const ASPECT_RATIO
。代码:
/// <reference path="d3.d.ts" />
"use strict";
/* (c) brianjenkins94 | brianjenkins94.me | MIT licensed */
// Get JSON, impose synchronicity
d3.json("js/data.json", function(error, treeData) {
if (!error) {
// Instantiate canvas
var canvas = d3.select("#canvas");
// Aspect ratio nonsense
const ASPECT_RATIO = 1.89260808926;
canvas.attr("viewBox", " 0 0 " + window.innerWidth + " " + (window.innerWidth * ASPECT_RATIO));
canvas.attr("preserveAspectRatio", "xMinYMin slice");
// Update
update();
function update() {
// Add an SVG group element
canvas.append("g");
// Instantiate group
var group = canvas.select("g");
// Translate group right
group.attr("transform", "translate(64, 0)");
// Instantiate layout tree
var layout = d3.layout.tree();
// Initialize layout dimensions
layout.size([(window.innerWidth * ASPECT_RATIO), window.innerWidth - 128]);
// Instantiate rotation diagonal
var diagonal = d3.svg.diagonal();
// Rotate projection 90 degrees about the diagonal
diagonal.projection(function(d) { return [d.y, d.x]; });
// Initialize node array
var nodes = layout.nodes(treeData);
// Initialize link array
var links = layout.links(nodes);
// Select all paths in group
group.selectAll("path")
// For each link, create a path
.data(links).enter().append("path")
// Provide the specific diagonal
.attr("d", diagonal);
// Select all groups in group
var node = group.selectAll("g")
// For each node, create a group
.data(nodes).enter().append("g")
// Translate accordingly
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
// Add a circle at every node
node.append("circle")
.attr("r", 3);
// Add label
node.append("text")
// To the left if the node has children, otherwise right
.attr("dx", function(d) { return d.children ? -8 : 8; })
.attr("dy", 0)
// Branch if the node has children
.attr("text-anchor", function(d) { return d.children ? "end" : "start"; })
.text(function(d) { return d.name; });
}
} else {
console.log("There was a connection error of some sort.");
}
});
演示:
答案 0 :(得分:1)
这是我学到的东西:
我的解决方案如下:
// Viewbox & preserveAspectRatio
canvas.attr("viewBox", " 0 0 " + window.innerWidth + " " + (2 * window.innerWidth));
canvas.attr("preserveAspectRatio", "xMinYMin slice");
...
// Initialize layout dimensions
layout.size([(2 * window.innerWidth), (window.innerWidth - 128)]);
因此消除了对const ASPECT_RATIO
的依赖,支持基于浏览器维度的相对测量。
这可能(并且几乎肯定会)导致多个视口之间的渲染不一致,但可以通过在渲染和使用修饰调整之前查询视口来相应地处理。