solid-recharts 0.2.0 → 0.2.1
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 +5 -3
- package/src/cartesian/Area.tsx +40 -55
- package/src/cartesian/Bar.tsx +66 -58
- package/src/cartesian/BarStack.tsx +5 -2
- package/src/cartesian/Brush.tsx +1 -1
- package/src/cartesian/Funnel.tsx +15 -19
- package/src/cartesian/Line.tsx +34 -51
- package/src/cartesian/LineDrawShape.tsx +8 -6
- package/src/cartesian/ReferenceArea.tsx +25 -35
- package/src/cartesian/ReferenceDot.tsx +24 -34
- package/src/cartesian/ReferenceLine.tsx +25 -34
- package/src/cartesian/Scatter.tsx +25 -37
- package/src/cartesian/XAxis.tsx +54 -67
- package/src/cartesian/YAxis.tsx +53 -66
- package/src/cartesian/ZAxis.tsx +27 -40
- package/src/chart/SunburstChart.tsx +1 -1
- package/src/component/ActivePoints.tsx +0 -9
- package/src/component/Dots.tsx +7 -3
- package/src/context/ErrorBarContext.tsx +15 -24
- package/src/polar/Pie.tsx +36 -48
- package/src/polar/PolarAngleAxis.tsx +41 -50
- package/src/polar/PolarRadiusAxis.tsx +40 -48
- package/src/polar/Radar.tsx +22 -34
- package/src/polar/RadialBar.tsx +21 -39
- package/src/shape/Curve.tsx +1 -1
- package/src/shape/Symbols.tsx +1 -1
- package/src/state/SetLegendPayload.ts +19 -27
- package/src/state/SetTooltipEntrySettings.tsx +9 -26
- package/src/state/cartesianAxisSlice.ts +40 -60
- package/src/state/createCollectionActions.ts +51 -0
- package/src/state/createSelector.ts +97 -0
- package/src/state/externalEventsMiddleware.ts +2 -11
- package/src/state/graphicalItemsSlice.ts +27 -40
- package/src/state/isEventThrottled.ts +12 -0
- package/src/state/keyboardEventsMiddleware.ts +2 -8
- package/src/state/layoutSlice.ts +8 -4
- package/src/state/legendSlice.ts +24 -26
- package/src/state/mouseEventsMiddleware.ts +2 -13
- package/src/state/patched.ts +19 -0
- package/src/state/referenceElementsSlice.ts +40 -31
- package/src/state/registerInStore.ts +68 -0
- package/src/state/selectors/areaSelectors.ts +13 -36
- package/src/state/selectors/arrayEqualityCheck.ts +32 -7
- package/src/state/selectors/axisSelectors.ts +215 -169
- package/src/state/selectors/barSelectors.ts +8 -36
- package/src/state/selectors/combiners/combineConfiguredScale.ts +1 -1
- package/src/state/selectors/combiners/combineRealScaleType.ts +1 -1
- package/src/state/selectors/dataSelectors.ts +35 -16
- package/src/state/selectors/numberDomainEqualityCheck.ts +16 -8
- package/src/state/selectors/selectAxisForGraphicalItem.ts +52 -0
- package/src/state/tooltipSlice.ts +93 -64
- package/src/util/ActiveShapeUtils.tsx +0 -7
- package/src/util/BarUtils.tsx +27 -22
- package/src/util/ChartUtils.ts +69 -25
- package/src/util/propsAreEqual.ts +3 -33
- package/src/util/stacks/stackTypes.ts +1 -1
- package/src/util/types.ts +1 -1
- package/test/cartesian/CartesianAxis.spec.tsx +1 -1
- package/test/cartesian/GraphicalItemClipPath.scale-behavior.spec.tsx +1 -1
- package/test/cartesian/ReferenceLine/getEndPoints.spec.ts +1 -1
- package/test/cartesian/XAxis/XAxis.timescale.spec.tsx +1 -1
- package/test/helper/mockAxes.ts +1 -1
- package/test/shape/Curve.spec.tsx +1 -1
- package/test/state/createCollectionActions.spec.ts +87 -0
- package/test/state/createSelector.spec.ts +158 -0
- package/test/state/registerInStore.spec.tsx +101 -0
- package/test/state/selectors/combiners/combineConfiguredScale.spec.ts +1 -1
- package/test/state/selectors/combiners/combineRealScaleType.spec.ts +1 -1
- package/test/state/selectors/selectorMemoization.spec.tsx +136 -0
- package/test/util/CartesianUtils/CartesianUtils.spec.ts +1 -1
- package/test/util/ChartUtils/ChartUtils.spec.ts +1 -1
- package/test/util/ChartUtils/getCateCoordinateOfLine.spec.ts +14 -0
- package/test/util/ChartUtils/getStackedData.spec.ts +1 -1
- package/test/util/ChartUtils/truncateByDomain.spec.ts +1 -1
- package/test/util/scale/createCategoricalInverse.spec.ts +1 -1
- package/test-results/.last-run.json +4 -0
- package/src/state/reduxDevtoolsJsonStringifyReplacer.ts +0 -15
- package/src/util/axisPropsAreEqual.ts +0 -42
- package/src/util/resolveDefaultProps.tsx +0 -8
- package/src/util/typedDataKey.ts +0 -8
- package/test/state/reduxDevtoolsJsonStringifyReplacer.spec.ts +0 -25
- package/test/util/axisPropsAreEqual.spec.ts +0 -93
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// Regression gate for the memoized selector graph (ADR-0002).
|
|
2
|
+
//
|
|
3
|
+
// This is the direct test of the performance win: the expensive
|
|
4
|
+
// applied-values / displayed-data chain must be SHARED (a repeat call returns
|
|
5
|
+
// the identical reference) and must NOT be invalidated by a tooltip/mousemove
|
|
6
|
+
// interaction (the classic recharts hotspot), while STILL invalidating when the
|
|
7
|
+
// underlying chart data actually changes. Reference identity is the observable
|
|
8
|
+
// proxy for "did the O(series×points) combiner re-run".
|
|
9
|
+
import { describe, expect, it } from "vitest";
|
|
10
|
+
import { flush } from "solid-js";
|
|
11
|
+
import { render } from "@solidjs/testing-library";
|
|
12
|
+
import { Line, LineChart, XAxis } from "../../../src";
|
|
13
|
+
import { useAppStore } from "../../../src/state/hooks";
|
|
14
|
+
import { defaultAxisId } from "../../../src/state/cartesianAxisSlice";
|
|
15
|
+
import {
|
|
16
|
+
selectAllAppliedValues,
|
|
17
|
+
selectAxisDomain,
|
|
18
|
+
selectAxisScale,
|
|
19
|
+
selectCartesianItemsSettings,
|
|
20
|
+
selectDisplayedData,
|
|
21
|
+
selectNumericalDomain,
|
|
22
|
+
selectTicksOfGraphicalItem,
|
|
23
|
+
} from "../../../src/state/selectors/axisSelectors";
|
|
24
|
+
import type { RechartsStore } from "../../../src/state/store";
|
|
25
|
+
|
|
26
|
+
const data = [
|
|
27
|
+
{ name: "a", uv: 10 },
|
|
28
|
+
{ name: "b", uv: 30 },
|
|
29
|
+
{ name: "c", uv: 20 },
|
|
30
|
+
{ name: "d", uv: 40 },
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
function renderChartAndCaptureStore(): RechartsStore {
|
|
34
|
+
let store: RechartsStore | undefined;
|
|
35
|
+
const Capture = (): null => {
|
|
36
|
+
store = useAppStore();
|
|
37
|
+
return null;
|
|
38
|
+
};
|
|
39
|
+
render(() => (
|
|
40
|
+
<LineChart width={200} height={200} data={data}>
|
|
41
|
+
<XAxis dataKey="name" />
|
|
42
|
+
<Line dataKey="uv" isAnimationActive={false} />
|
|
43
|
+
<Capture />
|
|
44
|
+
</LineChart>
|
|
45
|
+
));
|
|
46
|
+
flush();
|
|
47
|
+
flush();
|
|
48
|
+
flush();
|
|
49
|
+
if (store == null) {
|
|
50
|
+
throw new Error("store capture failed");
|
|
51
|
+
}
|
|
52
|
+
return store;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
describe("memoized selector graph", () => {
|
|
56
|
+
it("shares the applied-values chain: a repeat call returns the identical reference", () => {
|
|
57
|
+
const store = renderChartAndCaptureStore();
|
|
58
|
+
const first = selectAllAppliedValues(store.state, "xAxis", defaultAxisId, false);
|
|
59
|
+
const second = selectAllAppliedValues(store.state, "xAxis", defaultAxisId, false);
|
|
60
|
+
expect(second).toBe(first);
|
|
61
|
+
// The intermediate nodes are shared too.
|
|
62
|
+
expect(selectDisplayedData(store.state, "xAxis", defaultAxisId, false)).toBe(
|
|
63
|
+
selectDisplayedData(store.state, "xAxis", defaultAxisId, false),
|
|
64
|
+
);
|
|
65
|
+
expect(selectCartesianItemsSettings(store.state, "xAxis", defaultAxisId)).toBe(
|
|
66
|
+
selectCartesianItemsSettings(store.state, "xAxis", defaultAxisId),
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("does NOT invalidate the data chain on a tooltip/mousemove interaction (the fan-out win)", () => {
|
|
71
|
+
const store = renderChartAndCaptureStore();
|
|
72
|
+
const before = selectAllAppliedValues(store.state, "xAxis", defaultAxisId, false);
|
|
73
|
+
const displayedBefore = selectDisplayedData(store.state, "xAxis", defaultAxisId, false);
|
|
74
|
+
|
|
75
|
+
// Simulate the per-frame mousemove state write.
|
|
76
|
+
store.actions.tooltip.setMouseOverAxisIndex({
|
|
77
|
+
activeIndex: "2",
|
|
78
|
+
activeDataKey: undefined,
|
|
79
|
+
activeCoordinate: { x: 50, y: 50 },
|
|
80
|
+
});
|
|
81
|
+
flush();
|
|
82
|
+
|
|
83
|
+
const after = selectAllAppliedValues(store.state, "xAxis", defaultAxisId, false);
|
|
84
|
+
const displayedAfter = selectDisplayedData(store.state, "xAxis", defaultAxisId, false);
|
|
85
|
+
// The expensive chain is untouched by the interaction — same references,
|
|
86
|
+
// so no combiner re-ran. This is what collapses the ~10× mousemove fan-out.
|
|
87
|
+
expect(after).toBe(before);
|
|
88
|
+
expect(displayedAfter).toBe(displayedBefore);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("keeps the full domain→scale→ticks chain stable across a mousemove", () => {
|
|
92
|
+
const store = renderChartAndCaptureStore();
|
|
93
|
+
const axes = ["xAxis", "yAxis"] as const;
|
|
94
|
+
const before = axes.map((axisType) => ({
|
|
95
|
+
numericalDomain: selectNumericalDomain(store.state, axisType, defaultAxisId, false),
|
|
96
|
+
axisDomain: selectAxisDomain(store.state, axisType, defaultAxisId, false),
|
|
97
|
+
scale: selectAxisScale(store.state, axisType, defaultAxisId, false),
|
|
98
|
+
ticks: selectTicksOfGraphicalItem(store.state, axisType, defaultAxisId, false),
|
|
99
|
+
}));
|
|
100
|
+
|
|
101
|
+
store.actions.tooltip.setMouseOverAxisIndex({
|
|
102
|
+
activeIndex: "1",
|
|
103
|
+
activeDataKey: undefined,
|
|
104
|
+
activeCoordinate: { x: 30, y: 30 },
|
|
105
|
+
});
|
|
106
|
+
flush();
|
|
107
|
+
|
|
108
|
+
axes.forEach((axisType, i) => {
|
|
109
|
+
const prev = before[i]!;
|
|
110
|
+
expect(selectNumericalDomain(store.state, axisType, defaultAxisId, false)).toBe(
|
|
111
|
+
prev.numericalDomain,
|
|
112
|
+
);
|
|
113
|
+
expect(selectAxisDomain(store.state, axisType, defaultAxisId, false)).toBe(prev.axisDomain);
|
|
114
|
+
expect(selectAxisScale(store.state, axisType, defaultAxisId, false)).toBe(prev.scale);
|
|
115
|
+
expect(selectTicksOfGraphicalItem(store.state, axisType, defaultAxisId, false)).toBe(
|
|
116
|
+
prev.ticks,
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("DOES invalidate when the chart data changes (correctness)", () => {
|
|
122
|
+
const store = renderChartAndCaptureStore();
|
|
123
|
+
const before = selectAllAppliedValues(store.state, "xAxis", defaultAxisId, false);
|
|
124
|
+
|
|
125
|
+
store.actions.chartData.setChartData([
|
|
126
|
+
{ name: "a", uv: 11 },
|
|
127
|
+
{ name: "b", uv: 31 },
|
|
128
|
+
{ name: "c", uv: 21 },
|
|
129
|
+
]);
|
|
130
|
+
flush();
|
|
131
|
+
|
|
132
|
+
const after = selectAllAppliedValues(store.state, "xAxis", defaultAxisId, false);
|
|
133
|
+
expect(after).not.toBe(before);
|
|
134
|
+
expect(after.map((v) => v.value)).toEqual(["a", "b", "c"]);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { scaleLinear, scaleBand } from "
|
|
2
|
+
import { scaleLinear, scaleBand } from "d3-scale";
|
|
3
3
|
import { getAngledRectangleWidth, normalizeAngle } from "../../../src/util/CartesianUtils";
|
|
4
4
|
import { rechartsScaleFactory } from "../../../src/util/scale/RechartsScale";
|
|
5
5
|
import { CartesianScaleHelperImpl } from "../../../src/util/scale/CartesianScaleHelper";
|
|
@@ -79,5 +79,19 @@ describe("getCateCoordinateOfLine", () => {
|
|
|
79
79
|
});
|
|
80
80
|
expect(actual).toBe(18);
|
|
81
81
|
});
|
|
82
|
+
|
|
83
|
+
it("should not match NaN tick values and should fall back to the indexed tick", () => {
|
|
84
|
+
const actual = getCateCoordinateOfLine({
|
|
85
|
+
axis: { type: "category", dataKey: "foo", scale: mockScale },
|
|
86
|
+
bandSize: 4,
|
|
87
|
+
entry: { foo: NaN },
|
|
88
|
+
index: 0,
|
|
89
|
+
ticks: [
|
|
90
|
+
{ coordinate: 8, index: 0, value: "fallback" },
|
|
91
|
+
{ coordinate: 16, index: 1, value: NaN },
|
|
92
|
+
],
|
|
93
|
+
});
|
|
94
|
+
expect(actual).toBe(10);
|
|
95
|
+
});
|
|
82
96
|
});
|
|
83
97
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Ported from recharts 3.8.1 test/util/scale/createCategoricalInverse.spec.ts (commit 7a23854).
|
|
2
2
|
import { describe, it, expect } from "vitest";
|
|
3
|
-
import { scaleLinear } from "
|
|
3
|
+
import { scaleLinear } from "d3-scale";
|
|
4
4
|
import { bisect, createCategoricalInverse } from "../../../src/util/scale/createCategoricalInverse";
|
|
5
5
|
import { CustomScaleDefinition } from "../../../src/util/scale/CustomScaleDefinition";
|
|
6
6
|
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// Ported from recharts 3.8.1 src/state/reduxDevtoolsJsonStringifyReplacer.ts
|
|
2
|
-
// Pure util — no framework surface — behavior is byte-identical to recharts.
|
|
3
|
-
|
|
4
|
-
export function reduxDevtoolsJsonStringifyReplacer(key: string, value: unknown) {
|
|
5
|
-
if (value instanceof HTMLElement) {
|
|
6
|
-
return `HTMLElement <${value.tagName} class="${value.className}">`;
|
|
7
|
-
}
|
|
8
|
-
if (value === window) {
|
|
9
|
-
return "global.window";
|
|
10
|
-
}
|
|
11
|
-
if (key === "children" && typeof value === "object" && value !== null) {
|
|
12
|
-
return "<<CHILDREN>>";
|
|
13
|
-
}
|
|
14
|
-
return value;
|
|
15
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
// Ported from recharts 3.8.1 src/util/axisPropsAreEqual.ts (commit 7a23854).
|
|
2
|
-
import { AxisRange } from "../state/selectors/axisSelectors";
|
|
3
|
-
import { AxisDomain } from "./types";
|
|
4
|
-
import { propsAreEqual } from "./propsAreEqual";
|
|
5
|
-
|
|
6
|
-
function shortArraysAreEqual(
|
|
7
|
-
arr1: AxisDomain | AxisRange | undefined,
|
|
8
|
-
arr2: AxisDomain | AxisRange | undefined,
|
|
9
|
-
): boolean {
|
|
10
|
-
if (arr1 === arr2) {
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (Array.isArray(arr1) && arr1.length === 2 && Array.isArray(arr2) && arr2.length === 2) {
|
|
15
|
-
return arr1[0] === arr2[0] && arr1[1] === arr2[1];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function axisPropsAreEqual<
|
|
22
|
-
T extends Record<string, unknown> & {
|
|
23
|
-
domain?: AxisDomain;
|
|
24
|
-
range?: AxisRange;
|
|
25
|
-
},
|
|
26
|
-
>(prevProps: T, nextProps: T): boolean {
|
|
27
|
-
if (prevProps === nextProps) {
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
const { domain: prevDomain, range: prevRange, ...prevRest } = prevProps;
|
|
31
|
-
const { domain: nextDomain, range: nextRange, ...nextRest } = nextProps;
|
|
32
|
-
|
|
33
|
-
if (!shortArraysAreEqual(prevDomain, nextDomain)) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (!shortArraysAreEqual(prevRange, nextRange)) {
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return propsAreEqual(prevRest, nextRest);
|
|
42
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// SKIPPED — intentionally NOT ported to the SolidJS port.
|
|
2
|
-
//
|
|
3
|
-
// Reason: React defaultProps shim — use Solid merge()
|
|
4
|
-
//
|
|
5
|
-
// TODO: do not port this file as-is. The Solid-native port replaces it (see the
|
|
6
|
-
// reason above). If a consumer needs this path, wire it to the Solid equivalent
|
|
7
|
-
// instead.
|
|
8
|
-
export {};
|
package/src/util/typedDataKey.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// SKIPPED — intentionally NOT ported to the SolidJS port.
|
|
2
|
-
//
|
|
3
|
-
// Reason: already inlined as TypedDataKey in util/types.ts
|
|
4
|
-
//
|
|
5
|
-
// TODO: do not port this file as-is. The Solid-native port replaces it (see the
|
|
6
|
-
// reason above). If a consumer needs this path, wire it to the Solid equivalent
|
|
7
|
-
// instead.
|
|
8
|
-
export {};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { reduxDevtoolsJsonStringifyReplacer } from "../../src/state/reduxDevtoolsJsonStringifyReplacer";
|
|
3
|
-
|
|
4
|
-
describe("reduxDevtoolsJsonStringifyReplacer", () => {
|
|
5
|
-
it("should return the original value if the value is not an object", () => {
|
|
6
|
-
expect(reduxDevtoolsJsonStringifyReplacer("", "foo")).toBe("foo");
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
it("should return string if the value is an HTML element", () => {
|
|
10
|
-
const p = document.createElement("p");
|
|
11
|
-
p.classList.add("my-example-class");
|
|
12
|
-
expect(reduxDevtoolsJsonStringifyReplacer("", p)).toBe(
|
|
13
|
-
'HTMLElement <P class="my-example-class">',
|
|
14
|
-
);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it("should return string if the value is a global window object", () => {
|
|
18
|
-
/*
|
|
19
|
-
* Firefox devtools throw exceptions when attempting to deeply serialize window object
|
|
20
|
-
* because some of the properties inside belong to another iframe
|
|
21
|
-
* and that other iframe sometimes has cross-origin access limitations.
|
|
22
|
-
*/
|
|
23
|
-
expect(reduxDevtoolsJsonStringifyReplacer("", window)).toBe("global.window");
|
|
24
|
-
});
|
|
25
|
-
});
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
// Ported from recharts 3.8.1 test/util/axisPropsAreEqual.spec.ts (commit 7a23854).
|
|
2
|
-
// Solid deviation: the comparator is pure, so tests use plain prop records rather
|
|
3
|
-
// than importing React-oriented axis prop types.
|
|
4
|
-
import { describe, expect, it } from "vitest";
|
|
5
|
-
import { axisPropsAreEqual } from "../../src/util/axisPropsAreEqual";
|
|
6
|
-
import { AxisRange } from "../../src/state/selectors/axisSelectors";
|
|
7
|
-
|
|
8
|
-
describe("axisPropsAreEqual", () => {
|
|
9
|
-
it("should return true for identical props", () => {
|
|
10
|
-
const props1 = { xAxisId: 1 };
|
|
11
|
-
const props2 = { xAxisId: 1 };
|
|
12
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(true);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("should return false for different props", () => {
|
|
16
|
-
const props1 = { width: "auto" };
|
|
17
|
-
const props2 = { width: "auto", height: "auto" };
|
|
18
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(false);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it("should return false for different nested props", () => {
|
|
22
|
-
const props1 = { mirror: true, padding: { left: 0 } };
|
|
23
|
-
const props2 = { mirror: true, padding: { left: 10 } };
|
|
24
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(false);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("should return true for same reference nested props", () => {
|
|
28
|
-
const nested = { left: 0 };
|
|
29
|
-
const props1 = { minTickGap: 1, padding: nested };
|
|
30
|
-
const props2 = { minTickGap: 1, padding: nested };
|
|
31
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(true);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it("should return true for same value, different reference, allowlisted nested props", () => {
|
|
35
|
-
const props1 = { axisLine: { x: 10, y: 20 } };
|
|
36
|
-
const props2 = { axisLine: { x: 10, y: 20 } };
|
|
37
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(true);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("should return false for different value, different reference, allowlisted nested props", () => {
|
|
41
|
-
const props1 = { axisLine: { x: 10, y: 20 } };
|
|
42
|
-
const props2 = { axisLine: { x: 10, y: 30 } };
|
|
43
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(false);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("should treat undefined and null as if they were equal", () => {
|
|
47
|
-
const props1: { label: null | undefined } = { label: undefined };
|
|
48
|
-
const props2: { label: null | undefined } = { label: null };
|
|
49
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(true);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("should treat positive and negative zero as equal", () => {
|
|
53
|
-
const props1 = { tickMargin: 0 };
|
|
54
|
-
const props2 = { tickMargin: -0 };
|
|
55
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(true);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it("should treat NaN values as equal", () => {
|
|
59
|
-
const props1 = { angle: NaN };
|
|
60
|
-
const props2 = { angle: NaN };
|
|
61
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(true);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("should treat two equal domain arrays as equal", () => {
|
|
65
|
-
const props1 = { domain: [0, 100] };
|
|
66
|
-
const props2 = { domain: [0, 100] };
|
|
67
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(true);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("should treat two different domain arrays as different", () => {
|
|
71
|
-
const props1 = { domain: [0, 100] };
|
|
72
|
-
const props2 = { domain: [0, 200] };
|
|
73
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(false);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it("should treat two equal range arrays as equal", () => {
|
|
77
|
-
const props1: { range: AxisRange } = { range: [0, 500] };
|
|
78
|
-
const props2: { range: AxisRange } = { range: [0, 500] };
|
|
79
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(true);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it("should treat two different range arrays as different", () => {
|
|
83
|
-
const props1: { range: AxisRange } = { range: [0, 500] };
|
|
84
|
-
const props2: { range: AxisRange } = { range: [0, 600] };
|
|
85
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(false);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it("should treat two same categorical domains as different", () => {
|
|
89
|
-
const props1 = { domain: ["a", "b", "c"] };
|
|
90
|
-
const props2 = { domain: ["a", "b", "c"] };
|
|
91
|
-
expect(axisPropsAreEqual(props1, props2)).toBe(false);
|
|
92
|
-
});
|
|
93
|
-
});
|