Skip to content
This repository has been archived by the owner on Apr 19, 2024. It is now read-only.

update wheel handler #425

Merged
merged 2 commits into from
Jul 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@netdata/dashboard",
"version": "2.26.7",
"version": "2.26.8",
"homepage": ".",
"main": "./lib/src/index-npm.js",
"files": [
Expand Down
116 changes: 38 additions & 78 deletions src/domains/chart/components/lib-charts/dygraph-chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -708,87 +708,22 @@ export const DygraphChart = ({
},

wheel(event: WheelEvent, dygraph: Dygraph) {
// Take the offset of a mouse event on the dygraph canvas and
// convert it to a pair of percentages from the bottom left.
// (Not top left, bottom is where the lower value is.)
function offsetToPercentage(g: Dygraph, offsetX: number, offsetY: number) {
// This is calculating the pixel offset of the leftmost date.
const xOffset = g.toDomXCoord(g.xAxisRange()[0])
const yar0 = g.yAxisRange(0)

// This is calculating the pixel of the highest value. (Top pixel)
const yOffset = g.toDomYCoord(yar0[1])

// x y w and h are relative to the corner of the drawing area,
// so that the upper corner of the drawing area is (0, 0).
const x = offsetX - xOffset
const y = offsetY - yOffset

// This is computing the rightmost pixel, effectively defining the
// width.
// const w = g.toDomCoords(g.xAxisRange()[1], null)[0] - xOffset
const w = g.toDomXCoord(g.xAxisRange()[1]) - xOffset

// This is computing the lowest pixel, effectively defining the height.
// const h = g.toDomCoords(null, yar0[0])[1] - yOffset
const h = g.toDomYCoord(yar0[0]) - yOffset

// Percentage from the left.
const xPct = w === 0 ? 0 : (x / w)
// Percentage from the top.
const yPct = h === 0 ? 0 : (y / h)
if (!event.shiftKey && !event.altKey) return

// The (1-) part below changes it from "% distance down from the top"
// to "% distance up from the bottom".
return [xPct, (1 - yPct)]
}
latestIsUserAction.current = true
event.preventDefault()
event.stopPropagation()

function adjustAxis(axis: [number, number], zoomInPercentage: number, bias: number) {
const delta = axis[1] - axis[0]
// https://dygraphs.com/gallery/interaction-api.js
const zoom = (g, zoomInPercentage, bias) => {
bias = bias || 0.5
const [afterAxis, beforeAxis] = g.xAxisRange()
const delta = afterAxis - beforeAxis
const increment = delta * zoomInPercentage
const foo = [increment * bias, increment * (1 - bias)]

return [axis[0] + foo[0], axis[1] - foo[1]]
}

// Adjusts [x, y] toward each other by zoomInPercentage%
// Split it so the left/bottom axis gets xBias/yBias of that change and
// tight/top gets (1-xBias)/(1-yBias) of that change.
//
// If a bias is missing it splits it down the middle.
function zoomRange(g: Dygraph, zoomInPercentage: number, xBias: number, yBias: number) {
const yAxes = g.yAxisRanges()
const newYAxes = []
for (let i = 0; i < yAxes.length; i += 1) {
newYAxes[i] = adjustAxis(yAxes[i], zoomInPercentage, (yBias || 0.5))
}

return adjustAxis(g.xAxisRange(), zoomInPercentage, (xBias || 0.5))
}

if (event.altKey || event.shiftKey) {
latestIsUserAction.current = true

// http://dygraphs.com/gallery/interaction-api.js
let normalDef
// @ts-ignore
if (typeof event.wheelDelta === "number" && !Number.isNaN(event.wheelDelta)) {
// chrome
// @ts-ignore
normalDef = event.wheelDelta / 40
} else {
// firefox
normalDef = event.deltaY * -1.2
}

const normal = (event.detail) ? event.detail * -1 : normalDef
const percentage = normal / 50

const percentages = offsetToPercentage(dygraph, event.offsetX, event.offsetY)
const xPct = percentages[0]
const yPct = percentages[1]
const [afterIncrement, beforeIncrement] = [increment * bias, increment * (1 - bias)]

const [after, before] = zoomRange(dygraph, percentage, xPct, yPct)
const after = afterAxis + afterIncrement
const before = beforeAxis - beforeIncrement

propsRef.current.updateChartPanOrZoom({
after,
Expand All @@ -800,9 +735,34 @@ export const DygraphChart = ({
})
},
})
}

event.preventDefault()
const offsetToPercentage = (g, offsetX) => {
// This is calculating the pixel offset of the leftmost date.
const [axisAfterOffset] = g.toDomCoords(g.xAxisRange()[0], null)
// x and w are relative to the corner of the drawing area,
// so that the upper corner of the drawing area is (0, 0).
const x = offsetX - axisAfterOffset
// This is computing the rightmost pixel, effectively defining the
// width.
const w = g.toDomCoords(g.xAxisRange()[1], null)[0] - axisAfterOffset

// Percentage from the left.
return w == 0 ? 0 : x / w
}

const normalDef =
typeof event.wheelDelta === "number" && !Number.isNaN(event.wheelDelta)
? event.wheelDelta / 40
: event.deltaY * -1.2

const normal = event.detail ? event.detail * -1 : normalDef
const percentage = normal / 50

if (!event.offsetX) event.offsetX = event.layerX - event.target.offsetLeft
const xPct = offsetToPercentage(dygraph, event.offsetX)

zoom(dygraph, percentage, xPct)
},

click(event: MouseEvent) {
Expand Down