D3 v7时间刻度从日期限制的平移和缩放

huangapple go评论65阅读模式
英文:

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(&#39;2022-01-10T00:00:01&#39;)
const domainEnd = new Date()
const xScale: ScaleTime&lt;number, number&gt; = 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(&#39;zoom&#39;, ({transform}) =&gt; {
axis.scale(transform.rescaleX(xScale))
axisG.call(axis)
});
const svg = d3.select(&#39;#scale&#39;)
.append(&#39;svg&#39;)
.attr(&#39;width&#39;, width)
.attr(&#39;height&#39;, height + margin.top + margin.bottom)
.call(zoom)
const axis = d3.axisBottom(xScale)
const axisG = svg.append(&#39;g&#39;)
.attr(&#39;class&#39;, &#39;x-axis&#39;)
.attr(&#39;clip-path&#39;, &#39;url(#clip)&#39;)
.attr(&#39;transform&#39;, `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)

huangapple
  • 本文由 发表于 2023年5月31日 23:39:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76375215.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定