@tranding-custom-chart/react 0.0.0-stage → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -2
- package/dist/AccessibleChartTable.d.ts +12 -0
- package/dist/AccessibleChartTable.d.ts.map +1 -0
- package/dist/AccessibleChartTable.js +19 -0
- package/dist/BaselineSeries.d.ts +13 -0
- package/dist/BaselineSeries.d.ts.map +1 -0
- package/dist/BaselineSeries.js +32 -0
- package/dist/BoxPlotSeries.d.ts +11 -0
- package/dist/BoxPlotSeries.d.ts.map +1 -0
- package/dist/BoxPlotSeries.js +37 -0
- package/dist/BubbleSeries.d.ts +11 -0
- package/dist/BubbleSeries.d.ts.map +1 -0
- package/dist/BubbleSeries.js +37 -0
- package/dist/CandlestickSeries.d.ts +13 -0
- package/dist/CandlestickSeries.d.ts.map +1 -0
- package/dist/CandlestickSeries.js +54 -0
- package/dist/ChartContainer.d.ts +73 -0
- package/dist/ChartContainer.d.ts.map +1 -0
- package/dist/ChartContainer.js +631 -0
- package/dist/ChartContext.d.ts +36 -0
- package/dist/ChartContext.d.ts.map +1 -0
- package/dist/ChartContext.js +13 -0
- package/dist/ChartSyncGroup.d.ts +14 -0
- package/dist/ChartSyncGroup.d.ts.map +1 -0
- package/dist/ChartSyncGroup.js +18 -0
- package/dist/ColumnsSeries.d.ts +13 -0
- package/dist/ColumnsSeries.d.ts.map +1 -0
- package/dist/ColumnsSeries.js +54 -0
- package/dist/CrosshairOverlay.d.ts +10 -0
- package/dist/CrosshairOverlay.d.ts.map +1 -0
- package/dist/CrosshairOverlay.js +65 -0
- package/dist/DrawingOverlay.d.ts +16 -0
- package/dist/DrawingOverlay.d.ts.map +1 -0
- package/dist/DrawingOverlay.js +50 -0
- package/dist/GridAxes.d.ts +19 -0
- package/dist/GridAxes.d.ts.map +1 -0
- package/dist/GridAxes.js +50 -0
- package/dist/HeatmapSeries.d.ts +11 -0
- package/dist/HeatmapSeries.d.ts.map +1 -0
- package/dist/HeatmapSeries.js +74 -0
- package/dist/HighLowSeries.d.ts +12 -0
- package/dist/HighLowSeries.d.ts.map +1 -0
- package/dist/HighLowSeries.js +29 -0
- package/dist/HlcAreaSeries.d.ts +13 -0
- package/dist/HlcAreaSeries.d.ts.map +1 -0
- package/dist/HlcAreaSeries.js +28 -0
- package/dist/HollowCandlestickSeries.d.ts +13 -0
- package/dist/HollowCandlestickSeries.d.ts.map +1 -0
- package/dist/HollowCandlestickSeries.js +30 -0
- package/dist/HorizontalBarSeries.d.ts +15 -0
- package/dist/HorizontalBarSeries.d.ts.map +1 -0
- package/dist/HorizontalBarSeries.js +42 -0
- package/dist/InteractiveLegend.d.ts +19 -0
- package/dist/InteractiveLegend.d.ts.map +1 -0
- package/dist/InteractiveLegend.js +39 -0
- package/dist/LastPriceLine.d.ts +11 -0
- package/dist/LastPriceLine.d.ts.map +1 -0
- package/dist/LastPriceLine.js +29 -0
- package/dist/LineSeries.d.ts +20 -0
- package/dist/LineSeries.d.ts.map +1 -0
- package/dist/LineSeries.js +74 -0
- package/dist/LineWithMarkersSeries.d.ts +13 -0
- package/dist/LineWithMarkersSeries.d.ts.map +1 -0
- package/dist/LineWithMarkersSeries.js +30 -0
- package/dist/MixedChartSeries.d.ts +14 -0
- package/dist/MixedChartSeries.d.ts.map +1 -0
- package/dist/MixedChartSeries.js +30 -0
- package/dist/OhlcBarSeries.d.ts +14 -0
- package/dist/OhlcBarSeries.d.ts.map +1 -0
- package/dist/OhlcBarSeries.js +31 -0
- package/dist/PieSeries.d.ts +18 -0
- package/dist/PieSeries.d.ts.map +1 -0
- package/dist/PieSeries.js +85 -0
- package/dist/PluginLayer.d.ts +11 -0
- package/dist/PluginLayer.d.ts.map +1 -0
- package/dist/PluginLayer.js +14 -0
- package/dist/PolarAreaSeries.d.ts +11 -0
- package/dist/PolarAreaSeries.d.ts.map +1 -0
- package/dist/PolarAreaSeries.js +35 -0
- package/dist/RadarSeries.d.ts +16 -0
- package/dist/RadarSeries.d.ts.map +1 -0
- package/dist/RadarSeries.js +47 -0
- package/dist/ScatterSeries.d.ts +11 -0
- package/dist/ScatterSeries.d.ts.map +1 -0
- package/dist/ScatterSeries.js +60 -0
- package/dist/SeriesMarkersOverlay.d.ts +10 -0
- package/dist/SeriesMarkersOverlay.d.ts.map +1 -0
- package/dist/SeriesMarkersOverlay.js +28 -0
- package/dist/StackedBarSeries.d.ts +13 -0
- package/dist/StackedBarSeries.d.ts.map +1 -0
- package/dist/StackedBarSeries.js +26 -0
- package/dist/StepLineSeries.d.ts +15 -0
- package/dist/StepLineSeries.d.ts.map +1 -0
- package/dist/StepLineSeries.js +28 -0
- package/dist/SupertrendSeries.d.ts +16 -0
- package/dist/SupertrendSeries.d.ts.map +1 -0
- package/dist/SupertrendSeries.js +40 -0
- package/dist/UniversalSeries.d.ts +21 -0
- package/dist/UniversalSeries.d.ts.map +1 -0
- package/dist/UniversalSeries.js +222 -0
- package/dist/VolumeProfileSeries.d.ts +21 -0
- package/dist/VolumeProfileSeries.d.ts.map +1 -0
- package/dist/VolumeProfileSeries.js +57 -0
- package/dist/VolumeSeries.d.ts +14 -0
- package/dist/VolumeSeries.d.ts.map +1 -0
- package/dist/VolumeSeries.js +33 -0
- package/dist/WatermarkOverlay.d.ts +11 -0
- package/dist/WatermarkOverlay.d.ts.map +1 -0
- package/dist/WatermarkOverlay.js +27 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/useChart.d.ts +16 -0
- package/dist/useChart.d.ts.map +1 -0
- package/dist/useChart.js +34 -0
- package/package.json +39 -4
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/ScatterSeries.tsx
|
|
3
|
+
* Declarative Scatter Plot series component.
|
|
4
|
+
*/
|
|
5
|
+
import React, { useEffect, useId } from 'react';
|
|
6
|
+
import { renderScatter } from '@tranding-custom-chart/renderer-canvas';
|
|
7
|
+
import { useChartContext } from './ChartContext.js';
|
|
8
|
+
export function ScatterSeries({ data, defaultRadius = 4, defaultColor = '#3b82f6', strokeColor = '#ffffff', strokeWidth = 1.5, shape = 'circle', }) {
|
|
9
|
+
const { registerDataLayer, registerHitTest, xScale, yScale } = useChartContext();
|
|
10
|
+
const id = useId();
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!data || data.length === 0 || !xScale || !yScale)
|
|
13
|
+
return;
|
|
14
|
+
const unregisterHit = registerHitTest(id, (x, y) => {
|
|
15
|
+
for (let i = 0; i < data.length; i++) {
|
|
16
|
+
const p = data[i];
|
|
17
|
+
const px = xScale.scale(p.x);
|
|
18
|
+
const py = yScale.scale(p.y);
|
|
19
|
+
const r = (p.radius ?? defaultRadius) + 4;
|
|
20
|
+
if (Math.hypot(px - x, py - y) <= r) {
|
|
21
|
+
return {
|
|
22
|
+
elementType: 'dataPoint',
|
|
23
|
+
seriesId: id,
|
|
24
|
+
dataIndex: i,
|
|
25
|
+
pointId: ('id' in p ? p.id : i) ?? i,
|
|
26
|
+
label: `(${p.x}, ${p.y})`,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
});
|
|
32
|
+
return unregisterHit;
|
|
33
|
+
}, [registerHitTest, id, data, xScale, yScale, defaultRadius]);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (!data || data.length === 0 || !xScale || !yScale)
|
|
36
|
+
return;
|
|
37
|
+
const unregister = registerDataLayer(id, (ctx) => {
|
|
38
|
+
renderScatter(ctx, data, xScale, yScale, {
|
|
39
|
+
defaultRadius,
|
|
40
|
+
defaultColor,
|
|
41
|
+
strokeColor,
|
|
42
|
+
strokeWidth,
|
|
43
|
+
shape,
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
return unregister;
|
|
47
|
+
}, [
|
|
48
|
+
registerDataLayer,
|
|
49
|
+
id,
|
|
50
|
+
data,
|
|
51
|
+
xScale,
|
|
52
|
+
yScale,
|
|
53
|
+
defaultRadius,
|
|
54
|
+
defaultColor,
|
|
55
|
+
strokeColor,
|
|
56
|
+
strokeWidth,
|
|
57
|
+
shape,
|
|
58
|
+
]);
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/SeriesMarkersOverlay.tsx
|
|
3
|
+
* Declarative component for series marker annotations and event badges.
|
|
4
|
+
*/
|
|
5
|
+
import type { SeriesMarker } from '@tranding-custom-chart/core';
|
|
6
|
+
export interface SeriesMarkersOverlayProps {
|
|
7
|
+
readonly markers: readonly SeriesMarker[];
|
|
8
|
+
}
|
|
9
|
+
export declare function SeriesMarkersOverlay({ markers }: SeriesMarkersOverlayProps): null;
|
|
10
|
+
//# sourceMappingURL=SeriesMarkersOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SeriesMarkersOverlay.d.ts","sourceRoot":"","sources":["../src/SeriesMarkersOverlay.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAIhE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C;AAED,wBAAgB,oBAAoB,CAAC,EAAE,OAAO,EAAE,EAAE,yBAAyB,GAAG,IAAI,CAuBjF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/SeriesMarkersOverlay.tsx
|
|
3
|
+
* Declarative component for series marker annotations and event badges.
|
|
4
|
+
*/
|
|
5
|
+
import React, { useEffect, useId } from 'react';
|
|
6
|
+
import { renderSeriesMarkers } from '@tranding-custom-chart/renderer-canvas';
|
|
7
|
+
import { useChartContext } from './ChartContext.js';
|
|
8
|
+
export function SeriesMarkersOverlay({ markers }) {
|
|
9
|
+
const { registerOverlayLayer, xScale, yScale, bounds, padding, dpr } = useChartContext();
|
|
10
|
+
const id = useId();
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!xScale || !yScale)
|
|
13
|
+
return;
|
|
14
|
+
const unregister = registerOverlayLayer(id, (ctx) => {
|
|
15
|
+
renderSeriesMarkers({
|
|
16
|
+
ctx,
|
|
17
|
+
bounds,
|
|
18
|
+
padding,
|
|
19
|
+
xScale,
|
|
20
|
+
yScale,
|
|
21
|
+
markers,
|
|
22
|
+
dpr,
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
return unregister;
|
|
26
|
+
}, [registerOverlayLayer, id, xScale, yScale, bounds, padding, markers, dpr]);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/StackedBarSeries.tsx
|
|
3
|
+
* Declarative Stacked Bar series component.
|
|
4
|
+
*/
|
|
5
|
+
import type { StackedBarDatum } from '@tranding-custom-chart/core';
|
|
6
|
+
export interface StackedBarSeriesProps {
|
|
7
|
+
readonly data: readonly StackedBarDatum[];
|
|
8
|
+
readonly columnWidthRatio?: number | undefined;
|
|
9
|
+
readonly defaultColors?: readonly string[] | undefined;
|
|
10
|
+
readonly borderRadius?: number | undefined;
|
|
11
|
+
}
|
|
12
|
+
export declare function StackedBarSeries({ data, columnWidthRatio, defaultColors, borderRadius, }: StackedBarSeriesProps): null;
|
|
13
|
+
//# sourceMappingURL=StackedBarSeries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StackedBarSeries.d.ts","sourceRoot":"","sources":["../src/StackedBarSeries.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAInE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,SAAS,eAAe,EAAE,CAAC;IAC1C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5C;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,gBAAsB,EACtB,aAAa,EACb,YAAgB,GACjB,EAAE,qBAAqB,GAAG,IAAI,CAqB9B"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/StackedBarSeries.tsx
|
|
3
|
+
* Declarative Stacked Bar series component.
|
|
4
|
+
*/
|
|
5
|
+
import React, { useEffect, useId } from 'react';
|
|
6
|
+
import { renderStackedBars } from '@tranding-custom-chart/renderer-canvas';
|
|
7
|
+
import { useChartContext } from './ChartContext.js';
|
|
8
|
+
export function StackedBarSeries({ data, columnWidthRatio = 0.6, defaultColors, borderRadius = 4, }) {
|
|
9
|
+
const { registerDataLayer, xScale, yScale } = useChartContext();
|
|
10
|
+
const id = useId();
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!xScale || !yScale || data.length === 0)
|
|
13
|
+
return;
|
|
14
|
+
const unregister = registerDataLayer(id, (ctx) => {
|
|
15
|
+
renderStackedBars(ctx, data, {
|
|
16
|
+
xScale,
|
|
17
|
+
yScale,
|
|
18
|
+
columnWidthRatio,
|
|
19
|
+
defaultColors,
|
|
20
|
+
borderRadius,
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
return unregister;
|
|
24
|
+
}, [registerDataLayer, id, data, xScale, yScale, columnWidthRatio, defaultColors, borderRadius]);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/StepLineSeries.tsx
|
|
3
|
+
* Declarative Step Line series component.
|
|
4
|
+
*/
|
|
5
|
+
export interface StepLineSeriesProps {
|
|
6
|
+
readonly data: readonly (number | null)[];
|
|
7
|
+
readonly color?: string | undefined;
|
|
8
|
+
readonly strokeWidth?: number | undefined;
|
|
9
|
+
readonly areaFill?: {
|
|
10
|
+
readonly baselineY: number;
|
|
11
|
+
readonly fillColor: string;
|
|
12
|
+
} | undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare function StepLineSeries({ data, color, strokeWidth, areaFill, }: StepLineSeriesProps): null;
|
|
15
|
+
//# sourceMappingURL=StepLineSeries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StepLineSeries.d.ts","sourceRoot":"","sources":["../src/StepLineSeries.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAClB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,GAAG,SAAS,CAAC;CACf;AAED,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,KAAiB,EACjB,WAAe,EACf,QAAQ,GACT,EAAE,mBAAmB,GAAG,IAAI,CAuB5B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/StepLineSeries.tsx
|
|
3
|
+
* Declarative Step Line series component.
|
|
4
|
+
*/
|
|
5
|
+
import React, { useEffect, useId } from 'react';
|
|
6
|
+
import { renderStepLine } from '@tranding-custom-chart/renderer-canvas';
|
|
7
|
+
import { useChartContext } from './ChartContext.js';
|
|
8
|
+
export function StepLineSeries({ data, color = '#3b82f6', strokeWidth = 2, areaFill, }) {
|
|
9
|
+
const { registerDataLayer, xScale, yScale } = useChartContext();
|
|
10
|
+
const id = useId();
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!xScale || !yScale || data.length === 0)
|
|
13
|
+
return;
|
|
14
|
+
const unregister = registerDataLayer(id, (ctx) => {
|
|
15
|
+
renderStepLine({
|
|
16
|
+
ctx,
|
|
17
|
+
data,
|
|
18
|
+
xScale,
|
|
19
|
+
yScale,
|
|
20
|
+
color,
|
|
21
|
+
strokeWidth,
|
|
22
|
+
areaFill,
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
return unregister;
|
|
26
|
+
}, [registerDataLayer, id, data, xScale, yScale, color, strokeWidth, areaFill]);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/SupertrendSeries.tsx
|
|
3
|
+
* Declarative Supertrend series component for React.
|
|
4
|
+
*/
|
|
5
|
+
import type { OHLCVBar } from '@tranding-custom-chart/core';
|
|
6
|
+
export interface SupertrendSeriesProps {
|
|
7
|
+
readonly bars: readonly OHLCVBar[];
|
|
8
|
+
readonly period?: number | undefined;
|
|
9
|
+
readonly multiplier?: number | undefined;
|
|
10
|
+
readonly upColor?: string | undefined;
|
|
11
|
+
readonly downColor?: string | undefined;
|
|
12
|
+
readonly strokeWidth?: number | undefined;
|
|
13
|
+
readonly showReversalMarkers?: boolean | undefined;
|
|
14
|
+
}
|
|
15
|
+
export declare function SupertrendSeries({ bars, period, multiplier, upColor, downColor, strokeWidth, showReversalMarkers, }: SupertrendSeriesProps): null;
|
|
16
|
+
//# sourceMappingURL=SupertrendSeries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SupertrendSeries.d.ts","sourceRoot":"","sources":["../src/SupertrendSeries.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,6BAA6B,CAAC;AAK9E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACpD;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,MAAW,EACX,UAAgB,EAChB,OAAmB,EACnB,SAAqB,EACrB,WAAe,EACf,mBAA0B,GAC3B,EAAE,qBAAqB,GAAG,IAAI,CAqC9B"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/SupertrendSeries.tsx
|
|
3
|
+
* Declarative Supertrend series component for React.
|
|
4
|
+
*/
|
|
5
|
+
import React, { useEffect, useId, useMemo } from 'react';
|
|
6
|
+
import { computeSupertrend } from '@tranding-custom-chart/financial';
|
|
7
|
+
import { renderSupertrend } from '@tranding-custom-chart/renderer-canvas';
|
|
8
|
+
import { useChartContext } from './ChartContext.js';
|
|
9
|
+
export function SupertrendSeries({ bars, period = 10, multiplier = 3.0, upColor = '#16a34a', downColor = '#dc2626', strokeWidth = 2, showReversalMarkers = true, }) {
|
|
10
|
+
const { registerDataLayer, xScale, yScale } = useChartContext();
|
|
11
|
+
const id = useId();
|
|
12
|
+
const supertrend = useMemo(() => computeSupertrend(bars, { period, multiplier }), [bars, period, multiplier]);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
if (!xScale || !yScale || supertrend.points.length === 0)
|
|
15
|
+
return;
|
|
16
|
+
return registerDataLayer(id, (ctx) => {
|
|
17
|
+
renderSupertrend({
|
|
18
|
+
ctx,
|
|
19
|
+
supertrend,
|
|
20
|
+
xScale,
|
|
21
|
+
yScale,
|
|
22
|
+
upColor,
|
|
23
|
+
downColor,
|
|
24
|
+
strokeWidth,
|
|
25
|
+
showReversalMarkers,
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}, [
|
|
29
|
+
registerDataLayer,
|
|
30
|
+
id,
|
|
31
|
+
supertrend,
|
|
32
|
+
xScale,
|
|
33
|
+
yScale,
|
|
34
|
+
upColor,
|
|
35
|
+
downColor,
|
|
36
|
+
strokeWidth,
|
|
37
|
+
showReversalMarkers,
|
|
38
|
+
]);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/UniversalSeries.tsx
|
|
3
|
+
* Universal series component dynamically rendering any of the supported chart types
|
|
4
|
+
* with complete styling, color, and behavior customization.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { ChartType, OHLCVBar } from '@tranding-custom-chart/core';
|
|
8
|
+
export interface UniversalSeriesProps {
|
|
9
|
+
readonly chartType: ChartType;
|
|
10
|
+
readonly bars: readonly OHLCVBar[];
|
|
11
|
+
readonly upColor?: string | undefined;
|
|
12
|
+
readonly downColor?: string | undefined;
|
|
13
|
+
readonly lineColor?: string | undefined;
|
|
14
|
+
readonly lineWidth?: number | undefined;
|
|
15
|
+
readonly baselineValue?: number | undefined;
|
|
16
|
+
readonly baselineAboveColor?: string | undefined;
|
|
17
|
+
readonly baselineBelowColor?: string | undefined;
|
|
18
|
+
readonly candleWidthRatio?: number | undefined;
|
|
19
|
+
}
|
|
20
|
+
export declare function UniversalSeries({ chartType, bars, upColor, downColor, lineColor, lineWidth, baselineValue, baselineAboveColor, baselineBelowColor, candleWidthRatio, }: UniversalSeriesProps): React.JSX.Element | null;
|
|
21
|
+
//# sourceMappingURL=UniversalSeries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UniversalSeries.d.ts","sourceRoot":"","sources":["../src/UniversalSeries.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAA8B,MAAM,6BAA6B,CAAC;AAwBnG,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChD;AAED,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,IAAI,EACJ,OAAO,EACP,SAAS,EACT,SAAqB,EACrB,SAAa,EACb,aAAa,EACb,kBAA8B,EAC9B,kBAA8B,EAC9B,gBAAsB,GACvB,EAAE,oBAAoB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CA2VjD"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* @file packages/chart-react/src/UniversalSeries.tsx
|
|
4
|
+
* Universal series component dynamically rendering any of the supported chart types
|
|
5
|
+
* with complete styling, color, and behavior customization.
|
|
6
|
+
*/
|
|
7
|
+
import React, { useMemo } from 'react';
|
|
8
|
+
import { calculateBoxPlotStats } from '@tranding-custom-chart/core';
|
|
9
|
+
import { computeHeikinAshi, computeRenko, computeKagi, computeLineBreak } from '@tranding-custom-chart/financial';
|
|
10
|
+
import { CandlestickSeries } from './CandlestickSeries.js';
|
|
11
|
+
import { HollowCandlestickSeries } from './HollowCandlestickSeries.js';
|
|
12
|
+
import { OhlcBarSeries } from './OhlcBarSeries.js';
|
|
13
|
+
import { LineSeries } from './LineSeries.js';
|
|
14
|
+
import { StepLineSeries } from './StepLineSeries.js';
|
|
15
|
+
import { BaselineSeries } from './BaselineSeries.js';
|
|
16
|
+
import { HighLowSeries } from './HighLowSeries.js';
|
|
17
|
+
import { ColumnsSeries } from './ColumnsSeries.js';
|
|
18
|
+
import { LineWithMarkersSeries } from './LineWithMarkersSeries.js';
|
|
19
|
+
import { HlcAreaSeries } from './HlcAreaSeries.js';
|
|
20
|
+
import { PieSeries } from './PieSeries.js';
|
|
21
|
+
import { ScatterSeries } from './ScatterSeries.js';
|
|
22
|
+
import { BubbleSeries } from './BubbleSeries.js';
|
|
23
|
+
import { PolarAreaSeries } from './PolarAreaSeries.js';
|
|
24
|
+
import { HorizontalBarSeries } from './HorizontalBarSeries.js';
|
|
25
|
+
import { StackedBarSeries } from './StackedBarSeries.js';
|
|
26
|
+
import { RadarSeries } from './RadarSeries.js';
|
|
27
|
+
import { BoxPlotSeries } from './BoxPlotSeries.js';
|
|
28
|
+
import { HeatmapSeries } from './HeatmapSeries.js';
|
|
29
|
+
import { useChartContext } from './ChartContext.js';
|
|
30
|
+
export function UniversalSeries({ chartType, bars, upColor, downColor, lineColor = '#2563eb', lineWidth = 2, baselineValue, baselineAboveColor = '#16794c', baselineBelowColor = '#b42318', candleWidthRatio = 0.7, }) {
|
|
31
|
+
const { bounds, padding } = useChartContext();
|
|
32
|
+
const closePrices = useMemo(() => bars.map((b) => b.close), [bars]);
|
|
33
|
+
const haBars = useMemo(() => (chartType === 'heikin_ashi' ? computeHeikinAshi(bars) : []), [bars, chartType]);
|
|
34
|
+
const renkoBricks = useMemo(() => (chartType === 'renko' ? computeRenko(bars) : []), [bars, chartType]);
|
|
35
|
+
const kagiBars = useMemo(() => (chartType === 'kagi' ? computeKagi(bars) : []), [bars, chartType]);
|
|
36
|
+
const lineBreakBars = useMemo(() => (chartType === 'line_break' ? computeLineBreak(bars) : []), [bars, chartType]);
|
|
37
|
+
const effectiveBaseline = useMemo(() => {
|
|
38
|
+
if (baselineValue !== undefined)
|
|
39
|
+
return baselineValue;
|
|
40
|
+
if (bars.length === 0)
|
|
41
|
+
return 0;
|
|
42
|
+
// Default baseline: opening price of the series
|
|
43
|
+
return bars[0].open;
|
|
44
|
+
}, [baselineValue, bars]);
|
|
45
|
+
switch (chartType) {
|
|
46
|
+
case 'candlestick':
|
|
47
|
+
return (_jsx(CandlestickSeries, { data: bars, upColor: upColor, downColor: downColor, candleWidthRatio: candleWidthRatio }));
|
|
48
|
+
case 'hollow_candlestick':
|
|
49
|
+
return (_jsx(HollowCandlestickSeries, { data: bars, upColor: upColor, downColor: downColor, candleWidthRatio: candleWidthRatio }));
|
|
50
|
+
case 'bar':
|
|
51
|
+
return (_jsx(OhlcBarSeries, { data: bars, upColor: upColor, downColor: downColor, lineWidth: lineWidth }));
|
|
52
|
+
case 'heikin_ashi':
|
|
53
|
+
return (_jsx(CandlestickSeries, { data: haBars, upColor: upColor, downColor: downColor, candleWidthRatio: candleWidthRatio }));
|
|
54
|
+
case 'renko':
|
|
55
|
+
return (_jsx(CandlestickSeries, { data: renkoBricks, upColor: upColor, downColor: downColor, candleWidthRatio: candleWidthRatio }));
|
|
56
|
+
case 'kagi':
|
|
57
|
+
return (_jsx(CandlestickSeries, { data: kagiBars, upColor: upColor ?? '#10b981', downColor: downColor ?? '#ef4444', candleWidthRatio: 0.4 }));
|
|
58
|
+
case 'line_break':
|
|
59
|
+
return (_jsx(CandlestickSeries, { data: lineBreakBars, upColor: upColor ?? '#10b981', downColor: downColor ?? '#ef4444', candleWidthRatio: candleWidthRatio }));
|
|
60
|
+
case 'columns':
|
|
61
|
+
return (_jsx(ColumnsSeries, { data: bars, upColor: upColor, downColor: downColor, columnWidthRatio: candleWidthRatio }));
|
|
62
|
+
case 'line':
|
|
63
|
+
return (_jsx(LineSeries, { data: closePrices, color: lineColor, strokeWidth: lineWidth }));
|
|
64
|
+
case 'line_with_markers':
|
|
65
|
+
return (_jsx(LineWithMarkersSeries, { data: closePrices, color: lineColor, strokeWidth: lineWidth }));
|
|
66
|
+
case 'step_line':
|
|
67
|
+
return (_jsx(StepLineSeries, { data: closePrices, color: lineColor, strokeWidth: lineWidth }));
|
|
68
|
+
case 'area':
|
|
69
|
+
return (_jsx(LineSeries, { data: closePrices, color: lineColor, strokeWidth: lineWidth, areaFill: {
|
|
70
|
+
gradientTopColor: 'rgba(37, 99, 235, 0.40)',
|
|
71
|
+
gradientBottomColor: 'rgba(37, 99, 235, 0.02)',
|
|
72
|
+
baselineY: bounds.height - padding.bottom,
|
|
73
|
+
} }));
|
|
74
|
+
case 'hlc_area':
|
|
75
|
+
return (_jsx(HlcAreaSeries, { data: bars, closeLineColor: lineColor, closeLineWidth: lineWidth }));
|
|
76
|
+
case 'baseline':
|
|
77
|
+
return (_jsx(BaselineSeries, { data: closePrices, baselineValue: effectiveBaseline, aboveColor: baselineAboveColor, belowColor: baselineBelowColor, lineWidth: lineWidth }));
|
|
78
|
+
case 'high_low':
|
|
79
|
+
return (_jsx(HighLowSeries, { data: bars, color: lineColor, lineWidth: lineWidth }));
|
|
80
|
+
case 'doughnut':
|
|
81
|
+
case 'pie': {
|
|
82
|
+
const pieSlices = bars.slice(0, 8).map((b, i) => ({
|
|
83
|
+
id: `slice-${i}`,
|
|
84
|
+
label: b.dateStr?.slice(5, 10) ?? `P${i}`,
|
|
85
|
+
value: Math.max(1, Math.round(b.close)),
|
|
86
|
+
color: ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899', '#06b6d4', '#84cc16'][i % 8],
|
|
87
|
+
}));
|
|
88
|
+
return (_jsx(PieSeries, { slices: pieSlices, innerRadius: chartType === 'doughnut' ? 45 : 0 }));
|
|
89
|
+
}
|
|
90
|
+
case 'scatter': {
|
|
91
|
+
const scatterPoints = bars.map((b, i) => ({
|
|
92
|
+
x: i,
|
|
93
|
+
y: b.close,
|
|
94
|
+
radius: 4.5,
|
|
95
|
+
color: b.close >= b.open ? upColor ?? '#16794c' : downColor ?? '#b42318',
|
|
96
|
+
shape: 'circle',
|
|
97
|
+
}));
|
|
98
|
+
return _jsx(ScatterSeries, { data: scatterPoints });
|
|
99
|
+
}
|
|
100
|
+
case 'bubble': {
|
|
101
|
+
const bubbles = bars.map((b, i) => ({
|
|
102
|
+
x: i,
|
|
103
|
+
y: b.close,
|
|
104
|
+
r: Math.max(3, Math.min(22, ((b.volume ?? 50000) / 8000))),
|
|
105
|
+
color: b.close >= b.open ? 'rgba(22, 121, 76, 0.65)' : 'rgba(180, 35, 24, 0.65)',
|
|
106
|
+
}));
|
|
107
|
+
return _jsx(BubbleSeries, { data: bubbles });
|
|
108
|
+
}
|
|
109
|
+
case 'polar_area': {
|
|
110
|
+
const paData = bars.slice(0, 8).map((b, i) => ({
|
|
111
|
+
id: `pa-${i}`,
|
|
112
|
+
label: b.dateStr?.slice(5, 10) ?? `P${i}`,
|
|
113
|
+
value: Math.max(5, Math.round(b.close)),
|
|
114
|
+
color: [
|
|
115
|
+
'rgba(59, 130, 246, 0.75)',
|
|
116
|
+
'rgba(16, 185, 129, 0.75)',
|
|
117
|
+
'rgba(245, 158, 11, 0.75)',
|
|
118
|
+
'rgba(239, 68, 68, 0.75)',
|
|
119
|
+
'rgba(139, 92, 246, 0.75)',
|
|
120
|
+
'rgba(236, 72, 153, 0.75)',
|
|
121
|
+
'rgba(6, 182, 212, 0.75)',
|
|
122
|
+
'rgba(132, 204, 22, 0.75)',
|
|
123
|
+
][i % 8],
|
|
124
|
+
}));
|
|
125
|
+
return _jsx(PolarAreaSeries, { data: paData });
|
|
126
|
+
}
|
|
127
|
+
case 'horizontal_bar': {
|
|
128
|
+
const hbData = bars.slice(0, 10).map((b, i) => ({
|
|
129
|
+
category: b.dateStr?.slice(5, 10) ?? `P${i}`,
|
|
130
|
+
value: Math.max(1, Math.round(b.close)),
|
|
131
|
+
color: b.close >= b.open ? upColor ?? '#16794c' : downColor ?? '#b42318',
|
|
132
|
+
}));
|
|
133
|
+
return _jsx(HorizontalBarSeries, { data: hbData, defaultColor: lineColor });
|
|
134
|
+
}
|
|
135
|
+
case 'stacked_bar': {
|
|
136
|
+
const sbData = bars.slice(0, 8).map((b, i) => {
|
|
137
|
+
const body = Math.max(1, Math.abs(b.close - b.open));
|
|
138
|
+
const upper = Math.max(1, b.high - Math.max(b.close, b.open));
|
|
139
|
+
const lower = Math.max(1, Math.min(b.close, b.open) - b.low);
|
|
140
|
+
return {
|
|
141
|
+
category: b.dateStr?.slice(5, 10) ?? `P${i}`,
|
|
142
|
+
values: [Math.round(body), Math.round(upper), Math.round(lower)],
|
|
143
|
+
};
|
|
144
|
+
});
|
|
145
|
+
return _jsx(StackedBarSeries, { data: sbData, defaultColors: ['#3b82f6', '#10b981', '#f59e0b'] });
|
|
146
|
+
}
|
|
147
|
+
case 'radar': {
|
|
148
|
+
const highMax = Math.max(...bars.map((b) => b.high)) * 1.05 || 100;
|
|
149
|
+
const radarAxes = [
|
|
150
|
+
{ key: 'open', label: 'Open', max: highMax },
|
|
151
|
+
{ key: 'high', label: 'High', max: highMax },
|
|
152
|
+
{ key: 'low', label: 'Low', max: highMax },
|
|
153
|
+
{ key: 'close', label: 'Close', max: highMax },
|
|
154
|
+
{ key: 'volume', label: 'Volume (norm)', max: 100 },
|
|
155
|
+
];
|
|
156
|
+
const recentBar = bars[bars.length - 1] ?? { open: 50, high: 60, low: 40, close: 55, volume: 50 };
|
|
157
|
+
const avgBar = bars[Math.floor(bars.length / 2)] ?? recentBar;
|
|
158
|
+
const radarDatasets = [
|
|
159
|
+
{
|
|
160
|
+
id: 'latest',
|
|
161
|
+
label: 'Latest Session',
|
|
162
|
+
data: {
|
|
163
|
+
open: recentBar.open,
|
|
164
|
+
high: recentBar.high,
|
|
165
|
+
low: recentBar.low,
|
|
166
|
+
close: recentBar.close,
|
|
167
|
+
volume: 75,
|
|
168
|
+
},
|
|
169
|
+
strokeColor: upColor ?? '#10b981',
|
|
170
|
+
fillColor: 'rgba(16, 185, 129, 0.25)',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
id: 'average',
|
|
174
|
+
label: 'Midpoint Session',
|
|
175
|
+
data: {
|
|
176
|
+
open: avgBar.open,
|
|
177
|
+
high: avgBar.high,
|
|
178
|
+
low: avgBar.low,
|
|
179
|
+
close: avgBar.close,
|
|
180
|
+
volume: 50,
|
|
181
|
+
},
|
|
182
|
+
strokeColor: lineColor ?? '#3b82f6',
|
|
183
|
+
fillColor: 'rgba(59, 130, 246, 0.2)',
|
|
184
|
+
},
|
|
185
|
+
];
|
|
186
|
+
return _jsx(RadarSeries, { axes: radarAxes, datasets: radarDatasets });
|
|
187
|
+
}
|
|
188
|
+
case 'box_plot': {
|
|
189
|
+
const chunkSize = Math.max(5, Math.floor(bars.length / 6));
|
|
190
|
+
const boxData = [];
|
|
191
|
+
for (let i = 0; i < bars.length && boxData.length < 8; i += chunkSize) {
|
|
192
|
+
const slice = bars.slice(i, i + chunkSize);
|
|
193
|
+
const prices = slice.flatMap((b) => [b.open, b.high, b.low, b.close]);
|
|
194
|
+
const cat = slice[0]?.dateStr?.slice(5, 10) ?? `B${boxData.length + 1}`;
|
|
195
|
+
boxData.push(calculateBoxPlotStats(cat, prices, boxData.length % 2 === 0 ? upColor ?? '#10b981' : lineColor ?? '#3b82f6'));
|
|
196
|
+
}
|
|
197
|
+
return _jsx(BoxPlotSeries, { data: boxData });
|
|
198
|
+
}
|
|
199
|
+
case 'heatmap': {
|
|
200
|
+
const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
|
|
201
|
+
const sessions = ['Open', 'Midday', 'Close', 'Post'];
|
|
202
|
+
const heatmapData = [];
|
|
203
|
+
let idx = 0;
|
|
204
|
+
for (const d of days) {
|
|
205
|
+
for (const s of sessions) {
|
|
206
|
+
const bar = bars[idx % bars.length];
|
|
207
|
+
const ret = bar ? ((bar.close - bar.open) / (bar.open || 1)) * 100 : 0;
|
|
208
|
+
heatmapData.push({
|
|
209
|
+
x: d,
|
|
210
|
+
y: s,
|
|
211
|
+
value: Math.round(ret * 10) / 10,
|
|
212
|
+
label: `${(ret >= 0 ? '+' : '') + ret.toFixed(1)}%`,
|
|
213
|
+
});
|
|
214
|
+
idx++;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return _jsx(HeatmapSeries, { data: heatmapData, showLabels: true });
|
|
218
|
+
}
|
|
219
|
+
default:
|
|
220
|
+
return (_jsx(CandlestickSeries, { data: bars, upColor: upColor, downColor: downColor }));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/VolumeProfileSeries.tsx
|
|
3
|
+
* Declarative Visible Range Volume Profile (VRVP) component with POC and Value Area.
|
|
4
|
+
*/
|
|
5
|
+
import type { OHLCVBar } from '@tranding-custom-chart/core';
|
|
6
|
+
export interface VolumeProfileSeriesProps {
|
|
7
|
+
readonly bars: readonly OHLCVBar[];
|
|
8
|
+
readonly binCount?: number | undefined;
|
|
9
|
+
readonly valueAreaRatio?: number | undefined;
|
|
10
|
+
readonly maxBarWidth?: number | undefined;
|
|
11
|
+
readonly alignment?: 'right' | 'left' | undefined;
|
|
12
|
+
readonly buyColor?: string | undefined;
|
|
13
|
+
readonly sellColor?: string | undefined;
|
|
14
|
+
readonly valueAreaBuyColor?: string | undefined;
|
|
15
|
+
readonly valueAreaSellColor?: string | undefined;
|
|
16
|
+
readonly pocColor?: string | undefined;
|
|
17
|
+
readonly showPOCLine?: boolean | undefined;
|
|
18
|
+
readonly showLabels?: boolean | undefined;
|
|
19
|
+
}
|
|
20
|
+
export declare function VolumeProfileSeries({ bars, binCount, valueAreaRatio, maxBarWidth, alignment, buyColor, sellColor, valueAreaBuyColor, valueAreaSellColor, pocColor, showPOCLine, showLabels, }: VolumeProfileSeriesProps): null;
|
|
21
|
+
//# sourceMappingURL=VolumeProfileSeries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VolumeProfileSeries.d.ts","sourceRoot":"","sources":["../src/VolumeProfileSeries.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAuB,MAAM,6BAA6B,CAAC;AAKjF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC3C;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,QAAa,EACb,cAAoB,EACpB,WAAiB,EACjB,SAAmB,EACnB,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,WAAkB,EAClB,UAAiB,GAClB,EAAE,wBAAwB,GAAG,IAAI,CAuDjC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/VolumeProfileSeries.tsx
|
|
3
|
+
* Declarative Visible Range Volume Profile (VRVP) component with POC and Value Area.
|
|
4
|
+
*/
|
|
5
|
+
import React, { useEffect, useId, useMemo } from 'react';
|
|
6
|
+
import { computeVolumeProfile } from '@tranding-custom-chart/financial';
|
|
7
|
+
import { renderVolumeProfile } from '@tranding-custom-chart/renderer-canvas';
|
|
8
|
+
import { useChartContext } from './ChartContext.js';
|
|
9
|
+
export function VolumeProfileSeries({ bars, binCount = 24, valueAreaRatio = 0.7, maxBarWidth = 140, alignment = 'right', buyColor, sellColor, valueAreaBuyColor, valueAreaSellColor, pocColor, showPOCLine = true, showLabels = true, }) {
|
|
10
|
+
const { registerDataLayer, yScale, bounds, padding } = useChartContext();
|
|
11
|
+
const id = useId();
|
|
12
|
+
const profile = useMemo(() => computeVolumeProfile(bars, { binCount, valueAreaRatio }), [bars, binCount, valueAreaRatio]);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
if (!yScale || profile.bins.length === 0)
|
|
15
|
+
return;
|
|
16
|
+
const unregister = registerDataLayer(id, (ctx) => {
|
|
17
|
+
renderVolumeProfile({
|
|
18
|
+
ctx,
|
|
19
|
+
profile,
|
|
20
|
+
yScale,
|
|
21
|
+
chartWidth: bounds.width,
|
|
22
|
+
chartHeight: bounds.height,
|
|
23
|
+
paddingRight: padding.right,
|
|
24
|
+
paddingLeft: padding.left,
|
|
25
|
+
maxBarWidth,
|
|
26
|
+
alignment,
|
|
27
|
+
buyColor,
|
|
28
|
+
sellColor,
|
|
29
|
+
valueAreaBuyColor,
|
|
30
|
+
valueAreaSellColor,
|
|
31
|
+
pocColor,
|
|
32
|
+
showPOCLine,
|
|
33
|
+
showLabels,
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
return unregister;
|
|
37
|
+
}, [
|
|
38
|
+
registerDataLayer,
|
|
39
|
+
id,
|
|
40
|
+
profile,
|
|
41
|
+
yScale,
|
|
42
|
+
bounds.width,
|
|
43
|
+
bounds.height,
|
|
44
|
+
padding.right,
|
|
45
|
+
padding.left,
|
|
46
|
+
maxBarWidth,
|
|
47
|
+
alignment,
|
|
48
|
+
buyColor,
|
|
49
|
+
sellColor,
|
|
50
|
+
valueAreaBuyColor,
|
|
51
|
+
valueAreaSellColor,
|
|
52
|
+
pocColor,
|
|
53
|
+
showPOCLine,
|
|
54
|
+
showLabels,
|
|
55
|
+
]);
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/VolumeSeries.tsx
|
|
3
|
+
* Declarative Volume series component.
|
|
4
|
+
*/
|
|
5
|
+
import type { OHLCVBar, Scale } from '@tranding-custom-chart/core';
|
|
6
|
+
export interface VolumeSeriesProps {
|
|
7
|
+
readonly data: readonly OHLCVBar[];
|
|
8
|
+
readonly volumeScale: Scale<number>;
|
|
9
|
+
readonly baselineY: number;
|
|
10
|
+
readonly upColor?: string | undefined;
|
|
11
|
+
readonly downColor?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export declare function VolumeSeries({ data, volumeScale, baselineY, upColor, downColor, }: VolumeSeriesProps): null;
|
|
14
|
+
//# sourceMappingURL=VolumeSeries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VolumeSeries.d.ts","sourceRoot":"","sources":["../src/VolumeSeries.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAInE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,WAAW,EACX,SAAS,EACT,OAAO,EACP,SAAS,GACV,EAAE,iBAAiB,GAAG,IAAI,CA6B1B"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/chart-react/src/VolumeSeries.tsx
|
|
3
|
+
* Declarative Volume series component.
|
|
4
|
+
*/
|
|
5
|
+
import React, { useEffect, useId } from 'react';
|
|
6
|
+
import { renderBarSeries } from '@tranding-custom-chart/renderer-canvas';
|
|
7
|
+
import { useChartContext } from './ChartContext.js';
|
|
8
|
+
export function VolumeSeries({ data, volumeScale, baselineY, upColor, downColor, }) {
|
|
9
|
+
const { registerDataLayer, xScale, theme } = useChartContext();
|
|
10
|
+
const id = useId();
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!xScale || data.length === 0)
|
|
13
|
+
return;
|
|
14
|
+
const items = data.map((b) => ({
|
|
15
|
+
value: b.volume ?? 0,
|
|
16
|
+
isUp: b.close >= b.open,
|
|
17
|
+
}));
|
|
18
|
+
const unregister = registerDataLayer(id, (ctx, bounds, padding, dpr) => {
|
|
19
|
+
renderBarSeries({
|
|
20
|
+
ctx,
|
|
21
|
+
items,
|
|
22
|
+
xScale,
|
|
23
|
+
yScale: volumeScale,
|
|
24
|
+
baselineY,
|
|
25
|
+
dpr,
|
|
26
|
+
upColor: upColor ?? theme.volumeUp,
|
|
27
|
+
downColor: downColor ?? theme.volumeDown,
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
return unregister;
|
|
31
|
+
}, [registerDataLayer, id, data, xScale, volumeScale, baselineY, theme, upColor, downColor]);
|
|
32
|
+
return null;
|
|
33
|
+
}
|