@spider-analyzer/timeline 5.0.6 → 5.0.8
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/CHANGELOG.md +22 -0
- package/dist/index.js +39 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +39 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/Cursor.jsx +3 -3
- package/src/TimeLine.tsx +12 -3
- package/src/cursorElements/CursorSelection.jsx +3 -3
- package/src/cursorElements/DragOverlay.jsx +3 -3
- package/src/moment-shim.ts +25 -0
- package/src/timeLineElements/HistoToolTip.jsx +3 -3
- package/src/timeLineElements/Histogram.jsx +3 -3
- package/src/timeLineElements/QualityLine.jsx +2 -2
- package/src/timeLineElements/XAxis.jsx +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spider-analyzer/timeline",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.8",
|
|
4
4
|
"description": "React graphical component to display metric over time with a time selection feature.",
|
|
5
5
|
"author": "Thibaut Raballand <spider.analyzer@gmail.com> (https://spider-analyzer.io)",
|
|
6
6
|
"license": "MIT",
|
package/src/Cursor.jsx
CHANGED
|
@@ -12,7 +12,7 @@ import RightHandle from './cursorElements/RightHandle';
|
|
|
12
12
|
import ZoomIn from './cursorElements/ZoomIn';
|
|
13
13
|
import LeftToolTip from './cursorElements/LeftToolTip';
|
|
14
14
|
import RightToolTip from './cursorElements/RightToolTip';
|
|
15
|
-
import moment from './moment-shim';
|
|
15
|
+
import moment, { momentType } from './moment-shim';
|
|
16
16
|
|
|
17
17
|
export default function Cursor({
|
|
18
18
|
overlayWidth, overlayHeight,
|
|
@@ -209,8 +209,8 @@ Cursor.propTypes = {
|
|
|
209
209
|
overlayHeight: PropTypes.number.isRequired,
|
|
210
210
|
overlayWidth: PropTypes.number.isRequired,
|
|
211
211
|
items: PropTypes.arrayOf(PropTypes.shape({
|
|
212
|
-
start:
|
|
213
|
-
end:
|
|
212
|
+
start: momentType.isRequired,
|
|
213
|
+
end: momentType.isRequired,
|
|
214
214
|
x1: PropTypes.number,
|
|
215
215
|
x2: PropTypes.number,
|
|
216
216
|
metrics: PropTypes.arrayOf(PropTypes.number).isRequired,
|
package/src/TimeLine.tsx
CHANGED
|
@@ -758,15 +758,24 @@ const TimeLineInner = forwardRef<TimeLineHandle, any>(function TimeLine(props, r
|
|
|
758
758
|
const { isActive, domain, histoWidth, margin, start, stop, maxZoom, minZoom,
|
|
759
759
|
maxTimespan, barHovered, tooltipVisible, ticks, dragging } = state;
|
|
760
760
|
|
|
761
|
+
// Memoize the expensive per-render bits so cursor drag (which flips
|
|
762
|
+
// only state.start/state.stop 60x/sec) doesn't rebuild the histogram
|
|
763
|
+
// bar list on every event. Under the Luxon-backed shim, rebuilding
|
|
764
|
+
// ~550 bars costs ~150 ms/render — enough to tank drag framerate.
|
|
765
|
+
const verticalScaleData = useMemo(() => prepareVerticalScale(), [prepareVerticalScale]);
|
|
766
|
+
const items = useMemo(
|
|
767
|
+
() => prepareHistogram({ domain, verticalScale: verticalScaleData.verticalScale }),
|
|
768
|
+
[prepareHistogram, domain, verticalScaleData, histoWidth],
|
|
769
|
+
);
|
|
770
|
+
itemsRef.current = items;
|
|
771
|
+
|
|
761
772
|
const xAxisHeight = xAxisProp.height || xAxisDefault.height;
|
|
762
773
|
const pointZero = { x: 0, y: height - margin.bottom - xAxisHeight };
|
|
763
774
|
const originCursor = { x: 0, y: margin.top - 5 };
|
|
764
775
|
|
|
765
776
|
if (!isFunction(xAxisRef.current)) return null;
|
|
766
777
|
|
|
767
|
-
const { verticalScale, verticalMarks, maxHeight } =
|
|
768
|
-
const items = prepareHistogram({ domain, verticalScale });
|
|
769
|
-
itemsRef.current = items;
|
|
778
|
+
const { verticalScale, verticalMarks, maxHeight } = verticalScaleData;
|
|
770
779
|
|
|
771
780
|
return (
|
|
772
781
|
<svg
|
|
@@ -5,7 +5,7 @@ import {pointer, select} from 'd3-selection';
|
|
|
5
5
|
import {drag} from 'd3-drag';
|
|
6
6
|
|
|
7
7
|
import clsx from 'clsx';
|
|
8
|
-
import moment from '../moment-shim';
|
|
8
|
+
import moment, { momentType } from '../moment-shim';
|
|
9
9
|
import {handleHistoOver, handleHistoOut} from './handleHistoHovering';
|
|
10
10
|
|
|
11
11
|
|
|
@@ -106,8 +106,8 @@ CursorSelection.propTypes = {
|
|
|
106
106
|
|
|
107
107
|
|
|
108
108
|
items: PropTypes.arrayOf(PropTypes.shape({
|
|
109
|
-
start:
|
|
110
|
-
end:
|
|
109
|
+
start: momentType.isRequired,
|
|
110
|
+
end: momentType.isRequired,
|
|
111
111
|
x1: PropTypes.number,
|
|
112
112
|
x2: PropTypes.number,
|
|
113
113
|
metrics: PropTypes.arrayOf(PropTypes.number).isRequired,
|
|
@@ -2,7 +2,7 @@ import React, {forwardRef, useCallback, useEffect, useRef, useState} from 'react
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import {pointer, select} from 'd3-selection';
|
|
4
4
|
import {drag} from 'd3-drag';
|
|
5
|
-
import moment from '../moment-shim';
|
|
5
|
+
import moment, { momentType } from '../moment-shim';
|
|
6
6
|
|
|
7
7
|
import {handleHistoOver, handleHistoOut} from './handleHistoHovering';
|
|
8
8
|
|
|
@@ -104,8 +104,8 @@ DragOverlay.propTypes = {
|
|
|
104
104
|
marginBottom: PropTypes.number,
|
|
105
105
|
|
|
106
106
|
items: PropTypes.arrayOf(PropTypes.shape({
|
|
107
|
-
start:
|
|
108
|
-
end:
|
|
107
|
+
start: momentType.isRequired,
|
|
108
|
+
end: momentType.isRequired,
|
|
109
109
|
x1: PropTypes.number,
|
|
110
110
|
x2: PropTypes.number,
|
|
111
111
|
metrics: PropTypes.arrayOf(PropTypes.number).isRequired,
|
package/src/moment-shim.ts
CHANGED
|
@@ -165,5 +165,30 @@ moment.tz = (x: any, zone: string): MomentLike => {
|
|
|
165
165
|
return new MomentLike(base.setZone(zone));
|
|
166
166
|
};
|
|
167
167
|
|
|
168
|
+
// PropTypes helper — the library's internal .jsx components use
|
|
169
|
+
// `PropTypes.instanceOf(moment)` which doesn't work against the shim
|
|
170
|
+
// (moment is the factory function, not a class). Use this instead:
|
|
171
|
+
// time: momentType
|
|
172
|
+
// time: momentType.isRequired
|
|
173
|
+
function validate(props: Record<string, any>, propName: string, componentName: string): Error | null {
|
|
174
|
+
const v = props[propName];
|
|
175
|
+
if (v == null) return null;
|
|
176
|
+
if (moment.isMoment(v)) return null;
|
|
177
|
+
return new Error(
|
|
178
|
+
`Invalid prop \`${propName}\` supplied to \`${componentName}\`, expected a moment-like object.`,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
const required = (props: Record<string, any>, propName: string, componentName: string): Error | null => {
|
|
182
|
+
const v = props[propName];
|
|
183
|
+
if (v == null) {
|
|
184
|
+
return new Error(
|
|
185
|
+
`The prop \`${propName}\` is marked as required in \`${componentName}\`, but its value is \`${v}\`.`,
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
return validate(props, propName, componentName);
|
|
189
|
+
};
|
|
190
|
+
export const momentType: any = validate;
|
|
191
|
+
momentType.isRequired = required;
|
|
192
|
+
|
|
168
193
|
export default moment;
|
|
169
194
|
export type Moment = MomentLike;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cn } from "../styles";
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
|
-
import moment from '../moment-shim';
|
|
4
|
+
import moment, { momentType } from '../moment-shim';
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
7
|
|
|
@@ -50,8 +50,8 @@ export default function HistoTooltip({metricsDefinition, item, onFormatTimeToolT
|
|
|
50
50
|
HistoTooltip.propTypes = {
|
|
51
51
|
classes: PropTypes.object,
|
|
52
52
|
item: PropTypes.shape({
|
|
53
|
-
start:
|
|
54
|
-
end:
|
|
53
|
+
start: momentType.isRequired,
|
|
54
|
+
end: momentType.isRequired,
|
|
55
55
|
x1: PropTypes.number,
|
|
56
56
|
x2: PropTypes.number,
|
|
57
57
|
metrics: PropTypes.arrayOf(PropTypes.number).isRequired,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cn } from "../styles";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import moment from '../moment-shim';
|
|
3
|
+
import moment, { momentType } from '../moment-shim';
|
|
4
4
|
import { sum as _sum } from '../utils';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import clsx from 'clsx';
|
|
@@ -72,8 +72,8 @@ export default function Histogram({
|
|
|
72
72
|
Histogram.propTypes = {
|
|
73
73
|
classes: PropTypes.object,
|
|
74
74
|
items: PropTypes.arrayOf(PropTypes.shape({
|
|
75
|
-
start:
|
|
76
|
-
end:
|
|
75
|
+
start: momentType.isRequired,
|
|
76
|
+
end: momentType.isRequired,
|
|
77
77
|
x1: PropTypes.number,
|
|
78
78
|
x2: PropTypes.number,
|
|
79
79
|
metrics: PropTypes.arrayOf(PropTypes.number).isRequired,
|
|
@@ -3,7 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import clsx from 'clsx';
|
|
5
5
|
|
|
6
|
-
import moment from '../moment-shim';
|
|
6
|
+
import moment, { momentType } from '../moment-shim';
|
|
7
7
|
import ToolTip from '../ToolTip';
|
|
8
8
|
|
|
9
9
|
const qualityHeight = 3;
|
|
@@ -64,7 +64,7 @@ QualityLine.propTypes = {
|
|
|
64
64
|
xAxis: PropTypes.func.isRequired,
|
|
65
65
|
quality: PropTypes.shape({
|
|
66
66
|
items: PropTypes.arrayOf(PropTypes.shape({
|
|
67
|
-
time:
|
|
67
|
+
time: momentType.isRequired,
|
|
68
68
|
quality: PropTypes.number.isRequired,
|
|
69
69
|
tip: PropTypes.node
|
|
70
70
|
})),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import moment from '../moment-shim';
|
|
2
|
+
import moment, { momentType } from '../moment-shim';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import {timeDay} from 'd3-time';
|
|
5
5
|
import clsx from 'clsx';
|
|
@@ -69,8 +69,8 @@ export default function XAxis({min, max, origin, axisWidth, marks, xAxis, classe
|
|
|
69
69
|
XAxis.propTypes = {
|
|
70
70
|
axisWidth:PropTypes.number.isRequired,
|
|
71
71
|
classes: PropTypes.object,
|
|
72
|
-
min:
|
|
73
|
-
max:
|
|
72
|
+
min: momentType,
|
|
73
|
+
max: momentType,
|
|
74
74
|
origin: PropTypes.shape({
|
|
75
75
|
x: PropTypes.number.isRequired,
|
|
76
76
|
y: PropTypes.number.isRequired
|