shap-svg 0.2.1 → 0.2.2
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/README.md +38 -0
- package/dist/{chunk-ZWO4CN22.js → chunk-4X6PMJYT.js} +91 -35
- package/dist/chunk-4X6PMJYT.js.map +1 -0
- package/dist/index.cjs +92 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -7
- package/dist/index.d.ts +15 -7
- package/dist/index.js +5 -1
- package/dist/{format-wEav_cPe.d.cts → labels-7wofev8M.d.cts} +44 -1
- package/dist/{format-wEav_cPe.d.ts → labels-7wofev8M.d.ts} +44 -1
- package/dist/react.cjs +120 -51
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +29 -5
- package/dist/react.d.ts +29 -5
- package/dist/react.js +35 -18
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-ZWO4CN22.js.map +0 -1
package/dist/react.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { E as Explanation, R as RowSort, V as ValuePrecision } from './
|
|
2
|
+
import { E as Explanation, a as PlotLabels, R as RowSort, V as ValuePrecision } from './labels-7wofev8M.cjs';
|
|
3
3
|
|
|
4
4
|
type ShapBarProps = {
|
|
5
5
|
explanation: Explanation;
|
|
@@ -10,9 +10,15 @@ type ShapBarProps = {
|
|
|
10
10
|
classIndex?: number;
|
|
11
11
|
width?: number;
|
|
12
12
|
rowHeight?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Wording for every piece of text the chart draws; keys not given keep SHAP's.
|
|
15
|
+
* Pass a stable object (a module constant or a memo): a new one each render
|
|
16
|
+
* recomputes the layout each render.
|
|
17
|
+
*/
|
|
18
|
+
labels?: Partial<PlotLabels>;
|
|
13
19
|
onFeatureClick?: (featureIndex: number | null) => void;
|
|
14
20
|
};
|
|
15
|
-
declare function ShapBar({ explanation, maxDisplay, faithfulOtherRow, groupByGenus, classIndex, width, rowHeight, onFeatureClick, }: ShapBarProps): react.JSX.Element;
|
|
21
|
+
declare function ShapBar({ explanation, maxDisplay, faithfulOtherRow, groupByGenus, classIndex, width, rowHeight, labels, onFeatureClick, }: ShapBarProps): react.JSX.Element;
|
|
16
22
|
|
|
17
23
|
type ShapBeeswarmProps = {
|
|
18
24
|
explanation: Explanation;
|
|
@@ -29,9 +35,15 @@ type ShapBeeswarmProps = {
|
|
|
29
35
|
dotRadius?: number;
|
|
30
36
|
/** SHAP's Low–High feature value colour bar, as color_bar=True draws it. */
|
|
31
37
|
colorBar?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Wording for every piece of text the chart draws; keys not given keep SHAP's.
|
|
40
|
+
* Pass a stable object (a module constant or a memo): a new one each render
|
|
41
|
+
* recomputes the layout each render.
|
|
42
|
+
*/
|
|
43
|
+
labels?: Partial<PlotLabels>;
|
|
32
44
|
onFeatureClick?: (featureIndex: number | null) => void;
|
|
33
45
|
};
|
|
34
|
-
declare function ShapBeeswarm({ explanation, maxDisplay, faithfulOtherRow, groupByGenus, rowSort, classIndex, width, rowHeight, seed, dotRadius, colorBar, onFeatureClick, }: ShapBeeswarmProps): react.JSX.Element;
|
|
46
|
+
declare function ShapBeeswarm({ explanation, maxDisplay, faithfulOtherRow, groupByGenus, rowSort, classIndex, width, rowHeight, seed, dotRadius, colorBar, labels, onFeatureClick, }: ShapBeeswarmProps): react.JSX.Element;
|
|
35
47
|
|
|
36
48
|
type ShapHeatmapProps = {
|
|
37
49
|
explanation: Explanation;
|
|
@@ -46,10 +58,16 @@ type ShapHeatmapProps = {
|
|
|
46
58
|
rowHeight?: number;
|
|
47
59
|
/** SHAP's colour bar for the SHAP value range, as _heatmap.py always draws it. */
|
|
48
60
|
colorBar?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Wording for every piece of text the chart draws; keys not given keep SHAP's.
|
|
63
|
+
* Pass a stable object (a module constant or a memo): a new one each render
|
|
64
|
+
* recomputes the layout each render.
|
|
65
|
+
*/
|
|
66
|
+
labels?: Partial<PlotLabels>;
|
|
49
67
|
onFeatureClick?: (featureIndex: number | null) => void;
|
|
50
68
|
onSampleClick?: (sampleId: string) => void;
|
|
51
69
|
};
|
|
52
|
-
declare function ShapHeatmap({ explanation, maxDisplay, faithfulOtherRow, groupByGenus, rowSort, classIndex, width, rowHeight, colorBar, onFeatureClick, onSampleClick, }: ShapHeatmapProps): react.JSX.Element;
|
|
70
|
+
declare function ShapHeatmap({ explanation, maxDisplay, faithfulOtherRow, groupByGenus, rowSort, classIndex, width, rowHeight, colorBar, labels, onFeatureClick, onSampleClick, }: ShapHeatmapProps): react.JSX.Element;
|
|
53
71
|
|
|
54
72
|
type ShapWaterfallProps = {
|
|
55
73
|
explanation: Explanation;
|
|
@@ -63,9 +81,15 @@ type ShapWaterfallProps = {
|
|
|
63
81
|
rowHeight?: number;
|
|
64
82
|
/** Decimal places for the bar labels. Display only — it changes no geometry but the text width. */
|
|
65
83
|
decimals?: ValuePrecision;
|
|
84
|
+
/**
|
|
85
|
+
* Wording for every piece of text the chart draws; keys not given keep SHAP's.
|
|
86
|
+
* Pass a stable object (a module constant or a memo): a new one each render
|
|
87
|
+
* recomputes the layout each render.
|
|
88
|
+
*/
|
|
89
|
+
labels?: Partial<PlotLabels>;
|
|
66
90
|
onFeatureClick?: (featureIndex: number | null) => void;
|
|
67
91
|
};
|
|
68
|
-
declare function ShapWaterfall({ explanation, sampleIndex, maxDisplay, faithfulOtherRow, groupByGenus, classIndex, width, rowHeight, decimals, onFeatureClick, }: ShapWaterfallProps): react.JSX.Element;
|
|
92
|
+
declare function ShapWaterfall({ explanation, sampleIndex, maxDisplay, faithfulOtherRow, groupByGenus, classIndex, width, rowHeight, decimals, labels, onFeatureClick, }: ShapWaterfallProps): react.JSX.Element;
|
|
69
93
|
|
|
70
94
|
/**
|
|
71
95
|
* The four charts, named the way shap names them in Python: `shap.plots.bar`
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { E as Explanation, R as RowSort, V as ValuePrecision } from './
|
|
2
|
+
import { E as Explanation, a as PlotLabels, R as RowSort, V as ValuePrecision } from './labels-7wofev8M.js';
|
|
3
3
|
|
|
4
4
|
type ShapBarProps = {
|
|
5
5
|
explanation: Explanation;
|
|
@@ -10,9 +10,15 @@ type ShapBarProps = {
|
|
|
10
10
|
classIndex?: number;
|
|
11
11
|
width?: number;
|
|
12
12
|
rowHeight?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Wording for every piece of text the chart draws; keys not given keep SHAP's.
|
|
15
|
+
* Pass a stable object (a module constant or a memo): a new one each render
|
|
16
|
+
* recomputes the layout each render.
|
|
17
|
+
*/
|
|
18
|
+
labels?: Partial<PlotLabels>;
|
|
13
19
|
onFeatureClick?: (featureIndex: number | null) => void;
|
|
14
20
|
};
|
|
15
|
-
declare function ShapBar({ explanation, maxDisplay, faithfulOtherRow, groupByGenus, classIndex, width, rowHeight, onFeatureClick, }: ShapBarProps): react.JSX.Element;
|
|
21
|
+
declare function ShapBar({ explanation, maxDisplay, faithfulOtherRow, groupByGenus, classIndex, width, rowHeight, labels, onFeatureClick, }: ShapBarProps): react.JSX.Element;
|
|
16
22
|
|
|
17
23
|
type ShapBeeswarmProps = {
|
|
18
24
|
explanation: Explanation;
|
|
@@ -29,9 +35,15 @@ type ShapBeeswarmProps = {
|
|
|
29
35
|
dotRadius?: number;
|
|
30
36
|
/** SHAP's Low–High feature value colour bar, as color_bar=True draws it. */
|
|
31
37
|
colorBar?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Wording for every piece of text the chart draws; keys not given keep SHAP's.
|
|
40
|
+
* Pass a stable object (a module constant or a memo): a new one each render
|
|
41
|
+
* recomputes the layout each render.
|
|
42
|
+
*/
|
|
43
|
+
labels?: Partial<PlotLabels>;
|
|
32
44
|
onFeatureClick?: (featureIndex: number | null) => void;
|
|
33
45
|
};
|
|
34
|
-
declare function ShapBeeswarm({ explanation, maxDisplay, faithfulOtherRow, groupByGenus, rowSort, classIndex, width, rowHeight, seed, dotRadius, colorBar, onFeatureClick, }: ShapBeeswarmProps): react.JSX.Element;
|
|
46
|
+
declare function ShapBeeswarm({ explanation, maxDisplay, faithfulOtherRow, groupByGenus, rowSort, classIndex, width, rowHeight, seed, dotRadius, colorBar, labels, onFeatureClick, }: ShapBeeswarmProps): react.JSX.Element;
|
|
35
47
|
|
|
36
48
|
type ShapHeatmapProps = {
|
|
37
49
|
explanation: Explanation;
|
|
@@ -46,10 +58,16 @@ type ShapHeatmapProps = {
|
|
|
46
58
|
rowHeight?: number;
|
|
47
59
|
/** SHAP's colour bar for the SHAP value range, as _heatmap.py always draws it. */
|
|
48
60
|
colorBar?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Wording for every piece of text the chart draws; keys not given keep SHAP's.
|
|
63
|
+
* Pass a stable object (a module constant or a memo): a new one each render
|
|
64
|
+
* recomputes the layout each render.
|
|
65
|
+
*/
|
|
66
|
+
labels?: Partial<PlotLabels>;
|
|
49
67
|
onFeatureClick?: (featureIndex: number | null) => void;
|
|
50
68
|
onSampleClick?: (sampleId: string) => void;
|
|
51
69
|
};
|
|
52
|
-
declare function ShapHeatmap({ explanation, maxDisplay, faithfulOtherRow, groupByGenus, rowSort, classIndex, width, rowHeight, colorBar, onFeatureClick, onSampleClick, }: ShapHeatmapProps): react.JSX.Element;
|
|
70
|
+
declare function ShapHeatmap({ explanation, maxDisplay, faithfulOtherRow, groupByGenus, rowSort, classIndex, width, rowHeight, colorBar, labels, onFeatureClick, onSampleClick, }: ShapHeatmapProps): react.JSX.Element;
|
|
53
71
|
|
|
54
72
|
type ShapWaterfallProps = {
|
|
55
73
|
explanation: Explanation;
|
|
@@ -63,9 +81,15 @@ type ShapWaterfallProps = {
|
|
|
63
81
|
rowHeight?: number;
|
|
64
82
|
/** Decimal places for the bar labels. Display only — it changes no geometry but the text width. */
|
|
65
83
|
decimals?: ValuePrecision;
|
|
84
|
+
/**
|
|
85
|
+
* Wording for every piece of text the chart draws; keys not given keep SHAP's.
|
|
86
|
+
* Pass a stable object (a module constant or a memo): a new one each render
|
|
87
|
+
* recomputes the layout each render.
|
|
88
|
+
*/
|
|
89
|
+
labels?: Partial<PlotLabels>;
|
|
66
90
|
onFeatureClick?: (featureIndex: number | null) => void;
|
|
67
91
|
};
|
|
68
|
-
declare function ShapWaterfall({ explanation, sampleIndex, maxDisplay, faithfulOtherRow, groupByGenus, classIndex, width, rowHeight, decimals, onFeatureClick, }: ShapWaterfallProps): react.JSX.Element;
|
|
92
|
+
declare function ShapWaterfall({ explanation, sampleIndex, maxDisplay, faithfulOtherRow, groupByGenus, classIndex, width, rowHeight, decimals, labels, onFeatureClick, }: ShapWaterfallProps): react.JSX.Element;
|
|
69
93
|
|
|
70
94
|
/**
|
|
71
95
|
* The four charts, named the way shap names them in Python: `shap.plots.bar`
|
package/dist/react.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
beeswarmLayout,
|
|
8
8
|
beeswarmRows,
|
|
9
9
|
collapseToDisplay,
|
|
10
|
+
formatLevel,
|
|
10
11
|
formatShapValue,
|
|
11
12
|
globalImportance,
|
|
12
13
|
groupExplanationByGenus,
|
|
@@ -14,9 +15,10 @@ import {
|
|
|
14
15
|
heatmapRows,
|
|
15
16
|
orderFeatures,
|
|
16
17
|
parseExplanation,
|
|
18
|
+
resolveLabels,
|
|
17
19
|
waterfallLayout,
|
|
18
20
|
waterfallRows
|
|
19
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-4X6PMJYT.js";
|
|
20
22
|
|
|
21
23
|
// src/react/ShapBar.tsx
|
|
22
24
|
import { useMemo, useState } from "react";
|
|
@@ -90,9 +92,11 @@ function ShapBar({
|
|
|
90
92
|
classIndex = 1,
|
|
91
93
|
width = 720,
|
|
92
94
|
rowHeight = 26,
|
|
95
|
+
labels,
|
|
93
96
|
onFeatureClick
|
|
94
97
|
}) {
|
|
95
98
|
const [hovered, setHovered] = useState(null);
|
|
99
|
+
const words = useMemo(() => resolveLabels(labels), [labels]);
|
|
96
100
|
const layout = useMemo(() => {
|
|
97
101
|
const raw = parseExplanation(explanation, { classIndex });
|
|
98
102
|
const parsed = groupByGenus ? groupExplanationByGenus(raw) : raw;
|
|
@@ -103,23 +107,25 @@ function ShapBar({
|
|
|
103
107
|
importance,
|
|
104
108
|
order,
|
|
105
109
|
maxDisplay,
|
|
106
|
-
faithfulOtherRow
|
|
110
|
+
faithfulOtherRow,
|
|
111
|
+
words
|
|
107
112
|
);
|
|
108
113
|
return barLayout(rows, {
|
|
109
114
|
width,
|
|
110
115
|
rowHeight,
|
|
111
116
|
marginLeft: 260,
|
|
112
117
|
marginRight: 90,
|
|
113
|
-
marginTop: 8
|
|
118
|
+
marginTop: 8,
|
|
119
|
+
labels: words
|
|
114
120
|
});
|
|
115
|
-
}, [groupByGenus, explanation, maxDisplay, faithfulOtherRow, classIndex, width, rowHeight]);
|
|
121
|
+
}, [groupByGenus, explanation, maxDisplay, faithfulOtherRow, classIndex, width, rowHeight, words]);
|
|
116
122
|
return /* @__PURE__ */ jsxs2(
|
|
117
123
|
"svg",
|
|
118
124
|
{
|
|
119
125
|
width,
|
|
120
126
|
height: layout.height,
|
|
121
127
|
role: "img",
|
|
122
|
-
"aria-label":
|
|
128
|
+
"aria-label": `Mean absolute ${words.shapValue} per feature`,
|
|
123
129
|
children: [
|
|
124
130
|
/* @__PURE__ */ jsx2(
|
|
125
131
|
"line",
|
|
@@ -274,14 +280,16 @@ function ShapBeeswarm({
|
|
|
274
280
|
seed = 0,
|
|
275
281
|
dotRadius = 3,
|
|
276
282
|
colorBar = true,
|
|
283
|
+
labels,
|
|
277
284
|
onFeatureClick
|
|
278
285
|
}) {
|
|
279
286
|
const [hovered, setHovered] = useState2(null);
|
|
287
|
+
const words = useMemo2(() => resolveLabels(labels), [labels]);
|
|
280
288
|
const marginTop = 8;
|
|
281
289
|
const layout = useMemo2(() => {
|
|
282
290
|
const raw = parseExplanation(explanation, { classIndex });
|
|
283
291
|
const parsed = groupByGenus ? groupExplanationByGenus(raw) : raw;
|
|
284
|
-
const rows = beeswarmRows(parsed, maxDisplay, faithfulOtherRow, seed, rowSort);
|
|
292
|
+
const rows = beeswarmRows(parsed, maxDisplay, faithfulOtherRow, seed, rowSort, words);
|
|
285
293
|
return beeswarmLayout(rows, {
|
|
286
294
|
width,
|
|
287
295
|
rowHeight,
|
|
@@ -289,12 +297,14 @@ function ShapBeeswarm({
|
|
|
289
297
|
marginRight: 90,
|
|
290
298
|
marginTop,
|
|
291
299
|
dotRadius,
|
|
292
|
-
colorBar
|
|
300
|
+
colorBar,
|
|
301
|
+
labels: words
|
|
293
302
|
});
|
|
294
303
|
}, [
|
|
295
304
|
groupByGenus,
|
|
296
305
|
rowSort,
|
|
297
306
|
colorBar,
|
|
307
|
+
words,
|
|
298
308
|
explanation,
|
|
299
309
|
maxDisplay,
|
|
300
310
|
faithfulOtherRow,
|
|
@@ -393,8 +403,8 @@ function ShapBeeswarm({
|
|
|
393
403
|
children: [
|
|
394
404
|
/* @__PURE__ */ jsx4("rect", { x: 0, y: -16, width: 210, height: 54, rx: 3, fill: "#ffffff", stroke: "#cccccc" }),
|
|
395
405
|
/* @__PURE__ */ jsx4("text", { x: 7, y: 0, fontSize: 11, fill: "#222222", children: activeRow.label }),
|
|
396
|
-
/* @__PURE__ */ jsx4("text", { x: 7, y: 15, fontSize: 11, fill: "#222222", children:
|
|
397
|
-
/* @__PURE__ */ jsx4("text", { x: 7, y: 30, fontSize: 11, fill: "#222222", children:
|
|
406
|
+
/* @__PURE__ */ jsx4("text", { x: 7, y: 15, fontSize: 11, fill: "#222222", children: `${words.shapValue}: ${formatShapValue(activePoint.valueX)}` }),
|
|
407
|
+
/* @__PURE__ */ jsx4("text", { x: 7, y: 30, fontSize: 11, fill: "#222222", children: `${words.featureValue}: ${Number.isFinite(activePoint.featureValue) ? formatLevel(activePoint.featureValue) : words.missingFeatureValue}` })
|
|
398
408
|
]
|
|
399
409
|
}
|
|
400
410
|
)
|
|
@@ -414,27 +424,30 @@ function ShapHeatmap({
|
|
|
414
424
|
width = 720,
|
|
415
425
|
rowHeight = 26,
|
|
416
426
|
colorBar = true,
|
|
427
|
+
labels,
|
|
417
428
|
onFeatureClick,
|
|
418
429
|
onSampleClick
|
|
419
430
|
}) {
|
|
420
431
|
const [hoveredColumn, setHoveredColumn] = useState3(null);
|
|
432
|
+
const words = useMemo3(() => resolveLabels(labels), [labels]);
|
|
421
433
|
const marginTop = 72;
|
|
422
434
|
const layout = useMemo3(() => {
|
|
423
435
|
const raw = parseExplanation(explanation, { classIndex });
|
|
424
436
|
const parsed = groupByGenus ? groupExplanationByGenus(raw) : raw;
|
|
425
|
-
const rows = heatmapRows(parsed, maxDisplay, faithfulOtherRow, rowSort);
|
|
437
|
+
const rows = heatmapRows(parsed, maxDisplay, faithfulOtherRow, rowSort, words);
|
|
426
438
|
return heatmapLayout(rows, {
|
|
427
439
|
width,
|
|
428
440
|
rowHeight,
|
|
429
441
|
marginLeft: 260,
|
|
430
442
|
marginRight: 100,
|
|
431
443
|
marginTop,
|
|
432
|
-
colorBar
|
|
444
|
+
colorBar,
|
|
445
|
+
labels: words
|
|
433
446
|
});
|
|
434
|
-
}, [groupByGenus, rowSort, colorBar, explanation, maxDisplay, faithfulOtherRow, classIndex, width, rowHeight]);
|
|
447
|
+
}, [groupByGenus, rowSort, colorBar, words, explanation, maxDisplay, faithfulOtherRow, classIndex, width, rowHeight]);
|
|
435
448
|
const activeColumn = hoveredColumn === null ? void 0 : layout.columns[hoveredColumn];
|
|
436
449
|
const nameOf = (column) => {
|
|
437
|
-
if (!column.sampleLabel) return
|
|
450
|
+
if (!column.sampleLabel) return words.sampleFallback(column.sampleIndex + 1);
|
|
438
451
|
return layout.sampleLabelColumn ? `${layout.sampleLabelColumn}: ${column.sampleLabel}` : column.sampleLabel;
|
|
439
452
|
};
|
|
440
453
|
const tooltipWidth = activeColumn ? Math.max(190, nameOf(activeColumn).length * 6.5 + 16) : 190;
|
|
@@ -587,7 +600,7 @@ function ShapHeatmap({
|
|
|
587
600
|
width: column.width,
|
|
588
601
|
height: layout.plotBottom - 8,
|
|
589
602
|
fill: "transparent",
|
|
590
|
-
"aria-label": `${nameOf(column)}, total
|
|
603
|
+
"aria-label": `${nameOf(column)}, total ${words.shapValue} ${formatShapValue(column.total)}`,
|
|
591
604
|
onMouseEnter: () => setHoveredColumn(columnIndex),
|
|
592
605
|
onMouseLeave: () => setHoveredColumn(null),
|
|
593
606
|
onClick: () => {
|
|
@@ -600,7 +613,7 @@ function ShapHeatmap({
|
|
|
600
613
|
activeColumn && /* @__PURE__ */ jsxs5("g", { pointerEvents: "none", transform: `translate(${tooltipX} 10)`, children: [
|
|
601
614
|
/* @__PURE__ */ jsx5("rect", { x: 0, y: 0, width: tooltipWidth, height: 42, rx: 3, fill: "#ffffff", stroke: "#cccccc" }),
|
|
602
615
|
/* @__PURE__ */ jsx5("text", { x: 7, y: 15, fontSize: 11, fill: "#222222", children: nameOf(activeColumn) }),
|
|
603
|
-
/* @__PURE__ */ jsx5("text", { x: 7, y: 31, fontSize: 11, fill: "#222222", children:
|
|
616
|
+
/* @__PURE__ */ jsx5("text", { x: 7, y: 31, fontSize: 11, fill: "#222222", children: `${words.sampleTotal}: ${formatShapValue(activeColumn.total)}` })
|
|
604
617
|
] })
|
|
605
618
|
] });
|
|
606
619
|
}
|
|
@@ -618,21 +631,24 @@ function ShapWaterfall({
|
|
|
618
631
|
width = 720,
|
|
619
632
|
rowHeight = 30,
|
|
620
633
|
decimals = 2,
|
|
634
|
+
labels,
|
|
621
635
|
onFeatureClick
|
|
622
636
|
}) {
|
|
623
637
|
const [hovered, setHovered] = useState4(null);
|
|
638
|
+
const words = useMemo4(() => resolveLabels(labels), [labels]);
|
|
624
639
|
const marginTop = 34;
|
|
625
640
|
const layout = useMemo4(() => {
|
|
626
641
|
const raw = parseExplanation(explanation, { classIndex });
|
|
627
642
|
const parsed = groupByGenus ? groupExplanationByGenus(raw) : raw;
|
|
628
|
-
const rows = waterfallRows(parsed, sampleIndex, maxDisplay, faithfulOtherRow);
|
|
643
|
+
const rows = waterfallRows(parsed, sampleIndex, maxDisplay, faithfulOtherRow, words);
|
|
629
644
|
return waterfallLayout(rows, {
|
|
630
645
|
width,
|
|
631
646
|
rowHeight,
|
|
632
647
|
marginLeft: 260,
|
|
633
648
|
marginRight: 110,
|
|
634
649
|
marginTop,
|
|
635
|
-
decimals
|
|
650
|
+
decimals,
|
|
651
|
+
labels: words
|
|
636
652
|
});
|
|
637
653
|
}, [
|
|
638
654
|
groupByGenus,
|
|
@@ -643,7 +659,8 @@ function ShapWaterfall({
|
|
|
643
659
|
classIndex,
|
|
644
660
|
width,
|
|
645
661
|
rowHeight,
|
|
646
|
-
decimals
|
|
662
|
+
decimals,
|
|
663
|
+
words
|
|
647
664
|
]);
|
|
648
665
|
return /* @__PURE__ */ jsxs6(
|
|
649
666
|
"svg",
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/ShapBar.tsx","../src/react/XAxis.tsx","../src/react/ShapBeeswarm.tsx","../src/react/ColorBar.tsx","../src/react/ShapHeatmap.tsx","../src/react/ShapWaterfall.tsx","../react.ts"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { Explanation } from \"../core/types\";\nimport { parseExplanation } from \"../core/parse\";\nimport { groupExplanationByGenus } from \"../core/taxonomy\";\nimport { globalImportance, orderFeatures } from \"../core/order\";\nimport { collapseToDisplay } from \"../core/collapse\";\nimport { barLayout } from \"../core/barLayout\";\nimport { formatShapValue } from \"../core/format\";\nimport { XAxis } from \"./XAxis\";\n\nexport type ShapBarProps = {\n explanation: Explanation;\n maxDisplay?: number;\n faithfulOtherRow?: boolean;\n /** Collapse `Genus_species` Features into their genus before drawing. */\n groupByGenus?: boolean;\n classIndex?: number;\n width?: number;\n rowHeight?: number;\n onFeatureClick?: (featureIndex: number | null) => void;\n};\n\nexport function ShapBar({\n explanation,\n maxDisplay = 10,\n faithfulOtherRow = false,\n groupByGenus = false,\n classIndex = 1,\n width = 720,\n rowHeight = 26,\n onFeatureClick,\n}: ShapBarProps) {\n const [hovered, setHovered] = useState<number | null>(null);\n\n const layout = useMemo(() => {\n const raw = parseExplanation(explanation, { classIndex });\n const parsed = groupByGenus ? groupExplanationByGenus(raw) : raw;\n const importance = globalImportance(parsed);\n const order = orderFeatures(importance);\n const rows = collapseToDisplay(\n parsed.featureNames, importance, order, maxDisplay, faithfulOtherRow,\n );\n return barLayout(rows, {\n width, rowHeight, marginLeft: 260, marginRight: 90, marginTop: 8,\n });\n }, [groupByGenus, explanation, maxDisplay, faithfulOtherRow, classIndex, width, rowHeight]);\n\n return (\n <svg width={width} height={layout.height} role=\"img\"\n aria-label=\"Mean absolute SHAP value per feature\">\n <line x1={layout.zeroLine.x} x2={layout.zeroLine.x}\n y1={layout.zeroLine.y1} y2={layout.zeroLine.y2}\n stroke=\"#333333\" strokeWidth={1} />\n <XAxis ticks={layout.xTicks} spine={layout.xSpine} title={layout.xTitle}\n plotBottom={layout.plotBottom} tickFontSize={11} />\n {layout.bars.map((bar, i) => (\n <g key={`row-${i}`}\n onMouseEnter={() => setHovered(i)}\n onMouseLeave={() => setHovered(null)}\n onClick={() => onFeatureClick?.(bar.featureIndex)}\n style={{ cursor: onFeatureClick ? \"pointer\" : \"default\" }}>\n <rect x={0} y={bar.y - (rowHeight - bar.height) / 2}\n width={width} height={rowHeight}\n fill={hovered === i ? \"#00000008\" : \"transparent\"} />\n <text x={250} y={bar.centerY} textAnchor=\"end\" dominantBaseline=\"middle\"\n fontSize={13} fill=\"#333333\"\n fontStyle={bar.isOtherRow ? \"normal\" : \"italic\"}>\n {bar.label}\n </text>\n <rect x={bar.x} y={bar.y} width={bar.width} height={bar.height}\n fill={bar.color} stroke=\"rgba(255,255,255,0.8)\" strokeWidth={1} />\n <text x={bar.x + bar.width + 6} y={bar.centerY} dominantBaseline=\"middle\"\n fontSize={12} fill={bar.color}>\n {formatShapValue(bar.value)}\n </text>\n </g>\n ))}\n </svg>\n );\n}\n","import {\n AxisSpine,\n AxisTick,\n AxisTitle,\n TICK_LABEL_DY,\n TICK_LENGTH,\n} from \"../core/ticks\";\n\n/**\n * The bottom axis the summary charts share: optional spine, outward ticks with\n * labels, and a centred title. The layouts decide every position; this only\n * draws them, so the three charts cannot drift apart in how an axis looks.\n */\nexport function XAxis({\n ticks,\n spine,\n title,\n plotBottom,\n tickFontSize = 11,\n}: {\n ticks: AxisTick[];\n spine: AxisSpine | null;\n title: AxisTitle;\n plotBottom: number;\n /** SHAP's tick label size for the chart, in the same units as the text. */\n tickFontSize?: number;\n}) {\n return (\n <g aria-hidden=\"true\">\n {spine && (\n <line\n x1={spine.x1}\n x2={spine.x2}\n y1={spine.y}\n y2={spine.y}\n stroke=\"#333333\"\n strokeWidth={1}\n />\n )}\n {ticks.map((tick) => (\n <g key={`xtick-${tick.value}`}>\n <line\n x1={tick.x}\n x2={tick.x}\n y1={plotBottom}\n y2={plotBottom + TICK_LENGTH}\n stroke=\"#333333\"\n strokeWidth={1}\n />\n <text\n x={tick.x}\n y={plotBottom + TICK_LABEL_DY}\n textAnchor=\"middle\"\n fontSize={tickFontSize}\n fill=\"#333333\"\n >\n {tick.label}\n </text>\n </g>\n ))}\n <text\n x={title.x}\n y={title.y}\n textAnchor=\"middle\"\n fontSize={title.fontSize}\n fill=\"#333333\"\n >\n {title.text}\n </text>\n </g>\n );\n}\n","import { MouseEvent as ReactMouseEvent, useMemo, useState } from \"react\";\nimport { beeswarmLayout, beeswarmRows } from \"../core/beeswarmLayout\";\nimport { formatShapValue } from \"../core/format\";\nimport { ColorBar } from \"./ColorBar\";\nimport { XAxis } from \"./XAxis\";\nimport { parseExplanation } from \"../core/parse\";\nimport { groupExplanationByGenus } from \"../core/taxonomy\";\nimport { RowSort } from \"../core/rowSort\";\nimport { Explanation } from \"../core/types\";\n\nexport type ShapBeeswarmProps = {\n explanation: Explanation;\n maxDisplay?: number;\n faithfulOtherRow?: boolean;\n /** Collapse `Genus_species` Features into their genus before drawing. */\n groupByGenus?: boolean;\n /** Order of the displayed rows. Never changes which rows are shown. */\n rowSort?: RowSort;\n classIndex?: number;\n width?: number;\n rowHeight?: number;\n seed?: number;\n dotRadius?: number;\n /** SHAP's Low–High feature value colour bar, as color_bar=True draws it. */\n colorBar?: boolean;\n onFeatureClick?: (featureIndex: number | null) => void;\n};\n\ntype HoveredPoint = { rowIndex: number; pointIndex: number };\n\nexport function ShapBeeswarm({\n explanation,\n maxDisplay = 10,\n faithfulOtherRow = false,\n groupByGenus = false,\n rowSort = \"importance\",\n classIndex = 1,\n width = 720,\n rowHeight = 28,\n seed = 0,\n dotRadius = 3,\n colorBar = true,\n onFeatureClick,\n}: ShapBeeswarmProps) {\n const [hovered, setHovered] = useState<HoveredPoint | null>(null);\n const marginTop = 8;\n\n const layout = useMemo(() => {\n const raw = parseExplanation(explanation, { classIndex });\n const parsed = groupByGenus ? groupExplanationByGenus(raw) : raw;\n const rows = beeswarmRows(parsed, maxDisplay, faithfulOtherRow, seed, rowSort);\n return beeswarmLayout(rows, {\n width,\n rowHeight,\n marginLeft: 260,\n marginRight: 90,\n marginTop,\n dotRadius,\n colorBar,\n });\n }, [groupByGenus, rowSort, colorBar,\n explanation,\n maxDisplay,\n faithfulOtherRow,\n classIndex,\n width,\n rowHeight,\n seed,\n dotRadius,\n ]);\n\n const handlePointHover = (rowIndex: number, event: ReactMouseEvent<SVGGElement>) => {\n const attribute = (event.target as Element).getAttribute?.(\"data-point-index\");\n if (attribute === null || attribute === undefined) return;\n const pointIndex = Number(attribute);\n if (Number.isInteger(pointIndex)) setHovered({ rowIndex, pointIndex });\n };\n\n const fallbackRow = layout.rows[0];\n const activeRow = hovered ? layout.rows[hovered.rowIndex] : fallbackRow;\n const activePoint = hovered\n ? activeRow?.points[hovered.pointIndex]\n : activeRow?.points[0];\n\n return (\n <svg width={width} height={layout.height} role=\"img\" aria-label=\"Global SHAP beeswarm\">\n <line\n x1={layout.xZero}\n x2={layout.xZero}\n y1={marginTop}\n y2={layout.plotBottom}\n stroke=\"#777777\"\n strokeWidth={1}\n />\n\n {layout.rows.map((row, rowIndex) => (\n <g\n key={`row-${rowIndex}`}\n onMouseOver={(event) => handlePointHover(rowIndex, event)}\n onMouseLeave={() => setHovered(null)}\n onClick={() => onFeatureClick?.(row.featureIndex)}\n style={{ cursor: onFeatureClick ? \"pointer\" : \"default\" }}\n >\n <rect\n x={0}\n y={row.centerY - rowHeight / 2}\n width={width}\n height={rowHeight}\n fill={hovered?.rowIndex === rowIndex ? \"#00000008\" : \"transparent\"}\n />\n <text\n x={250}\n y={row.centerY}\n textAnchor=\"end\"\n dominantBaseline=\"middle\"\n fontSize={13}\n fill=\"#333333\"\n fontStyle={row.isOtherRow ? \"normal\" : \"italic\"}\n >\n {row.label}\n </text>\n {row.points.map((point, pointIndex) => (\n <circle\n key={`point-${point.sampleIndex}`}\n data-point-index={pointIndex}\n cx={point.x}\n cy={point.y}\n r={point.radius}\n fill={point.color}\n fillOpacity={0.7}\n />\n ))}\n </g>\n ))}\n\n <XAxis\n ticks={layout.xTicks}\n spine={layout.xSpine}\n title={layout.xTitle}\n plotBottom={layout.plotBottom}\n tickFontSize={11}\n />\n\n {layout.colorBar && <ColorBar bar={layout.colorBar} />}\n\n {activeRow && activePoint && (\n <g\n opacity={hovered ? 1 : 0}\n pointerEvents=\"none\"\n transform={`translate(${activePoint.x + 8} ${activePoint.y - 8})`}\n >\n <rect x={0} y={-16} width={210} height={54} rx={3} fill=\"#ffffff\" stroke=\"#cccccc\" />\n <text x={7} y={0} fontSize={11} fill=\"#222222\">{activeRow.label}</text>\n <text x={7} y={15} fontSize={11} fill=\"#222222\">\n {`SHAP value: ${formatShapValue(activePoint.valueX)}`}\n </text>\n <text x={7} y={30} fontSize={11} fill=\"#222222\">\n {`Feature value: ${Number.isFinite(activePoint.featureValue)\n ? formatShapValue(activePoint.featureValue)\n : \"missing\"}`}\n </text>\n </g>\n )}\n </svg>\n );\n}\n","import { ColorBarGeometry } from \"../core/colorBar\";\n\n/**\n * A vertical colour bar the way matplotlib draws SHAP's: no outline, no tick\n * marks, a label at each end, and the title rotated to read bottom to top.\n */\nexport function ColorBar({ bar }: { bar: ColorBarGeometry }) {\n return (\n <g role=\"img\" aria-label={`${bar.label.text}: ${bar.ticks[0].label} to ${bar.ticks[1].label}`}>\n {bar.steps.map((step, index) => (\n <rect\n key={`colorbar-step-${index}`}\n x={bar.x}\n y={step.y}\n width={bar.width}\n height={step.height}\n fill={step.color}\n />\n ))}\n {bar.ticks.map((tick, index) => (\n <text\n key={`colorbar-tick-${index}`}\n x={bar.tickX}\n y={tick.y}\n dominantBaseline=\"middle\"\n fontSize={bar.tickFontSize}\n fill=\"#333333\"\n >\n {tick.label}\n </text>\n ))}\n {bar.offsetText && (\n <text\n x={bar.offsetText.x}\n y={bar.offsetText.y}\n fontSize={bar.tickFontSize}\n fill=\"#333333\"\n >\n {bar.offsetText.text}\n </text>\n )}\n <text\n x={bar.label.x}\n y={bar.label.y}\n transform={`rotate(-90 ${bar.label.x} ${bar.label.y})`}\n textAnchor=\"middle\"\n fontSize={bar.label.fontSize}\n fill=\"#333333\"\n >\n {bar.label.text}\n </text>\n </g>\n );\n}\n","import { useMemo, useState } from \"react\";\nimport { formatShapValue } from \"../core/format\";\nimport { XAxis } from \"./XAxis\";\nimport { ColorBar } from \"./ColorBar\";\nimport { heatmapLayout, heatmapRows } from \"../core/heatmapLayout\";\nimport { parseExplanation } from \"../core/parse\";\nimport { groupExplanationByGenus } from \"../core/taxonomy\";\nimport { RowSort } from \"../core/rowSort\";\nimport { Explanation } from \"../core/types\";\n\nexport type ShapHeatmapProps = {\n explanation: Explanation;\n maxDisplay?: number;\n faithfulOtherRow?: boolean;\n /** Collapse `Genus_species` Features into their genus before drawing. */\n groupByGenus?: boolean;\n /** Order of the displayed rows. Never changes which rows are shown. */\n rowSort?: RowSort;\n classIndex?: number;\n width?: number;\n rowHeight?: number;\n /** SHAP's colour bar for the SHAP value range, as _heatmap.py always draws it. */\n colorBar?: boolean;\n onFeatureClick?: (featureIndex: number | null) => void;\n onSampleClick?: (sampleId: string) => void;\n};\n\nexport function ShapHeatmap({\n explanation,\n maxDisplay = 10,\n faithfulOtherRow = false,\n groupByGenus = false,\n rowSort = \"importance\",\n classIndex = 1,\n width = 720,\n rowHeight = 26,\n colorBar = true,\n onFeatureClick,\n onSampleClick,\n}: ShapHeatmapProps) {\n const [hoveredColumn, setHoveredColumn] = useState<number | null>(null);\n const marginTop = 72;\n\n const layout = useMemo(() => {\n const raw = parseExplanation(explanation, { classIndex });\n const parsed = groupByGenus ? groupExplanationByGenus(raw) : raw;\n const rows = heatmapRows(parsed, maxDisplay, faithfulOtherRow, rowSort);\n return heatmapLayout(rows, {\n width,\n rowHeight,\n marginLeft: 260,\n marginRight: 100,\n marginTop,\n colorBar,\n });\n }, [groupByGenus, rowSort, colorBar, explanation, maxDisplay, faithfulOtherRow, classIndex, width, rowHeight]);\n\n const activeColumn = hoveredColumn === null ? undefined : layout.columns[hoveredColumn];\n\n // What a person reads for a column. sampleId is the record UUID — the key\n // onSampleClick hands back — and is never shown: an old payload without\n // labels reads \"Sample n\" rather than a UUID.\n const nameOf = (column: { sampleIndex: number; sampleLabel?: string }) => {\n if (!column.sampleLabel) return `Sample ${column.sampleIndex + 1}`;\n return layout.sampleLabelColumn\n ? `${layout.sampleLabelColumn}: ${column.sampleLabel}`\n : column.sampleLabel;\n };\n // Real ids (\"subject_id: CCIS02856720ST-4-0\") run past a fixed box.\n const tooltipWidth = activeColumn\n ? Math.max(190, nameOf(activeColumn).length * 6.5 + 16)\n : 190;\n const tooltipX = activeColumn\n ? Math.max(0, Math.min(activeColumn.centerX + 8, width - tooltipWidth - 8))\n : 0;\n\n return (\n <svg width={width} height={layout.height} role=\"img\" aria-label=\"Global SHAP heatmap\">\n {layout.fxAxisMarks.map((mark) => (\n <g key={`fx-axis-${mark.value}`}>\n <line\n x1={layout.gridLeft - 4}\n x2={layout.gridRight}\n y1={mark.y}\n y2={mark.y}\n stroke=\"#dddddd\"\n strokeWidth={1}\n />\n <text\n x={layout.gridLeft - 8}\n y={mark.y}\n textAnchor=\"end\"\n dominantBaseline=\"middle\"\n fontSize={10}\n fill=\"#666666\"\n >\n {mark.label}\n </text>\n </g>\n ))}\n\n <polyline\n points={layout.fxLine.map((point) => `${point.x},${point.y}`).join(\" \")}\n fill=\"none\"\n stroke=\"#333333\"\n strokeWidth={1.5}\n />\n <line\n x1={layout.gridLeft}\n x2={layout.gridRight}\n y1={layout.separatorY}\n y2={layout.separatorY}\n stroke=\"#888888\"\n strokeWidth={1}\n strokeDasharray=\"4 4\"\n />\n\n <XAxis\n ticks={layout.xTicks}\n spine={layout.xSpine}\n title={layout.xTitle}\n plotBottom={layout.plotBottom}\n tickFontSize={10}\n />\n\n <g aria-hidden=\"true\">\n {[layout.spines.left, layout.spines.right].map((spine, index) => (\n <line\n key={`spine-${index}`}\n x1={spine.x}\n x2={spine.x}\n y1={spine.y1}\n y2={spine.y2}\n stroke=\"#333333\"\n strokeWidth={1}\n />\n ))}\n {layout.yTicks.map((tick, index) => (\n <line\n key={`ytick-${index}`}\n x1={tick.x1}\n x2={tick.x2}\n y1={tick.y}\n y2={tick.y}\n stroke=\"#333333\"\n strokeWidth={1}\n />\n ))}\n </g>\n\n {layout.colorBar && <ColorBar bar={layout.colorBar} />}\n\n {layout.rows.map((row, rowIndex) => (\n <g\n key={`row-${rowIndex}`}\n onClick={() => onFeatureClick?.(row.featureIndex)}\n style={{ cursor: onFeatureClick ? \"pointer\" : \"default\" }}\n >\n <text\n x={250}\n y={row.centerY}\n textAnchor=\"end\"\n dominantBaseline=\"middle\"\n fontSize={13}\n fill=\"#333333\"\n fontStyle={row.isOtherRow ? \"normal\" : \"italic\"}\n >\n {row.label}\n </text>\n {row.cells.map((cell, columnIndex) => (\n <rect\n key={`cell-${columnIndex}`}\n x={cell.x}\n y={cell.y}\n width={cell.width}\n height={cell.height}\n fill={cell.color}\n />\n ))}\n <rect\n x={row.sideBar.x}\n y={row.sideBar.y}\n width={row.sideBar.width}\n height={row.sideBar.height}\n fill=\"#777777\"\n />\n </g>\n ))}\n\n {activeColumn && (\n <rect\n x={activeColumn.x}\n y={8}\n width={activeColumn.width}\n height={layout.plotBottom - 8}\n fill=\"#000000\"\n fillOpacity={0.1}\n pointerEvents=\"none\"\n />\n )}\n\n {layout.columns.map((column, columnIndex) => (\n <rect\n key={`column-hit-${column.sampleIndex}`}\n x={column.x}\n y={8}\n width={column.width}\n height={layout.plotBottom - 8}\n fill=\"transparent\"\n aria-label={`${nameOf(column)}, total SHAP value ${formatShapValue(column.total)}`}\n onMouseEnter={() => setHoveredColumn(columnIndex)}\n onMouseLeave={() => setHoveredColumn(null)}\n onClick={() => {\n if (column.sampleId !== undefined) onSampleClick?.(column.sampleId);\n }}\n style={{ cursor: column.sampleId && onSampleClick ? \"pointer\" : \"default\" }}\n />\n ))}\n\n {activeColumn && (\n <g pointerEvents=\"none\" transform={`translate(${tooltipX} 10)`}>\n <rect x={0} y={0} width={tooltipWidth} height={42} rx={3} fill=\"#ffffff\" stroke=\"#cccccc\" />\n <text x={7} y={15} fontSize={11} fill=\"#222222\">\n {nameOf(activeColumn)}\n </text>\n <text x={7} y={31} fontSize={11} fill=\"#222222\">\n {`Σφ: ${formatShapValue(activeColumn.total)}`}\n </text>\n </g>\n )}\n </svg>\n );\n}\n","import { useMemo, useState } from \"react\";\nimport { Explanation } from \"../core/types\";\nimport { parseExplanation } from \"../core/parse\";\nimport { groupExplanationByGenus } from \"../core/taxonomy\";\nimport { ValuePrecision } from \"../core/format\";\nimport {\n WATERFALL_BASE_LABEL_DY,\n WATERFALL_TICK_LABEL_DY,\n waterfallLayout,\n waterfallRows,\n} from \"../core/waterfallLayout\";\n\nexport type ShapWaterfallProps = {\n explanation: Explanation;\n sampleIndex?: number;\n maxDisplay?: number;\n faithfulOtherRow?: boolean;\n /** Collapse `Genus_species` Features into their genus before drawing. */\n groupByGenus?: boolean;\n classIndex?: number;\n width?: number;\n rowHeight?: number;\n /** Decimal places for the bar labels. Display only — it changes no geometry but the text width. */\n decimals?: ValuePrecision;\n onFeatureClick?: (featureIndex: number | null) => void;\n};\n\nexport function ShapWaterfall({\n explanation,\n sampleIndex = 0,\n maxDisplay = 10,\n faithfulOtherRow = false,\n groupByGenus = false,\n classIndex = 1,\n width = 720,\n rowHeight = 30,\n decimals = 2,\n onFeatureClick,\n}: ShapWaterfallProps) {\n const [hovered, setHovered] = useState<number | null>(null);\n const marginTop = 34;\n\n const layout = useMemo(() => {\n const raw = parseExplanation(explanation, { classIndex });\n const parsed = groupByGenus ? groupExplanationByGenus(raw) : raw;\n const rows = waterfallRows(parsed, sampleIndex, maxDisplay, faithfulOtherRow);\n return waterfallLayout(rows, {\n width,\n rowHeight,\n marginLeft: 260,\n marginRight: 110,\n marginTop,\n decimals,\n });\n }, [groupByGenus, \n explanation, sampleIndex, maxDisplay, faithfulOtherRow,\n classIndex, width, rowHeight, decimals,\n ]);\n\n return (\n <svg\n width={width}\n height={layout.height}\n role=\"img\"\n aria-label={`Local SHAP waterfall for Sample ${sampleIndex}`}\n >\n {layout.separators.map((separator, index) => (\n <line\n key={`separator-${index}`}\n x1={separator.x1}\n x2={separator.x2}\n y1={separator.y}\n y2={separator.y}\n stroke=\"#cccccc\"\n strokeWidth={1}\n strokeDasharray=\"1 5\"\n />\n ))}\n\n <g aria-hidden=\"true\">\n <line\n x1={layout.plotLeft}\n x2={layout.plotRight}\n y1={layout.plotBottom}\n y2={layout.plotBottom}\n stroke=\"#333333\"\n strokeWidth={1}\n />\n {layout.xTicks.map((tick) => (\n <g key={`tick-${tick.value}`}>\n <line\n x1={tick.x}\n x2={tick.x}\n y1={layout.plotBottom}\n y2={layout.plotBottom + 5}\n stroke=\"#333333\"\n strokeWidth={1}\n />\n <text\n x={tick.x}\n y={layout.plotBottom + WATERFALL_TICK_LABEL_DY}\n textAnchor=\"middle\"\n fontSize={11}\n fill=\"#333333\"\n >\n {tick.label}\n </text>\n </g>\n ))}\n </g>\n\n {layout.connectors.map((connector, index) => (\n <line\n key={`connector-${index}`}\n x1={connector.x}\n x2={connector.x}\n y1={connector.y1}\n y2={connector.y2}\n stroke=\"#bbbbbb\"\n strokeWidth={1}\n strokeDasharray=\"4 4\"\n />\n ))}\n\n {layout.axisMarks.map((mark) => (\n <g key={mark.kind}>\n <line\n x1={mark.x}\n x2={mark.x}\n y1={mark.y1}\n y2={mark.y2}\n stroke=\"#bbbbbb\"\n strokeWidth={1}\n strokeDasharray=\"4 4\"\n />\n <text\n x={mark.x}\n y={\n mark.kind === \"output\"\n ? marginTop - 10\n : layout.plotBottom + WATERFALL_BASE_LABEL_DY\n }\n textAnchor=\"middle\"\n fontSize={12}\n fill=\"#777777\"\n >\n {mark.label}\n </text>\n </g>\n ))}\n\n {layout.arrows.map((arrow, index) => (\n <g\n key={`row-${index}`}\n onMouseEnter={() => setHovered(index)}\n onMouseLeave={() => setHovered(null)}\n onClick={() => onFeatureClick?.(arrow.featureIndex)}\n style={{ cursor: onFeatureClick ? \"pointer\" : \"default\" }}\n >\n <rect\n x={0}\n y={arrow.centerY - rowHeight / 2}\n width={width}\n height={rowHeight}\n fill={hovered === index ? \"#00000008\" : \"transparent\"}\n />\n <text\n x={250}\n y={arrow.centerY}\n textAnchor=\"end\"\n dominantBaseline=\"middle\"\n fontSize={13}\n fill=\"#333333\"\n fontStyle={arrow.isOtherRow ? \"normal\" : \"italic\"}\n >\n {arrow.label}\n </text>\n <polygon\n points={arrow.points.map((point) => `${point.x},${point.y}`).join(\" \")}\n fill={arrow.color}\n stroke=\"rgba(255,255,255,0.8)\"\n strokeWidth={1}\n />\n <text\n x={arrow.valueLabel.x}\n y={arrow.centerY}\n textAnchor={arrow.valueLabel.anchor}\n dominantBaseline=\"middle\"\n fontSize={12}\n fill={arrow.valueLabel.inside ? \"#ffffff\" : arrow.color}\n >\n {arrow.valueLabel.text}\n </text>\n </g>\n ))}\n </svg>\n );\n}\n","import { ShapBar, type ShapBarProps } from \"./src/react/ShapBar\";\nimport { ShapBeeswarm, type ShapBeeswarmProps } from \"./src/react/ShapBeeswarm\";\nimport { ShapHeatmap, type ShapHeatmapProps } from \"./src/react/ShapHeatmap\";\nimport { ShapWaterfall, type ShapWaterfallProps } from \"./src/react/ShapWaterfall\";\n\n/** Give a chart the name it is written as, so React DevTools shows `Plots.bar`. */\nfunction named<T extends object>(component: T, displayName: string): T & { displayName: string } {\n return Object.assign(component, { displayName });\n}\n\n/**\n * The four charts, named the way shap names them in Python: `shap.plots.bar`\n * becomes `<Plots.bar />`.\n *\n * One import brings all four charts into a bundle, even on a page that draws\n * one — about 30 KB minified, against about 8 KB for a single chart, measured\n * with esbuild. That trade was chosen for the single import name.\n */\nexport const Plots = {\n bar: named(ShapBar, \"Plots.bar\"),\n beeswarm: named(ShapBeeswarm, \"Plots.beeswarm\"),\n heatmap: named(ShapHeatmap, \"Plots.heatmap\"),\n waterfall: named(ShapWaterfall, \"Plots.waterfall\"),\n} as const;\n\nexport type BarPlotProps = ShapBarProps;\nexport type BeeswarmPlotProps = ShapBeeswarmProps;\nexport type HeatmapPlotProps = ShapHeatmapProps;\nexport type WaterfallPlotProps = ShapWaterfallProps;\n"],"mappings":"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","names":["jsx","jsxs","useMemo","useState","jsx","jsxs","jsx","jsxs","useState","useMemo","useMemo","useState","jsx","jsxs","useState","useMemo","useMemo","useState","jsx","jsxs","useState","useMemo"]}
|
|
1
|
+
{"version":3,"sources":["../src/react/ShapBar.tsx","../src/react/XAxis.tsx","../src/react/ShapBeeswarm.tsx","../src/react/ColorBar.tsx","../src/react/ShapHeatmap.tsx","../src/react/ShapWaterfall.tsx","../react.ts"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { Explanation } from \"../core/types\";\nimport { parseExplanation } from \"../core/parse\";\nimport { groupExplanationByGenus } from \"../core/taxonomy\";\nimport { globalImportance, orderFeatures } from \"../core/order\";\nimport { collapseToDisplay } from \"../core/collapse\";\nimport { barLayout } from \"../core/barLayout\";\nimport { formatShapValue } from \"../core/format\";\nimport { XAxis } from \"./XAxis\";\nimport { PlotLabels, resolveLabels } from \"../core/labels\";\n\nexport type ShapBarProps = {\n explanation: Explanation;\n maxDisplay?: number;\n faithfulOtherRow?: boolean;\n /** Collapse `Genus_species` Features into their genus before drawing. */\n groupByGenus?: boolean;\n classIndex?: number;\n width?: number;\n rowHeight?: number;\n /**\n * Wording for every piece of text the chart draws; keys not given keep SHAP's.\n * Pass a stable object (a module constant or a memo): a new one each render\n * recomputes the layout each render.\n */\n labels?: Partial<PlotLabels>;\n onFeatureClick?: (featureIndex: number | null) => void;\n};\n\nexport function ShapBar({\n explanation,\n maxDisplay = 10,\n faithfulOtherRow = false,\n groupByGenus = false,\n classIndex = 1,\n width = 720,\n rowHeight = 26,\n labels,\n onFeatureClick,\n}: ShapBarProps) {\n const [hovered, setHovered] = useState<number | null>(null);\n const words = useMemo(() => resolveLabels(labels), [labels]);\n\n const layout = useMemo(() => {\n const raw = parseExplanation(explanation, { classIndex });\n const parsed = groupByGenus ? groupExplanationByGenus(raw) : raw;\n const importance = globalImportance(parsed);\n const order = orderFeatures(importance);\n const rows = collapseToDisplay(\n parsed.featureNames, importance, order, maxDisplay, faithfulOtherRow, words,\n );\n return barLayout(rows, {\n width, rowHeight, marginLeft: 260, marginRight: 90, marginTop: 8, labels: words,\n });\n }, [groupByGenus, explanation, maxDisplay, faithfulOtherRow, classIndex, width, rowHeight, words]);\n\n return (\n <svg width={width} height={layout.height} role=\"img\"\n aria-label={`Mean absolute ${words.shapValue} per feature`}>\n <line x1={layout.zeroLine.x} x2={layout.zeroLine.x}\n y1={layout.zeroLine.y1} y2={layout.zeroLine.y2}\n stroke=\"#333333\" strokeWidth={1} />\n <XAxis ticks={layout.xTicks} spine={layout.xSpine} title={layout.xTitle}\n plotBottom={layout.plotBottom} tickFontSize={11} />\n {layout.bars.map((bar, i) => (\n <g key={`row-${i}`}\n onMouseEnter={() => setHovered(i)}\n onMouseLeave={() => setHovered(null)}\n onClick={() => onFeatureClick?.(bar.featureIndex)}\n style={{ cursor: onFeatureClick ? \"pointer\" : \"default\" }}>\n <rect x={0} y={bar.y - (rowHeight - bar.height) / 2}\n width={width} height={rowHeight}\n fill={hovered === i ? \"#00000008\" : \"transparent\"} />\n <text x={250} y={bar.centerY} textAnchor=\"end\" dominantBaseline=\"middle\"\n fontSize={13} fill=\"#333333\"\n fontStyle={bar.isOtherRow ? \"normal\" : \"italic\"}>\n {bar.label}\n </text>\n <rect x={bar.x} y={bar.y} width={bar.width} height={bar.height}\n fill={bar.color} stroke=\"rgba(255,255,255,0.8)\" strokeWidth={1} />\n <text x={bar.x + bar.width + 6} y={bar.centerY} dominantBaseline=\"middle\"\n fontSize={12} fill={bar.color}>\n {formatShapValue(bar.value)}\n </text>\n </g>\n ))}\n </svg>\n );\n}\n","import {\n AxisSpine,\n AxisTick,\n AxisTitle,\n TICK_LABEL_DY,\n TICK_LENGTH,\n} from \"../core/ticks\";\n\n/**\n * The bottom axis the summary charts share: optional spine, outward ticks with\n * labels, and a centred title. The layouts decide every position; this only\n * draws them, so the three charts cannot drift apart in how an axis looks.\n */\nexport function XAxis({\n ticks,\n spine,\n title,\n plotBottom,\n tickFontSize = 11,\n}: {\n ticks: AxisTick[];\n spine: AxisSpine | null;\n title: AxisTitle;\n plotBottom: number;\n /** SHAP's tick label size for the chart, in the same units as the text. */\n tickFontSize?: number;\n}) {\n return (\n <g aria-hidden=\"true\">\n {spine && (\n <line\n x1={spine.x1}\n x2={spine.x2}\n y1={spine.y}\n y2={spine.y}\n stroke=\"#333333\"\n strokeWidth={1}\n />\n )}\n {ticks.map((tick) => (\n <g key={`xtick-${tick.value}`}>\n <line\n x1={tick.x}\n x2={tick.x}\n y1={plotBottom}\n y2={plotBottom + TICK_LENGTH}\n stroke=\"#333333\"\n strokeWidth={1}\n />\n <text\n x={tick.x}\n y={plotBottom + TICK_LABEL_DY}\n textAnchor=\"middle\"\n fontSize={tickFontSize}\n fill=\"#333333\"\n >\n {tick.label}\n </text>\n </g>\n ))}\n <text\n x={title.x}\n y={title.y}\n textAnchor=\"middle\"\n fontSize={title.fontSize}\n fill=\"#333333\"\n >\n {title.text}\n </text>\n </g>\n );\n}\n","import { MouseEvent as ReactMouseEvent, useMemo, useState } from \"react\";\nimport { beeswarmLayout, beeswarmRows } from \"../core/beeswarmLayout\";\nimport { formatLevel, formatShapValue } from \"../core/format\";\nimport { PlotLabels, resolveLabels } from \"../core/labels\";\nimport { ColorBar } from \"./ColorBar\";\nimport { XAxis } from \"./XAxis\";\nimport { parseExplanation } from \"../core/parse\";\nimport { groupExplanationByGenus } from \"../core/taxonomy\";\nimport { RowSort } from \"../core/rowSort\";\nimport { Explanation } from \"../core/types\";\n\nexport type ShapBeeswarmProps = {\n explanation: Explanation;\n maxDisplay?: number;\n faithfulOtherRow?: boolean;\n /** Collapse `Genus_species` Features into their genus before drawing. */\n groupByGenus?: boolean;\n /** Order of the displayed rows. Never changes which rows are shown. */\n rowSort?: RowSort;\n classIndex?: number;\n width?: number;\n rowHeight?: number;\n seed?: number;\n dotRadius?: number;\n /** SHAP's Low–High feature value colour bar, as color_bar=True draws it. */\n colorBar?: boolean;\n /**\n * Wording for every piece of text the chart draws; keys not given keep SHAP's.\n * Pass a stable object (a module constant or a memo): a new one each render\n * recomputes the layout each render.\n */\n labels?: Partial<PlotLabels>;\n onFeatureClick?: (featureIndex: number | null) => void;\n};\n\ntype HoveredPoint = { rowIndex: number; pointIndex: number };\n\nexport function ShapBeeswarm({\n explanation,\n maxDisplay = 10,\n faithfulOtherRow = false,\n groupByGenus = false,\n rowSort = \"importance\",\n classIndex = 1,\n width = 720,\n rowHeight = 28,\n seed = 0,\n dotRadius = 3,\n colorBar = true,\n labels,\n onFeatureClick,\n}: ShapBeeswarmProps) {\n const [hovered, setHovered] = useState<HoveredPoint | null>(null);\n const words = useMemo(() => resolveLabels(labels), [labels]);\n const marginTop = 8;\n\n const layout = useMemo(() => {\n const raw = parseExplanation(explanation, { classIndex });\n const parsed = groupByGenus ? groupExplanationByGenus(raw) : raw;\n const rows = beeswarmRows(parsed, maxDisplay, faithfulOtherRow, seed, rowSort, words);\n return beeswarmLayout(rows, {\n width,\n rowHeight,\n marginLeft: 260,\n marginRight: 90,\n marginTop,\n dotRadius,\n colorBar,\n labels: words,\n });\n }, [groupByGenus, rowSort, colorBar, words,\n explanation,\n maxDisplay,\n faithfulOtherRow,\n classIndex,\n width,\n rowHeight,\n seed,\n dotRadius,\n ]);\n\n const handlePointHover = (rowIndex: number, event: ReactMouseEvent<SVGGElement>) => {\n const attribute = (event.target as Element).getAttribute?.(\"data-point-index\");\n if (attribute === null || attribute === undefined) return;\n const pointIndex = Number(attribute);\n if (Number.isInteger(pointIndex)) setHovered({ rowIndex, pointIndex });\n };\n\n const fallbackRow = layout.rows[0];\n const activeRow = hovered ? layout.rows[hovered.rowIndex] : fallbackRow;\n const activePoint = hovered\n ? activeRow?.points[hovered.pointIndex]\n : activeRow?.points[0];\n\n return (\n <svg width={width} height={layout.height} role=\"img\" aria-label=\"Global SHAP beeswarm\">\n <line\n x1={layout.xZero}\n x2={layout.xZero}\n y1={marginTop}\n y2={layout.plotBottom}\n stroke=\"#777777\"\n strokeWidth={1}\n />\n\n {layout.rows.map((row, rowIndex) => (\n <g\n key={`row-${rowIndex}`}\n onMouseOver={(event) => handlePointHover(rowIndex, event)}\n onMouseLeave={() => setHovered(null)}\n onClick={() => onFeatureClick?.(row.featureIndex)}\n style={{ cursor: onFeatureClick ? \"pointer\" : \"default\" }}\n >\n <rect\n x={0}\n y={row.centerY - rowHeight / 2}\n width={width}\n height={rowHeight}\n fill={hovered?.rowIndex === rowIndex ? \"#00000008\" : \"transparent\"}\n />\n <text\n x={250}\n y={row.centerY}\n textAnchor=\"end\"\n dominantBaseline=\"middle\"\n fontSize={13}\n fill=\"#333333\"\n fontStyle={row.isOtherRow ? \"normal\" : \"italic\"}\n >\n {row.label}\n </text>\n {row.points.map((point, pointIndex) => (\n <circle\n key={`point-${point.sampleIndex}`}\n data-point-index={pointIndex}\n cx={point.x}\n cy={point.y}\n r={point.radius}\n fill={point.color}\n fillOpacity={0.7}\n />\n ))}\n </g>\n ))}\n\n <XAxis\n ticks={layout.xTicks}\n spine={layout.xSpine}\n title={layout.xTitle}\n plotBottom={layout.plotBottom}\n tickFontSize={11}\n />\n\n {layout.colorBar && <ColorBar bar={layout.colorBar} />}\n\n {activeRow && activePoint && (\n <g\n opacity={hovered ? 1 : 0}\n pointerEvents=\"none\"\n transform={`translate(${activePoint.x + 8} ${activePoint.y - 8})`}\n >\n <rect x={0} y={-16} width={210} height={54} rx={3} fill=\"#ffffff\" stroke=\"#cccccc\" />\n <text x={7} y={0} fontSize={11} fill=\"#222222\">{activeRow.label}</text>\n <text x={7} y={15} fontSize={11} fill=\"#222222\">\n {`${words.shapValue}: ${formatShapValue(activePoint.valueX)}`}\n </text>\n <text x={7} y={30} fontSize={11} fill=\"#222222\">\n {/* Unsigned: a feature value is an input, not a push in either direction. */}\n {`${words.featureValue}: ${Number.isFinite(activePoint.featureValue)\n ? formatLevel(activePoint.featureValue)\n : words.missingFeatureValue}`}\n </text>\n </g>\n )}\n </svg>\n );\n}\n","import { ColorBarGeometry } from \"../core/colorBar\";\n\n/**\n * A vertical colour bar the way matplotlib draws SHAP's: no outline, no tick\n * marks, a label at each end, and the title rotated to read bottom to top.\n */\nexport function ColorBar({ bar }: { bar: ColorBarGeometry }) {\n return (\n <g role=\"img\" aria-label={`${bar.label.text}: ${bar.ticks[0].label} to ${bar.ticks[1].label}`}>\n {bar.steps.map((step, index) => (\n <rect\n key={`colorbar-step-${index}`}\n x={bar.x}\n y={step.y}\n width={bar.width}\n height={step.height}\n fill={step.color}\n />\n ))}\n {bar.ticks.map((tick, index) => (\n <text\n key={`colorbar-tick-${index}`}\n x={bar.tickX}\n y={tick.y}\n dominantBaseline=\"middle\"\n fontSize={bar.tickFontSize}\n fill=\"#333333\"\n >\n {tick.label}\n </text>\n ))}\n {bar.offsetText && (\n <text\n x={bar.offsetText.x}\n y={bar.offsetText.y}\n fontSize={bar.tickFontSize}\n fill=\"#333333\"\n >\n {bar.offsetText.text}\n </text>\n )}\n <text\n x={bar.label.x}\n y={bar.label.y}\n transform={`rotate(-90 ${bar.label.x} ${bar.label.y})`}\n textAnchor=\"middle\"\n fontSize={bar.label.fontSize}\n fill=\"#333333\"\n >\n {bar.label.text}\n </text>\n </g>\n );\n}\n","import { useMemo, useState } from \"react\";\nimport { formatShapValue } from \"../core/format\";\nimport { XAxis } from \"./XAxis\";\nimport { ColorBar } from \"./ColorBar\";\nimport { PlotLabels, resolveLabels } from \"../core/labels\";\nimport { heatmapLayout, heatmapRows } from \"../core/heatmapLayout\";\nimport { parseExplanation } from \"../core/parse\";\nimport { groupExplanationByGenus } from \"../core/taxonomy\";\nimport { RowSort } from \"../core/rowSort\";\nimport { Explanation } from \"../core/types\";\n\nexport type ShapHeatmapProps = {\n explanation: Explanation;\n maxDisplay?: number;\n faithfulOtherRow?: boolean;\n /** Collapse `Genus_species` Features into their genus before drawing. */\n groupByGenus?: boolean;\n /** Order of the displayed rows. Never changes which rows are shown. */\n rowSort?: RowSort;\n classIndex?: number;\n width?: number;\n rowHeight?: number;\n /** SHAP's colour bar for the SHAP value range, as _heatmap.py always draws it. */\n colorBar?: boolean;\n /**\n * Wording for every piece of text the chart draws; keys not given keep SHAP's.\n * Pass a stable object (a module constant or a memo): a new one each render\n * recomputes the layout each render.\n */\n labels?: Partial<PlotLabels>;\n onFeatureClick?: (featureIndex: number | null) => void;\n onSampleClick?: (sampleId: string) => void;\n};\n\nexport function ShapHeatmap({\n explanation,\n maxDisplay = 10,\n faithfulOtherRow = false,\n groupByGenus = false,\n rowSort = \"importance\",\n classIndex = 1,\n width = 720,\n rowHeight = 26,\n colorBar = true,\n labels,\n onFeatureClick,\n onSampleClick,\n}: ShapHeatmapProps) {\n const [hoveredColumn, setHoveredColumn] = useState<number | null>(null);\n const words = useMemo(() => resolveLabels(labels), [labels]);\n const marginTop = 72;\n\n const layout = useMemo(() => {\n const raw = parseExplanation(explanation, { classIndex });\n const parsed = groupByGenus ? groupExplanationByGenus(raw) : raw;\n const rows = heatmapRows(parsed, maxDisplay, faithfulOtherRow, rowSort, words);\n return heatmapLayout(rows, {\n width,\n rowHeight,\n marginLeft: 260,\n marginRight: 100,\n marginTop,\n colorBar,\n labels: words,\n });\n }, [groupByGenus, rowSort, colorBar, words, explanation, maxDisplay, faithfulOtherRow, classIndex, width, rowHeight]);\n\n const activeColumn = hoveredColumn === null ? undefined : layout.columns[hoveredColumn];\n\n // What a person reads for a column. sampleId is the record UUID — the key\n // onSampleClick hands back — and is never shown: an old payload without\n // labels reads \"Sample n\" rather than a UUID.\n const nameOf = (column: { sampleIndex: number; sampleLabel?: string }) => {\n if (!column.sampleLabel) return words.sampleFallback(column.sampleIndex + 1);\n return layout.sampleLabelColumn\n ? `${layout.sampleLabelColumn}: ${column.sampleLabel}`\n : column.sampleLabel;\n };\n // Real ids (\"subject_id: CCIS02856720ST-4-0\") run past a fixed box.\n const tooltipWidth = activeColumn\n ? Math.max(190, nameOf(activeColumn).length * 6.5 + 16)\n : 190;\n const tooltipX = activeColumn\n ? Math.max(0, Math.min(activeColumn.centerX + 8, width - tooltipWidth - 8))\n : 0;\n\n return (\n <svg width={width} height={layout.height} role=\"img\" aria-label=\"Global SHAP heatmap\">\n {layout.fxAxisMarks.map((mark) => (\n <g key={`fx-axis-${mark.value}`}>\n <line\n x1={layout.gridLeft - 4}\n x2={layout.gridRight}\n y1={mark.y}\n y2={mark.y}\n stroke=\"#dddddd\"\n strokeWidth={1}\n />\n <text\n x={layout.gridLeft - 8}\n y={mark.y}\n textAnchor=\"end\"\n dominantBaseline=\"middle\"\n fontSize={10}\n fill=\"#666666\"\n >\n {mark.label}\n </text>\n </g>\n ))}\n\n <polyline\n points={layout.fxLine.map((point) => `${point.x},${point.y}`).join(\" \")}\n fill=\"none\"\n stroke=\"#333333\"\n strokeWidth={1.5}\n />\n <line\n x1={layout.gridLeft}\n x2={layout.gridRight}\n y1={layout.separatorY}\n y2={layout.separatorY}\n stroke=\"#888888\"\n strokeWidth={1}\n strokeDasharray=\"4 4\"\n />\n\n <XAxis\n ticks={layout.xTicks}\n spine={layout.xSpine}\n title={layout.xTitle}\n plotBottom={layout.plotBottom}\n tickFontSize={10}\n />\n\n <g aria-hidden=\"true\">\n {[layout.spines.left, layout.spines.right].map((spine, index) => (\n <line\n key={`spine-${index}`}\n x1={spine.x}\n x2={spine.x}\n y1={spine.y1}\n y2={spine.y2}\n stroke=\"#333333\"\n strokeWidth={1}\n />\n ))}\n {layout.yTicks.map((tick, index) => (\n <line\n key={`ytick-${index}`}\n x1={tick.x1}\n x2={tick.x2}\n y1={tick.y}\n y2={tick.y}\n stroke=\"#333333\"\n strokeWidth={1}\n />\n ))}\n </g>\n\n {layout.colorBar && <ColorBar bar={layout.colorBar} />}\n\n {layout.rows.map((row, rowIndex) => (\n <g\n key={`row-${rowIndex}`}\n onClick={() => onFeatureClick?.(row.featureIndex)}\n style={{ cursor: onFeatureClick ? \"pointer\" : \"default\" }}\n >\n <text\n x={250}\n y={row.centerY}\n textAnchor=\"end\"\n dominantBaseline=\"middle\"\n fontSize={13}\n fill=\"#333333\"\n fontStyle={row.isOtherRow ? \"normal\" : \"italic\"}\n >\n {row.label}\n </text>\n {row.cells.map((cell, columnIndex) => (\n <rect\n key={`cell-${columnIndex}`}\n x={cell.x}\n y={cell.y}\n width={cell.width}\n height={cell.height}\n fill={cell.color}\n />\n ))}\n <rect\n x={row.sideBar.x}\n y={row.sideBar.y}\n width={row.sideBar.width}\n height={row.sideBar.height}\n fill=\"#777777\"\n />\n </g>\n ))}\n\n {activeColumn && (\n <rect\n x={activeColumn.x}\n y={8}\n width={activeColumn.width}\n height={layout.plotBottom - 8}\n fill=\"#000000\"\n fillOpacity={0.1}\n pointerEvents=\"none\"\n />\n )}\n\n {layout.columns.map((column, columnIndex) => (\n <rect\n key={`column-hit-${column.sampleIndex}`}\n x={column.x}\n y={8}\n width={column.width}\n height={layout.plotBottom - 8}\n fill=\"transparent\"\n aria-label={`${nameOf(column)}, total ${words.shapValue} ${formatShapValue(column.total)}`}\n onMouseEnter={() => setHoveredColumn(columnIndex)}\n onMouseLeave={() => setHoveredColumn(null)}\n onClick={() => {\n if (column.sampleId !== undefined) onSampleClick?.(column.sampleId);\n }}\n style={{ cursor: column.sampleId && onSampleClick ? \"pointer\" : \"default\" }}\n />\n ))}\n\n {activeColumn && (\n <g pointerEvents=\"none\" transform={`translate(${tooltipX} 10)`}>\n <rect x={0} y={0} width={tooltipWidth} height={42} rx={3} fill=\"#ffffff\" stroke=\"#cccccc\" />\n <text x={7} y={15} fontSize={11} fill=\"#222222\">\n {nameOf(activeColumn)}\n </text>\n <text x={7} y={31} fontSize={11} fill=\"#222222\">\n {`${words.sampleTotal}: ${formatShapValue(activeColumn.total)}`}\n </text>\n </g>\n )}\n </svg>\n );\n}\n","import { useMemo, useState } from \"react\";\nimport { Explanation } from \"../core/types\";\nimport { parseExplanation } from \"../core/parse\";\nimport { groupExplanationByGenus } from \"../core/taxonomy\";\nimport { ValuePrecision } from \"../core/format\";\nimport { PlotLabels, resolveLabels } from \"../core/labels\";\nimport {\n WATERFALL_BASE_LABEL_DY,\n WATERFALL_TICK_LABEL_DY,\n waterfallLayout,\n waterfallRows,\n} from \"../core/waterfallLayout\";\n\nexport type ShapWaterfallProps = {\n explanation: Explanation;\n sampleIndex?: number;\n maxDisplay?: number;\n faithfulOtherRow?: boolean;\n /** Collapse `Genus_species` Features into their genus before drawing. */\n groupByGenus?: boolean;\n classIndex?: number;\n width?: number;\n rowHeight?: number;\n /** Decimal places for the bar labels. Display only — it changes no geometry but the text width. */\n decimals?: ValuePrecision;\n /**\n * Wording for every piece of text the chart draws; keys not given keep SHAP's.\n * Pass a stable object (a module constant or a memo): a new one each render\n * recomputes the layout each render.\n */\n labels?: Partial<PlotLabels>;\n onFeatureClick?: (featureIndex: number | null) => void;\n};\n\nexport function ShapWaterfall({\n explanation,\n sampleIndex = 0,\n maxDisplay = 10,\n faithfulOtherRow = false,\n groupByGenus = false,\n classIndex = 1,\n width = 720,\n rowHeight = 30,\n decimals = 2,\n labels,\n onFeatureClick,\n}: ShapWaterfallProps) {\n const [hovered, setHovered] = useState<number | null>(null);\n const words = useMemo(() => resolveLabels(labels), [labels]);\n const marginTop = 34;\n\n const layout = useMemo(() => {\n const raw = parseExplanation(explanation, { classIndex });\n const parsed = groupByGenus ? groupExplanationByGenus(raw) : raw;\n const rows = waterfallRows(parsed, sampleIndex, maxDisplay, faithfulOtherRow, words);\n return waterfallLayout(rows, {\n width,\n rowHeight,\n marginLeft: 260,\n marginRight: 110,\n marginTop,\n decimals,\n labels: words,\n });\n }, [groupByGenus, \n explanation, sampleIndex, maxDisplay, faithfulOtherRow,\n classIndex, width, rowHeight, decimals, words,\n ]);\n\n return (\n <svg\n width={width}\n height={layout.height}\n role=\"img\"\n aria-label={`Local SHAP waterfall for Sample ${sampleIndex}`}\n >\n {layout.separators.map((separator, index) => (\n <line\n key={`separator-${index}`}\n x1={separator.x1}\n x2={separator.x2}\n y1={separator.y}\n y2={separator.y}\n stroke=\"#cccccc\"\n strokeWidth={1}\n strokeDasharray=\"1 5\"\n />\n ))}\n\n <g aria-hidden=\"true\">\n <line\n x1={layout.plotLeft}\n x2={layout.plotRight}\n y1={layout.plotBottom}\n y2={layout.plotBottom}\n stroke=\"#333333\"\n strokeWidth={1}\n />\n {layout.xTicks.map((tick) => (\n <g key={`tick-${tick.value}`}>\n <line\n x1={tick.x}\n x2={tick.x}\n y1={layout.plotBottom}\n y2={layout.plotBottom + 5}\n stroke=\"#333333\"\n strokeWidth={1}\n />\n <text\n x={tick.x}\n y={layout.plotBottom + WATERFALL_TICK_LABEL_DY}\n textAnchor=\"middle\"\n fontSize={11}\n fill=\"#333333\"\n >\n {tick.label}\n </text>\n </g>\n ))}\n </g>\n\n {layout.connectors.map((connector, index) => (\n <line\n key={`connector-${index}`}\n x1={connector.x}\n x2={connector.x}\n y1={connector.y1}\n y2={connector.y2}\n stroke=\"#bbbbbb\"\n strokeWidth={1}\n strokeDasharray=\"4 4\"\n />\n ))}\n\n {layout.axisMarks.map((mark) => (\n <g key={mark.kind}>\n <line\n x1={mark.x}\n x2={mark.x}\n y1={mark.y1}\n y2={mark.y2}\n stroke=\"#bbbbbb\"\n strokeWidth={1}\n strokeDasharray=\"4 4\"\n />\n <text\n x={mark.x}\n y={\n mark.kind === \"output\"\n ? marginTop - 10\n : layout.plotBottom + WATERFALL_BASE_LABEL_DY\n }\n textAnchor=\"middle\"\n fontSize={12}\n fill=\"#777777\"\n >\n {mark.label}\n </text>\n </g>\n ))}\n\n {layout.arrows.map((arrow, index) => (\n <g\n key={`row-${index}`}\n onMouseEnter={() => setHovered(index)}\n onMouseLeave={() => setHovered(null)}\n onClick={() => onFeatureClick?.(arrow.featureIndex)}\n style={{ cursor: onFeatureClick ? \"pointer\" : \"default\" }}\n >\n <rect\n x={0}\n y={arrow.centerY - rowHeight / 2}\n width={width}\n height={rowHeight}\n fill={hovered === index ? \"#00000008\" : \"transparent\"}\n />\n <text\n x={250}\n y={arrow.centerY}\n textAnchor=\"end\"\n dominantBaseline=\"middle\"\n fontSize={13}\n fill=\"#333333\"\n fontStyle={arrow.isOtherRow ? \"normal\" : \"italic\"}\n >\n {arrow.label}\n </text>\n <polygon\n points={arrow.points.map((point) => `${point.x},${point.y}`).join(\" \")}\n fill={arrow.color}\n stroke=\"rgba(255,255,255,0.8)\"\n strokeWidth={1}\n />\n <text\n x={arrow.valueLabel.x}\n y={arrow.centerY}\n textAnchor={arrow.valueLabel.anchor}\n dominantBaseline=\"middle\"\n fontSize={12}\n fill={arrow.valueLabel.inside ? \"#ffffff\" : arrow.color}\n >\n {arrow.valueLabel.text}\n </text>\n </g>\n ))}\n </svg>\n );\n}\n","import { ShapBar, type ShapBarProps } from \"./src/react/ShapBar\";\nimport { ShapBeeswarm, type ShapBeeswarmProps } from \"./src/react/ShapBeeswarm\";\nimport { ShapHeatmap, type ShapHeatmapProps } from \"./src/react/ShapHeatmap\";\nimport { ShapWaterfall, type ShapWaterfallProps } from \"./src/react/ShapWaterfall\";\n\n/** Give a chart the name it is written as, so React DevTools shows `Plots.bar`. */\nfunction named<T extends object>(component: T, displayName: string): T & { displayName: string } {\n return Object.assign(component, { displayName });\n}\n\n/**\n * The four charts, named the way shap names them in Python: `shap.plots.bar`\n * becomes `<Plots.bar />`.\n *\n * One import brings all four charts into a bundle, even on a page that draws\n * one — about 30 KB minified, against about 8 KB for a single chart, measured\n * with esbuild. That trade was chosen for the single import name.\n */\nexport const Plots = {\n bar: named(ShapBar, \"Plots.bar\"),\n beeswarm: named(ShapBeeswarm, \"Plots.beeswarm\"),\n heatmap: named(ShapHeatmap, \"Plots.heatmap\"),\n waterfall: named(ShapWaterfall, \"Plots.waterfall\"),\n} as const;\n\nexport type BarPlotProps = ShapBarProps;\nexport type BeeswarmPlotProps = ShapBeeswarmProps;\nexport type HeatmapPlotProps = ShapHeatmapProps;\nexport type WaterfallPlotProps = ShapWaterfallProps;\n"],"mappings":"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","names":["jsx","jsxs","useMemo","useState","jsx","jsxs","jsx","jsxs","useState","useMemo","useMemo","useState","jsx","jsxs","useState","useMemo","useMemo","useState","jsx","jsxs","useState","useMemo"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shap-svg",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Interactive SVG charts for SHAP explanations — bar, beeswarm, heatmap and waterfall — drawn in the browser from SHAP values, with a framework-free core and React components.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Pongsakorn P.",
|