Javascript D3放大折线图的一部分
我试图在折线图的一部分上使用onclick函数放大。我已经阅读了很多关于这个问题的文章和问题,但是大多数都是关于轮子的缩放,我需要的只是点击按钮进行缩放。类似于(折线图)的东西。 我搞不懂的是,如何计算缩放应该被正确平移和缩放的确切位置(我需要图形的右侧,从要放大的特定x轴值开始)。希望有人能帮忙。 我在代码中包含了模拟数据,但实际数据更细粒度 我的代码: 也Javascript D3放大折线图的一部分,javascript,d3.js,svg,Javascript,D3.js,Svg,我试图在折线图的一部分上使用onclick函数放大。我已经阅读了很多关于这个问题的文章和问题,但是大多数都是关于轮子的缩放,我需要的只是点击按钮进行缩放。类似于(折线图)的东西。 我搞不懂的是,如何计算缩放应该被正确平移和缩放的确切位置(我需要图形的右侧,从要放大的特定x轴值开始)。希望有人能帮忙。 我在代码中包含了模拟数据,但实际数据更细粒度 我的代码: 也 快速移动 数据集=[ { “num”:100, “月”:1, “年份”:2016年, “mmyy”:“2016年1月”, “集团”:“
快速移动
数据集=[
{
“num”:100,
“月”:1,
“年份”:2016年,
“mmyy”:“2016年1月”,
“集团”:“一家”,
“mmyy_rec”:“2016年1月”
},
{
“num”:80,
“月”:1,
“年份”:2017年,
“mmyy”:“2017年1月”,
“集团”:“一家”,
“mmyy_rec”:“2017年1月”
},
{
“num”:10,
“月”:1,
“年份”:2018年,
“mmyy”:“2018年1月”,
“集团”:“一家”,
“mmyy_rec”:“2018年1月”
}
]
设维数={
宽度:800,
身高:400,
保证金:{
前20名,
右:15,
底数:40,
左:60,,
},
}
dimensions.boundedWidth=dimensions.width-dimensions.margin.left-dimensions.margin.right
尺寸.boundedHeight=尺寸.height-尺寸.margin.top-尺寸.margin.bottom
常量包装器=d3。选择(“包装器”)
.append(“svg”)
.attr(“宽度”,尺寸.宽度)
.attr(“高度”,尺寸。高度);
const bounds=wrapper.append(“g”)
.style(“transform”,`translate(${dimensions.margin.left}px,${dimensions.margin.top}px)`)
.attr(“类”、“测试”);
常量xScale=d3.scalePoint()
.domain(dataset.map(d=>d.mmyy_rec))
.范围([0,维度.边界宽度]);
常量yScale=d3.scaleLinear()
.domain([0,d3.max(数据集,d=>d.num)])
.范围([尺寸.边界高度,0]);
常量行=d3.line()
.曲线(d3.曲线自然)
.x(d=>xScale(d.mmyy_rec))
.y(d=>yScale(d.num));
常量路径1=边界
.append('路径')
.数据集(数据集)
.attr('填充','无')
.attr('笔划','绿色')
.attr(“类别”、“第1行”)
.attr('d',行)
常量yAxisGenerator=d3.axisLeft().scale(yScale)
调用(yAxisGenerator);
d3.选择(“缩放”)。在(“单击”,函数()上{
const d0=“2017年1月”;
const d1=“2018年12月”;
常数k=尺寸.边界宽度/(xScale(d1)-xScale(d0));
常量长度=尺寸。边界高度-yScale(100);
const centerX=尺寸。边界宽度/2;
常数中心=尺寸。边界高度/2;
const translate=[dimensions.boundedWidth/2-centerX*k,dimensions.boundedHeight/2-centerY*k]
const zoom=d3.zoom()
.scaleExtent([1,2])
.translateExtent([[0,0],[dimensions.boundedWidth,dimensions.boundedHeight]]
.extent([[0,0],[dimensions.boundedWidth,dimensions.boundedHeight]]
.on('zoom',function(){
path1.attr('transform',d3.event.transform);
});
zoom.scaleBy(路径1.transition().duration(750),k)
.翻译(centerX、centerY);
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<div id="wrapper" class="wrapper"></div>
<button id="zoom">Zoom</button>
<script>
dataset = [
{
"num": 100,
"month": 1,
"year": 2016,
"mmyy": "2016 _ 1",
"group": "one",
"mmyy_rec": "Jan 2016"
},
{
"num": 80,
"month": 1,
"year": 2017,
"mmyy": "2017 _ 1",
"group": "one",
"mmyy_rec": "Jan 2017"
},
{
"num": 10,
"month": 1,
"year": 2018,
"mmyy": "2018 _ 1",
"group": "one",
"mmyy_rec": "Jan 2018"
}
]
let dimensions = {
width: 800,
height: 400,
margin: {
top: 20,
right: 15,
bottom: 40,
left: 60,
},
}
dimensions.boundedWidth = dimensions.width - dimensions.margin.left - dimensions.margin.right
dimensions.boundedHeight = dimensions.height - dimensions.margin.top - dimensions.margin.bottom
const wrapper = d3.select("#wrapper")
.append("svg")
.attr("width", dimensions.width)
.attr("height", dimensions.height);
const bounds = wrapper.append("g")
.style("transform", `translate(${dimensions.margin.left}px, ${dimensions.margin.top}px)`)
.attr("class", "test");
const xScale = d3.scalePoint()
.domain(dataset.map(d=> d.mmyy_rec))
.range([0, dimensions.boundedWidth]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(dataset,d=>d.num)])
.range([dimensions.boundedHeight,0]);
const line = d3.line()
.curve(d3.curveNatural)
.x(d => xScale(d.mmyy_rec))
.y(d => yScale(d.num));
const path1 = bounds
.append('path')
.datum(dataset)
.attr('fill', 'none')
.attr('stroke', 'green')
.attr("class", "line1")
.attr('d', line)
const yAxisGenerator = d3.axisLeft().scale(yScale)
bounds.call(yAxisGenerator);
d3.select("#zoom").on("click", function() {
const d0 = "Jan 2017";
const d1 = "Dec 2018";
const k = dimensions.boundedWidth / (xScale(d1) - xScale(d0));
const length = dimensions.boundedHeight - yScale(100);
const centerX = dimensions.boundedWidth /2;
const centerY = dimensions.boundedHeight /2;
const translate = [dimensions.boundedWidth / 2 - centerX * k, dimensions.boundedHeight / 2 - centerY * k]
const zoom = d3.zoom()
.scaleExtent([1, 2])
.translateExtent([[0, 0], [dimensions.boundedWidth, dimensions.boundedHeight]])
.extent([[0, 0], [dimensions.boundedWidth, dimensions.boundedHeight]])
.on('zoom', function() {
path1.attr('transform', d3.event.transform);
});
zoom.scaleBy(path1.transition().duration(750), k)
.translate(centerX,centerY);
});
</script>
</body>
</html>