D3: Zoom не сбрасывает масштаб

У меня есть простая диаграмма с смоделированными данными в реальном времени. Вы можете включать и выключать рисунок. Когда рисование выключено, вы можете увеличивать и уменьшать масштаб.

https://codesandbox.io/s/wqyz1q3o45

Вот в чем проблема:

  1. Подождите некоторое время, чтобы на экране появились данные
  2. Нажмите «Переключить», чтобы прекратить рисование новых данных.
  3. Увеличение (колесо мыши или двойной щелчок) и уменьшение
  4. Нажмите «Переключить», чтобы снова начать рисование.

Вы можете видеть, что леска съедается слева. Это потому, что весы не сбрасываются.

Вот метод render

public render(data: ISample[]) {
  this.xScale.domain(extent(data, d => d.timestamp) as [number, number]);
  this.yScale.domain(extent(data, d => d.value) as [number, number]);

  this.xAxisGroup.call(this.xAxis as any);
  this.yAxisGroup.call(this.yAxis as any);

  this.xGridGroup.call(this.xGrid as any);
  this.yGridGroup.call(this.yGrid as any);

  this.lineGroup.datum(data).attr("d", this.line);
}

И метод zoom

public zoom = () => {
  const newXScale = event.transform.rescaleX(this.xScale);
  const newYScale = event.transform.rescaleY(this.yScale);

  this.xAxisGroup.call(this.xAxis.scale(newXScale));
  this.yAxisGroup.call(this.yAxis.scale(newYScale));

  this.xGridGroup.call(this.xGrid.scale(newXScale));
  this.yGridGroup.call(this.yGrid.scale(newYScale));

  this.line.x(d => newXScale(d.timestamp)).y(d => newYScale(d.value));

  this.lineGroup.attr("d", this.line as any);
};

Если вместо этого вы используете следующий код в методе render или закомментируете / раскомментируете соответствующие строки, он будет работать.

this.xAxisGroup.call(this.xAxis.scale(this.xScale));
this.yAxisGroup.call(this.yAxis.scale(this.yScale));

this.xGridGroup.call(this.xGrid.scale(this.xScale));
this.yGridGroup.call(this.yGrid.scale(this.yScale));

this.line.x(d => this.xScale(d.timestamp)).y(d => this.yScale(d.value));

Вы можете нажать «Переключить» и увеличивать / уменьшать масштаб сколь угодно сильно.

Зачем нужно сбрасывать весы в методе render? Особенно что-то вроде

this.line.x(d => this.xScale(d.timestamp)).y(d => this.yScale(d.value));

это никогда не меняется. Всегда должно быть одно и то же. Я думал, что уменьшение масштаба снова сбрасывает масштаб до исходного значения.

Спасибо за помощь!

вы не обновляете line.x() и line.y() после увеличения (строка закомментирована)

rioV8 17.12.2018 17:44

а для оси и сеток: переключите версии комментариев: вам нужно обновить масштаб оси после масштабирования

rioV8 17.12.2018 17:57
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
126
1

Ответы 1

Изменить функцию рендеринга chart.ts

  public render(data: ISample[]) {
    this.xScale.domain(extent(data, d => d.timestamp) as [number, number]);
    this.yScale.domain(extent(data, d => d.value) as [number, number]);

    // this.xAxisGroup.call(this.xAxis as any);
    this.xAxisGroup.call(this.xAxis.scale(this.xScale));

    // this.yAxisGroup.call(this.yAxis as any);
    this.yAxisGroup.call(this.yAxis.scale(this.yScale));

    // this.xGridGroup.call(this.xGrid as any);
    // this.yGridGroup.call(this.yGrid as any);
    this.xGridGroup.call(this.xGrid.scale(this.xScale));
    this.yGridGroup.call(this.yGrid.scale(this.yScale));

    this.line.x(d => this.xScale(d.timestamp)).y(d => this.yScale(d.value));

    this.lineGroup.datum(data).attr("d", this.line);
  }

но почему? Мне не нужно каждый раз сбрасывать шкалу. Уменьшение масштаба должно сбросить масштаб. Если вы не увеличиваете / уменьшаете масштаб, все работает нормально. Ваше решение - это просто код, который я дал в вопросе.

zemirco 17.12.2018 19:55

@zemirco: вы изменяете масштаб (ы) и функции доступа в обработчике масштабирования, вам нужно установить их обратно

rioV8 17.12.2018 20:50

Другие вопросы по теме