@fc-plot/ts-graph 0.22.14 → 0.22.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.
- package/dist/BundleReport.html +2 -2
- package/dist/index.js +1 -1
- package/examples/index.js +8712 -6
- package/package.json +1 -1
- package/src/index.ts +36 -26
- package/src/tooltip.ts +35 -25
- package/src/utils.ts +67 -2
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -30,8 +30,11 @@ import {
|
|
|
30
30
|
XScales,
|
|
31
31
|
YScales,
|
|
32
32
|
} from "./interface";
|
|
33
|
-
import {
|
|
34
|
-
|
|
33
|
+
import {
|
|
34
|
+
getTouchPosition,
|
|
35
|
+
getYkeyValue,
|
|
36
|
+
getNearestPointsByEvent,
|
|
37
|
+
} from "./utils";
|
|
35
38
|
import "../assets/style.less";
|
|
36
39
|
|
|
37
40
|
const eventEmitter = new EventEmitter();
|
|
@@ -54,6 +57,7 @@ export default class TsGraph {
|
|
|
54
57
|
zoom!: Zoom;
|
|
55
58
|
transform!: Transform;
|
|
56
59
|
shapes!: Shapes;
|
|
60
|
+
isMouserover!: boolean;
|
|
57
61
|
constructor(userOptions: Options) {
|
|
58
62
|
const defaultOptions = {
|
|
59
63
|
ratio: window.devicePixelRatio || 1,
|
|
@@ -169,6 +173,7 @@ export default class TsGraph {
|
|
|
169
173
|
init(options: Options) {
|
|
170
174
|
const { chart } = options;
|
|
171
175
|
|
|
176
|
+
this.isMouserover = false;
|
|
172
177
|
this.options = options;
|
|
173
178
|
this.options.notDisplayedSeries = [];
|
|
174
179
|
this.options.chart.containerWidth = chart.width;
|
|
@@ -258,8 +263,10 @@ export default class TsGraph {
|
|
|
258
263
|
return [...this.options.series];
|
|
259
264
|
}
|
|
260
265
|
|
|
261
|
-
showTooltip = (eventPosition: EventPosition) => {
|
|
262
|
-
this.
|
|
266
|
+
showTooltip = (eventPosition: EventPosition, forceTimestamp?: number) => {
|
|
267
|
+
if (!this.isMouserover) {
|
|
268
|
+
this.tooltip.draw(eventPosition, this, forceTimestamp);
|
|
269
|
+
}
|
|
263
270
|
};
|
|
264
271
|
|
|
265
272
|
hideTooltip = () => {
|
|
@@ -276,11 +283,11 @@ export default class TsGraph {
|
|
|
276
283
|
let mousedownPos: EventPosition = {} as EventPosition;
|
|
277
284
|
let mouseupPos: EventPosition = {} as EventPosition;
|
|
278
285
|
let mouseleavePos: EventPosition;
|
|
279
|
-
let isMouserover = false;
|
|
280
286
|
// eslint-disable-next-line no-underscore-dangle
|
|
281
287
|
const _this = this;
|
|
288
|
+
_this.isMouserover = false;
|
|
282
289
|
const handleMouseover = debounce((eventPosition: EventPosition) => {
|
|
283
|
-
if (isMouserover) {
|
|
290
|
+
if (_this.isMouserover) {
|
|
284
291
|
_this.tooltip.draw(eventPosition, _this);
|
|
285
292
|
if (mousedownStatus) {
|
|
286
293
|
_this.zoom.drawMarker(mousedownPos, eventPosition);
|
|
@@ -292,34 +299,37 @@ export default class TsGraph {
|
|
|
292
299
|
}, 5);
|
|
293
300
|
const handleClick = () => {
|
|
294
301
|
if (typeof _this.options.onClick === "function") {
|
|
295
|
-
const {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
const nearestPoints = getNearestPoints({
|
|
302
|
-
x,
|
|
303
|
-
xkey,
|
|
304
|
-
ykey,
|
|
305
|
-
ykey2,
|
|
306
|
-
oykey,
|
|
307
|
-
timestamp,
|
|
308
|
-
series,
|
|
309
|
-
fillNull,
|
|
310
|
-
});
|
|
302
|
+
const { x, y, nearestPoints } = getNearestPointsByEvent(
|
|
303
|
+
d3.event,
|
|
304
|
+
_this.options,
|
|
305
|
+
_this.xScales,
|
|
306
|
+
_this.yScales
|
|
307
|
+
);
|
|
311
308
|
_this.options.onClick(d3.event, x, y, nearestPoints);
|
|
312
309
|
}
|
|
313
310
|
};
|
|
314
311
|
d3.select(this.eventCanvas)
|
|
315
312
|
.on("mousemove", function mousemove(this: HTMLCanvasElement) {
|
|
316
|
-
isMouserover = true;
|
|
313
|
+
_this.isMouserover = true;
|
|
317
314
|
handleMouseover(d3.event);
|
|
318
|
-
if (cascade)
|
|
315
|
+
if (cascade) {
|
|
316
|
+
const { nearestPoints } = getNearestPointsByEvent(
|
|
317
|
+
d3.event,
|
|
318
|
+
_this.options,
|
|
319
|
+
_this.xScales,
|
|
320
|
+
_this.yScales
|
|
321
|
+
);
|
|
322
|
+
let timestamp;
|
|
323
|
+
if (nearestPoints.length) {
|
|
324
|
+
const firstNearestPoint = nearestPoints[0];
|
|
325
|
+
timestamp = firstNearestPoint.timestamp;
|
|
326
|
+
}
|
|
327
|
+
eventEmitter.emit(plotmoveType, d3.event, timestamp);
|
|
328
|
+
}
|
|
319
329
|
})
|
|
320
330
|
.on("mouseleave", function mouseleave(this: HTMLCanvasElement) {
|
|
321
331
|
mouseleavePos = d3.event;
|
|
322
|
-
isMouserover = false;
|
|
332
|
+
_this.isMouserover = false;
|
|
323
333
|
handleMouseLeave();
|
|
324
334
|
if (cascade) eventEmitter.emit(plotleaveType);
|
|
325
335
|
})
|
|
@@ -384,7 +394,7 @@ export default class TsGraph {
|
|
|
384
394
|
}
|
|
385
395
|
})
|
|
386
396
|
.on("touchend", function mouseleave(this: HTMLCanvasElement) {
|
|
387
|
-
isMouserover = false;
|
|
397
|
+
_this.isMouserover = false;
|
|
388
398
|
handleMouseLeave();
|
|
389
399
|
|
|
390
400
|
// 触发 zoom
|
package/src/tooltip.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
import { Options, EventPosition, Point, XScales, YScales } from "./interface";
|
|
10
10
|
import TsGraph from "./index";
|
|
11
11
|
import getNearestPoints from "./getNearestPoints";
|
|
12
|
+
import { getPointsByTime } from "./utils";
|
|
12
13
|
|
|
13
14
|
export default class Tooltip {
|
|
14
15
|
options: Options;
|
|
@@ -67,7 +68,8 @@ export default class Tooltip {
|
|
|
67
68
|
eventPosition: EventPosition,
|
|
68
69
|
xScales: XScales,
|
|
69
70
|
yScales: YScales,
|
|
70
|
-
cbk: (nearestPoints: Point[]) => void
|
|
71
|
+
cbk: (nearestPoints: Point[]) => void,
|
|
72
|
+
forceTimestamp?: number
|
|
71
73
|
) {
|
|
72
74
|
const {
|
|
73
75
|
series = [],
|
|
@@ -80,23 +82,28 @@ export default class Tooltip {
|
|
|
80
82
|
timestamp,
|
|
81
83
|
fillNull,
|
|
82
84
|
} = this.options;
|
|
83
|
-
// const containerRect = this.container.getBoundingClientRect();
|
|
84
85
|
const offsetX = eventPosition.offsetX || eventPosition.layerX;
|
|
85
86
|
const x = xScales.invert(offsetX);
|
|
86
87
|
let nearestPoints: Point[] = [];
|
|
87
88
|
|
|
88
89
|
if (this.isMouserover === false) return;
|
|
90
|
+
let tempNearestPoints: any[] = [];
|
|
91
|
+
if (forceTimestamp) {
|
|
92
|
+
tempNearestPoints = getPointsByTime(forceTimestamp, this.options);
|
|
93
|
+
} else {
|
|
94
|
+
tempNearestPoints = getNearestPoints({
|
|
95
|
+
x,
|
|
96
|
+
xkey,
|
|
97
|
+
ykey,
|
|
98
|
+
ykey2,
|
|
99
|
+
oykey,
|
|
100
|
+
timestamp,
|
|
101
|
+
series,
|
|
102
|
+
fillNull,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
89
105
|
|
|
90
|
-
nearestPoints =
|
|
91
|
-
x,
|
|
92
|
-
xkey,
|
|
93
|
-
ykey,
|
|
94
|
-
ykey2,
|
|
95
|
-
oykey,
|
|
96
|
-
timestamp,
|
|
97
|
-
series,
|
|
98
|
-
fillNull,
|
|
99
|
-
}).map((item: any) => {
|
|
106
|
+
nearestPoints = tempNearestPoints.map((item: any) => {
|
|
100
107
|
return {
|
|
101
108
|
...item,
|
|
102
109
|
x: xScales(item.timestamp),
|
|
@@ -149,22 +156,25 @@ export default class Tooltip {
|
|
|
149
156
|
draw(
|
|
150
157
|
eventPosition: EventPosition,
|
|
151
158
|
instance: TsGraph,
|
|
152
|
-
|
|
159
|
+
forceTimestamp?: number
|
|
153
160
|
) {
|
|
154
161
|
const { xScales, yScales, yAxis } = instance;
|
|
155
162
|
this.isMouserover = true;
|
|
156
|
-
this.getNearestPoints(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
this.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
163
|
+
this.getNearestPoints(
|
|
164
|
+
eventPosition,
|
|
165
|
+
xScales,
|
|
166
|
+
yScales,
|
|
167
|
+
(nearestPoints) => {
|
|
168
|
+
this.clear();
|
|
169
|
+
if (nearestPoints.length) {
|
|
170
|
+
if (nearestPoints[0].x < yAxis.tickMaxWidth) return; // 判断是否在 y 轴上
|
|
171
|
+
this.drawCrosshair(nearestPoints[0].x);
|
|
172
|
+
this.drawSymbol(nearestPoints);
|
|
173
|
+
this.drawModal(nearestPoints, eventPosition);
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
forceTimestamp
|
|
177
|
+
);
|
|
168
178
|
}
|
|
169
179
|
|
|
170
180
|
drawModal(nearestPoints: Point[], eventPosition: EventPosition) {
|
package/src/utils.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import * as d3 from "d3";
|
|
2
|
-
import { max } from "lodash";
|
|
3
|
-
import {
|
|
2
|
+
import { max, pickBy } from "lodash";
|
|
3
|
+
import {
|
|
4
|
+
Timestamp,
|
|
5
|
+
Options,
|
|
6
|
+
XScales,
|
|
7
|
+
YScales,
|
|
8
|
+
NearestPoint,
|
|
9
|
+
} from "./interface";
|
|
10
|
+
import getNearestPoints from "./getNearestPoints";
|
|
4
11
|
|
|
5
12
|
type Point = {
|
|
6
13
|
x: number;
|
|
@@ -119,3 +126,61 @@ export function getYkeyValue(
|
|
|
119
126
|
}
|
|
120
127
|
return val;
|
|
121
128
|
}
|
|
129
|
+
|
|
130
|
+
export function getNearestPointsByEvent(
|
|
131
|
+
event: any,
|
|
132
|
+
options: Options,
|
|
133
|
+
xScales: XScales,
|
|
134
|
+
yScales: YScales
|
|
135
|
+
) {
|
|
136
|
+
const { xkey, ykey, ykey2, oykey, timestamp, series, fillNull } = options;
|
|
137
|
+
const offsetX = event.offsetX || event.layerX;
|
|
138
|
+
const offsetY = event.offsetY || event.layerY;
|
|
139
|
+
const x = xScales.invert(offsetX);
|
|
140
|
+
const y = yScales.invert(offsetY);
|
|
141
|
+
const nearestPoints = getNearestPoints({
|
|
142
|
+
x,
|
|
143
|
+
xkey,
|
|
144
|
+
ykey,
|
|
145
|
+
ykey2,
|
|
146
|
+
oykey,
|
|
147
|
+
timestamp,
|
|
148
|
+
series,
|
|
149
|
+
fillNull,
|
|
150
|
+
});
|
|
151
|
+
return {
|
|
152
|
+
x,
|
|
153
|
+
y,
|
|
154
|
+
nearestPoints,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function getPointsByTime(time: number, options: Options) {
|
|
159
|
+
const { series = [], xkey, ykey, oykey, timestamp } = options;
|
|
160
|
+
const points: NearestPoint[] = [];
|
|
161
|
+
series.forEach((serie, i) => {
|
|
162
|
+
if (serie.visible === false) return;
|
|
163
|
+
const { name, color } = serie;
|
|
164
|
+
const serieWithEffective = pickBy(serie, (_val: string, key: string) => {
|
|
165
|
+
return key !== "data";
|
|
166
|
+
});
|
|
167
|
+
let { data = [] } = serie;
|
|
168
|
+
if (Object.prototype.toString.call(data) !== "[object Array]") return;
|
|
169
|
+
data.forEach((item) => {
|
|
170
|
+
const x = getMsTs(item[xkey], timestamp);
|
|
171
|
+
if (x === time) {
|
|
172
|
+
points.push({
|
|
173
|
+
...item,
|
|
174
|
+
name,
|
|
175
|
+
color,
|
|
176
|
+
timestamp: x,
|
|
177
|
+
value: item[ykey],
|
|
178
|
+
origin: item[oykey],
|
|
179
|
+
serieIndex: i,
|
|
180
|
+
serieOptions: serieWithEffective,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
return points;
|
|
186
|
+
}
|