在鼠标悬停时获取轴值

Get axis value on mouse hover

我们如何获得 X 轴值?

如果你看到上图,如果鼠标移动到图表上或点击图表的任何地方,我们如何获得 X 轴值,是否有任何回调函数?

您可以将事件处理程序附加到 chart.onChartBackgroundMouseMove 事件。

然后您需要将事件位置转换为引擎坐标 space。这可以通过 publicEngine.engineLocation2Client() 方法完成,chart.engine.clientLocation2Engine(ev.clientX, ev.clientY)

最后一个是将引擎位置转换为刻度上的一个点。这可以通过 translatePoint() 函数来完成。 const onScale = translatePoint(engineLocation, chart.engine.scale, {x: chart.getDefaultAxisX().scale, y: chart.getDefaultAxisY().scale})

chartOHLC.onChartBackgroundMouseMove((obj, ev)=>{
    const point = obj.engine.clientLocation2Engine(ev.clientX, ev.clientY)
    const onScale = translatePoint(point, obj.engine.scale, {x:obj.getDefaultAxisX().scale, y:obj.getDefaultAxisY().scale})
    console.log(onScale)
})

请参阅下面的代码片段,我在其中记录了鼠标在控制台上的位置。

// Extract required parts from LightningChartJS.
const {
  lightningChart,
  AxisTickStrategies,
  LegendBoxBuilders,
  SolidFill,
  SolidLine,
  emptyLine,
  ColorRGBA,
  UIOrigins,
  Themes,
  translatePoint
} = lcjs

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

// Create dashboard to house two charts
const db = lightningChart().Dashboard({
  // theme: Themes.dark 
  numberOfRows: 2,
  numberOfColumns: 1
})

// Decide on an origin for DateTime axis.
const dateOrigin = new Date(2018, 0, 1)
// Chart that contains the OHLC candle stick series and Bollinger band
const chartOHLC = db.createChartXY({
  columnIndex: 0,
  rowIndex: 0,
  columnSpan: 1,
  rowSpan: 1
})
// Use DateTime TickStrategy with custom date origin for X Axis.
chartOHLC
  .getDefaultAxisX()
  .setTickStrategy(
    AxisTickStrategies.DateTime,
    (tickStrategy) => tickStrategy.setDateOrigin(dateOrigin)
  )
// Modify Chart.
chartOHLC
  .setTitle('Trading dashboard')
  //Style AutoCursor.
  .setAutoCursor(cursor => {
    cursor.disposeTickMarkerY()
    cursor.setGridStrokeYStyle(emptyLine)
  })
  .setPadding({
    right: 40
  })

chartOHLC.onChartBackgroundMouseMove((obj, ev) => {
  const point = obj.engine.clientLocation2Engine(ev.clientX, ev.clientY)
  const onScale = translatePoint(point, obj.engine.scale, {
    x: obj.getDefaultAxisX().scale,
    y: obj.getDefaultAxisY().scale
  })
  console.log(onScale)
})

// The top chart should have 66% of view height allocated to it. By giving the first row a height of 2, the relative
// height of the row becomes 2/3 of the whole view (default value for row height / column width is 1)
db.setRowHeight(0, 2)

// Create a LegendBox for Candle-Stick and Bollinger Band
const legendBoxOHLC = chartOHLC.addLegendBox(LegendBoxBuilders.HorizontalLegendBox)
  .setPosition({
    x: 100,
    y: 100
  })
  .setOrigin(UIOrigins.RightTop)

// Define function which sets Y axis intervals nicely.
let setViewNicely

// Create OHLC Figures and Area-range.
//#region

// Get Y-axis for series (view is set manually).
const stockAxisY = chartOHLC.getDefaultAxisY()
  .setScrollStrategy(undefined)
  .setTitle('USD')
// Add series.
const areaRangeFill = new SolidFill().setColor(ColorRGBA(100, 149, 237, 50))
const areaRangeStroke = new SolidLine()
  .setFillStyle(new SolidFill().setColor(ColorRGBA(100, 149, 237)))
  .setThickness(1)
const areaRange = chartOHLC.addAreaRangeSeries({
    yAxis: stockAxisY
  })
  .setName('Bollinger band')
  .setHighFillStyle(areaRangeFill)
  .setLowFillStyle(areaRangeFill)
  .setHighStrokeStyle(areaRangeStroke)
  .setLowStrokeStyle(areaRangeStroke)
  .setMouseInteractions(false)
  .setCursorEnabled(false)

const stockFigureWidth = 5.0
const borderBlack = new SolidLine().setFillStyle(new SolidFill().setColor(ColorRGBA(0, 0, 0))).setThickness(1.0)
const fillBrightRed = new SolidFill().setColor(ColorRGBA(255, 0, 0))
const fillDimRed = new SolidFill().setColor(ColorRGBA(128, 0, 0))
const fillBrightGreen = new SolidFill().setColor(ColorRGBA(0, 255, 0))
const fillDimGreen = new SolidFill().setColor(ColorRGBA(0, 128, 0))
const stock = chartOHLC.addOHLCSeries({
    yAxis: stockAxisY
  })
  .setName('Candle-Sticks')
  // Setting width of figures
  .setFigureWidth(stockFigureWidth)
  // Styling positive candlestick
  .setPositiveStyle(candlestick => candlestick
    // Candlestick body fill style
    .setBodyFillStyle(fillBrightGreen)
    // Candlestick body fill style
    .setBodyStrokeStyle(borderBlack)
    // Candlestick stroke style
    .setStrokeStyle((strokeStyle) => strokeStyle.setFillStyle(fillDimGreen))
  )
  .setNegativeStyle(candlestick => candlestick
    .setBodyFillStyle(fillBrightRed)
    .setBodyStrokeStyle(borderBlack)
    .setStrokeStyle((strokeStyle) => strokeStyle.setFillStyle(fillDimRed))
  )

