@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spider-analyzer/timeline",
3
- "version": "5.0.6",
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: PropTypes.instanceOf(moment).isRequired,
213
- end: PropTypes.instanceOf(moment).isRequired,
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 } = prepareVerticalScale();
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: PropTypes.instanceOf(moment).isRequired,
110
- end: PropTypes.instanceOf(moment).isRequired,
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: PropTypes.instanceOf(moment).isRequired,
108
- end: PropTypes.instanceOf(moment).isRequired,
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,
@@ -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: PropTypes.instanceOf(moment).isRequired,
54
- end: PropTypes.instanceOf(moment).isRequired,
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: PropTypes.instanceOf(moment).isRequired,
76
- end: PropTypes.instanceOf(moment).isRequired,
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: PropTypes.instanceOf(moment).isRequired,
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: PropTypes.instanceOf(moment),
73
- max: PropTypes.instanceOf(moment),
72
+ min: momentType,
73
+ max: momentType,
74
74
  origin: PropTypes.shape({
75
75
  x: PropTypes.number.isRequired,
76
76
  y: PropTypes.number.isRequired