Skip to content

Commit

Permalink
feat: candlestick tooltip
Browse files Browse the repository at this point in the history
  • Loading branch information
Sciator committed Feb 16, 2021
1 parent 5fdb617 commit 4ce5803
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 11 deletions.
82 changes: 82 additions & 0 deletions giraffe/src/components/CandlestickHoverLayer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, {FunctionComponent} from 'react'

import {Tooltip} from './Tooltip'
import {CandlestickLayerProps} from './CandlestickLayer'
import {TooltipData} from '../types'

const createCheckMouseBounding = ({
height,
width,
}: {
width: number
height: number
}) => ({mouseX, mouseY}: {mouseX: number; mouseY: number}) => {
return (
mouseX !== undefined &&
mouseX !== null &&
mouseX >= 0 &&
mouseX < width &&
mouseY !== undefined &&
mouseY !== null &&
mouseY >= 0 &&
mouseY < height
)
}

export const CandlestickHoverLayer: FunctionComponent<CandlestickLayerProps> = props => {
const {
plotConfig,
spec: {values, calculatedWindow, table},
config: {
xColumnKey,
openColumnKey,
highColumnKey,
lowColumnKey,
closeColumnKey,
},
xScale,
hoverX,
hoverY,
columnFormatter,
} = props

const checkMouseBounding = createCheckMouseBounding(props)

if (!checkMouseBounding({mouseX: hoverX, mouseY: hoverY})) {
return null
}

const xIndex =
Math.round(xScale.invert(hoverX) / calculatedWindow) * calculatedWindow

const value = values.find(x => x.windowStart === xIndex)

if (!value) {
return null
}

const tableIndexes = value.entriesTableIndexes

const tooltipData: TooltipData = [
xColumnKey,
openColumnKey,
highColumnKey,
lowColumnKey,
closeColumnKey,
].map(key => {
const col = table.getColumn(key)
const type = table.getColumnType(key)
const formater = columnFormatter(key)
return {
colors: [],
key,
name: key,
type,
values: tableIndexes.map(i => formater(col[i])),
}
})

return <Tooltip data={tooltipData} config={plotConfig} />
}

CandlestickHoverLayer.displayName = 'ScatterHoverLayer'
39 changes: 37 additions & 2 deletions giraffe/src/components/CandlestickLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
} from '../types'
import {CANDLESTICK_THEME_DARK} from '../constants/candlestickStyles'
import {OHLCResultEntry} from '../utils/ohlc'
import {useHoverPointIndices} from '../utils/useHoverPointIndices'
import {CandlestickHoverLayer} from './CandlestickHoverLayer'

interface CandleValue {
open: number
Expand All @@ -16,7 +18,7 @@ interface CandleValue {
low: number
}

interface CandleProps {
export interface CandleProps {
theme: CandlestickLayerConfig
candle: CandleValue
/** width of candle */
Expand Down Expand Up @@ -138,9 +140,20 @@ export interface Props extends LayerProps {
spec: CandlestickLayerSpec
}

export type CandlestickLayerProps = Props

//todo: only proxies props into Candlestick ? if true -> candlestick should be implemented here
export const CandlestickLayer: FunctionComponent<Props> = props => {
const {config: _theme, width, height, spec, xScale, yScale} = props
const {
config: _theme,
width,
height,
spec,
xScale,
yScale,
hoverX,
hoverY,
} = props
// todo default values already present in _theme ?
const theme: CandlestickLayerConfig = {
...CANDLESTICK_THEME_DARK,
Expand Down Expand Up @@ -175,6 +188,27 @@ export const CandlestickLayer: FunctionComponent<Props> = props => {
)
}

//#region hover

const hoverDimension: 'x' | 'y' | 'xy' = 'y'

const hoverRowIndices = useHoverPointIndices(
hoverDimension,
hoverX,
hoverY,
spec.inputTable.getColumn('_time', 'number'),
spec.inputTable.getColumn('open', 'number'),
[],
xScale,
yScale,
width,
height
)

const hasHoverData = hoverRowIndices && hoverRowIndices.length > 0

//#endregion hover

return (
<>
<svg
Expand All @@ -196,6 +230,7 @@ export const CandlestickLayer: FunctionComponent<Props> = props => {
</>
))}
</svg>
{hasHoverData && <CandlestickHoverLayer {...props} />}
</>
)
}
11 changes: 8 additions & 3 deletions giraffe/src/transforms/candlestick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,20 @@ export const candlestickTransform = (
// xMax is window start but we want to show whole window
xMax += window

const res = {
const yColumnKey = openColumnKey

const res: CandlestickLayerSpec = {
type: 'candlestick',
inputTable,
table: inputTable,
values,
calculatedWindow: window,
xDomain: [xMin, xMax],
yDomain: [yMin, yMax],
xColumnKey,
xColumnType: inputTable.getColumnType(xColumnKey),
} as CandlestickLayerSpec
return res as any
yColumnKey,
yColumnType: inputTable.getColumnType(yColumnKey),
}
return res
}
7 changes: 1 addition & 6 deletions giraffe/src/utils/ohlc.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import {pairs} from 'd3-array'
import {
CandlestickLayerConfig,
NumericColumnData,
OHLCValue,
Table,
} from '../types'
import {NumericColumnData, OHLCValue, Table} from '../types'
import {Sorting} from './array'

const {ascending} = Sorting
Expand Down

0 comments on commit 4ce5803

Please sign in to comment.