@tradingaction/interactive 2.0.13 → 2.0.16

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.
@@ -0,0 +1,352 @@
1
+ import * as React from "react";
2
+ import { ascending as d3Ascending } from "d3-array";
3
+ import { noop, strokeDashTypes } from "@tradingaction/core";
4
+ import { getXValue } from "@tradingaction/core/lib/utils/ChartDataUtil";
5
+ import { isHover, saveNodeType } from "../utils";
6
+ import { ClickableCircle, HoverTextNearMouse, InteractiveRectangle } from "../components";
7
+
8
+ export interface EachRectangleProps {
9
+ readonly topLeftX: any;
10
+ readonly topRightX: any;
11
+ readonly topLeftY: any;
12
+ readonly topRightY: any;
13
+ readonly bottomLeftX: any;
14
+ readonly bottomLeftY: any;
15
+ readonly bottomRightX: any;
16
+ readonly bottomRightY: any;
17
+ readonly index?: number;
18
+ readonly type:
19
+ | "XLINE" // extends from -Infinity to +Infinity
20
+ | "RAY" // extends to +/-Infinity in one direction
21
+ | "LINE"; // extends between the set bounds
22
+ readonly onDrag: (e: React.MouseEvent, index: number | undefined, moreProps: any) => void;
23
+ readonly onEdge1Drag: any; // func
24
+ readonly onEdge2Drag: any; // func
25
+ readonly onDragComplete?: (e: React.MouseEvent, moreProps: any) => void;
26
+ readonly onSelect: (e: React.MouseEvent, interactives: any[], moreProps: any) => void;
27
+ readonly onDoubleClickWhenHover?: (e: React.MouseEvent, moreProps: any, index: any) => void;
28
+ readonly onClickWhenHover?: (e: React.MouseEvent, moreProps: any, index: any) => void;
29
+ readonly onClickOutside?: (e: React.MouseEvent, moreProps: any, index: any) => void;
30
+ readonly onContextMenuWhenHover?: (e: React.MouseEvent, moreProps: any, index: any) => void;
31
+ readonly?: (e: React.MouseEvent, moreProps: any, index: any) => void;
32
+ readonly r: number;
33
+ readonly strokeOpacity: number;
34
+ readonly defaultClassName?: string;
35
+ readonly selected?: boolean;
36
+ readonly strokeStyle: string;
37
+ readonly strokeWidth: number;
38
+ readonly strokeDasharray: strokeDashTypes;
39
+ readonly edgeStrokeWidth: number;
40
+ readonly rectangleFill: string;
41
+ readonly edgeStroke: string;
42
+ readonly edgeInteractiveCursor: string;
43
+ readonly lineInteractiveCursor: string;
44
+ readonly edgeFill: string;
45
+ readonly hoverText: {
46
+ readonly enable: boolean;
47
+ readonly fontFamily: string;
48
+ readonly fontSize: number;
49
+ readonly fill: string;
50
+ readonly text: string;
51
+ readonly selectedText: string;
52
+ readonly bgFill: string;
53
+ readonly bgOpacity: number;
54
+ readonly bgWidth: number | string;
55
+ readonly bgHeight: number | string;
56
+ };
57
+ }
58
+
59
+ interface EachRectangleState {
60
+ anchor?: string;
61
+ hover?: any;
62
+ }
63
+
64
+ export class EachRectangle extends React.Component<EachRectangleProps, EachRectangleState> {
65
+ public static defaultProps = {
66
+ onDrag: noop,
67
+ onEdge1Drag: noop,
68
+ onEdge2Drag: noop,
69
+ onSelect: noop,
70
+ selected: false,
71
+ edgeStroke: "#000000",
72
+ edgeFill: "#FFFFFF",
73
+ edgeStrokeWidth: 2,
74
+ rectangleFill: 'transparent',
75
+ r: 5,
76
+ strokeWidth: 1,
77
+ strokeDasharray: "Solid",
78
+ hoverText: {
79
+ enable: false,
80
+ },
81
+ };
82
+
83
+ // private dragStart: any;//code: drag_disabled_for_now //because it is not working properly, in future if required to drag rectangle, then i will take care of it :-)
84
+ // @ts-ignore
85
+ private isHover: any;
86
+ private saveNodeType: any;
87
+
88
+ public constructor(props: EachRectangleProps) {
89
+ super(props);
90
+
91
+ this.isHover = isHover.bind(this);
92
+ this.saveNodeType = saveNodeType.bind(this);
93
+
94
+ this.state = {
95
+ hover: false,
96
+ };
97
+ }
98
+
99
+ public render() {
100
+ const {
101
+ topLeftX,
102
+ topLeftY,
103
+ topRightX,
104
+ topRightY,
105
+ bottomLeftX,
106
+ bottomLeftY,
107
+ bottomRightX,
108
+ bottomRightY,
109
+ type,
110
+ strokeStyle,
111
+ strokeWidth,
112
+ strokeDasharray,
113
+ r,
114
+ edgeStrokeWidth,
115
+ edgeFill,
116
+ edgeStroke,
117
+ edgeInteractiveCursor,
118
+ rectangleFill,
119
+ lineInteractiveCursor,//may need adjustment in future
120
+ hoverText,
121
+ selected,
122
+ // onDragComplete, //code: drag_disabled_for_now
123
+ } = this.props;
124
+
125
+ const {
126
+ enable: hoverTextEnabled,
127
+ selectedText: hoverTextSelected,
128
+ text: hoverTextUnselected,
129
+ ...restHoverTextProps
130
+ } = hoverText;
131
+
132
+ const { hover, anchor } = this.state;
133
+
134
+ return (
135
+ <g>
136
+ <InteractiveRectangle
137
+ ref={this.saveNodeType("line")}
138
+ selected={selected || hover}
139
+ onHover={this.handleHover}
140
+ onUnHover={this.handleHover}
141
+ topLeftX={topLeftX}
142
+ topLeftY={topLeftY}
143
+ topRightX={topRightX}
144
+ topRightY={topRightY}
145
+ bottomLeftX={bottomLeftX}
146
+ bottomLeftY={bottomLeftY}
147
+ bottomRightX={bottomRightX}
148
+ bottomRightY={bottomRightY}
149
+ type={type}
150
+ strokeStyle={strokeStyle}
151
+ strokeWidth={hover || selected ? strokeWidth + 1 : strokeWidth}
152
+ rectangleFill={rectangleFill}
153
+ strokeDasharray={strokeDasharray}
154
+ interactiveCursorClass={lineInteractiveCursor}
155
+ ////////////////////////////////////////////////////////////////
156
+ // code: drag_disabled_for_now
157
+ // onDragStart={this.handleLineDragStart}
158
+ // onDrag={this.handleLineDrag}
159
+ // onDragComplete={onDragComplete}
160
+ ////////////////////////////////////////////////////////////////
161
+ onDoubleClickWhenHover={this.handleDoubleClickWhenHover}
162
+ onClickWhenHover={this.handleClickWhenHover}
163
+ onClickOutside={this.handleClickOutside}
164
+ onContextMenuWhenHover={this.handleContextMenuWhenHover}
165
+ />
166
+ <ClickableCircle
167
+ ref={this.saveNodeType("edge1")}
168
+ show={selected || hover}
169
+ cx={topLeftX}
170
+ cy={topLeftY}
171
+ r={r}
172
+ fillStyle={edgeFill}
173
+ strokeStyle={anchor === "edge1" ? strokeStyle : edgeStroke}
174
+ strokeWidth={edgeStrokeWidth}
175
+ interactiveCursorClass={edgeInteractiveCursor}
176
+ onDragStart={this.handleEdge1DragStart}
177
+ onDrag={this.handleEdge1Drag}
178
+ onDragComplete={this.handleDragComplete}
179
+ />
180
+ <ClickableCircle
181
+ ref={this.saveNodeType("edge2")}
182
+ show={selected || hover}
183
+ cx={topRightX}
184
+ cy={topRightY}
185
+ r={r}
186
+ fillStyle={edgeFill}
187
+ strokeStyle={anchor === "edge2" ? strokeStyle : edgeStroke}
188
+ strokeWidth={edgeStrokeWidth}
189
+ interactiveCursorClass={edgeInteractiveCursor}
190
+ onDragStart={this.handleEdge2DragStart}
191
+ onDrag={this.handleEdge2Drag}
192
+ onDragComplete={this.handleDragComplete}
193
+ />
194
+ <HoverTextNearMouse
195
+ show={hoverTextEnabled && hover}
196
+ {...restHoverTextProps}
197
+ text={selected ? hoverTextSelected : hoverTextUnselected}
198
+ />
199
+ </g>
200
+ );
201
+ }
202
+
203
+ private readonly handleHover = (_: React.MouseEvent, moreProps: any) => {
204
+ if (this.state.hover !== moreProps.hovering) {
205
+ this.setState({
206
+ hover: moreProps.hovering,
207
+ });
208
+ }
209
+ };
210
+
211
+ private readonly handleEdge2Drag = (e: React.MouseEvent, moreProps: any) => {
212
+ const { index, onDrag, topLeftX, topLeftY } = this.props;
213
+
214
+ const [topRightX, topRightY] = getNewXY(moreProps);
215
+
216
+ onDrag(e, index, {
217
+ topLeftX,
218
+ topLeftY,
219
+ topRightX,
220
+ topRightY,
221
+ });
222
+ };
223
+
224
+ private readonly handleDoubleClickWhenHover = (e: React.MouseEvent, moreProps: any) => {
225
+ if (this.props.onDoubleClickWhenHover) {
226
+ const { index, onDoubleClickWhenHover } = this.props;
227
+ onDoubleClickWhenHover(e, moreProps, index);
228
+ }
229
+ };
230
+ private readonly handleClickWhenHover = (e: React.MouseEvent, moreProps: any) => {
231
+ if (this.props.onClickWhenHover) {
232
+ const { index, onClickWhenHover } = this.props;
233
+ onClickWhenHover(e, moreProps, index);
234
+ }
235
+ };
236
+ private readonly handleClickOutside = (e: React.MouseEvent, moreProps: any) => {
237
+ if (this.props.onClickOutside) {
238
+ const { index, onClickOutside } = this.props;
239
+ onClickOutside(e, moreProps, index);
240
+ }
241
+ };
242
+ private readonly handleContextMenuWhenHover = (e: React.MouseEvent, moreProps: any) => {
243
+ if (this.props.onContextMenuWhenHover) {
244
+ const { index, onContextMenuWhenHover } = this.props;
245
+ onContextMenuWhenHover(e, moreProps, index);
246
+ }
247
+ };
248
+
249
+ private readonly handleEdge1Drag = (e: React.MouseEvent, moreProps: any) => {
250
+ const { index, onDrag, topRightX, topRightY } = this.props;
251
+
252
+ const [topLeftX, topLeftY] = getNewXY(moreProps);
253
+
254
+ onDrag(e, index, {
255
+ topLeftX,
256
+ topLeftY,
257
+ topRightX,
258
+ topRightY,
259
+ });
260
+ };
261
+
262
+ private readonly handleDragComplete = (e: React.MouseEvent, moreProps: any) => {
263
+ this.setState({
264
+ anchor: undefined,
265
+ });
266
+
267
+ const { onDragComplete } = this.props;
268
+ if (onDragComplete === undefined) {
269
+ return;
270
+ }
271
+
272
+ onDragComplete(e, moreProps);
273
+ };
274
+
275
+ private readonly handleEdge2DragStart = () => {
276
+ this.setState({
277
+ anchor: "edge1",
278
+ });
279
+ };
280
+
281
+ private readonly handleEdge1DragStart = () => {
282
+ this.setState({
283
+ anchor: "edge2",
284
+ });
285
+ };
286
+ /////////////////////////////////////////////////////////////////////////////////////
287
+ // //code: drag_disabled_for_now
288
+ // private readonly handleLineDrag = (e: React.MouseEvent, moreProps: any) => {
289
+ // const { index, onDrag } = this.props;
290
+
291
+ // const { topLeftX, topLeftY, topRightX, topRightY } = this.dragStart;
292
+
293
+ // const {
294
+ // xScale,
295
+ // chartConfig: { yScale },
296
+ // xAccessor,
297
+ // fullData,
298
+ // } = moreProps;
299
+ // const { startPos, mouseXY } = moreProps;
300
+
301
+ // const x1 = xScale(topLeftX);
302
+ // const y1 = yScale(topLeftY);
303
+ // const x2 = xScale(topRightX);
304
+ // const y2 = yScale(topRightY);
305
+
306
+ // const dx = startPos[0] - mouseXY[0];
307
+ // const dy = startPos[1] - mouseXY[1];
308
+
309
+ // const newX1Value = getXValue(xScale, xAccessor, [x1 - dx, y1 - dy], fullData);
310
+ // const newY1Value = yScale.invert(y1 - dy);
311
+ // const newX2Value = getXValue(xScale, xAccessor, [x2 - dx, y2 - dy], fullData);
312
+ // const newY2Value = yScale.invert(y2 - dy);
313
+
314
+ // onDrag(e, index, {
315
+ // topLeftX: newX1Value,
316
+ // topLeftY: newY1Value,
317
+ // topRightX: newX2Value,
318
+ // topRightY: newY2Value,
319
+ // });
320
+ // };
321
+
322
+ // private readonly handleLineDragStart = () => {
323
+ // const { topLeftX, topLeftY, topRightX, topRightY } = this.props;
324
+
325
+ // this.dragStart = {
326
+ // topLeftX,
327
+ // topLeftY,
328
+ // topRightX,
329
+ // topRightY,
330
+ // };
331
+ // };
332
+ /////////////////////////////////////////////////////////////////////////////////////
333
+ }
334
+
335
+ export function getNewXY(moreProps: any) {
336
+ const {
337
+ xScale,
338
+ chartConfig: { yScale },
339
+ xAccessor,
340
+ plotData,
341
+ mouseXY,
342
+ } = moreProps;
343
+ const mouseY = mouseXY[1];
344
+
345
+ const x = getXValue(xScale, xAccessor, mouseXY, plotData);
346
+
347
+ const [small, big] = yScale.domain().slice().sort(d3Ascending);
348
+ const y = yScale.invert(mouseY);
349
+ const newY = Math.min(Math.max(y, small), big);
350
+
351
+ return [x, newY];
352
+ }
@@ -5,3 +5,4 @@ export { EachInteractiveYCoordinate } from "./EachInteractiveYCoordinate";
5
5
  export { EachLinearRegressionChannel } from "./EachLinearRegressionChannel";
6
6
  export { EachText } from "./EachText";
7
7
  export { EachTrendLine } from "./EachTrendLine";
8
+ export { EachRectangle } from "./EachRectangle";