Skip to content

Commit

Permalink
Merge pull request #17717 from apache/fix-11042
Browse files Browse the repository at this point in the history
feat(candlestick): provide borderColorDoji option for custom doji color
  • Loading branch information
Ovilia committed Oct 17, 2022
2 parents 788e091 + 728cf4e commit 004c3fa
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 43 deletions.
2 changes: 2 additions & 0 deletions src/chart/candlestick/CandlestickSeries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type CandlestickDataValue = OptionDataValue[];
interface CandlestickItemStyleOption extends ItemStyleOption {
color0?: ZRColor
borderColor0?: ColorString
borderColorDoji?: ZRColor
}
export interface CandlestickStateOption {
itemStyle?: CandlestickItemStyleOption
Expand Down Expand Up @@ -116,6 +117,7 @@ class CandlestickSeriesModel extends SeriesModel<CandlestickSeriesOption> {
color0: '#47b262', // negative
borderColor: '#eb5454',
borderColor0: '#47b262',
borderColorDoji: null, // when close === open
// borderColor: '#d24040',
// borderColor0: '#398f4f',
borderWidth: 1
Expand Down
13 changes: 12 additions & 1 deletion src/chart/candlestick/CandlestickView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,16 @@ function createLarge(
ignoreCoarsePointer: true
});
group.add(elN);
const elDoji = new LargeBoxPath({
shape: {points: largePoints},
__sign: 0,
ignoreCoarsePointer: true
});
group.add(elDoji);

setLargeStyle(1, elP, seriesModel, data);
setLargeStyle(-1, elN, seriesModel, data);
setLargeStyle(0, elDoji, seriesModel, data);

if (incremental) {
elP.incremental = true;
Expand All @@ -384,8 +391,12 @@ function createLarge(

function setLargeStyle(sign: number, el: LargeBoxPath, seriesModel: CandlestickSeriesModel, data: SeriesData) {
// TODO put in visual?
const borderColor = seriesModel.get(['itemStyle', sign > 0 ? 'borderColor' : 'borderColor0'])
let borderColor = seriesModel.get(['itemStyle', sign > 0 ? 'borderColor' : 'borderColor0'])
// Use color for border color by default.
|| seriesModel.get(['itemStyle', sign > 0 ? 'color' : 'color0']);
if (sign === 0) {
borderColor = seriesModel.get(['itemStyle', 'borderColorDoji']);
}

// Color must be excluded.
// Because symbol provide setColor individually to set fill and stroke
Expand Down
37 changes: 26 additions & 11 deletions src/chart/candlestick/candlestickLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import createRenderPlanner from '../helper/createRenderPlanner';
import {parsePercent} from '../../util/number';
import {map, retrieve2} from 'zrender/src/core/util';
import { DimensionIndex, StageHandler, StageHandlerProgressParams } from '../../util/types';
import CandlestickSeriesModel from './CandlestickSeries';
import CandlestickSeriesModel, { CandlestickDataItemOption } from './CandlestickSeries';
import SeriesData from '../../data/SeriesData';
import { RectLike } from 'zrender/src/core/BoundingRect';
import DataStore from '../../data/DataStore';
Expand Down Expand Up @@ -106,8 +106,10 @@ const candlestickLayout: StageHandler = {
subPixelOptimizePoint(ocLowPoint)
);

const itemModel = data.getItemModel<CandlestickDataItemOption>(dataIndex);
const hasDojiColor = !!itemModel.get(['itemStyle', 'borderColorDoji']);
data.setItemLayout(dataIndex, {
sign: getSign(store, dataIndex, openVal, closeVal, closeDimI),
sign: getSign(store, dataIndex, openVal, closeVal, closeDimI, hasDojiColor),
initBaseline: openVal > closeVal
? ocHighPoint[vDimIdx] : ocLowPoint[vDimIdx], // open point.
ends: ends,
Expand Down Expand Up @@ -170,6 +172,7 @@ const candlestickLayout: StageHandler = {
const tmpOut: number[] = [];
let dataIndex;
const store = data.getStore();
const hasDojiColor = !!seriesModel.get(['itemStyle', 'borderColorDoji']);

while ((dataIndex = params.next()) != null) {
const axisDimVal = store.get(cDimI, dataIndex) as number;
Expand All @@ -184,7 +187,7 @@ const candlestickLayout: StageHandler = {
continue;
}

points[offset++] = getSign(store, dataIndex, openVal, closeVal, closeDimI);
points[offset++] = getSign(store, dataIndex, openVal, closeVal, closeDimI, hasDojiColor);

tmpIn[cDimIdx] = axisDimVal;

Expand All @@ -202,22 +205,34 @@ const candlestickLayout: StageHandler = {
}
};

/**
* Get the sign of a single data.
*
* @returns 0 for doji with hasDojiColor: true,
* 1 for positive,
* -1 for negative.
*/
function getSign(
store: DataStore, dataIndex: number, openVal: number, closeVal: number, closeDimI: DimensionIndex
): -1 | 1 {
let sign: -1 | 1;
store: DataStore, dataIndex: number, openVal: number, closeVal: number, closeDimI: DimensionIndex,
hasDojiColor: boolean
): -1 | 1 | 0 {
let sign: -1 | 1 | 0;
if (openVal > closeVal) {
sign = -1;
}
else if (openVal < closeVal) {
sign = 1;
}
else {
sign = dataIndex > 0
// If close === open, compare with close of last record
? (store.get(closeDimI, dataIndex - 1) <= closeVal ? 1 : -1)
// No record of previous, set to be positive
: 1;
sign = hasDojiColor
// When doji color is set, use it instead of color/color0.
? 0
: (dataIndex > 0
// If close === open, compare with close of last record
? (store.get(closeDimI, dataIndex - 1) <= closeVal ? 1 : -1)
// No record of previous, set to be positive
: 1
);
}

return sign;
Expand Down
6 changes: 5 additions & 1 deletion src/chart/candlestick/candlestickVisual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { extend } from 'zrender/src/core/util';

const positiveBorderColorQuery = ['itemStyle', 'borderColor'] as const;
const negativeBorderColorQuery = ['itemStyle', 'borderColor0'] as const;
const dojiBorderColorQuery = ['itemStyle', 'borderColorDoji'] as const;
const positiveColorQuery = ['itemStyle', 'color'] as const;
const negativeColorQuery = ['itemStyle', 'color0'] as const;

Expand All @@ -47,7 +48,10 @@ const candlestickVisual: StageHandler = {

function getBorderColor(sign: number, model: Model<Pick<CandlestickDataItemOption, 'itemStyle'>>) {
return model.get(
sign > 0 ? positiveBorderColorQuery : negativeBorderColorQuery
sign === 0 ? dojiBorderColorQuery
: sign > 0
? positiveBorderColorQuery
: negativeBorderColorQuery
);
}

Expand Down
Loading

0 comments on commit 004c3fa

Please sign in to comment.