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/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 './format-wEav_cPe.cjs';
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 './format-wEav_cPe.js';
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-ZWO4CN22.js";
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": "Mean absolute SHAP value per feature",
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: `SHAP value: ${formatShapValue(activePoint.valueX)}` }),
397
- /* @__PURE__ */ jsx4("text", { x: 7, y: 30, fontSize: 11, fill: "#222222", children: `Feature value: ${Number.isFinite(activePoint.featureValue) ? formatShapValue(activePoint.featureValue) : "missing"}` })
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 `Sample ${column.sampleIndex + 1}`;
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 SHAP value ${formatShapValue(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: `\u03A3\u03C6: ${formatShapValue(activeColumn.total)}` })
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.1",
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.",