Есть ли в LightningChartJS способ сделать масштабирование перетаскиванием, когда масштабирование для X и Y всегда равно?

Моя проблема заключается в том, что, например, когда я перетаскиваю масштабирование прямоугольника (gyazo gif), ось X шире, чем Y. В результате ось X увеличивается более подробно, чем Y, и визуальный вид графика отличается от исходного графика. .

https://gyazo.com/749db917465a8037b7c5f21792f572ce

Я ищу способ, при котором, если я масштабирую перетаскивание прямоугольника, функция аналогична масштабированию с помощью колесика мыши, где масштабирование по осям x и y кажется равным.


person Patrick John Pacana    schedule 10.06.2021    source источник
comment
Таким образом, соотношение сторон между осями X и Y всегда остается одинаковым, независимо от взаимодействия с пользователем? Звучит как очень хороший пример использования. Я вижу два способа приблизиться к этому: 1. Переопределить изменение интервала оси, подключившись к событию изменения масштаба. 2. Удалите действие масштабирования по умолчанию и создайте пользовательское, сохраняющее соотношение сторон. Я думаю, что второй вариант лучше, потому что в этом случае прямоугольник также может быть отрисован с фиксированным соотношением сторон, в отличие от первого варианта.   -  person Niilo Keinänen    schedule 10.06.2021
comment
Привет, Патрик, пожалуйста, ознакомьтесь с последним фрагментом кода от @Alexander. Мне кажется, что теперь, после нескольких правок, он отлично работает.   -  person Niilo Keinänen    schedule 22.06.2021
comment
Привет, Нило, извините за поздний ответ, вчера я попробовал решение, и да, оно сработало хорошо, немного глючило, но я также не особо углублялся в редактирование/исправление кода. Однако мне не очень понравился пользовательский интерфейс, поэтому на данный момент я откладываю решение до тех пор, пока не захочу вернуться к нему, действительно ли я этого хочу или нет. Однако большое спасибо за решение.   -  person Patrick John Pacana    schedule 22.06.2021


Ответы (1)


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

// Extract required parts from LightningChartJS.
const {
  ColorRGBA,
  ColorHEX,
  emptyFill, 
  SolidFill,
  SolidLine,
  translatePoint,
  _point,
  lightningChart
} = lcjs;

// Import data-generator from 'xydata'-library.
const {
  createProgressiveTraceGenerator
} = xydata


const chart = lightningChart()
    .ChartXY()
    // Disable default chart interactions with left mouse button.
    // .setMouseInteractionRectangleFit(false)
    .setMouseInteractionRectangleZoom(false)
    .setTitleFillStyle(emptyFill)

// generate data and creating the series
const series = chart.addLineSeries().setStrokeStyle(
    new SolidLine({
        fillStyle: new SolidFill({ color: ColorHEX('#fff') }),
        thickness: 2,
    }),
)

 // generate data and create series
  createProgressiveTraceGenerator()
      .setNumberOfPoints(200)
      .generate()
      .toPromise()
      .then((data) => {
          return series.add(data)
      })
  
  // create zooming rect and dispose it
  const rect = chart
      .addRectangleSeries()
      .add({
          x: 0,
          y: 0,
          width: 0,
          height: 0,
      })
      .setFillStyle(new SolidFill({ color: ColorRGBA(255, 255, 255, 30) }))
      .setStrokeStyle(
          new SolidLine({
              thickness: 2,
              fillStyle: new SolidFill({ color: ColorRGBA(255, 255, 255, 255) }),
          }),
      )
      .dispose()
  
  // om Mouse drag restor rectange and set position and coordinates
      chart.onSeriesBackgroundMouseDrag((obj, event, button, startLocation, delta) => {
      if (button !== 0) return
  
      const startLocationOnScale = translatePoint(
          chart.engine.clientLocation2Engine(startLocation.x, startLocation.y),
          chart.engine.scale,
          series.scale,
      )
      const curLocationOnScale = translatePoint(chart.engine.clientLocation2Engine(event.x, event.y), chart.engine.scale, series.scale)
  
          const x = Math.abs(series.getBoundaries().min.x) + Math.abs(series.getBoundaries().max.x)
      const y = Math.abs(series.getBoundaries().min.y) + Math.abs(series.getBoundaries().max.y)
      const ratio = x / y
      const width = Math.abs(curLocationOnScale.x - startLocationOnScale.x)
      const height = Math.abs(curLocationOnScale.y - startLocationOnScale.y)
      const heightDirection = curLocationOnScale.y - startLocationOnScale.y // check direction of rect
  
      // check for mouse direction to prevet fit and zoom conflict
      if (curLocationOnScale.x > startLocationOnScale.x) {
          rect.setDimensions({
              x: startLocationOnScale.x,
              y: startLocationOnScale.y,
              width: width > height * ratio ? width : height * ratio,
              height: width > height * ratio ? (heightDirection > 0 ? width : -width) / ratio : heightDirection,
          }).restore()
      } else {
          // prevent phantom rectangle if you change zoom to fit during the dragging
          rect.setDimensions({
              x: 0,
              y: 0,
              width: 0,
              height: 0,
          }).dispose()
      }
  })
  
  
  // on mouse drag stop dispose rect and zoom relative to its dimensions
  chart.onSeriesBackgroundMouseDragStop((_, event, button, startLocation) => {
      if (button !== 0) return

      const rectZooom = rect.getDimensionsPositionAndSize()
      if (rectZooom.width !== 0) {
          chart.getDefaultAxisX().setInterval(rectZooom.x, (rectZooom.x + rectZooom.width), true, true)
          if(rectZooom.height > 0){
            chart.getDefaultAxisY().setInterval(rectZooom.y, (rectZooom.y + Math.abs(rectZooom.height)), true, true)
          }else{
              chart.getDefaultAxisY().setInterval((rectZooom.y - Math.abs(rectZooom.height)),rectZooom.y, true, true)
          }
      }
      rect.setDimensions({
          x: 0,
          y: 0,
          width: 0,
          height: 0,
      }).dispose()
  })
<script src="https://unpkg.com/@arction/[email protected]/dist/xydata.iife.js"></script>
<script src="https://unpkg.com/@arction/[email protected]/dist/lcjs.iife.js"></script>

person Alexander    schedule 11.06.2021