// Make function that handles adding OHLC segments to series.
const add = (ohlc) => {
  // ohlc is equal to [x, open, high, low, close]
  stock.add(ohlc)
  // AreaRange looks better if it extends a bit further than the actual OHLC values.
  const areaOffset = 0.2
  areaRange.add({
    position: ohlc[0],
    high: ohlc[2] - areaOffset,
    low: ohlc[3] + areaOffset,

  })
}

// Generate some static data.
createOHLCGenerator()
  .setNumberOfPoints(100)
  .setDataFrequency(24 * 60 * 60 * 1000)
  .generate()
  .toPromise()
  .then(data => {
    data.forEach(add)
    setViewNicely()
  })

//#endregion

// Create volume.
//#region
const chartVolume = db.createChartXY({
  columnIndex: 0,
  rowIndex: 1,
  columnSpan: 1,
  rowSpan: 1
})
// Use DateTime TickStrategy with custom date origin for X Axis.
chartVolume
  .getDefaultAxisX()
  .setTickStrategy(
    AxisTickStrategies.DateTime,
    (tickStrategy) => tickStrategy.setDateOrigin(dateOrigin)
  )
// Modify Chart.
chartVolume
  .setTitle('Volume')
  .setPadding({
    right: 40
  })
// Create a LegendBox as part of the chart.
const legendBoxVolume = chartVolume.addLegendBox(LegendBoxBuilders.HorizontalLegendBox)
  .setPosition({
    x: 100,
    y: 100
  })
  .setOrigin(UIOrigins.RightTop)

// Create Y-axis for series (view is set manually).
const volumeAxisY = chartVolume.getDefaultAxisY()
  .setTitle('USD')
  // Modify TickStyle to hide gridstrokes.
  .setTickStrategy(
    // Base TickStrategy that should be styled.
    AxisTickStrategies.Numeric,
    // Modify the the tickStyles through a mutator.
    (tickStrat) => tickStrat
    // Modify the Major tickStyle to not render the grid strokes.
    .setMajorTickStyle(
      tickStyle => tickStyle.setGridStrokeStyle(emptyLine)
    )
    // Modify the Minor tickStyle to not render the grid strokes.
    .setMinorTickStyle(
      tickStyle => tickStyle.setGridStrokeStyle(emptyLine)
    )
  )
const volumeFillStyle = new SolidFill().setColor(ColorRGBA(0, 128, 128, 60))
const volumeStrokeStyle = new SolidLine()
  .setFillStyle(volumeFillStyle.setA(255))
  .setThickness(1)
const volume = chartVolume.addAreaSeries({
    yAxis: volumeAxisY
  })
  .setName('Volume')
  .setFillStyle(volumeFillStyle)
  .setStrokeStyle(volumeStrokeStyle)

createProgressiveTraceGenerator()
  .setNumberOfPoints(990)
  .generate()
  .toPromise()
  .then(data => {
    volume.add(data.map(point => ({
      x: point.x * 2.4 * 60 * 60 * 1000,
      y: Math.abs(point.y) * 10
    })))
    setViewNicely()
  })

//#endregion


// Add series to LegendBox and style entries.
const entries1 = legendBoxOHLC.add(chartOHLC)
entries1[0]
  .setButtonOnFillStyle(areaRangeStroke.getFillStyle())
  .setButtonOnStrokeStyle(emptyLine)

const entries2 = legendBoxVolume.add(chartVolume)
entries2[0]
  .setButtonOnFillStyle(volumeStrokeStyle.getFillStyle())
  .setButtonOnStrokeStyle(emptyLine)

setViewNicely = () => {
  const yBoundsStock = {
    min: areaRange.getYMin(),
    max: areaRange.getYMax(),
    range: areaRange.getYMax() - areaRange.getYMin()
  }
  const yBoundsVolume = {
    min: volume.getYMin(),
    max: volume.getYMax(),
    range: volume.getYMax() - volume.getYMin()
  }
  // Set Y axis intervals so that series don't overlap and volume is under stocks.
  volumeAxisY.setInterval(yBoundsVolume.min, yBoundsVolume.max)
  stockAxisY.setInterval(yBoundsStock.min - yBoundsStock.range * .33, yBoundsStock.max)
}

stock.setResultTableFormatter((builder, series, segment) => {
  return builder
    .addRow(series.getName())
    .addRow(series.axisX.formatValue(segment.getPosition()))
    .addRow('Open ' + segment.getOpen().toFixed(2))
    .addRow('High ' + segment.getHigh().toFixed(2))
    .addRow('Low ' + segment.getLow().toFixed(2))
    .addRow('Close ' + segment.getClose().toFixed(2))
})

volume.setResultTableFormatter((builder, series, position, high, low) => {
  return builder
    .addRow(series.getName())
    .addRow(series.axisX.formatValue(position))
    .addRow('Value ' + Math.round(high))
    .addRow('Base ' + Math.round(low))
})
<script src="https://unpkg.com/@arction/xydata@1.4.0/dist/xydata.iife.js"></script>
<script src="https://unpkg.com/@arction/lcjs@2.2.1/dist/lcjs.iife.js"></script>