D3.js 设置初始缩放级别
Posted
技术标签:
【中文标题】D3.js 设置初始缩放级别【英文标题】:D3.js Set initial zoom level 【发布时间】:2013-04-17 04:47:54 【问题描述】:我设置了几个图表来放大容器,效果很好。但是,在初始加载时,缩放级别太接近了。有没有一种方法可以设置初始缩放级别以避免必须先缩小?我熟悉.scale()
方法,但没有任何运气来实现它。这是要走的路还是我缺少什么?
这是我迄今为止关于缩放的内容:
var margin = top: 20, right: 120, bottom: 20, left: 120,
width = 50000 - margin.right - margin.left,
height = 120000 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([0, width])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, height])
.range([height, 0]);
var tree = d3.layout.tree()
.size([height, width])
.separation(function(a, b) return (a.parent == b.parent ? 1 : 2) / a.depth; );
var diagonal = d3.svg.diagonal()
.projection(function(d) return [d.x, d.y]; );
function zoom(d)
svg.attr("transform",
"translate(" + d3.event.translate + ")"+ " scale(" + d3.event.scale + ")");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("pointer-events", "all")
.call(d3.behavior.zoom()
.x(x)
.y(y)
.scaleExtent([0,8])
.on("zoom", zoom))
.append('g');
svg.append('rect')
.attr('width', width*5)
.attr('height', height)
.attr('border-radius', '20')
.attr('fill', 'sienna');
【问题讨论】:
既然您使用 SVG 转换scale
进行缩放,为什么不静态设置一个缩放值来提供您想要的缩放级别?
听起来很棒!我该怎么做?
Lars,scale 值到底是怎么静态设置的?
【参考方案1】:
D3v4 答案
如果您在这里寻找相同但使用 D3 v4,
var zoom = d3.zoom().on("zoom", function()
svg.attr("transform", d3.event.transform);
);
vis = svg.append("svg:svg")
.attr("width", width)
.attr("height", height)
.call(zoom) // here
.call(zoom.transform, d3.zoomIdentity.translate(100, 50).scale(0.5))
.append("svg:g")
.attr("transform","translate(100,50) scale(.5,.5)");
【讨论】:
无法让此解决方案在 d3 v5 上运行。你知道有什么变化吗?【参考方案2】:我终于通过将初始变换和缩放行为设置为相同的值来实现这一点。
var zoom = d3.behavior.zoom().translate([100,50]).scale(.5);
vis = svg.append("svg:svg")
.attr("width", width)
.attr("height", height)
.call(zoom.on("zoom",zooming))
.append("svg:g")
.attr("transform","translate(100,50)scale(.5,.5)");
【讨论】:
【参考方案3】:将此答案添加为已接受答案的附录,以防任何人仍有问题:
让这件事变得非常容易理解的是 here
话虽如此,我设置了三个变量:
缩放、缩放宽度和缩放高度
scale是你希望缩放的初始比例,然后
zoomWidth 和 zoomHeight 定义如下:
zoomWidth = (width-scale*width)/2
zoomHeight = (height-scale*height)/2
其中 width 和 height 是 "vis" svg 元素的宽度和高度
然后将上面的翻译修改为:
.attr("transform", "translate("+zoomWidth+","+zoomHeight+") scale("+scale+")")
还有缩放功能:
d3.behavior.zoom().translate([zoomWidth,zoomHeight]).scale(scale)
这样做可以有效地确保您的元素在加载可视化时缩放并居中。
如果这对您有帮助,请告诉我!干杯。
【讨论】:
我从 JSON 加载了缩放级别,我正在尝试在 svg 加载时重新创建缩放级别。你能发布你的完整解决方案吗? :) 如果该链接仍然有效,那就太好了......感谢上帝the Wayback Archive 更新我的原始答案以引用存档链接。谢谢! 在我的情况下是zoomWidth
和 zoomHeight
其中“offsetLeft”和“offsetTop”【参考方案4】:
适用于 d3.js v4
这类似于davcs86's answer,但它重用了初始变换并实现了缩放功能。
// Initial transform to apply
var transform = d3.zoomIdentity.translate(200, 0).scale(1);
var zoom = d3.zoom().on("zoom", handleZoom);
var svg = d3.select("body")
.append('svg')
.attr('width', 800)
.attr('height', 300)
.style("background", "red")
.call(zoom) // Adds zoom functionality
.call(zoom.transform, transform); // Calls/inits handleZoom
var zoomable = svg
.append("g")
.attr("class", "zoomable")
.attr("transform", transform); // Applies initial transform
var circles = zoomable.append('circle')
.attr("id", "circles")
.attr("cx", 100)
.attr("cy", 100)
.attr('r', 20);
function handleZoom()
if (zoomable)
zoomable.attr("transform", d3.event.transform);
;
查看实际操作:jsbin link
【讨论】:
感谢handleZoom中的if条件【参考方案5】:我使用 d3 和 react 并且对初始缩放不起作用感到非常沮丧。
我在这里尝试了解决方案,但都没有奏效,取而代之的是使用初始比例因子和位置,然后根据这些比例因子和位置更新缩放功能
const initialScale = 3;
const initialTranslate = [
width * (1 - initialScale) / 2,
height * (1 - initialScale) / 2,
];
const container = svg
.append('g')
.attr(
'transform',
`translate($initialTranslate[0], $initialTranslate[1])scale($initialScale)`
);
缩放功能看起来像这样
svg.call(
zoom().on('zoom', () =>
const transformation = getEvent().transform;
let x, y, k = transformation;
x += initialTranslate[0];
y += initialTranslate[1];
k *= initialScale;
container.attr('transform', `translate($x, $y)scale($k)`);
)
);
如果您注意到 getEvent()
是一个函数,那是因为从 d3-selection
导入事件在我的情况下不起作用。所以我不得不这样做
const getEvent = () => require('d3-selection').event;
【讨论】:
在 d3 版本 5 中是:d3.event.transform【参考方案6】:D3JS 6 答案
假设您希望初始位置和比例分别为x
、y
、scale
。
const zoom = d3.zoom();
const svg = d3.select("#containerId")
.append("svg")
.attr("width", width)
.attr("height", height)
.call(zoom.transform, d3.zoomIdentity.translate(x, y).scale(scale)
.call(zoom.on('zoom', (event) =>
svg.attr('transform', event.transform);
))
.append("g")
.attr('transform', `translate($x, $y)scale($k)`);
.call(zoom.transform, d3.zoomIdentity.translate(x, y).scale(scale)
确保在触发缩放事件时,event.transform
变量会考虑平移和缩放。紧随其后的行处理缩放,而最后一行用于在“启动”时应用平移和缩放一次。
【讨论】:
以上是关于D3.js 设置初始缩放级别的主要内容,如果未能解决你的问题,请参考以下文章