Skip to content

Commit

Permalink
opt: opt indicator line render
Browse files Browse the repository at this point in the history
  • Loading branch information
liihuu committed Mar 16, 2024
1 parent 944ab47 commit a09fc26
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/common/Styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ function getDefaultCandleStyle (): CandleStyle {
function getDefaultIndicatorStyle (): IndicatorStyle {
const lines = ['#FF9600', '#935EBD', blue, '#E11D74', '#01C5C4'].map(color => ({
style: LineType.Solid,
smooth: true,
smooth: false,
size: 1,
dashedValue: [2, 2],
color
Expand Down
8 changes: 6 additions & 2 deletions src/component/Indicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ export type IndicatorCreate<D = any> = ExcludePickPartial<Omit<Indicator<D>, 're

export type IndicatorConstructor<D = any> = new () => IndicatorImp<D>

export type EachFigureCallback = (figure: IndicatorFigure, figureStyles: IndicatorFigureStyle) => void
export type EachFigureCallback = (figure: IndicatorFigure, figureStyles: IndicatorFigureStyle, index: number) => void

export function eachFigures<D> (
kLineDataList: KLineData[],
Expand All @@ -243,21 +243,25 @@ export function eachFigures<D> (
let lineCount = 0

let defaultFigureStyles
let figureIndex = 0
figures.forEach(figure => {
switch (figure.type) {
case 'circle': {
figureIndex = circleCount
const styles = circleStyles[circleCount % circleStyleCount]
defaultFigureStyles = { ...styles, color: styles.noChangeColor }
circleCount++
break
}
case 'bar': {
figureIndex = barCount
const styles = barStyles[barCount % barStyleCount]
defaultFigureStyles = { ...styles, color: styles.noChangeColor }
barCount++
break
}
case 'line': {
figureIndex = lineCount
defaultFigureStyles = lineStyles[lineCount % lineStyleCount]
lineCount++
break
Expand All @@ -272,7 +276,7 @@ export function eachFigures<D> (
}
const ss = figure.styles?.(cbData, indicator, defaultStyles)
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
eachFigureCallback(figure, { ...defaultFigureStyles, ...ss })
eachFigureCallback(figure, { ...defaultFigureStyles, ...ss }, figureIndex)
}
})
}
Expand Down
69 changes: 58 additions & 11 deletions src/view/IndicatorView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@
import type Nullable from '../common/Nullable'
import type VisibleData from '../common/VisibleData'
import type BarSpace from '../common/BarSpace'
import { CandleType } from '../common/Styles'
import { CandleType, type SmoothLineStyle } from '../common/Styles'
import { formatValue } from '../common/utils/format'
import { isNumber, isValid } from '../common/utils/typeChecks'
import type Coordinate from '../common/Coordinate'

import type ChartStore from '../store/ChartStore'

import { eachFigures, type IndicatorFigure, type IndicatorFigureAttrs, type IndicatorFigureStyle } from '../component/Indicator'

import CandleBarView, { type CandleBarOptions } from './CandleBarView'

import { formatValue } from '../common/utils/format'
import { isNumber, isValid } from '../common/utils/typeChecks'

export default class IndicatorView extends CandleBarView {
override getCandleBarOptions (chartStore: ChartStore): Nullable<CandleBarOptions> {
const pane = this.getWidget().getPane()
Expand Down Expand Up @@ -99,6 +99,7 @@ export default class IndicatorView extends CandleBarView {
}
if (!isCover) {
const result = indicator.result
const lines: Array<Array<{ coordinates: Coordinate[], styles: SmoothLineStyle }>> = []

this.eachChildren((data: VisibleData, barSpace: BarSpace) => {
const { halfGapBar, gapBar } = barSpace
Expand All @@ -125,7 +126,7 @@ export default class IndicatorView extends CandleBarView {
nextCoordinate[key] = yAxis.convertToPixel(nextValue)
}
})
eachFigures(dataList, indicator, dataIndex, defaultStyles, (figure: IndicatorFigure, figureStyles: IndicatorFigureStyle) => {
eachFigures(dataList, indicator, dataIndex, defaultStyles, (figure: IndicatorFigure, figureStyles: IndicatorFigureStyle, figureIndex: number) => {
if (isValid(currentIndicatorData[figure.key])) {
const valueY = currentCoordinate[figure.key]
let attrs = figure.attrs?.({
Expand Down Expand Up @@ -164,30 +165,76 @@ export default class IndicatorView extends CandleBarView {
break
}
case 'line': {
if (!isValid(lines[figureIndex])) {
lines[figureIndex] = []
}
if (isNumber(currentCoordinate[figure.key]) && isNumber(nextCoordinate[figure.key])) {
attrs = {
lines[figureIndex].push({
coordinates: [
{ x: currentCoordinate.x, y: currentCoordinate[figure.key] },
{ x: nextCoordinate.x, y: nextCoordinate[figure.key] }
]
}
],
styles: figureStyles as unknown as SmoothLineStyle
})
}
break
}
default: { break }
}
}
if (isValid<IndicatorFigureAttrs>(attrs)) {
const name = figure.type!
const type = figure.type!
if (isValid<IndicatorFigureAttrs>(attrs) && type !== 'line') {
this.createFigure({
name: name === 'bar' ? 'rect' : name,
name: type === 'bar' ? 'rect' : type,
attrs,
styles: figureStyles
})?.draw(ctx)
}
// merge line render
}
})
})

// merge line and render
lines.forEach(items => {
if (items.length > 1) {
const mergeLines = [
{
coordinates: [items[0].coordinates[0], items[0].coordinates[1]],
styles: items[0].styles
}
]
for (let i = 1; i < items.length; i++) {
const lastMergeLine = mergeLines[mergeLines.length - 1]
const current = items[i]
const lastMergeLineLastCoordinate = lastMergeLine.coordinates[lastMergeLine.coordinates.length - 1]
if (
lastMergeLineLastCoordinate.x === current.coordinates[0].x &&
lastMergeLineLastCoordinate.y === current.coordinates[0].y &&
lastMergeLine.styles.style === current.styles.style &&
lastMergeLine.styles.color === current.styles.color &&
lastMergeLine.styles.size === current.styles.size &&
lastMergeLine.styles.smooth === current.styles.smooth &&
lastMergeLine.styles.dashedValue[0] === current.styles.dashedValue[0] &&
lastMergeLine.styles.dashedValue[1] === current.styles.dashedValue[1]
) {
lastMergeLine.coordinates.push(current.coordinates[1])
} else {
mergeLines.push({
coordinates: [current.coordinates[0], current.coordinates[1]],
styles: current.styles
})
}
}
mergeLines.forEach(({ coordinates, styles }) => {
this.createFigure({
name: 'line',
attrs: { coordinates },
styles
})?.draw(ctx)
})
}
})
}
}
})
Expand Down

0 comments on commit a09fc26

Please sign in to comment.