首页 > 解决方案 > 在 LightningChartJS 中,有没有办法在 X 和 Y 的缩放始终相等的情况下进行拖动缩放?

问题描述

我的问题是,例如,当我拖动矩形缩放(gyazo gif)时,X 轴比 Y 宽。实际上,X 轴比 Y 轴放大了更多细节,并且图形的视觉效果与原始图形不同.

https://gyazo.com/749db917465a8037b7c5f21792f572ce

我正在寻找一种方法,如果我缩放矩形拖动,该功能类似于通过鼠标滚轮进行缩放,其中 x 和 y 缩放感觉相等。

标签: lightningchart

解决方案


在这里,您将找到一个示例,如何执行自定义缩放矩形而不是默认值并保持轴的比例。

// 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/xydata@1.4.0/dist/xydata.iife.js"></script>
<script src="https://unpkg.com/@arction/lcjs@3.0.0/dist/lcjs.iife.js"></script>


推荐阅读