英文:
D3 v7 timeScale paning and zooming from-to date limit
问题
D3 v7时间刻度平移和缩放日期限制
大家好
我有一个问题。
我需要为自定义视频播放器创建一个带有限日期的时间刻度。
例如,从2021年1月1日到现在。
我的代码是:
const domainEnd = new Date()
const xScale = d3.scaleTime()
.domain([new Date(domainEnd.getTime() - (30*60*1000)), domainEnd])
.range([0, width]);
const zoomMin = 1;
const zoomMax = (domainEnd.getTime() - domainStart.getTime()) / (1000 * 60)
const zoom = d3.zoom()
.scaleExtent([zoomMin, zoomMax])
.on('zoom', (event) => {
const transformer = event.transform.rescaleX(xScale2)
axis.scale(transformer)
axisG.call(axis)
});
const svg = d3.select('#scale')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.call(zoom)
const axis = d3.axisBottom(xScale)
const axisG = svg.append('g')
.attr('class', 'x-axis')
.attr('transform', `translate(0,${height})`)
.call(axis)
问题是:
如何限制在两个日期之间缩放和平移刻度?谢谢
英文:
D3 v7 timeScale pan and zoom from-to date limit
Hello everyone
I have an issue.
I need to have a time scale for a custom video player with limited dates.
For ex. from 2021, 1, 1 to Date.now
My code is:
const domainStart = new Date(2021, 1, 1)
const domainEnd = new Date()
const xScale = d3.scaleTime()
.domain([new Date(domainEnd.getTime() - (30*60*1000)), domainEnd])
.range([0, width]);
const zoomMin = 1;
const zoomMax = (domainEnd.getTime() - domainStart.getTime()) / (1000 * 60)
const zoom = d3.zoom()
.scaleExtent([zoomMin, zoomMax])
.on('zoom', (event) => {
const transformer = event.transform.rescaleX(xScale2)
axis.scale(transformer)
axisG.call(axis)
});
const svg = d3.select('#scale')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.call(zoom)
const axis = d3.axisBottom(xScale)
const axisG = svg.append('g')
.attr('class', 'x-axis')
.attr('transform', `translate(0,${height})`)
.call(axis)
The question is:
How can I limit scale zooming and panning between two dates? Thx
答案1
得分: 0
好的,以下是代码部分的中文翻译:
// 我处理了这个问题。解决方案如下:
const margin = { top: 0, right: 20, bottom: 60, left: 20 };
const width = 600;
const height = 100;
const domainStart = new Date('2022-01-10T00:00:01');
const domainEnd = new Date();
const xScale: ScaleTime<number, number> = d3
.scaleTime()
.domain([domainStart, domainEnd])
.rangeRound([0, width]);
const zoomMin = 1;
const zoomMax = (domainEnd.getTime() - domainStart.getTime()) / (1000 * 60);
const zoom = d3.zoom()
.scaleExtent([zoomMin, zoomMax])
.translateExtent([[0, 0], [width, height]])
.extent([[0, 0], [width, height]])
.on('zoom', ({ transform }) => {
axis.scale(transform.rescaleX(xScale));
axisG.call(axis);
});
const svg = d3.select('#scale')
.append('svg')
.attr('width', width)
.attr('height', height + margin.top + margin.bottom)
.call(zoom);
const axis = d3.axisBottom(xScale);
const axisG = svg.append('g')
.attr('class', 'x-axis')
.attr('clip-path', 'url(#clip)')
.attr('transform', `translate(0,${height})`)
.call(axis);
const k = (domainEnd.getTime() - domainStart.getTime()) / (1000 * 60 * 30);
const centerDate = xScale.invert((width) / 2);
zoom.scaleTo(svg, k);
zoom.translateTo(svg, centerDate.getTime(), 0);
请注意,我只翻译了代码部分,没有包括其他内容。如果您需要进一步的帮助,请随时提出。
英文:
Ok I handled this issue. the solution:
const margin = {top: 0, right: 20, bottom: 60, left: 20}
const width = 600;
const height = 100;
const domainStart = new Date('2022-01-10T00:00:01')
const domainEnd = new Date()
const xScale: ScaleTime<number, number> = d3
.scaleTime()
.domain([domainStart, domainEnd])
.rangeRound([0, width])
const zoomMin = 1;
const zoomMax = (domainEnd.getTime() - domainStart.getTime()) / (1000 * 60);
const zoom = d3.zoom()
.scaleExtent([zoomMin, zoomMax])
.translateExtent([[0, 0], [width, height]])
.extent([[0, 0], [width, height]])
.on('zoom', ({transform}) => {
axis.scale(transform.rescaleX(xScale))
axisG.call(axis)
});
const svg = d3.select('#scale')
.append('svg')
.attr('width', width)
.attr('height', height + margin.top + margin.bottom)
.call(zoom)
const axis = d3.axisBottom(xScale)
const axisG = svg.append('g')
.attr('class', 'x-axis')
.attr('clip-path', 'url(#clip)')
.attr('transform', `translate(0,${height})`)
.call(axis);
const k = (domainEnd.getTime() - domainStart.getTime()) / (1000 * 60 * 30);
const centerDate = xScale.invert((width) / 2);
zoom.scaleTo(svg, k)
zoom.translateTo(svg, centerDate.getTime(), 0)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论