@fusedashlabs/widgets 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +1 -1
- package/dist/components/chart-renderer/element/ui9000-chart-renderer.d.ts +1 -0
- package/dist/components/chart-renderer/element/ui9000-chart-renderer.d.ts.map +1 -1
- package/dist/components/chart-renderer/element/ui9000-chart-renderer.js +11 -1
- package/dist/components/chart-renderer/element/ui9000-chart-renderer.js.map +1 -1
- package/dist/components/chart-renderer/lib/registry.d.ts.map +1 -1
- package/dist/components/chart-renderer/lib/registry.js +3 -1
- package/dist/components/chart-renderer/lib/registry.js.map +1 -1
- package/dist/components/kpi-widget/element/styles.d.ts.map +1 -1
- package/dist/components/kpi-widget/element/styles.js +268 -5
- package/dist/components/kpi-widget/element/styles.js.map +1 -1
- package/dist/components/kpi-widget/element/ui9000-kpi-widget.d.ts +10 -1
- package/dist/components/kpi-widget/element/ui9000-kpi-widget.d.ts.map +1 -1
- package/dist/components/kpi-widget/element/ui9000-kpi-widget.js +154 -27
- package/dist/components/kpi-widget/element/ui9000-kpi-widget.js.map +1 -1
- package/dist/components/kpi-widget/index.d.ts +1 -1
- package/dist/components/kpi-widget/index.d.ts.map +1 -1
- package/dist/components/kpi-widget/index.js +7 -4
- package/dist/components/kpi-widget/lib/extract.d.ts +5 -1
- package/dist/components/kpi-widget/lib/extract.d.ts.map +1 -1
- package/dist/components/kpi-widget/lib/extract.js +110 -34
- package/dist/components/kpi-widget/lib/extract.js.map +1 -1
- package/dist/components/kpi-widget/lib/format.d.ts +5 -0
- package/dist/components/kpi-widget/lib/format.d.ts.map +1 -1
- package/dist/components/kpi-widget/lib/format.js +10 -1
- package/dist/components/kpi-widget/lib/format.js.map +1 -1
- package/dist/components/kpi-widget/lib/grid.d.ts +5 -0
- package/dist/components/kpi-widget/lib/grid.d.ts.map +1 -1
- package/dist/components/kpi-widget/lib/grid.js +18 -0
- package/dist/components/kpi-widget/lib/grid.js.map +1 -1
- package/dist/components/kpi-widget/lib/index.d.ts +5 -5
- package/dist/components/kpi-widget/lib/index.d.ts.map +1 -1
- package/dist/components/kpi-widget/lib/normalize.d.ts +2 -0
- package/dist/components/kpi-widget/lib/normalize.d.ts.map +1 -1
- package/dist/components/kpi-widget/lib/normalize.js +73 -12
- package/dist/components/kpi-widget/lib/normalize.js.map +1 -1
- package/dist/components/kpi-widget/lib/types.d.ts +41 -0
- package/dist/components/kpi-widget/lib/types.d.ts.map +1 -1
- package/dist/components/kpi-widget/metadata.json.d.ts +1 -1
- package/dist/components/kpi-widget/metadata.json.js +1 -1
- package/dist/components/map-chart/metadata.json.d.ts +1 -1
- package/dist/components/map-chart/metadata.json.js +1 -1
- package/dist/components/map-chart/render/draw.d.ts.map +1 -1
- package/dist/components/map-chart/render/draw.js +2 -1
- package/dist/components/map-chart/render/draw.js.map +1 -1
- package/dist/components/partial-dependence-chart/element/styles.d.ts +2 -0
- package/dist/components/partial-dependence-chart/element/styles.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/element/styles.js +48 -0
- package/dist/components/partial-dependence-chart/element/styles.js.map +1 -0
- package/dist/components/partial-dependence-chart/element/ui9000-partial-dependence-chart.d.ts +30 -0
- package/dist/components/partial-dependence-chart/element/ui9000-partial-dependence-chart.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/element/ui9000-partial-dependence-chart.js +163 -0
- package/dist/components/partial-dependence-chart/element/ui9000-partial-dependence-chart.js.map +1 -0
- package/dist/components/partial-dependence-chart/index.d.ts +5 -0
- package/dist/components/partial-dependence-chart/index.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/index.js +18 -0
- package/dist/components/partial-dependence-chart/index.js.map +1 -0
- package/dist/components/partial-dependence-chart/lib/domain.d.ts +6 -0
- package/dist/components/partial-dependence-chart/lib/domain.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/lib/domain.js +16 -0
- package/dist/components/partial-dependence-chart/lib/domain.js.map +1 -0
- package/dist/components/partial-dependence-chart/lib/index.d.ts +5 -0
- package/dist/components/partial-dependence-chart/lib/index.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/lib/normalize.d.ts +4 -0
- package/dist/components/partial-dependence-chart/lib/normalize.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/lib/normalize.js +167 -0
- package/dist/components/partial-dependence-chart/lib/normalize.js.map +1 -0
- package/dist/components/partial-dependence-chart/lib/series.d.ts +15 -0
- package/dist/components/partial-dependence-chart/lib/series.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/lib/series.js +63 -0
- package/dist/components/partial-dependence-chart/lib/series.js.map +1 -0
- package/dist/components/partial-dependence-chart/lib/types.d.ts +50 -0
- package/dist/components/partial-dependence-chart/lib/types.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/metadata.json.d.ts +80 -0
- package/dist/components/partial-dependence-chart/metadata.json.js +42 -0
- package/dist/components/partial-dependence-chart/metadata.json.js.map +1 -0
- package/dist/components/partial-dependence-chart/render/draw.d.ts +34 -0
- package/dist/components/partial-dependence-chart/render/draw.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/render/draw.js +95 -0
- package/dist/components/partial-dependence-chart/render/draw.js.map +1 -0
- package/dist/components/partial-dependence-chart/render/index.d.ts +2 -0
- package/dist/components/partial-dependence-chart/render/index.d.ts.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -10
- package/dist/index.js.map +1 -1
- package/dist/lazy/index.d.ts +2 -1
- package/dist/lazy/index.d.ts.map +1 -1
- package/dist/lazy/index.js +8 -0
- package/dist/lazy/index.js.map +1 -1
- package/dist/lazy/partial-dependence-chart.d.ts +4 -0
- package/dist/lazy/partial-dependence-chart.d.ts.map +1 -0
- package/dist/lazy/partial-dependence-chart.js +5 -0
- package/dist/lazy/partial-dependence-chart.js.map +1 -0
- package/dist/utils/chart-helpers.d.ts +2 -0
- package/dist/utils/chart-helpers.d.ts.map +1 -1
- package/dist/utils/chart-helpers.js +15 -0
- package/dist/utils/chart-helpers.js.map +1 -1
- package/dist/utils/fusedash-visual.d.ts +12 -0
- package/dist/utils/fusedash-visual.d.ts.map +1 -1
- package/dist/utils/fusedash-visual.js +7 -0
- package/dist/utils/fusedash-visual.js.map +1 -1
- package/package.json +11 -2
- package/dist/node_modules/lit-html/directive.js +0 -28
- package/dist/node_modules/lit-html/directive.js.map +0 -1
- package/dist/node_modules/lit-html/directives/style-map.js +0 -37
- package/dist/node_modules/lit-html/directives/style-map.js.map +0 -1
- package/dist/node_modules/lit-html/lit-html.js +0 -231
- package/dist/node_modules/lit-html/lit-html.js.map +0 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PropertyValues } from 'lit';
|
|
2
|
+
import { Ui9000ChartElement } from '../../../element/ui9000-chart-base.js';
|
|
3
|
+
import { WidgetScale } from '../../../types/index.js';
|
|
4
|
+
export declare class Ui9000PartialDependenceChart extends Ui9000ChartElement {
|
|
5
|
+
static styles: import('lit').CSSResult[];
|
|
6
|
+
scale: WidgetScale;
|
|
7
|
+
showGrid: boolean;
|
|
8
|
+
showLegend: boolean;
|
|
9
|
+
showTooltip: boolean;
|
|
10
|
+
private _tooltip;
|
|
11
|
+
private _empty;
|
|
12
|
+
private _resizeObserver?;
|
|
13
|
+
private _raf;
|
|
14
|
+
connectedCallback(): void;
|
|
15
|
+
disconnectedCallback(): void;
|
|
16
|
+
updated(changed: PropertyValues): void;
|
|
17
|
+
private scheduleDraw;
|
|
18
|
+
private parseData;
|
|
19
|
+
/** Client legend carries the single "Average" entry; ICE curves stay unlabelled. */
|
|
20
|
+
private renderLegend;
|
|
21
|
+
private draw;
|
|
22
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
23
|
+
}
|
|
24
|
+
declare global {
|
|
25
|
+
interface HTMLElementTagNameMap {
|
|
26
|
+
'ui9000-partial-dependence-chart': Ui9000PartialDependenceChart;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export declare function registerPartialDependenceChart(): void;
|
|
30
|
+
//# sourceMappingURL=ui9000-partial-dependence-chart.d.ts.map
|
package/dist/components/partial-dependence-chart/element/ui9000-partial-dependence-chart.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui9000-partial-dependence-chart.d.ts","sourceRoot":"","sources":["../../../../src/components/partial-dependence-chart/element/ui9000-partial-dependence-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAKzD,OAAO,EAAoB,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC7F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAiB3D,qBACa,4BAA6B,SAAQ,kBAAkB;IAClE,OAAgB,MAAM,4BAA+C;IAGrE,KAAK,EAAE,WAAW,CAAa;IAG/B,QAAQ,UAAQ;IAGhB,UAAU,UAAQ;IAGlB,WAAW,UAAQ;IAGnB,OAAO,CAAC,QAAQ,CAA0D;IAG1E,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,IAAI,CAAK;IAER,iBAAiB,IAAI,IAAI;IAMzB,oBAAoB,IAAI,IAAI;IAM5B,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAI/C,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,SAAS;IAMjB,oFAAoF;IACpF,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,IAAI;IAkDH,MAAM;CA4BhB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iCAAiC,EAAE,4BAA4B,CAAC;KACjE;CACF;AAED,wBAAgB,8BAA8B,IAAI,IAAI,CAIrD"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { nothing, html } from "lit";
|
|
2
|
+
import { property, state, customElement } from "lit/decorators.js";
|
|
3
|
+
import { readThemeFromElement, readCssVar, CSS_VARS } from "../../../context/widget-context.js";
|
|
4
|
+
import { renderChartLegend } from "../../../element/chart-legend-render.js";
|
|
5
|
+
import { Ui9000ChartElement } from "../../../element/ui9000-chart-base.js";
|
|
6
|
+
import { parseJsonAttr, getPartialDependenceDimensions } from "../../../utils/chart-helpers.js";
|
|
7
|
+
import { chartPropsChanged } from "../../../utils/lit-draw.js";
|
|
8
|
+
import { renderPartialDependenceChart } from "../render/draw.js";
|
|
9
|
+
import { partialDependenceStyles } from "./styles.js";
|
|
10
|
+
import { normalizePartialDependenceData } from "../lib/normalize.js";
|
|
11
|
+
import { chartShellStyles } from "../../../element/chart-shell-styles.js";
|
|
12
|
+
var __defProp = Object.defineProperty;
|
|
13
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
14
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
15
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
16
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
17
|
+
if (decorator = decorators[i])
|
|
18
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
19
|
+
if (kind && result) __defProp(target, key, result);
|
|
20
|
+
return result;
|
|
21
|
+
};
|
|
22
|
+
const TOOLTIP_DECIMALS = 3;
|
|
23
|
+
let Ui9000PartialDependenceChart = class extends Ui9000ChartElement {
|
|
24
|
+
constructor() {
|
|
25
|
+
super(...arguments);
|
|
26
|
+
this.scale = "default";
|
|
27
|
+
this.showGrid = true;
|
|
28
|
+
this.showLegend = true;
|
|
29
|
+
this.showTooltip = true;
|
|
30
|
+
this._tooltip = null;
|
|
31
|
+
this._empty = false;
|
|
32
|
+
this._raf = 0;
|
|
33
|
+
}
|
|
34
|
+
connectedCallback() {
|
|
35
|
+
super.connectedCallback();
|
|
36
|
+
this._resizeObserver = new ResizeObserver(() => this.scheduleDraw());
|
|
37
|
+
this._resizeObserver.observe(this);
|
|
38
|
+
}
|
|
39
|
+
disconnectedCallback() {
|
|
40
|
+
var _a;
|
|
41
|
+
(_a = this._resizeObserver) == null ? void 0 : _a.disconnect();
|
|
42
|
+
cancelAnimationFrame(this._raf);
|
|
43
|
+
super.disconnectedCallback();
|
|
44
|
+
}
|
|
45
|
+
updated(changed) {
|
|
46
|
+
if (chartPropsChanged(changed)) this.scheduleDraw();
|
|
47
|
+
}
|
|
48
|
+
scheduleDraw() {
|
|
49
|
+
cancelAnimationFrame(this._raf);
|
|
50
|
+
this._raf = requestAnimationFrame(() => this.draw());
|
|
51
|
+
}
|
|
52
|
+
parseData() {
|
|
53
|
+
return normalizePartialDependenceData(
|
|
54
|
+
parseJsonAttr(this.dataJson, null)
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
/** Client legend carries the single "Average" entry; ICE curves stay unlabelled. */
|
|
58
|
+
renderLegend(model) {
|
|
59
|
+
if (!this.showLegend || !model.averageSeries.length) return nothing;
|
|
60
|
+
return renderChartLegend([
|
|
61
|
+
{ label: "Average", swatch: { kind: "dashed-line", color: model.color } }
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
draw() {
|
|
65
|
+
var _a, _b, _c, _d, _e;
|
|
66
|
+
const root = (_a = this.shadowRoot) == null ? void 0 : _a.querySelector(".chart-root");
|
|
67
|
+
if (!root) return;
|
|
68
|
+
const model = this.parseData();
|
|
69
|
+
this._empty = model.iceSeries.length === 0;
|
|
70
|
+
if (this._empty) {
|
|
71
|
+
root.replaceChildren();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const theme = readThemeFromElement(this);
|
|
75
|
+
const themeMode = readCssVar(this, CSS_VARS.mode, "light") === "dark" ? "dark" : "light";
|
|
76
|
+
const { width, height, margin } = getPartialDependenceDimensions(root, this.scale);
|
|
77
|
+
const xLabel = ((_c = (_b = model.axisDetails) == null ? void 0 : _b[model.xField]) == null ? void 0 : _c.label) ?? model.xField;
|
|
78
|
+
const yLabel = ((_e = (_d = model.axisDetails) == null ? void 0 : _d[model.yField]) == null ? void 0 : _e.label) ?? model.yField;
|
|
79
|
+
renderPartialDependenceChart(root, {
|
|
80
|
+
iceSeries: model.iceSeries,
|
|
81
|
+
averageSeries: model.averageSeries,
|
|
82
|
+
width,
|
|
83
|
+
height,
|
|
84
|
+
margin,
|
|
85
|
+
theme,
|
|
86
|
+
themeMode,
|
|
87
|
+
color: model.color,
|
|
88
|
+
showGrid: this.showGrid,
|
|
89
|
+
showTooltip: this.showTooltip,
|
|
90
|
+
onHover: this.showTooltip ? ({ x, y, event }) => {
|
|
91
|
+
const rect = this.getBoundingClientRect();
|
|
92
|
+
this._tooltip = {
|
|
93
|
+
x: event.clientX - rect.left,
|
|
94
|
+
y: event.clientY - rect.top,
|
|
95
|
+
lines: [
|
|
96
|
+
`${xLabel}: ${x.toFixed(TOOLTIP_DECIMALS)}`,
|
|
97
|
+
`${yLabel}: ${y == null ? "-" : y.toFixed(TOOLTIP_DECIMALS)}`
|
|
98
|
+
]
|
|
99
|
+
};
|
|
100
|
+
} : void 0,
|
|
101
|
+
onLeave: this.showTooltip ? () => {
|
|
102
|
+
this._tooltip = null;
|
|
103
|
+
} : void 0
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
render() {
|
|
107
|
+
const title = this.headerTitle();
|
|
108
|
+
const model = this._empty ? null : this.parseData();
|
|
109
|
+
return html`
|
|
110
|
+
<div class="widget-shell" part="shell">
|
|
111
|
+
${this.renderShellHeader(title)}
|
|
112
|
+
<div class="widget-body">
|
|
113
|
+
${model ? this.renderLegend(model) : nothing}
|
|
114
|
+
<div class="chart-root" part="chart" ?hidden=${this._empty}></div>
|
|
115
|
+
${this._empty ? html`<div class="empty" part="empty">
|
|
116
|
+
Partial dependence needs numeric X and Y fields with at least one ICE series.
|
|
117
|
+
</div>` : nothing}
|
|
118
|
+
${this._tooltip ? html`<div
|
|
119
|
+
class="tooltip"
|
|
120
|
+
part="tooltip"
|
|
121
|
+
style="left:${this._tooltip.x}px;top:${this._tooltip.y}px"
|
|
122
|
+
>
|
|
123
|
+
${this._tooltip.lines.map((line) => html`<div>${line}</div>`)}
|
|
124
|
+
</div>` : nothing}
|
|
125
|
+
${this.renderShellLabelTooltip()}
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
`;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
Ui9000PartialDependenceChart.styles = [partialDependenceStyles, chartShellStyles];
|
|
132
|
+
__decorateClass([
|
|
133
|
+
property({ type: String, attribute: "scale" })
|
|
134
|
+
], Ui9000PartialDependenceChart.prototype, "scale", 2);
|
|
135
|
+
__decorateClass([
|
|
136
|
+
property({ type: Boolean, attribute: "show-grid" })
|
|
137
|
+
], Ui9000PartialDependenceChart.prototype, "showGrid", 2);
|
|
138
|
+
__decorateClass([
|
|
139
|
+
property({ type: Boolean, attribute: "show-legend" })
|
|
140
|
+
], Ui9000PartialDependenceChart.prototype, "showLegend", 2);
|
|
141
|
+
__decorateClass([
|
|
142
|
+
property({ type: Boolean, attribute: "show-tooltip" })
|
|
143
|
+
], Ui9000PartialDependenceChart.prototype, "showTooltip", 2);
|
|
144
|
+
__decorateClass([
|
|
145
|
+
state()
|
|
146
|
+
], Ui9000PartialDependenceChart.prototype, "_tooltip", 2);
|
|
147
|
+
__decorateClass([
|
|
148
|
+
state()
|
|
149
|
+
], Ui9000PartialDependenceChart.prototype, "_empty", 2);
|
|
150
|
+
Ui9000PartialDependenceChart = __decorateClass([
|
|
151
|
+
customElement("ui9000-partial-dependence-chart")
|
|
152
|
+
], Ui9000PartialDependenceChart);
|
|
153
|
+
function registerPartialDependenceChart() {
|
|
154
|
+
if (!customElements.get("ui9000-partial-dependence-chart")) {
|
|
155
|
+
customElements.define("ui9000-partial-dependence-chart", Ui9000PartialDependenceChart);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
registerPartialDependenceChart();
|
|
159
|
+
export {
|
|
160
|
+
Ui9000PartialDependenceChart,
|
|
161
|
+
registerPartialDependenceChart
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=ui9000-partial-dependence-chart.js.map
|
package/dist/components/partial-dependence-chart/element/ui9000-partial-dependence-chart.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui9000-partial-dependence-chart.js","sources":["../../../../src/components/partial-dependence-chart/element/ui9000-partial-dependence-chart.ts"],"sourcesContent":["import { html, nothing, type PropertyValues } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { CSS_VARS, readCssVar, readThemeFromElement } from '../../../context/widget-context.js';\nimport { renderChartLegend } from '../../../element/chart-legend-render.js';\nimport { chartShellStyles, Ui9000ChartElement } from '../../../element/ui9000-chart-base.js';\nimport type { WidgetScale } from '../../../types/index.js';\nimport {\n getPartialDependenceDimensions,\n parseJsonAttr,\n} from '../../../utils/chart-helpers.js';\nimport { chartPropsChanged } from '../../../utils/lit-draw.js';\nimport {\n normalizePartialDependenceData,\n type PartialDependenceChartData,\n type PartialDependenceModel,\n} from '../lib/index.js';\nimport { renderPartialDependenceChart } from '../render/draw.js';\nimport { partialDependenceStyles } from './styles.js';\n\n/** Client tooltip prints three decimals for both axes. */\nconst TOOLTIP_DECIMALS = 3;\n\n@customElement('ui9000-partial-dependence-chart')\nexport class Ui9000PartialDependenceChart extends Ui9000ChartElement {\n static override styles = [partialDependenceStyles, chartShellStyles];\n\n @property({ type: String, attribute: 'scale' })\n scale: WidgetScale = 'default';\n\n @property({ type: Boolean, attribute: 'show-grid' })\n showGrid = true;\n\n @property({ type: Boolean, attribute: 'show-legend' })\n showLegend = true;\n\n @property({ type: Boolean, attribute: 'show-tooltip' })\n showTooltip = true;\n\n @state()\n private _tooltip: { x: number; y: number; lines: string[] } | null = null;\n\n @state()\n private _empty = false;\n\n private _resizeObserver?: ResizeObserver;\n private _raf = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._resizeObserver = new ResizeObserver(() => this.scheduleDraw());\n this._resizeObserver.observe(this);\n }\n\n override disconnectedCallback(): void {\n this._resizeObserver?.disconnect();\n cancelAnimationFrame(this._raf);\n super.disconnectedCallback();\n }\n\n override updated(changed: PropertyValues): void {\n if (chartPropsChanged(changed)) this.scheduleDraw();\n }\n\n private scheduleDraw(): void {\n cancelAnimationFrame(this._raf);\n this._raf = requestAnimationFrame(() => this.draw());\n }\n\n private parseData(): PartialDependenceModel {\n return normalizePartialDependenceData(\n parseJsonAttr<PartialDependenceChartData>(this.dataJson, null),\n );\n }\n\n /** Client legend carries the single \"Average\" entry; ICE curves stay unlabelled. */\n private renderLegend(model: PartialDependenceModel) {\n if (!this.showLegend || !model.averageSeries.length) return nothing;\n return renderChartLegend([\n { label: 'Average', swatch: { kind: 'dashed-line', color: model.color } },\n ]);\n }\n\n private draw(): void {\n const root = this.shadowRoot?.querySelector('.chart-root') as HTMLElement | null;\n if (!root) return;\n\n const model = this.parseData();\n this._empty = model.iceSeries.length === 0;\n if (this._empty) {\n root.replaceChildren();\n return;\n }\n\n const theme = readThemeFromElement(this);\n const themeMode =\n readCssVar(this, CSS_VARS.mode, 'light') === 'dark' ? 'dark' : 'light';\n const { width, height, margin } = getPartialDependenceDimensions(root, this.scale);\n const xLabel = model.axisDetails?.[model.xField]?.label ?? model.xField;\n const yLabel = model.axisDetails?.[model.yField]?.label ?? model.yField;\n\n renderPartialDependenceChart(root, {\n iceSeries: model.iceSeries,\n averageSeries: model.averageSeries,\n width,\n height,\n margin,\n theme,\n themeMode,\n color: model.color,\n showGrid: this.showGrid,\n showTooltip: this.showTooltip,\n onHover: this.showTooltip\n ? ({ x, y, event }) => {\n const rect = this.getBoundingClientRect();\n this._tooltip = {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n lines: [\n `${xLabel}: ${x.toFixed(TOOLTIP_DECIMALS)}`,\n `${yLabel}: ${y == null ? '-' : y.toFixed(TOOLTIP_DECIMALS)}`,\n ],\n };\n }\n : undefined,\n onLeave: this.showTooltip\n ? () => {\n this._tooltip = null;\n }\n : undefined,\n });\n }\n\n override render() {\n const title = this.headerTitle();\n const model = this._empty ? null : this.parseData();\n return html`\n <div class=\"widget-shell\" part=\"shell\">\n ${this.renderShellHeader(title)}\n <div class=\"widget-body\">\n ${model ? this.renderLegend(model) : nothing}\n <div class=\"chart-root\" part=\"chart\" ?hidden=${this._empty}></div>\n ${this._empty\n ? html`<div class=\"empty\" part=\"empty\">\n Partial dependence needs numeric X and Y fields with at least one ICE series.\n </div>`\n : nothing}\n ${this._tooltip\n ? html`<div\n class=\"tooltip\"\n part=\"tooltip\"\n style=\"left:${this._tooltip.x}px;top:${this._tooltip.y}px\"\n >\n ${this._tooltip.lines.map((line) => html`<div>${line}</div>`)}\n </div>`\n : nothing}\n ${this.renderShellLabelTooltip()}\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ui9000-partial-dependence-chart': Ui9000PartialDependenceChart;\n }\n}\n\nexport function registerPartialDependenceChart(): void {\n if (!customElements.get('ui9000-partial-dependence-chart')) {\n customElements.define('ui9000-partial-dependence-chart', Ui9000PartialDependenceChart);\n }\n}\n\nregisterPartialDependenceChart();\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { Ui9000PartialDependenceChart, registerPartialDependenceChart, } from './element/ui9000-partial-dependence-chart.js';
|
|
2
|
+
export { renderPartialDependenceChart } from './render/draw.js';
|
|
3
|
+
export { computeAverageSeries, nearestAveragePoint, normalizePartialDependenceData, pdpLinearDomain, type IcePoint, type IceSeries, type PartialDependenceChartData, type PartialDependenceModel, } from './lib/index.js';
|
|
4
|
+
export { default as partialDependenceChartMetadata } from './metadata.json';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/partial-dependence-chart/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,8BAA8B,GAC/B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,8BAA8B,EAC9B,eAAe,EACf,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,GAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,OAAO,IAAI,8BAA8B,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { registerPartialDependenceChart } from "./element/ui9000-partial-dependence-chart.js";
|
|
2
|
+
import { Ui9000PartialDependenceChart } from "./element/ui9000-partial-dependence-chart.js";
|
|
3
|
+
import { renderPartialDependenceChart } from "./render/draw.js";
|
|
4
|
+
import { default as default2 } from "./metadata.json.js";
|
|
5
|
+
import { computeAverageSeries, nearestAveragePoint } from "./lib/series.js";
|
|
6
|
+
import { normalizePartialDependenceData } from "./lib/normalize.js";
|
|
7
|
+
import { pdpLinearDomain } from "./lib/domain.js";
|
|
8
|
+
export {
|
|
9
|
+
Ui9000PartialDependenceChart,
|
|
10
|
+
computeAverageSeries,
|
|
11
|
+
nearestAveragePoint,
|
|
12
|
+
normalizePartialDependenceData,
|
|
13
|
+
default2 as partialDependenceChartMetadata,
|
|
14
|
+
pdpLinearDomain,
|
|
15
|
+
registerPartialDependenceChart,
|
|
16
|
+
renderPartialDependenceChart
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client PDP axis domain: raw extent, no zero baseline and no padding, with a
|
|
3
|
+
* hairline spread so a flat series still gets a usable scale.
|
|
4
|
+
*/
|
|
5
|
+
export declare function pdpLinearDomain(values: Iterable<number>): [number, number];
|
|
6
|
+
//# sourceMappingURL=domain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../../../src/components/partial-dependence-chart/lib/domain.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAW1E"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function pdpLinearDomain(values) {
|
|
2
|
+
let min = Infinity;
|
|
3
|
+
let max = -Infinity;
|
|
4
|
+
for (const v of values) {
|
|
5
|
+
if (!Number.isFinite(v)) continue;
|
|
6
|
+
if (v < min) min = v;
|
|
7
|
+
if (v > max) max = v;
|
|
8
|
+
}
|
|
9
|
+
if (!Number.isFinite(min) || !Number.isFinite(max)) return [0, 1];
|
|
10
|
+
if (min === max) return [min - 1e-6, max + 1e-6];
|
|
11
|
+
return [min, max];
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
pdpLinearDomain
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=domain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.js","sources":["../../../../src/components/partial-dependence-chart/lib/domain.ts"],"sourcesContent":["/**\n * Client PDP axis domain: raw extent, no zero baseline and no padding, with a\n * hairline spread so a flat series still gets a usable scale.\n */\nexport function pdpLinearDomain(values: Iterable<number>): [number, number] {\n let min = Infinity;\n let max = -Infinity;\n for (const v of values) {\n if (!Number.isFinite(v)) continue;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n if (!Number.isFinite(min) || !Number.isFinite(max)) return [0, 1];\n if (min === max) return [min - 1e-6, max + 1e-6];\n return [min, max];\n}\n"],"names":[],"mappings":"AAIO,SAAS,gBAAgB,QAA4C;AAC1E,MAAI,MAAM;AACV,MAAI,MAAM;AACV,aAAW,KAAK,QAAQ;AACtB,QAAI,CAAC,OAAO,SAAS,CAAC,EAAG;AACzB,QAAI,IAAI,IAAK,OAAM;AACnB,QAAI,IAAI,IAAK,OAAM;AAAA,EACrB;AACA,MAAI,CAAC,OAAO,SAAS,GAAG,KAAK,CAAC,OAAO,SAAS,GAAG,EAAG,QAAO,CAAC,GAAG,CAAC;AAChE,MAAI,QAAQ,IAAK,QAAO,CAAC,MAAM,MAAM,MAAM,IAAI;AAC/C,SAAO,CAAC,KAAK,GAAG;AAClB;"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { normalizePartialDependenceData } from './normalize.js';
|
|
2
|
+
export { computeAverageSeries, nearestAveragePoint } from './series.js';
|
|
3
|
+
export { pdpLinearDomain } from './domain.js';
|
|
4
|
+
export type { IcePoint, IceSeries, PartialDependenceChartData, PartialDependenceModel, } from './types.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/partial-dependence-chart/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACV,QAAQ,EACR,SAAS,EACT,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { PartialDependenceChartData, PartialDependenceModel } from './types.js';
|
|
2
|
+
/** Normalize chat / FuseDash WidgetItem payloads into ICE curves plus the average. */
|
|
3
|
+
export declare function normalizePartialDependenceData(input: PartialDependenceChartData): PartialDependenceModel;
|
|
4
|
+
//# sourceMappingURL=normalize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../src/components/partial-dependence-chart/lib/normalize.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAGV,0BAA0B,EAC1B,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAoKpB,sFAAsF;AACtF,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,0BAA0B,GAChC,sBAAsB,CA2CxB"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { resolveFormattingColor } from "../../../utils/fuse-palette.js";
|
|
2
|
+
import { isFuseWidgetPayload, rowsOf, firstField, resolveGroupByKey, resolveUniqueValuesOrder } from "../../../utils/fuse-widget.js";
|
|
3
|
+
import { toNumber, computeAverageSeries } from "./series.js";
|
|
4
|
+
const EMPTY = {
|
|
5
|
+
iceSeries: [],
|
|
6
|
+
averageSeries: [],
|
|
7
|
+
xField: "",
|
|
8
|
+
yField: "",
|
|
9
|
+
color: resolveFormattingColor(void 0, "default", 1)
|
|
10
|
+
};
|
|
11
|
+
const AVERAGE_KEY = /average/i;
|
|
12
|
+
function buildModel(curves, order, fields) {
|
|
13
|
+
for (const [key, points] of curves) {
|
|
14
|
+
if (AVERAGE_KEY.test(key)) {
|
|
15
|
+
curves.delete(key);
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
points.sort((a, b) => a.x - b.x);
|
|
19
|
+
}
|
|
20
|
+
const iceSeries = order.filter((key) => curves.has(key)).map((key) => ({ key, points: curves.get(key) }));
|
|
21
|
+
if (!iceSeries.length) return { ...EMPTY, ...fields };
|
|
22
|
+
return {
|
|
23
|
+
iceSeries,
|
|
24
|
+
averageSeries: computeAverageSeries(iceSeries.map((s) => s.points)),
|
|
25
|
+
...fields
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function fromRows(rows) {
|
|
29
|
+
const curves = /* @__PURE__ */ new Map();
|
|
30
|
+
const order = [];
|
|
31
|
+
for (const row of rows) {
|
|
32
|
+
const x = toNumber(row.x);
|
|
33
|
+
const y = toNumber(row.y);
|
|
34
|
+
if (x == null || y == null) continue;
|
|
35
|
+
const key = row.group != null ? String(row.group) : "default";
|
|
36
|
+
let points = curves.get(key);
|
|
37
|
+
if (!points) {
|
|
38
|
+
points = [];
|
|
39
|
+
curves.set(key, points);
|
|
40
|
+
order.push(key);
|
|
41
|
+
}
|
|
42
|
+
points.push({ x, y });
|
|
43
|
+
}
|
|
44
|
+
return buildModel(curves, order, {
|
|
45
|
+
xField: "x",
|
|
46
|
+
yField: "y",
|
|
47
|
+
groupField: order.length > 1 || order[0] !== "default" ? "group" : void 0,
|
|
48
|
+
color: resolveFormattingColor(void 0, "default", 1)
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function fromIceSeries(series, fields) {
|
|
52
|
+
const curves = /* @__PURE__ */ new Map();
|
|
53
|
+
const order = [];
|
|
54
|
+
series.forEach((entry, index) => {
|
|
55
|
+
const key = String(entry.key ?? index);
|
|
56
|
+
const points = [];
|
|
57
|
+
for (const p of entry.points ?? []) {
|
|
58
|
+
const x = toNumber(p.x);
|
|
59
|
+
const y = toNumber(p.y);
|
|
60
|
+
if (x == null || y == null) continue;
|
|
61
|
+
points.push({ x, y });
|
|
62
|
+
}
|
|
63
|
+
if (!points.length) return;
|
|
64
|
+
curves.set(key, points);
|
|
65
|
+
order.push(key);
|
|
66
|
+
});
|
|
67
|
+
return buildModel(curves, order, {
|
|
68
|
+
xField: fields.xField ?? "x",
|
|
69
|
+
yField: fields.yField ?? "y",
|
|
70
|
+
groupField: fields.groupField,
|
|
71
|
+
color: fields.color ?? resolveFormattingColor(void 0, "default", 1),
|
|
72
|
+
axisDetails: fields.axisDetails
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function fromSeries(series) {
|
|
76
|
+
const curves = /* @__PURE__ */ new Map();
|
|
77
|
+
const order = [];
|
|
78
|
+
series.forEach((entry, index) => {
|
|
79
|
+
const key = String(entry.name ?? entry.id ?? index);
|
|
80
|
+
const points = [];
|
|
81
|
+
for (const p of entry.points ?? []) {
|
|
82
|
+
const x = toNumber(p.x);
|
|
83
|
+
const y = toNumber(p.y);
|
|
84
|
+
if (x == null || y == null) continue;
|
|
85
|
+
points.push({ x, y });
|
|
86
|
+
}
|
|
87
|
+
if (!points.length) return;
|
|
88
|
+
curves.set(key, points);
|
|
89
|
+
order.push(key);
|
|
90
|
+
});
|
|
91
|
+
return buildModel(curves, order, {
|
|
92
|
+
xField: "x",
|
|
93
|
+
yField: "y",
|
|
94
|
+
groupField: "series",
|
|
95
|
+
color: resolveFormattingColor(void 0, "default", 1)
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function fromFuseWidget(widget) {
|
|
99
|
+
const rows = rowsOf(widget);
|
|
100
|
+
const xField = firstField(widget.xAxe ?? void 0) ?? "x";
|
|
101
|
+
const yField = firstField(widget.yAxe ?? void 0) ?? "y";
|
|
102
|
+
const groupField = resolveGroupByKey(widget) ?? "series";
|
|
103
|
+
const curves = /* @__PURE__ */ new Map();
|
|
104
|
+
for (const row of rows) {
|
|
105
|
+
const x = toNumber(row[xField]);
|
|
106
|
+
const y = toNumber(row[yField]);
|
|
107
|
+
if (x == null || y == null) continue;
|
|
108
|
+
const key = String(row[groupField] ?? "default");
|
|
109
|
+
let points = curves.get(key);
|
|
110
|
+
if (!points) {
|
|
111
|
+
points = [];
|
|
112
|
+
curves.set(key, points);
|
|
113
|
+
}
|
|
114
|
+
points.push({ x, y });
|
|
115
|
+
}
|
|
116
|
+
const order = resolveUniqueValuesOrder([...curves.keys()], widget.uniqueValues, groupField);
|
|
117
|
+
return buildModel(curves, order, {
|
|
118
|
+
xField,
|
|
119
|
+
yField,
|
|
120
|
+
groupField,
|
|
121
|
+
// The client paints every ICE curve and the average in one brand color, so
|
|
122
|
+
// the widget's formatting is read once instead of per group.
|
|
123
|
+
color: resolveFormattingColor(widget.formatting, "default", 1),
|
|
124
|
+
axisDetails: widget.axisDetails ?? void 0
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function normalizePartialDependenceData(input) {
|
|
128
|
+
if (!input) return EMPTY;
|
|
129
|
+
if (Array.isArray(input)) {
|
|
130
|
+
if (!input.length) return EMPTY;
|
|
131
|
+
const first = input[0];
|
|
132
|
+
if ("x" in first && "y" in first) {
|
|
133
|
+
return fromRows(input);
|
|
134
|
+
}
|
|
135
|
+
if ("label" in first && "value" in first) {
|
|
136
|
+
return fromRows(
|
|
137
|
+
input.map((d) => ({
|
|
138
|
+
x: d.label,
|
|
139
|
+
y: d.value
|
|
140
|
+
}))
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
return EMPTY;
|
|
144
|
+
}
|
|
145
|
+
if (isFuseWidgetPayload(input)) return fromFuseWidget(input);
|
|
146
|
+
if (typeof input === "object") {
|
|
147
|
+
const candidate = input;
|
|
148
|
+
if (Array.isArray(candidate.iceSeries)) {
|
|
149
|
+
return fromIceSeries(candidate.iceSeries, {
|
|
150
|
+
xField: candidate.xField,
|
|
151
|
+
yField: candidate.yField,
|
|
152
|
+
groupField: candidate.groupField,
|
|
153
|
+
color: candidate.color,
|
|
154
|
+
axisDetails: candidate.axisDetails
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
if (Array.isArray(candidate.series)) return fromSeries(candidate.series);
|
|
158
|
+
if (Array.isArray(candidate.points)) {
|
|
159
|
+
return fromRows(candidate.points.map((p) => ({ x: p.x, y: p.y })));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return EMPTY;
|
|
163
|
+
}
|
|
164
|
+
export {
|
|
165
|
+
normalizePartialDependenceData
|
|
166
|
+
};
|
|
167
|
+
//# sourceMappingURL=normalize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.js","sources":["../../../../src/components/partial-dependence-chart/lib/normalize.ts"],"sourcesContent":["import { resolveFormattingColor } from '../../../utils/fuse-palette.js';\nimport {\n firstField,\n isFuseWidgetPayload,\n resolveGroupByKey,\n resolveUniqueValuesOrder,\n rowsOf,\n type FuseWidgetLike,\n} from '../../../utils/fuse-widget.js';\nimport { computeAverageSeries, toNumber } from './series.js';\nimport type {\n IcePoint,\n IceSeries,\n PartialDependenceChartData,\n PartialDependenceModel,\n} from './types.js';\n\nconst EMPTY: PartialDependenceModel = {\n iceSeries: [],\n averageSeries: [],\n xField: '',\n yField: '',\n color: resolveFormattingColor(undefined, 'default', 1),\n};\n\n/** The chart always recomputes the average, so a supplied one is dropped. */\nconst AVERAGE_KEY = /average/i;\n\nfunction buildModel(\n curves: Map<string, IcePoint[]>,\n order: string[],\n fields: {\n xField: string;\n yField: string;\n groupField?: string;\n color: string;\n axisDetails?: PartialDependenceModel['axisDetails'];\n },\n): PartialDependenceModel {\n for (const [key, points] of curves) {\n if (AVERAGE_KEY.test(key)) {\n curves.delete(key);\n continue;\n }\n points.sort((a, b) => a.x - b.x);\n }\n\n const iceSeries: IceSeries[] = order\n .filter((key) => curves.has(key))\n .map((key) => ({ key, points: curves.get(key) as IcePoint[] }));\n\n if (!iceSeries.length) return { ...EMPTY, ...fields };\n\n return {\n iceSeries,\n averageSeries: computeAverageSeries(iceSeries.map((s) => s.points)),\n ...fields,\n };\n}\n\nfunction fromRows(\n rows: Array<{ x: unknown; y: unknown; group?: unknown }>,\n): PartialDependenceModel {\n const curves = new Map<string, IcePoint[]>();\n const order: string[] = [];\n for (const row of rows) {\n const x = toNumber(row.x);\n const y = toNumber(row.y);\n if (x == null || y == null) continue;\n const key = row.group != null ? String(row.group) : 'default';\n let points = curves.get(key);\n if (!points) {\n points = [];\n curves.set(key, points);\n order.push(key);\n }\n points.push({ x, y });\n }\n return buildModel(curves, order, {\n xField: 'x',\n yField: 'y',\n groupField: order.length > 1 || order[0] !== 'default' ? 'group' : undefined,\n color: resolveFormattingColor(undefined, 'default', 1),\n });\n}\n\nfunction fromIceSeries(\n series: Array<{ key?: unknown; points?: Array<{ x: unknown; y: unknown }> }>,\n fields: {\n xField?: string;\n yField?: string;\n groupField?: string;\n color?: string;\n axisDetails?: PartialDependenceModel['axisDetails'];\n },\n): PartialDependenceModel {\n const curves = new Map<string, IcePoint[]>();\n const order: string[] = [];\n series.forEach((entry, index) => {\n const key = String(entry.key ?? index);\n const points: IcePoint[] = [];\n for (const p of entry.points ?? []) {\n const x = toNumber(p.x);\n const y = toNumber(p.y);\n if (x == null || y == null) continue;\n points.push({ x, y });\n }\n if (!points.length) return;\n curves.set(key, points);\n order.push(key);\n });\n return buildModel(curves, order, {\n xField: fields.xField ?? 'x',\n yField: fields.yField ?? 'y',\n groupField: fields.groupField,\n color: fields.color ?? resolveFormattingColor(undefined, 'default', 1),\n axisDetails: fields.axisDetails,\n });\n}\n\nfunction fromSeries(\n series: Array<{ id?: string; name?: string; points?: Array<{ x: unknown; y: unknown }> }>,\n): PartialDependenceModel {\n const curves = new Map<string, IcePoint[]>();\n const order: string[] = [];\n series.forEach((entry, index) => {\n const key = String(entry.name ?? entry.id ?? index);\n const points: IcePoint[] = [];\n for (const p of entry.points ?? []) {\n const x = toNumber(p.x);\n const y = toNumber(p.y);\n if (x == null || y == null) continue;\n points.push({ x, y });\n }\n if (!points.length) return;\n curves.set(key, points);\n order.push(key);\n });\n return buildModel(curves, order, {\n xField: 'x',\n yField: 'y',\n groupField: 'series',\n color: resolveFormattingColor(undefined, 'default', 1),\n });\n}\n\nfunction fromFuseWidget(widget: FuseWidgetLike): PartialDependenceModel {\n const rows = rowsOf(widget);\n const xField = firstField(widget.xAxe ?? undefined) ?? 'x';\n const yField = firstField(widget.yAxe ?? undefined) ?? 'y';\n const groupField = resolveGroupByKey(widget) ?? 'series';\n\n const curves = new Map<string, IcePoint[]>();\n for (const row of rows) {\n const x = toNumber(row[xField]);\n const y = toNumber(row[yField]);\n if (x == null || y == null) continue;\n const key = String(row[groupField] ?? 'default');\n let points = curves.get(key);\n if (!points) {\n points = [];\n curves.set(key, points);\n }\n points.push({ x, y });\n }\n\n const order = resolveUniqueValuesOrder([...curves.keys()], widget.uniqueValues, groupField);\n\n return buildModel(curves, order, {\n xField,\n yField,\n groupField,\n // The client paints every ICE curve and the average in one brand color, so\n // the widget's formatting is read once instead of per group.\n color: resolveFormattingColor(widget.formatting, 'default', 1),\n axisDetails: widget.axisDetails ?? undefined,\n });\n}\n\n/** Normalize chat / FuseDash WidgetItem payloads into ICE curves plus the average. */\nexport function normalizePartialDependenceData(\n input: PartialDependenceChartData,\n): PartialDependenceModel {\n if (!input) return EMPTY;\n\n if (Array.isArray(input)) {\n if (!input.length) return EMPTY;\n const first = input[0] as Record<string, unknown>;\n if ('x' in first && 'y' in first) {\n return fromRows(input as Array<{ x: unknown; y: unknown; group?: unknown }>);\n }\n if ('label' in first && 'value' in first) {\n return fromRows(\n (input as Array<{ label: string | number; value: number }>).map((d) => ({\n x: d.label,\n y: d.value,\n })),\n );\n }\n return EMPTY;\n }\n\n if (isFuseWidgetPayload(input)) return fromFuseWidget(input);\n\n if (typeof input === 'object') {\n const candidate = input as Partial<PartialDependenceModel> & {\n points?: Array<{ x: unknown; y: unknown }>;\n series?: Array<{ id?: string; name?: string; points?: Array<{ x: unknown; y: unknown }> }>;\n };\n if (Array.isArray(candidate.iceSeries)) {\n return fromIceSeries(candidate.iceSeries, {\n xField: candidate.xField,\n yField: candidate.yField,\n groupField: candidate.groupField,\n color: candidate.color,\n axisDetails: candidate.axisDetails,\n });\n }\n if (Array.isArray(candidate.series)) return fromSeries(candidate.series);\n if (Array.isArray(candidate.points)) {\n return fromRows(candidate.points.map((p) => ({ x: p.x, y: p.y })));\n }\n }\n\n return EMPTY;\n}\n"],"names":[],"mappings":";;;AAiBA,MAAM,QAAgC;AAAA,EACpC,WAAW,CAAA;AAAA,EACX,eAAe,CAAA;AAAA,EACf,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO,uBAAuB,QAAW,WAAW,CAAC;AACvD;AAGA,MAAM,cAAc;AAEpB,SAAS,WACP,QACA,OACA,QAOwB;AACxB,aAAW,CAAC,KAAK,MAAM,KAAK,QAAQ;AAClC,QAAI,YAAY,KAAK,GAAG,GAAG;AACzB,aAAO,OAAO,GAAG;AACjB;AAAA,IACF;AACA,WAAO,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AAAA,EACjC;AAEA,QAAM,YAAyB,MAC5B,OAAO,CAAC,QAAQ,OAAO,IAAI,GAAG,CAAC,EAC/B,IAAI,CAAC,SAAS,EAAE,KAAK,QAAQ,OAAO,IAAI,GAAG,IAAkB;AAEhE,MAAI,CAAC,UAAU,OAAQ,QAAO,EAAE,GAAG,OAAO,GAAG,OAAA;AAE7C,SAAO;AAAA,IACL;AAAA,IACA,eAAe,qBAAqB,UAAU,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;AAAA,IAClE,GAAG;AAAA,EAAA;AAEP;AAEA,SAAS,SACP,MACwB;AACxB,QAAM,6BAAa,IAAA;AACnB,QAAM,QAAkB,CAAA;AACxB,aAAW,OAAO,MAAM;AACtB,UAAM,IAAI,SAAS,IAAI,CAAC;AACxB,UAAM,IAAI,SAAS,IAAI,CAAC;AACxB,QAAI,KAAK,QAAQ,KAAK,KAAM;AAC5B,UAAM,MAAM,IAAI,SAAS,OAAO,OAAO,IAAI,KAAK,IAAI;AACpD,QAAI,SAAS,OAAO,IAAI,GAAG;AAC3B,QAAI,CAAC,QAAQ;AACX,eAAS,CAAA;AACT,aAAO,IAAI,KAAK,MAAM;AACtB,YAAM,KAAK,GAAG;AAAA,IAChB;AACA,WAAO,KAAK,EAAE,GAAG,EAAA,CAAG;AAAA,EACtB;AACA,SAAO,WAAW,QAAQ,OAAO;AAAA,IAC/B,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,YAAY,MAAM,SAAS,KAAK,MAAM,CAAC,MAAM,YAAY,UAAU;AAAA,IACnE,OAAO,uBAAuB,QAAW,WAAW,CAAC;AAAA,EAAA,CACtD;AACH;AAEA,SAAS,cACP,QACA,QAOwB;AACxB,QAAM,6BAAa,IAAA;AACnB,QAAM,QAAkB,CAAA;AACxB,SAAO,QAAQ,CAAC,OAAO,UAAU;AAC/B,UAAM,MAAM,OAAO,MAAM,OAAO,KAAK;AACrC,UAAM,SAAqB,CAAA;AAC3B,eAAW,KAAK,MAAM,UAAU,CAAA,GAAI;AAClC,YAAM,IAAI,SAAS,EAAE,CAAC;AACtB,YAAM,IAAI,SAAS,EAAE,CAAC;AACtB,UAAI,KAAK,QAAQ,KAAK,KAAM;AAC5B,aAAO,KAAK,EAAE,GAAG,EAAA,CAAG;AAAA,IACtB;AACA,QAAI,CAAC,OAAO,OAAQ;AACpB,WAAO,IAAI,KAAK,MAAM;AACtB,UAAM,KAAK,GAAG;AAAA,EAChB,CAAC;AACD,SAAO,WAAW,QAAQ,OAAO;AAAA,IAC/B,QAAQ,OAAO,UAAU;AAAA,IACzB,QAAQ,OAAO,UAAU;AAAA,IACzB,YAAY,OAAO;AAAA,IACnB,OAAO,OAAO,SAAS,uBAAuB,QAAW,WAAW,CAAC;AAAA,IACrE,aAAa,OAAO;AAAA,EAAA,CACrB;AACH;AAEA,SAAS,WACP,QACwB;AACxB,QAAM,6BAAa,IAAA;AACnB,QAAM,QAAkB,CAAA;AACxB,SAAO,QAAQ,CAAC,OAAO,UAAU;AAC/B,UAAM,MAAM,OAAO,MAAM,QAAQ,MAAM,MAAM,KAAK;AAClD,UAAM,SAAqB,CAAA;AAC3B,eAAW,KAAK,MAAM,UAAU,CAAA,GAAI;AAClC,YAAM,IAAI,SAAS,EAAE,CAAC;AACtB,YAAM,IAAI,SAAS,EAAE,CAAC;AACtB,UAAI,KAAK,QAAQ,KAAK,KAAM;AAC5B,aAAO,KAAK,EAAE,GAAG,EAAA,CAAG;AAAA,IACtB;AACA,QAAI,CAAC,OAAO,OAAQ;AACpB,WAAO,IAAI,KAAK,MAAM;AACtB,UAAM,KAAK,GAAG;AAAA,EAChB,CAAC;AACD,SAAO,WAAW,QAAQ,OAAO;AAAA,IAC/B,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,OAAO,uBAAuB,QAAW,WAAW,CAAC;AAAA,EAAA,CACtD;AACH;AAEA,SAAS,eAAe,QAAgD;AACtE,QAAM,OAAO,OAAO,MAAM;AAC1B,QAAM,SAAS,WAAW,OAAO,QAAQ,MAAS,KAAK;AACvD,QAAM,SAAS,WAAW,OAAO,QAAQ,MAAS,KAAK;AACvD,QAAM,aAAa,kBAAkB,MAAM,KAAK;AAEhD,QAAM,6BAAa,IAAA;AACnB,aAAW,OAAO,MAAM;AACtB,UAAM,IAAI,SAAS,IAAI,MAAM,CAAC;AAC9B,UAAM,IAAI,SAAS,IAAI,MAAM,CAAC;AAC9B,QAAI,KAAK,QAAQ,KAAK,KAAM;AAC5B,UAAM,MAAM,OAAO,IAAI,UAAU,KAAK,SAAS;AAC/C,QAAI,SAAS,OAAO,IAAI,GAAG;AAC3B,QAAI,CAAC,QAAQ;AACX,eAAS,CAAA;AACT,aAAO,IAAI,KAAK,MAAM;AAAA,IACxB;AACA,WAAO,KAAK,EAAE,GAAG,EAAA,CAAG;AAAA,EACtB;AAEA,QAAM,QAAQ,yBAAyB,CAAC,GAAG,OAAO,MAAM,GAAG,OAAO,cAAc,UAAU;AAE1F,SAAO,WAAW,QAAQ,OAAO;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA,OAAO,uBAAuB,OAAO,YAAY,WAAW,CAAC;AAAA,IAC7D,aAAa,OAAO,eAAe;AAAA,EAAA,CACpC;AACH;AAGO,SAAS,+BACd,OACwB;AACxB,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,QAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,UAAM,QAAQ,MAAM,CAAC;AACrB,QAAI,OAAO,SAAS,OAAO,OAAO;AAChC,aAAO,SAAS,KAA2D;AAAA,IAC7E;AACA,QAAI,WAAW,SAAS,WAAW,OAAO;AACxC,aAAO;AAAA,QACJ,MAA2D,IAAI,CAAC,OAAO;AAAA,UACtE,GAAG,EAAE;AAAA,UACL,GAAG,EAAE;AAAA,QAAA,EACL;AAAA,MAAA;AAAA,IAEN;AACA,WAAO;AAAA,EACT;AAEA,MAAI,oBAAoB,KAAK,EAAG,QAAO,eAAe,KAAK;AAE3D,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,YAAY;AAIlB,QAAI,MAAM,QAAQ,UAAU,SAAS,GAAG;AACtC,aAAO,cAAc,UAAU,WAAW;AAAA,QACxC,QAAQ,UAAU;AAAA,QAClB,QAAQ,UAAU;AAAA,QAClB,YAAY,UAAU;AAAA,QACtB,OAAO,UAAU;AAAA,QACjB,aAAa,UAAU;AAAA,MAAA,CACxB;AAAA,IACH;AACA,QAAI,MAAM,QAAQ,UAAU,MAAM,EAAG,QAAO,WAAW,UAAU,MAAM;AACvE,QAAI,MAAM,QAAQ,UAAU,MAAM,GAAG;AACnC,aAAO,SAAS,UAAU,OAAO,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAA,EAAI,CAAC;AAAA,IACnE;AAAA,EACF;AAEA,SAAO;AACT;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IcePoint } from './types.js';
|
|
2
|
+
export declare function toNumber(value: unknown): number | null;
|
|
3
|
+
/**
|
|
4
|
+
* Average the ICE curves on the union of their x values — client
|
|
5
|
+
* `computeAverageSeries`, with the linear `findIndex` scan replaced by a binary
|
|
6
|
+
* search so a dense mock stays O(x · groups · log n).
|
|
7
|
+
* Each group must already be sorted by x.
|
|
8
|
+
*/
|
|
9
|
+
export declare function computeAverageSeries(groups: Iterable<IcePoint[]>): IcePoint[];
|
|
10
|
+
/**
|
|
11
|
+
* Value of the average curve closest to `x` — backs the client's
|
|
12
|
+
* "tooltip shows nearest avg value" pointermove handler.
|
|
13
|
+
*/
|
|
14
|
+
export declare function nearestAveragePoint(averageSeries: IcePoint[], x: number): IcePoint | null;
|
|
15
|
+
//# sourceMappingURL=series.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"series.d.ts","sourceRoot":"","sources":["../../../../src/components/partial-dependence-chart/lib/series.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAGtD;AAcD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,QAAQ,EAAE,CA8B7E;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,QAAQ,EAAE,EACzB,CAAC,EAAE,MAAM,GACR,QAAQ,GAAG,IAAI,CAcjB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
function toNumber(value) {
|
|
2
|
+
const n = Number(value);
|
|
3
|
+
return Number.isFinite(n) ? n : null;
|
|
4
|
+
}
|
|
5
|
+
function lowerBoundX(points, target) {
|
|
6
|
+
let lo = 0;
|
|
7
|
+
let hi = points.length;
|
|
8
|
+
while (lo < hi) {
|
|
9
|
+
const mid = lo + hi >> 1;
|
|
10
|
+
if (points[mid].x < target) lo = mid + 1;
|
|
11
|
+
else hi = mid;
|
|
12
|
+
}
|
|
13
|
+
return lo;
|
|
14
|
+
}
|
|
15
|
+
function computeAverageSeries(groups) {
|
|
16
|
+
const curves = [...groups].filter((points) => points.length > 0);
|
|
17
|
+
if (!curves.length) return [];
|
|
18
|
+
const xValues = /* @__PURE__ */ new Set();
|
|
19
|
+
for (const points of curves) {
|
|
20
|
+
for (const p of points) xValues.add(p.x);
|
|
21
|
+
}
|
|
22
|
+
const xs = [...xValues].sort((a, b) => a - b);
|
|
23
|
+
return xs.map((x) => {
|
|
24
|
+
let sum = 0;
|
|
25
|
+
let count = 0;
|
|
26
|
+
for (const points of curves) {
|
|
27
|
+
const i = lowerBoundX(points, x);
|
|
28
|
+
if (i >= points.length) {
|
|
29
|
+
sum += points[points.length - 1].y;
|
|
30
|
+
} else if (i === 0) {
|
|
31
|
+
sum += points[0].y;
|
|
32
|
+
} else {
|
|
33
|
+
const p0 = points[i - 1];
|
|
34
|
+
const p1 = points[i];
|
|
35
|
+
const t = (x - p0.x) / Math.max(1e-12, p1.x - p0.x);
|
|
36
|
+
sum += p0.y + t * (p1.y - p0.y);
|
|
37
|
+
}
|
|
38
|
+
count += 1;
|
|
39
|
+
}
|
|
40
|
+
return { x, y: count ? sum / count : 0 };
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function nearestAveragePoint(averageSeries, x) {
|
|
44
|
+
if (!averageSeries.length) return null;
|
|
45
|
+
const idx = lowerBoundX(averageSeries, x);
|
|
46
|
+
let best = null;
|
|
47
|
+
let bestDist = Infinity;
|
|
48
|
+
for (const candidate of [averageSeries[idx - 1], averageSeries[idx], averageSeries[idx + 1]]) {
|
|
49
|
+
if (!candidate) continue;
|
|
50
|
+
const dist = Math.abs(candidate.x - x);
|
|
51
|
+
if (dist < bestDist) {
|
|
52
|
+
best = candidate;
|
|
53
|
+
bestDist = dist;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return best;
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
computeAverageSeries,
|
|
60
|
+
nearestAveragePoint,
|
|
61
|
+
toNumber
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=series.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"series.js","sources":["../../../../src/components/partial-dependence-chart/lib/series.ts"],"sourcesContent":["import type { IcePoint } from './types.js';\n\nexport function toNumber(value: unknown): number | null {\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n}\n\n/** First index whose `x >= target`, or `points.length` when every x is smaller. */\nfunction lowerBoundX(points: IcePoint[], target: number): number {\n let lo = 0;\n let hi = points.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (points[mid].x < target) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\n/**\n * Average the ICE curves on the union of their x values — client\n * `computeAverageSeries`, with the linear `findIndex` scan replaced by a binary\n * search so a dense mock stays O(x · groups · log n).\n * Each group must already be sorted by x.\n */\nexport function computeAverageSeries(groups: Iterable<IcePoint[]>): IcePoint[] {\n const curves = [...groups].filter((points) => points.length > 0);\n if (!curves.length) return [];\n\n const xValues = new Set<number>();\n for (const points of curves) {\n for (const p of points) xValues.add(p.x);\n }\n const xs = [...xValues].sort((a, b) => a - b);\n\n return xs.map((x) => {\n let sum = 0;\n let count = 0;\n for (const points of curves) {\n const i = lowerBoundX(points, x);\n if (i >= points.length) {\n // x sits past this curve — hold its last value\n sum += points[points.length - 1].y;\n } else if (i === 0) {\n sum += points[0].y;\n } else {\n const p0 = points[i - 1];\n const p1 = points[i];\n const t = (x - p0.x) / Math.max(1e-12, p1.x - p0.x);\n sum += p0.y + t * (p1.y - p0.y);\n }\n count += 1;\n }\n return { x, y: count ? sum / count : 0 };\n });\n}\n\n/**\n * Value of the average curve closest to `x` — backs the client's\n * \"tooltip shows nearest avg value\" pointermove handler.\n */\nexport function nearestAveragePoint(\n averageSeries: IcePoint[],\n x: number,\n): IcePoint | null {\n if (!averageSeries.length) return null;\n const idx = lowerBoundX(averageSeries, x);\n let best: IcePoint | null = null;\n let bestDist = Infinity;\n for (const candidate of [averageSeries[idx - 1], averageSeries[idx], averageSeries[idx + 1]]) {\n if (!candidate) continue;\n const dist = Math.abs(candidate.x - x);\n if (dist < bestDist) {\n best = candidate;\n bestDist = dist;\n }\n }\n return best;\n}\n"],"names":[],"mappings":"AAEO,SAAS,SAAS,OAA+B;AACtD,QAAM,IAAI,OAAO,KAAK;AACtB,SAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAClC;AAGA,SAAS,YAAY,QAAoB,QAAwB;AAC/D,MAAI,KAAK;AACT,MAAI,KAAK,OAAO;AAChB,SAAO,KAAK,IAAI;AACd,UAAM,MAAO,KAAK,MAAO;AACzB,QAAI,OAAO,GAAG,EAAE,IAAI,aAAa,MAAM;AAAA,QAClC,MAAK;AAAA,EACZ;AACA,SAAO;AACT;AAQO,SAAS,qBAAqB,QAA0C;AAC7E,QAAM,SAAS,CAAC,GAAG,MAAM,EAAE,OAAO,CAAC,WAAW,OAAO,SAAS,CAAC;AAC/D,MAAI,CAAC,OAAO,OAAQ,QAAO,CAAA;AAE3B,QAAM,8BAAc,IAAA;AACpB,aAAW,UAAU,QAAQ;AAC3B,eAAW,KAAK,OAAQ,SAAQ,IAAI,EAAE,CAAC;AAAA,EACzC;AACA,QAAM,KAAK,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAE5C,SAAO,GAAG,IAAI,CAAC,MAAM;AACnB,QAAI,MAAM;AACV,QAAI,QAAQ;AACZ,eAAW,UAAU,QAAQ;AAC3B,YAAM,IAAI,YAAY,QAAQ,CAAC;AAC/B,UAAI,KAAK,OAAO,QAAQ;AAEtB,eAAO,OAAO,OAAO,SAAS,CAAC,EAAE;AAAA,MACnC,WAAW,MAAM,GAAG;AAClB,eAAO,OAAO,CAAC,EAAE;AAAA,MACnB,OAAO;AACL,cAAM,KAAK,OAAO,IAAI,CAAC;AACvB,cAAM,KAAK,OAAO,CAAC;AACnB,cAAM,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI,OAAO,GAAG,IAAI,GAAG,CAAC;AAClD,eAAO,GAAG,IAAI,KAAK,GAAG,IAAI,GAAG;AAAA,MAC/B;AACA,eAAS;AAAA,IACX;AACA,WAAO,EAAE,GAAG,GAAG,QAAQ,MAAM,QAAQ,EAAA;AAAA,EACvC,CAAC;AACH;AAMO,SAAS,oBACd,eACA,GACiB;AACjB,MAAI,CAAC,cAAc,OAAQ,QAAO;AAClC,QAAM,MAAM,YAAY,eAAe,CAAC;AACxC,MAAI,OAAwB;AAC5B,MAAI,WAAW;AACf,aAAW,aAAa,CAAC,cAAc,MAAM,CAAC,GAAG,cAAc,GAAG,GAAG,cAAc,MAAM,CAAC,CAAC,GAAG;AAC5F,QAAI,CAAC,UAAW;AAChB,UAAM,OAAO,KAAK,IAAI,UAAU,IAAI,CAAC;AACrC,QAAI,OAAO,UAAU;AACnB,aAAO;AACP,iBAAW;AAAA,IACb;AAAA,EACF;AACA,SAAO;AACT;"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { FuseWidgetLike } from '../../../utils/fuse-widget.js';
|
|
2
|
+
/** One point on an ICE (Individual Conditional Expectation) curve. */
|
|
3
|
+
export interface IcePoint {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
}
|
|
7
|
+
export interface IceSeries {
|
|
8
|
+
/** groupBy value the curve was built from */
|
|
9
|
+
key: string;
|
|
10
|
+
points: IcePoint[];
|
|
11
|
+
}
|
|
12
|
+
export interface PartialDependenceModel {
|
|
13
|
+
/** One curve per groupBy value, each sorted by x. */
|
|
14
|
+
iceSeries: IceSeries[];
|
|
15
|
+
/** Average curve computed locally — never taken from the payload. */
|
|
16
|
+
averageSeries: IcePoint[];
|
|
17
|
+
xField: string;
|
|
18
|
+
yField: string;
|
|
19
|
+
groupField?: string;
|
|
20
|
+
/** Single brand color shared by the ICE band and the average line. */
|
|
21
|
+
color: string;
|
|
22
|
+
axisDetails?: Record<string, {
|
|
23
|
+
label?: string;
|
|
24
|
+
measure_unit_symbol?: string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
/** Chat shapes accepted alongside the FuseDash widget payload. */
|
|
28
|
+
export type PartialDependenceChartData = Array<{
|
|
29
|
+
x: number;
|
|
30
|
+
y: number;
|
|
31
|
+
group?: string;
|
|
32
|
+
}> | Array<{
|
|
33
|
+
label: string | number;
|
|
34
|
+
value: number;
|
|
35
|
+
}> | {
|
|
36
|
+
points: Array<{
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
}>;
|
|
40
|
+
} | {
|
|
41
|
+
series: Array<{
|
|
42
|
+
id: string;
|
|
43
|
+
name?: string;
|
|
44
|
+
points: Array<{
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
}>;
|
|
48
|
+
}>;
|
|
49
|
+
} | FuseWidgetLike | PartialDependenceModel | null | undefined;
|
|
50
|
+
//# sourceMappingURL=types.d.ts.map
|