@tradingaction/table 2.1.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/LICENSE +21 -0
- package/README.md +51 -0
- package/lib/Table.d.ts +75 -0
- package/lib/Table.js +323 -0
- package/lib/Table.js.map +1 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +6 -0
- package/lib/index.js.map +1 -0
- package/lib/positionUtils.d.ts +40 -0
- package/lib/positionUtils.js +179 -0
- package/lib/positionUtils.js.map +1 -0
- package/lib/types.d.ts +83 -0
- package/lib/types.js +5 -0
- package/lib/types.js.map +1 -0
- package/package.json +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Reactive Markets
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# @tradingaction/table
|
|
2
|
+
|
|
3
|
+
Interactive table annotation for react-financial-charts.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Position tables at 9 different positions on your chart
|
|
8
|
+
- Automatic position calculation (no manual coordinate needed)
|
|
9
|
+
- Customize cell fill color and text color
|
|
10
|
+
- Origin-based positioning (stays consistent on pan)
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @tradingaction/table
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { Table } from '@tradingaction/table';
|
|
22
|
+
|
|
23
|
+
<Table
|
|
24
|
+
position="top_right"
|
|
25
|
+
rows={[
|
|
26
|
+
{ label: "Price", value: "$100.50", labelFill: "#fff", valueFill: "#ffff00" },
|
|
27
|
+
{ label: "Change", value: "+2.5%", labelFill: "#fff", valueFill: "#00ff00" },
|
|
28
|
+
]}
|
|
29
|
+
cellFill="#1a1a1a"
|
|
30
|
+
cellBorder="#555"
|
|
31
|
+
padding={8}
|
|
32
|
+
/>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Positions
|
|
36
|
+
|
|
37
|
+
Available positions (3x3 grid):
|
|
38
|
+
- `top_left`, `top_center`, `top_right`
|
|
39
|
+
- `middle_left`, `middle_center`, `middle_right`
|
|
40
|
+
- `bottom_left`, `bottom_center`, `bottom_right`
|
|
41
|
+
|
|
42
|
+
## Props
|
|
43
|
+
|
|
44
|
+
- `position`: Position on the chart
|
|
45
|
+
- `rows`: Array of row data with labels and values
|
|
46
|
+
- `cellFill`: Background color of cells
|
|
47
|
+
- `cellBorder`: Border color of cells
|
|
48
|
+
- `textFill`: Default text color
|
|
49
|
+
- `fontSize`: Font size (default: 12)
|
|
50
|
+
- `fontFamily`: Font family (default: system)
|
|
51
|
+
- `padding`: Cell padding (default: 4)
|
package/lib/Table.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Position, TableLayout, TableRow, RowsCallback, VisibilityCallback } from "./types";
|
|
3
|
+
export interface TableProps {
|
|
4
|
+
/** Position of the table on the chart (3x3 grid) */
|
|
5
|
+
readonly position: Position;
|
|
6
|
+
/** Array of rows to display in the table */
|
|
7
|
+
readonly rows: TableRow[] | RowsCallback;
|
|
8
|
+
/** Table layout: "vertical" (label | value columns) or "horizontal" (headers on top, rows below) */
|
|
9
|
+
readonly layout?: TableLayout;
|
|
10
|
+
/** Column headers for horizontal layout */
|
|
11
|
+
readonly headers?: string[];
|
|
12
|
+
/** Background fill color for cells */
|
|
13
|
+
readonly cellFill?: string;
|
|
14
|
+
/** Border/stroke color for cells */
|
|
15
|
+
readonly cellBorder?: string;
|
|
16
|
+
/** Default text fill color */
|
|
17
|
+
readonly textFill?: string;
|
|
18
|
+
/** Font family */
|
|
19
|
+
readonly fontFamily?: string;
|
|
20
|
+
/** Font size in pixels */
|
|
21
|
+
readonly fontSize?: number;
|
|
22
|
+
/** Font weight */
|
|
23
|
+
readonly fontWeight?: string | number;
|
|
24
|
+
/** Padding inside cells */
|
|
25
|
+
readonly padding?: number;
|
|
26
|
+
/** Stroke width for borders */
|
|
27
|
+
readonly strokeWidth?: number;
|
|
28
|
+
/** Corner radius for cells */
|
|
29
|
+
readonly borderRadius?: number;
|
|
30
|
+
/** Callback to determine visibility */
|
|
31
|
+
readonly isVisible?: VisibilityCallback;
|
|
32
|
+
/** Custom canvas selection function */
|
|
33
|
+
readonly selectCanvas?: (canvases: any) => any;
|
|
34
|
+
/** Enable border drawing */
|
|
35
|
+
readonly showBorder?: boolean;
|
|
36
|
+
/** To calculate middle / bottom positions */
|
|
37
|
+
readonly canvasHeight?: number;
|
|
38
|
+
}
|
|
39
|
+
interface TableState {
|
|
40
|
+
updateCount: number;
|
|
41
|
+
}
|
|
42
|
+
export declare class Table extends React.Component<TableProps, TableState> {
|
|
43
|
+
static defaultProps: {
|
|
44
|
+
cellFill: string;
|
|
45
|
+
cellBorder: string;
|
|
46
|
+
textFill: string;
|
|
47
|
+
fontFamily: string;
|
|
48
|
+
fontSize: number;
|
|
49
|
+
fontWeight: string;
|
|
50
|
+
padding: number;
|
|
51
|
+
strokeWidth: number;
|
|
52
|
+
borderRadius: number;
|
|
53
|
+
showBorder: boolean;
|
|
54
|
+
layout: TableLayout;
|
|
55
|
+
selectCanvas: (canvases: any) => any;
|
|
56
|
+
};
|
|
57
|
+
static contextType: React.Context<import("@tradingaction/core/lib/ChartCanvas").ChartCanvasContextType<number | Date>>;
|
|
58
|
+
constructor(props: TableProps);
|
|
59
|
+
render(): React.JSX.Element;
|
|
60
|
+
private readonly drawOnCanvas;
|
|
61
|
+
private readonly drawTable;
|
|
62
|
+
/**
|
|
63
|
+
* Draw vertical layout (label | value1, value2, ...)
|
|
64
|
+
*/
|
|
65
|
+
private readonly drawVerticalTable;
|
|
66
|
+
/**
|
|
67
|
+
* Draw horizontal layout (headers on top, rows below - no label column)
|
|
68
|
+
*/
|
|
69
|
+
private readonly drawHorizontalTable;
|
|
70
|
+
/**
|
|
71
|
+
* Draw a rounded rectangle
|
|
72
|
+
*/
|
|
73
|
+
private readonly drawRoundRect;
|
|
74
|
+
}
|
|
75
|
+
export {};
|
package/lib/Table.js
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { GenericComponent, ChartCanvasContext } from "@tradingaction/core";
|
|
3
|
+
import { calculatePositionInfo, calculateTableBounds, clampPositionInfo } from "./positionUtils";
|
|
4
|
+
export class Table extends React.Component {
|
|
5
|
+
constructor(props) {
|
|
6
|
+
super(props);
|
|
7
|
+
this.drawOnCanvas = (ctx, moreProps) => {
|
|
8
|
+
var _a, _b;
|
|
9
|
+
const { isVisible, canvasHeight } = this.props;
|
|
10
|
+
// console.log(moreProps, 'moreProps', moreProps.height)
|
|
11
|
+
// Check visibility
|
|
12
|
+
if (isVisible && !isVisible(moreProps)) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
ctx.save();
|
|
16
|
+
const context = this.context;
|
|
17
|
+
const { canvasOriginX, canvasOriginY, margin, ratio } = context;
|
|
18
|
+
// Set up transformation
|
|
19
|
+
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
20
|
+
ctx.scale(ratio, ratio);
|
|
21
|
+
const originX = canvasOriginX !== null && canvasOriginX !== void 0 ? canvasOriginX : margin.left + 0.5 * ratio;
|
|
22
|
+
const originY = canvasOriginY !== null && canvasOriginY !== void 0 ? canvasOriginY : margin.top + 0.5 * ratio;
|
|
23
|
+
ctx.translate(originX, originY);
|
|
24
|
+
// Debug: log available props
|
|
25
|
+
// console.log('moreProps keys:', Object.keys(moreProps).slice(0, 20));
|
|
26
|
+
// console.log('xScale:', moreProps.xScale);
|
|
27
|
+
// console.log('canvasHeight:', moreProps.canvasHeight, canvasHeight);
|
|
28
|
+
// console.log('margin:', margin);
|
|
29
|
+
// Get the chart dimensions
|
|
30
|
+
const xScaleRange = (_b = (_a = moreProps.xScale) === null || _a === void 0 ? void 0 : _a.range) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
31
|
+
const chartWidth = xScaleRange ? (xScaleRange[1] - xScaleRange[0]) : 6000;
|
|
32
|
+
const chartHeight = (canvasHeight !== null && canvasHeight !== void 0 ? canvasHeight : 600) - margin.top - margin.bottom;
|
|
33
|
+
// console.log('chartWidth:', chartWidth, 'chartHeight:', chartHeight);
|
|
34
|
+
// Translate to the center of the chart
|
|
35
|
+
// (position calculations assume origin is at chart center)
|
|
36
|
+
ctx.translate(chartWidth / 2, chartHeight / 2);
|
|
37
|
+
// Get rows
|
|
38
|
+
const { rows } = this.props;
|
|
39
|
+
const tableRows = Array.isArray(rows) ? rows : rows(moreProps);
|
|
40
|
+
if (!tableRows || tableRows.length === 0) {
|
|
41
|
+
ctx.restore();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// Get styling props
|
|
45
|
+
const { fontSize = 12, fontFamily = "-apple-system, system-ui, Roboto, 'Helvetica Neue', Ubuntu, sans-serif", padding = 4, } = this.props;
|
|
46
|
+
// Calculate bounds (uses the provided canvas context for accurate text measurement)
|
|
47
|
+
const tableBounds = calculateTableBounds(tableRows, fontSize, fontFamily, padding, ctx);
|
|
48
|
+
// Calculate position
|
|
49
|
+
const { position } = this.props;
|
|
50
|
+
let posInfo = calculatePositionInfo(position, { width: chartWidth, height: chartHeight }, tableBounds);
|
|
51
|
+
// Clamp position to ensure table stays visible
|
|
52
|
+
posInfo = clampPositionInfo(posInfo, { width: chartWidth, height: chartHeight }, tableBounds);
|
|
53
|
+
// Draw the table
|
|
54
|
+
this.drawTable(ctx, tableRows, posInfo);
|
|
55
|
+
ctx.restore();
|
|
56
|
+
};
|
|
57
|
+
this.drawTable = (ctx, rows, posInfo) => {
|
|
58
|
+
const { cellFill = "rgba(0, 0, 0, 0.7)", cellBorder = "#555555", textFill = "#ffffff", fontFamily = "-apple-system, system-ui, Roboto, 'Helvetica Neue', Ubuntu, sans-serif", fontSize = 12, fontWeight = "normal", padding = 4, strokeWidth = 1, borderRadius = 0, showBorder = true, layout = "vertical", headers, } = this.props;
|
|
59
|
+
const { x, y } = posInfo;
|
|
60
|
+
ctx.save();
|
|
61
|
+
ctx.translate(x, y);
|
|
62
|
+
if (layout === "horizontal") {
|
|
63
|
+
this.drawHorizontalTable(ctx, rows, {
|
|
64
|
+
cellFill,
|
|
65
|
+
cellBorder,
|
|
66
|
+
textFill,
|
|
67
|
+
fontFamily,
|
|
68
|
+
fontSize,
|
|
69
|
+
fontWeight,
|
|
70
|
+
padding,
|
|
71
|
+
strokeWidth,
|
|
72
|
+
borderRadius,
|
|
73
|
+
showBorder,
|
|
74
|
+
headers,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
this.drawVerticalTable(ctx, rows, {
|
|
79
|
+
cellFill,
|
|
80
|
+
cellBorder,
|
|
81
|
+
textFill,
|
|
82
|
+
fontFamily,
|
|
83
|
+
fontSize,
|
|
84
|
+
fontWeight,
|
|
85
|
+
padding,
|
|
86
|
+
strokeWidth,
|
|
87
|
+
borderRadius,
|
|
88
|
+
showBorder,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
ctx.restore();
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Draw vertical layout (label | value1, value2, ...)
|
|
95
|
+
*/
|
|
96
|
+
this.drawVerticalTable = (ctx, rows, styles) => {
|
|
97
|
+
var _a, _b;
|
|
98
|
+
const { cellFill, cellBorder, textFill, fontFamily, fontSize, fontWeight, padding, strokeWidth, borderRadius, showBorder, } = styles;
|
|
99
|
+
// Calculate row dimensions
|
|
100
|
+
const lineHeight = fontSize + padding * 2;
|
|
101
|
+
let maxLabelWidth = 0;
|
|
102
|
+
let maxValueWidth = 0;
|
|
103
|
+
ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
104
|
+
for (const row of rows) {
|
|
105
|
+
const labelWidth = ctx.measureText(String(row.label)).width;
|
|
106
|
+
maxLabelWidth = Math.max(maxLabelWidth, labelWidth);
|
|
107
|
+
// Handle both single value and multiple values
|
|
108
|
+
const values = row.values || (row.value !== undefined ? [row.value] : []);
|
|
109
|
+
for (const val of values) {
|
|
110
|
+
const valueWidth = ctx.measureText(String(val)).width;
|
|
111
|
+
maxValueWidth = Math.max(maxValueWidth, valueWidth);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const colGap = padding * 2;
|
|
115
|
+
const labelColWidth = maxLabelWidth + padding * 2;
|
|
116
|
+
const valueColWidth = maxValueWidth + padding * 2;
|
|
117
|
+
const tableWidth = labelColWidth + valueColWidth + colGap;
|
|
118
|
+
const totalHeight = lineHeight * rows.length;
|
|
119
|
+
// Draw background
|
|
120
|
+
ctx.fillStyle = cellFill;
|
|
121
|
+
ctx.strokeStyle = cellBorder;
|
|
122
|
+
ctx.lineWidth = strokeWidth;
|
|
123
|
+
if (borderRadius > 0) {
|
|
124
|
+
this.drawRoundRect(ctx, 0, 0, tableWidth, totalHeight, borderRadius);
|
|
125
|
+
ctx.fill();
|
|
126
|
+
if (showBorder) {
|
|
127
|
+
ctx.stroke();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
ctx.fillRect(0, 0, tableWidth, totalHeight);
|
|
132
|
+
if (showBorder) {
|
|
133
|
+
ctx.strokeRect(0, 0, tableWidth, totalHeight);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Draw rows
|
|
137
|
+
ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
138
|
+
for (let i = 0; i < rows.length; i++) {
|
|
139
|
+
const row = rows[i];
|
|
140
|
+
const rowY = i * lineHeight;
|
|
141
|
+
// Draw label cell background
|
|
142
|
+
if (row.labelFill) {
|
|
143
|
+
ctx.fillStyle = row.labelFill;
|
|
144
|
+
ctx.fillRect(0, rowY, labelColWidth, lineHeight);
|
|
145
|
+
}
|
|
146
|
+
// Draw label text
|
|
147
|
+
const labelTextColor = (_a = row.labelTextFill) !== null && _a !== void 0 ? _a : textFill;
|
|
148
|
+
ctx.fillStyle = labelTextColor;
|
|
149
|
+
ctx.textAlign = "left";
|
|
150
|
+
ctx.textBaseline = "middle";
|
|
151
|
+
ctx.fillText(String(row.label), padding, rowY + lineHeight / 2);
|
|
152
|
+
// Draw value cell background
|
|
153
|
+
const valueFills = Array.isArray(row.valueFill) ? row.valueFill : [row.valueFill];
|
|
154
|
+
if (valueFills[0]) {
|
|
155
|
+
ctx.fillStyle = valueFills[0];
|
|
156
|
+
ctx.fillRect(labelColWidth + colGap, rowY, valueColWidth, lineHeight);
|
|
157
|
+
}
|
|
158
|
+
// Draw value text (use first value or the single value)
|
|
159
|
+
const values = row.values || (row.value !== undefined ? [row.value] : []);
|
|
160
|
+
const displayValue = values.length > 0 ? values[0] : "";
|
|
161
|
+
const valueTextColors = Array.isArray(row.valueTextFill) ? row.valueTextFill : [row.valueTextFill];
|
|
162
|
+
const valueTextColor = (_b = valueTextColors[0]) !== null && _b !== void 0 ? _b : textFill;
|
|
163
|
+
ctx.fillStyle = valueTextColor;
|
|
164
|
+
ctx.textAlign = "left";
|
|
165
|
+
ctx.textBaseline = "middle";
|
|
166
|
+
ctx.fillText(String(displayValue), labelColWidth + colGap + padding, rowY + lineHeight / 2);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Draw horizontal layout (headers on top, rows below - no label column)
|
|
171
|
+
*/
|
|
172
|
+
this.drawHorizontalTable = (ctx, rows, styles) => {
|
|
173
|
+
const { cellFill, cellBorder, textFill, fontFamily, fontSize, fontWeight, padding, strokeWidth, borderRadius, showBorder, headers, } = styles;
|
|
174
|
+
const lineHeight = fontSize + padding * 2;
|
|
175
|
+
ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
176
|
+
// Determine number of columns from first row or headers
|
|
177
|
+
let numCols = 0;
|
|
178
|
+
if (headers && headers.length > 0) {
|
|
179
|
+
numCols = headers.length;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
for (const row of rows) {
|
|
183
|
+
const values = row.values || [];
|
|
184
|
+
numCols = Math.max(numCols, values.length);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (numCols === 0) {
|
|
188
|
+
return; // Nothing to draw
|
|
189
|
+
}
|
|
190
|
+
// Helper to extract cell value and styling
|
|
191
|
+
const extractCellData = (cellValue) => {
|
|
192
|
+
if (cellValue === null || cellValue === undefined) {
|
|
193
|
+
return { value: "", fill: undefined, textFill: undefined };
|
|
194
|
+
}
|
|
195
|
+
if (typeof cellValue === "object" && "value" in cellValue) {
|
|
196
|
+
return {
|
|
197
|
+
value: String(cellValue.value),
|
|
198
|
+
fill: cellValue.fill,
|
|
199
|
+
textFill: cellValue.textFill,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
return { value: String(cellValue), fill: undefined, textFill: undefined };
|
|
203
|
+
};
|
|
204
|
+
// Calculate column widths based on headers and values
|
|
205
|
+
const maxColWidths = Array(numCols).fill(0);
|
|
206
|
+
// Measure headers
|
|
207
|
+
const effectiveHeaders = headers || Array.from({ length: numCols }, (_, i) => `Col${i + 1}`);
|
|
208
|
+
for (let colIdx = 0; colIdx < numCols; colIdx++) {
|
|
209
|
+
const headerText = String(effectiveHeaders[colIdx] || "");
|
|
210
|
+
const headerWidth = ctx.measureText(headerText).width;
|
|
211
|
+
maxColWidths[colIdx] = headerWidth;
|
|
212
|
+
}
|
|
213
|
+
// Measure values
|
|
214
|
+
for (const row of rows) {
|
|
215
|
+
const values = row.values || [];
|
|
216
|
+
for (let colIdx = 0; colIdx < numCols; colIdx++) {
|
|
217
|
+
const cellData = extractCellData(values[colIdx]);
|
|
218
|
+
const valueWidth = ctx.measureText(cellData.value).width;
|
|
219
|
+
maxColWidths[colIdx] = Math.max(maxColWidths[colIdx], valueWidth);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const colWidths = maxColWidths.map((w) => w + padding * 2);
|
|
223
|
+
const colGap = padding;
|
|
224
|
+
const tableWidth = colWidths.reduce((sum, w, idx) => sum + w + (idx < colWidths.length - 1 ? colGap : 0), 0);
|
|
225
|
+
const totalHeight = lineHeight * (rows.length + 1); // +1 for header row
|
|
226
|
+
// Draw background
|
|
227
|
+
ctx.fillStyle = cellFill;
|
|
228
|
+
ctx.strokeStyle = cellBorder;
|
|
229
|
+
ctx.lineWidth = strokeWidth;
|
|
230
|
+
if (borderRadius > 0) {
|
|
231
|
+
this.drawRoundRect(ctx, 0, 0, tableWidth, totalHeight, borderRadius);
|
|
232
|
+
ctx.fill();
|
|
233
|
+
if (showBorder) {
|
|
234
|
+
ctx.stroke();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
ctx.fillRect(0, 0, tableWidth, totalHeight);
|
|
239
|
+
if (showBorder) {
|
|
240
|
+
ctx.strokeRect(0, 0, tableWidth, totalHeight);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Draw header row
|
|
244
|
+
ctx.font = `${fontWeight} bold ${fontSize}px ${fontFamily}`;
|
|
245
|
+
ctx.textAlign = "center";
|
|
246
|
+
ctx.textBaseline = "middle";
|
|
247
|
+
ctx.fillStyle = textFill;
|
|
248
|
+
let colX = 0;
|
|
249
|
+
for (let colIdx = 0; colIdx < numCols; colIdx++) {
|
|
250
|
+
const headerText = String(effectiveHeaders[colIdx] || "");
|
|
251
|
+
const colWidth = colWidths[colIdx];
|
|
252
|
+
ctx.fillText(headerText, colX + colWidth / 2, lineHeight / 2);
|
|
253
|
+
colX += colWidth + colGap;
|
|
254
|
+
}
|
|
255
|
+
// Draw data rows
|
|
256
|
+
ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
257
|
+
ctx.textAlign = "center";
|
|
258
|
+
ctx.textBaseline = "middle";
|
|
259
|
+
for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
|
|
260
|
+
const row = rows[rowIdx];
|
|
261
|
+
const rowY = (rowIdx + 1) * lineHeight;
|
|
262
|
+
const values = row.values || [];
|
|
263
|
+
colX = 0;
|
|
264
|
+
for (let colIdx = 0; colIdx < numCols; colIdx++) {
|
|
265
|
+
const colWidth = colWidths[colIdx];
|
|
266
|
+
const cellData = extractCellData(values[colIdx]);
|
|
267
|
+
// Draw cell background
|
|
268
|
+
const cellFillColor = cellData.fill || cellFill;
|
|
269
|
+
ctx.fillStyle = cellFillColor;
|
|
270
|
+
ctx.fillRect(colX, rowY, colWidth, lineHeight);
|
|
271
|
+
// Draw cell border if showBorder
|
|
272
|
+
if (showBorder) {
|
|
273
|
+
ctx.strokeStyle = cellBorder;
|
|
274
|
+
ctx.lineWidth = strokeWidth;
|
|
275
|
+
ctx.strokeRect(colX, rowY, colWidth, lineHeight);
|
|
276
|
+
}
|
|
277
|
+
// Draw cell text
|
|
278
|
+
const cellTextColor = cellData.textFill || textFill;
|
|
279
|
+
ctx.fillStyle = cellTextColor;
|
|
280
|
+
ctx.fillText(cellData.value, colX + colWidth / 2, rowY + lineHeight / 2);
|
|
281
|
+
colX += colWidth + colGap;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
/**
|
|
286
|
+
* Draw a rounded rectangle
|
|
287
|
+
*/
|
|
288
|
+
this.drawRoundRect = (ctx, x, y, width, height, radius) => {
|
|
289
|
+
ctx.beginPath();
|
|
290
|
+
ctx.moveTo(x + radius, y);
|
|
291
|
+
ctx.lineTo(x + width - radius, y);
|
|
292
|
+
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
|
|
293
|
+
ctx.lineTo(x + width, y + height - radius);
|
|
294
|
+
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
|
|
295
|
+
ctx.lineTo(x + radius, y + height);
|
|
296
|
+
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
|
|
297
|
+
ctx.lineTo(x, y + radius);
|
|
298
|
+
ctx.quadraticCurveTo(x, y, x + radius, y);
|
|
299
|
+
ctx.closePath();
|
|
300
|
+
};
|
|
301
|
+
this.state = { updateCount: 0 };
|
|
302
|
+
}
|
|
303
|
+
render() {
|
|
304
|
+
const { selectCanvas } = this.props;
|
|
305
|
+
return (React.createElement(GenericComponent, { canvasToDraw: selectCanvas, canvasDraw: this.drawOnCanvas, drawOn: ["pan", "zoom"] }));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
Table.defaultProps = {
|
|
309
|
+
cellFill: "rgba(0, 0, 0, 0.7)",
|
|
310
|
+
cellBorder: "#555555",
|
|
311
|
+
textFill: "#ffffff",
|
|
312
|
+
fontFamily: "-apple-system, system-ui, Roboto, 'Helvetica Neue', Ubuntu, sans-serif",
|
|
313
|
+
fontSize: 12,
|
|
314
|
+
fontWeight: "normal",
|
|
315
|
+
padding: 4,
|
|
316
|
+
strokeWidth: 1,
|
|
317
|
+
borderRadius: 0,
|
|
318
|
+
showBorder: true,
|
|
319
|
+
layout: "vertical",
|
|
320
|
+
selectCanvas: (canvases) => canvases.bg,
|
|
321
|
+
};
|
|
322
|
+
Table.contextType = ChartCanvasContext;
|
|
323
|
+
//# sourceMappingURL=Table.js.map
|
package/lib/Table.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Table.js","sourceRoot":"","sources":["../src/Table.tsx"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public exports for @tradingaction/table
|
|
3
|
+
*/
|
|
4
|
+
export { Table } from "./Table";
|
|
5
|
+
export type { TableProps } from "./Table";
|
|
6
|
+
export { calculatePositionInfo, calculateTableBounds, clampPositionInfo, HORIZONTAL_POSITIONS, VERTICAL_POSITIONS, ALL_POSITIONS, } from "./positionUtils";
|
|
7
|
+
export type { Position, TableLayout, TableRow, TableCell, CellValue, VisibilityCallback, RowsCallback, CellStyle, PositionInfo, TableBounds, } from "./types";
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public exports for @tradingaction/table
|
|
3
|
+
*/
|
|
4
|
+
export { Table } from "./Table";
|
|
5
|
+
export { calculatePositionInfo, calculateTableBounds, clampPositionInfo, HORIZONTAL_POSITIONS, VERTICAL_POSITIONS, ALL_POSITIONS, } from "./positionUtils";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,OAAO,EACH,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,GAChB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for calculating table positions
|
|
3
|
+
*/
|
|
4
|
+
import { Position, PositionInfo, TableBounds, TableRow } from "./types";
|
|
5
|
+
interface ChartDimensions {
|
|
6
|
+
readonly width: number;
|
|
7
|
+
readonly height: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Calculate position info based on position type and chart dimensions
|
|
11
|
+
*
|
|
12
|
+
* The coordinate system is origin-based (center), so:
|
|
13
|
+
* - Center of chart is (0, 0)
|
|
14
|
+
* - Top edge is at -height/2
|
|
15
|
+
* - Bottom edge is at +height/2
|
|
16
|
+
* - Left edge is at -width/2
|
|
17
|
+
* - Right edge is at +width/2
|
|
18
|
+
*/
|
|
19
|
+
export declare const calculatePositionInfo: (position: Position, chartDims: ChartDimensions, tableBounds: TableBounds) => PositionInfo;
|
|
20
|
+
/**
|
|
21
|
+
* Calculate the bounds (width/height) of a table based on content
|
|
22
|
+
*/
|
|
23
|
+
export declare const calculateTableBounds: (rows: TableRow[], fontSize: number, fontFamily: string, padding: number, ctx?: CanvasRenderingContext2D) => TableBounds;
|
|
24
|
+
/**
|
|
25
|
+
* Clamp position to keep table within visible bounds
|
|
26
|
+
*/
|
|
27
|
+
export declare const clampPositionInfo: (posInfo: PositionInfo, chartDims: ChartDimensions, tableBounds: TableBounds) => PositionInfo;
|
|
28
|
+
/**
|
|
29
|
+
* Horizontal position keys
|
|
30
|
+
*/
|
|
31
|
+
export declare const HORIZONTAL_POSITIONS: readonly ["left", "center", "right"];
|
|
32
|
+
/**
|
|
33
|
+
* Vertical position keys
|
|
34
|
+
*/
|
|
35
|
+
export declare const VERTICAL_POSITIONS: readonly ["top", "middle", "bottom"];
|
|
36
|
+
/**
|
|
37
|
+
* All valid positions
|
|
38
|
+
*/
|
|
39
|
+
export declare const ALL_POSITIONS: Position[];
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for calculating table positions
|
|
3
|
+
*/
|
|
4
|
+
const MARGIN = 10; // Margin from chart edges
|
|
5
|
+
/**
|
|
6
|
+
* Calculate position info based on position type and chart dimensions
|
|
7
|
+
*
|
|
8
|
+
* The coordinate system is origin-based (center), so:
|
|
9
|
+
* - Center of chart is (0, 0)
|
|
10
|
+
* - Top edge is at -height/2
|
|
11
|
+
* - Bottom edge is at +height/2
|
|
12
|
+
* - Left edge is at -width/2
|
|
13
|
+
* - Right edge is at +width/2
|
|
14
|
+
*/
|
|
15
|
+
export const calculatePositionInfo = (position, chartDims, tableBounds) => {
|
|
16
|
+
const { width, height } = chartDims;
|
|
17
|
+
const { width: tableWidth, height: tableHeight } = tableBounds;
|
|
18
|
+
let x;
|
|
19
|
+
let y;
|
|
20
|
+
let textAlign;
|
|
21
|
+
let textBaseline;
|
|
22
|
+
const halfWidth = width / 2;
|
|
23
|
+
const halfHeight = height / 2;
|
|
24
|
+
// Determine X position and text alignment based on horizontal position
|
|
25
|
+
if (position.endsWith("_left")) {
|
|
26
|
+
// Left side: position from left edge with margin
|
|
27
|
+
x = -halfWidth + MARGIN;
|
|
28
|
+
textAlign = "left";
|
|
29
|
+
}
|
|
30
|
+
else if (position.endsWith("_center")) {
|
|
31
|
+
// Center: position at center
|
|
32
|
+
x = -tableWidth / 2;
|
|
33
|
+
textAlign = "center";
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Right side: position from right edge with margin
|
|
37
|
+
x = halfWidth - MARGIN - tableWidth;
|
|
38
|
+
textAlign = "right";
|
|
39
|
+
}
|
|
40
|
+
// Determine Y position and text baseline based on vertical position
|
|
41
|
+
if (position.startsWith("top_")) {
|
|
42
|
+
// Top: position from top edge with margin
|
|
43
|
+
y = -halfHeight + MARGIN;
|
|
44
|
+
textBaseline = "top";
|
|
45
|
+
}
|
|
46
|
+
else if (position.startsWith("middle_")) {
|
|
47
|
+
// Middle: vertically center the table
|
|
48
|
+
y = -tableHeight / 2;
|
|
49
|
+
textBaseline = "middle";
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Bottom: position from bottom edge with margin
|
|
53
|
+
y = halfHeight - MARGIN - tableHeight;
|
|
54
|
+
textBaseline = "bottom";
|
|
55
|
+
}
|
|
56
|
+
return { x, y, textAlign, textBaseline };
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Extract the text value from a cell (handles both primitives and TableCell objects)
|
|
60
|
+
*/
|
|
61
|
+
const extractCellValue = (cell) => {
|
|
62
|
+
if (cell === null || cell === undefined) {
|
|
63
|
+
return "";
|
|
64
|
+
}
|
|
65
|
+
if (typeof cell === "object" && "value" in cell) {
|
|
66
|
+
return String(cell.value);
|
|
67
|
+
}
|
|
68
|
+
return String(cell);
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Calculate the bounds (width/height) of a table based on content
|
|
72
|
+
*/
|
|
73
|
+
export const calculateTableBounds = (rows, fontSize, fontFamily, padding, ctx) => {
|
|
74
|
+
// Estimate widths based on typical character widths
|
|
75
|
+
// This is a reasonable approximation, actual rendering may vary
|
|
76
|
+
let maxLabelWidth = 0;
|
|
77
|
+
let maxValueWidth = 0;
|
|
78
|
+
let maxColumnCount = 1;
|
|
79
|
+
if (ctx) {
|
|
80
|
+
ctx.font = `${fontSize}px ${fontFamily}`;
|
|
81
|
+
for (const row of rows) {
|
|
82
|
+
// Measure label for vertical layout
|
|
83
|
+
if (row.label) {
|
|
84
|
+
const labelWidth = ctx.measureText(String(row.label)).width;
|
|
85
|
+
maxLabelWidth = Math.max(maxLabelWidth, labelWidth);
|
|
86
|
+
}
|
|
87
|
+
// Measure values (handle both single and multiple values)
|
|
88
|
+
const values = row.values || (row.value !== undefined ? [row.value] : []);
|
|
89
|
+
maxColumnCount = Math.max(maxColumnCount, values.length);
|
|
90
|
+
for (const val of values) {
|
|
91
|
+
const cellValue = extractCellValue(val);
|
|
92
|
+
const valueWidth = ctx.measureText(cellValue).width;
|
|
93
|
+
maxValueWidth = Math.max(maxValueWidth, valueWidth);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// Fallback: rough estimate based on character count
|
|
99
|
+
const avgCharWidth = fontSize * 0.6;
|
|
100
|
+
for (const row of rows) {
|
|
101
|
+
if (row.label) {
|
|
102
|
+
const labelWidth = String(row.label).length * avgCharWidth;
|
|
103
|
+
maxLabelWidth = Math.max(maxLabelWidth, labelWidth);
|
|
104
|
+
}
|
|
105
|
+
const values = row.values || (row.value !== undefined ? [row.value] : []);
|
|
106
|
+
maxColumnCount = Math.max(maxColumnCount, values.length);
|
|
107
|
+
for (const val of values) {
|
|
108
|
+
const cellValue = extractCellValue(val);
|
|
109
|
+
const valueWidth = cellValue.length * avgCharWidth;
|
|
110
|
+
maxValueWidth = Math.max(maxValueWidth, valueWidth);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// For vertical layout: label + value in two columns
|
|
115
|
+
// For horizontal layout: each value in its own column
|
|
116
|
+
let width;
|
|
117
|
+
let height;
|
|
118
|
+
const cellGap = padding * 2;
|
|
119
|
+
const cellHeight = fontSize + padding * 2;
|
|
120
|
+
// Check if this is a horizontal layout (no labels, multiple values per row)
|
|
121
|
+
const hasLabels = rows.some((r) => r.label);
|
|
122
|
+
const hasMultipleValues = maxColumnCount > 1 || rows.some((r) => r.values && r.values.length > 1);
|
|
123
|
+
if (!hasLabels && hasMultipleValues) {
|
|
124
|
+
// Horizontal layout: columns for each value
|
|
125
|
+
const colWidth = maxValueWidth + padding * 2;
|
|
126
|
+
width = colWidth * maxColumnCount + cellGap * (maxColumnCount - 1) + padding * 2;
|
|
127
|
+
height = rows.length * cellHeight + cellHeight + padding * 2; // +1 for header row
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
// Vertical layout: label + value columns
|
|
131
|
+
const labelColWidth = maxLabelWidth + padding * 2;
|
|
132
|
+
const valueColWidth = maxValueWidth + padding * 2;
|
|
133
|
+
width = labelColWidth + valueColWidth + cellGap + padding * 2;
|
|
134
|
+
height = rows.length * cellHeight + padding * 2;
|
|
135
|
+
}
|
|
136
|
+
return { width, height };
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Clamp position to keep table within visible bounds
|
|
140
|
+
*/
|
|
141
|
+
export const clampPositionInfo = (posInfo, chartDims, tableBounds) => {
|
|
142
|
+
const { width, height } = chartDims;
|
|
143
|
+
const { width: tableWidth, height: tableHeight } = tableBounds;
|
|
144
|
+
const { x, y, textAlign, textBaseline } = posInfo;
|
|
145
|
+
const halfWidth = width / 2;
|
|
146
|
+
const halfHeight = height / 2;
|
|
147
|
+
// Clamp X to keep table within horizontal bounds
|
|
148
|
+
const minX = -halfWidth;
|
|
149
|
+
const maxX = halfWidth - tableWidth;
|
|
150
|
+
const clampedX = Math.max(minX, Math.min(maxX, x));
|
|
151
|
+
// Clamp Y to keep table within vertical bounds
|
|
152
|
+
const minY = -halfHeight;
|
|
153
|
+
const maxY = halfHeight - tableHeight;
|
|
154
|
+
const clampedY = Math.max(minY, Math.min(maxY, y));
|
|
155
|
+
return { x: clampedX, y: clampedY, textAlign, textBaseline };
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Horizontal position keys
|
|
159
|
+
*/
|
|
160
|
+
export const HORIZONTAL_POSITIONS = ["left", "center", "right"];
|
|
161
|
+
/**
|
|
162
|
+
* Vertical position keys
|
|
163
|
+
*/
|
|
164
|
+
export const VERTICAL_POSITIONS = ["top", "middle", "bottom"];
|
|
165
|
+
/**
|
|
166
|
+
* All valid positions
|
|
167
|
+
*/
|
|
168
|
+
export const ALL_POSITIONS = [
|
|
169
|
+
"top_left",
|
|
170
|
+
"top_center",
|
|
171
|
+
"top_right",
|
|
172
|
+
"middle_left",
|
|
173
|
+
"middle_center",
|
|
174
|
+
"middle_right",
|
|
175
|
+
"bottom_left",
|
|
176
|
+
"bottom_center",
|
|
177
|
+
"bottom_right",
|
|
178
|
+
];
|
|
179
|
+
//# sourceMappingURL=positionUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"positionUtils.js","sourceRoot":"","sources":["../src/positionUtils.ts"],"names":[],"mappings":"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"}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for the Table component
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Positions for the table on the chart (3x3 grid layout)
|
|
6
|
+
*/
|
|
7
|
+
export type Position = "top_left" | "top_center" | "top_right" | "middle_left" | "middle_center" | "middle_right" | "bottom_left" | "bottom_center" | "bottom_right";
|
|
8
|
+
/**
|
|
9
|
+
* Table layout options
|
|
10
|
+
*/
|
|
11
|
+
export type TableLayout = "vertical" | "horizontal";
|
|
12
|
+
/**
|
|
13
|
+
* Cell styling configuration
|
|
14
|
+
*/
|
|
15
|
+
export interface TableCell {
|
|
16
|
+
/** Cell value */
|
|
17
|
+
readonly value: string | number;
|
|
18
|
+
/** Background fill color for the cell */
|
|
19
|
+
readonly fill?: string;
|
|
20
|
+
/** Text color for the cell */
|
|
21
|
+
readonly textFill?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Cell value - can be a primitive or an object with styling
|
|
25
|
+
*/
|
|
26
|
+
export type CellValue = string | number | TableCell;
|
|
27
|
+
/**
|
|
28
|
+
* Represents a single row in the table
|
|
29
|
+
* Supports both single value and multiple values per row
|
|
30
|
+
*/
|
|
31
|
+
export interface TableRow {
|
|
32
|
+
/** Label/key for the row (vertical layout only) */
|
|
33
|
+
readonly label?: string;
|
|
34
|
+
/** Single value for the row (backward compatible, used in vertical layout) */
|
|
35
|
+
readonly value?: string | number;
|
|
36
|
+
/** Multiple values for the row (used in horizontal layout or vertical with multiple columns) */
|
|
37
|
+
readonly values?: CellValue[];
|
|
38
|
+
/** Optional fill color for the label cell */
|
|
39
|
+
readonly labelFill?: string;
|
|
40
|
+
/** Optional text color for the label */
|
|
41
|
+
readonly labelTextFill?: string;
|
|
42
|
+
/** Optional fill color for value cells (single color or array per value) */
|
|
43
|
+
readonly valueFill?: string | string[];
|
|
44
|
+
/** Optional text color for values (single color or array per value) */
|
|
45
|
+
readonly valueTextFill?: string | string[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Callback to determine if table should be visible
|
|
49
|
+
*/
|
|
50
|
+
export type VisibilityCallback = (moreProps: any) => boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Callback to filter/customize rows
|
|
53
|
+
*/
|
|
54
|
+
export type RowsCallback = (moreProps: any) => TableRow[];
|
|
55
|
+
/**
|
|
56
|
+
* Type for cell styling
|
|
57
|
+
*/
|
|
58
|
+
export interface CellStyle {
|
|
59
|
+
readonly fill?: string;
|
|
60
|
+
readonly stroke?: string;
|
|
61
|
+
readonly strokeWidth?: number;
|
|
62
|
+
readonly textFill?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Positioning information calculated for rendering
|
|
66
|
+
*/
|
|
67
|
+
export interface PositionInfo {
|
|
68
|
+
/** X coordinate (relative to origin) */
|
|
69
|
+
readonly x: number;
|
|
70
|
+
/** Y coordinate (relative to origin) */
|
|
71
|
+
readonly y: number;
|
|
72
|
+
/** Horizontal alignment for text */
|
|
73
|
+
readonly textAlign: CanvasTextAlign;
|
|
74
|
+
/** Vertical baseline for text */
|
|
75
|
+
readonly textBaseline: CanvasTextBaseline;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Table bounds
|
|
79
|
+
*/
|
|
80
|
+
export interface TableBounds {
|
|
81
|
+
readonly width: number;
|
|
82
|
+
readonly height: number;
|
|
83
|
+
}
|
package/lib/types.js
ADDED
package/lib/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tradingaction/table",
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Interactive table annotation for react-financial-charts",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"main": "./lib/index.js",
|
|
9
|
+
"typings": "./lib/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"lib"
|
|
12
|
+
],
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"author": "Reactive Markets",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"charts",
|
|
17
|
+
"charting",
|
|
18
|
+
"stockcharts",
|
|
19
|
+
"finance",
|
|
20
|
+
"financial",
|
|
21
|
+
"finance-chart",
|
|
22
|
+
"react",
|
|
23
|
+
"d3",
|
|
24
|
+
"table",
|
|
25
|
+
"chart-overlay"
|
|
26
|
+
],
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/reactivemarkets/react-financial-charts.git"
|
|
31
|
+
},
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/reactivemarkets/react-financial-charts/issues"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "npm run clean && npm run compile",
|
|
37
|
+
"clean": "rimraf lib",
|
|
38
|
+
"compile": "tsc -p tsconfig.json",
|
|
39
|
+
"watch": "tsc -p tsconfig.json --watch --preserveWatchOutput"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@tradingaction/core": "^2.1.2"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"react": "^16.0.0 || ^17.0.0 || ^18.0.0",
|
|
46
|
+
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0"
|
|
47
|
+
},
|
|
48
|
+
"gitHead": "142e4de01c4b5a7acc918ee5b889148ad18e4fe2"
|
|
49
|
+
}
|