@marimo-team/islands 0.22.6-dev9 → 0.23.1-dev13
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/main.js
CHANGED
|
@@ -57315,8 +57315,14 @@ ${c}
|
|
|
57315
57315
|
}
|
|
57316
57316
|
function hasPureLineTrace(e) {
|
|
57317
57317
|
return e ? e.some((e2) => {
|
|
57318
|
-
let r = e2
|
|
57319
|
-
return r === void 0 || LINE_CLICK_TRACE_TYPES.has(String(r)) ? isPureLineMode(
|
|
57318
|
+
let r = e2;
|
|
57319
|
+
return r.type === void 0 || LINE_CLICK_TRACE_TYPES.has(String(r.type)) ? isPureLineMode(r.mode) : false;
|
|
57320
|
+
}) : false;
|
|
57321
|
+
}
|
|
57322
|
+
function hasAreaTrace(e) {
|
|
57323
|
+
return e ? e.some((e2) => {
|
|
57324
|
+
let r = e2;
|
|
57325
|
+
return r.type !== void 0 && !LINE_CLICK_TRACE_TYPES.has(String(r.type)) ? false : typeof r.fill == "string" && r.fill !== "" && r.fill !== "none" || r.stackgroup != null;
|
|
57320
57326
|
}) : false;
|
|
57321
57327
|
}
|
|
57322
57328
|
function createDragmodeButton(e, r, c, d, f) {
|
|
@@ -57349,7 +57355,7 @@ ${c}
|
|
|
57349
57355
|
function shouldHandleClickSelection(e) {
|
|
57350
57356
|
return e.some((e2) => {
|
|
57351
57357
|
let r = getTraceSource(e2).type;
|
|
57352
|
-
return r === "bar" || r === "heatmap" || r === "histogram" || r === "waterfall" || isLinePoint(e2);
|
|
57358
|
+
return r === "bar" || r === "heatmap" || r === "histogram" || r === "waterfall" || r === "violin" || isLinePoint(e2);
|
|
57353
57359
|
});
|
|
57354
57360
|
}
|
|
57355
57361
|
function extractIndices(e) {
|
|
@@ -57523,7 +57529,7 @@ ${c}
|
|
|
57523
57529
|
}));
|
|
57524
57530
|
}, r[7] = w, r[8] = f, r[9] = I) : I = r[9];
|
|
57525
57531
|
let z = useEvent_default(I), G = useDeepCompareMemoize(h), q;
|
|
57526
|
-
r[10] === y.data ? q = r[11] : (q = hasPureLineTrace(y.data), r[10] = y.data, r[11] = q);
|
|
57532
|
+
r[10] === y.data ? q = r[11] : (q = hasPureLineTrace(y.data) || hasAreaTrace(y.data), r[10] = y.data, r[11] = q);
|
|
57527
57533
|
let Z7 = q, Q7, $7, e9;
|
|
57528
57534
|
if (r[12] !== G || r[13] !== M || r[14] !== z || r[15] !== Z7) {
|
|
57529
57535
|
let e2 = [
|
|
@@ -65645,7 +65651,7 @@ ${c}
|
|
|
65645
65651
|
return Logger.warn("Failed to get version from mount config"), null;
|
|
65646
65652
|
}
|
|
65647
65653
|
}
|
|
65648
|
-
const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.
|
|
65654
|
+
const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.23.1-dev13"), showCodeInRunModeAtom = atom(true);
|
|
65649
65655
|
atom(null);
|
|
65650
65656
|
var VIRTUAL_FILE_REGEX = /\/@file\/([^\s"&'/]+)\.([\dA-Za-z]+)/g, VirtualFileTracker = class e {
|
|
65651
65657
|
constructor() {
|
package/package.json
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
extractPoints,
|
|
20
20
|
extractSunburstPoints,
|
|
21
21
|
extractTreemapPoints,
|
|
22
|
+
hasAreaTrace,
|
|
22
23
|
hasPureLineTrace,
|
|
23
24
|
lineSelectionButtons,
|
|
24
25
|
type ModeBarButton,
|
|
@@ -113,7 +114,8 @@ export const PlotlyComponent = memo(
|
|
|
113
114
|
|
|
114
115
|
const configMemo = useDeepCompareMemoize(config);
|
|
115
116
|
const plotlyConfig = useMemo((): Partial<Plotly.Config> => {
|
|
116
|
-
const
|
|
117
|
+
const hasLineOrAreaTrace =
|
|
118
|
+
hasPureLineTrace(figure.data) || hasAreaTrace(figure.data);
|
|
117
119
|
const defaultButtons: ModeBarButton[] = [
|
|
118
120
|
// Custom button to reset the state
|
|
119
121
|
{
|
|
@@ -130,7 +132,7 @@ export const PlotlyComponent = memo(
|
|
|
130
132
|
click: handleResetWithClear,
|
|
131
133
|
},
|
|
132
134
|
];
|
|
133
|
-
if (
|
|
135
|
+
if (hasLineOrAreaTrace) {
|
|
134
136
|
defaultButtons.push(...lineSelectionButtons(handleSetDragmode));
|
|
135
137
|
}
|
|
136
138
|
|
|
@@ -111,4 +111,54 @@ describe("PlotlyPlugin", () => {
|
|
|
111
111
|
range: undefined,
|
|
112
112
|
});
|
|
113
113
|
});
|
|
114
|
+
|
|
115
|
+
it("clicking a violin element triggers onClick", async () => {
|
|
116
|
+
const setValue = vi.fn<Setter<unknown>>();
|
|
117
|
+
|
|
118
|
+
render(
|
|
119
|
+
<Suspense fallback={null}>
|
|
120
|
+
<PlotlyComponent
|
|
121
|
+
figure={{
|
|
122
|
+
data: [{ type: "violin" }],
|
|
123
|
+
layout: {},
|
|
124
|
+
frames: null,
|
|
125
|
+
}}
|
|
126
|
+
value={undefined}
|
|
127
|
+
setValue={setValue}
|
|
128
|
+
host={document.createElement("div")}
|
|
129
|
+
config={{}}
|
|
130
|
+
/>
|
|
131
|
+
</Suspense>,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
await waitFor(() => {
|
|
135
|
+
expect(capturedPlotProps).not.toBeNull();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
act(() => {
|
|
139
|
+
capturedPlotProps?.onClick?.({
|
|
140
|
+
points: [
|
|
141
|
+
{
|
|
142
|
+
data: { type: "violin" },
|
|
143
|
+
x: "Group A",
|
|
144
|
+
y: 3,
|
|
145
|
+
pointIndex: 0,
|
|
146
|
+
pointNumber: 0,
|
|
147
|
+
curveNumber: 0,
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
expect(setValue).toHaveBeenCalledTimes(1);
|
|
154
|
+
const updater = setValue.mock.calls[0][0] as (value: unknown) => unknown;
|
|
155
|
+
expect(updater({})).toEqual({
|
|
156
|
+
selections: [],
|
|
157
|
+
points: [
|
|
158
|
+
{ x: "Group A", y: 3, curveNumber: 0, pointNumber: 0, pointIndex: 0 },
|
|
159
|
+
],
|
|
160
|
+
indices: [0],
|
|
161
|
+
range: undefined,
|
|
162
|
+
});
|
|
163
|
+
});
|
|
114
164
|
});
|
|
@@ -5,6 +5,7 @@ import { describe, expect, it, vi } from "vitest";
|
|
|
5
5
|
import {
|
|
6
6
|
extractIndices,
|
|
7
7
|
extractPoints,
|
|
8
|
+
hasAreaTrace,
|
|
8
9
|
hasPureLineTrace,
|
|
9
10
|
lineSelectionButtons,
|
|
10
11
|
type ModeBarButton,
|
|
@@ -101,6 +102,14 @@ describe("shouldHandleClickSelection", () => {
|
|
|
101
102
|
expect(shouldHandleClickSelection([heatmapPoint])).toBe(true);
|
|
102
103
|
});
|
|
103
104
|
|
|
105
|
+
it("accepts violin clicks", () => {
|
|
106
|
+
const violinPoint = createPlotDatum({
|
|
107
|
+
data: { type: "violin" },
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
expect(shouldHandleClickSelection([violinPoint])).toBe(true);
|
|
111
|
+
});
|
|
112
|
+
|
|
104
113
|
it("accepts histogram clicks", () => {
|
|
105
114
|
const histogramPoint = createPlotDatum({
|
|
106
115
|
data: { type: "histogram" },
|
|
@@ -219,3 +228,67 @@ describe("extractPoints", () => {
|
|
|
219
228
|
]);
|
|
220
229
|
});
|
|
221
230
|
});
|
|
231
|
+
|
|
232
|
+
describe("hasAreaTrace", () => {
|
|
233
|
+
it("detects scatter trace with tozeroy fill", () => {
|
|
234
|
+
expect(
|
|
235
|
+
hasAreaTrace([createTrace({ type: "scatter", fill: "tozeroy" })]),
|
|
236
|
+
).toBe(true);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it("detects scatter trace with tonexty fill", () => {
|
|
240
|
+
expect(
|
|
241
|
+
hasAreaTrace([createTrace({ type: "scatter", fill: "tonexty" })]),
|
|
242
|
+
).toBe(true);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it("detects scatter trace with stackgroup (px.area pattern)", () => {
|
|
246
|
+
expect(
|
|
247
|
+
hasAreaTrace([
|
|
248
|
+
createTrace({ type: "scatter", mode: "lines", stackgroup: "one" }),
|
|
249
|
+
]),
|
|
250
|
+
).toBe(true);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it("detects area traces with mode=none (fill-only, no visible line)", () => {
|
|
254
|
+
expect(
|
|
255
|
+
hasAreaTrace([
|
|
256
|
+
createTrace({ type: "scatter", fill: "tozeroy", mode: "none" }),
|
|
257
|
+
]),
|
|
258
|
+
).toBe(true);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it("ignores scatter traces with no fill and no stackgroup", () => {
|
|
262
|
+
expect(
|
|
263
|
+
hasAreaTrace([
|
|
264
|
+
createTrace({ type: "scatter", mode: "lines" }),
|
|
265
|
+
createTrace({ type: "scatter", mode: "markers" }),
|
|
266
|
+
]),
|
|
267
|
+
).toBe(false);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it("ignores scatter traces with fill=none", () => {
|
|
271
|
+
expect(hasAreaTrace([createTrace({ type: "scatter", fill: "none" })])).toBe(
|
|
272
|
+
false,
|
|
273
|
+
);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it("ignores scatter traces with fill=empty string", () => {
|
|
277
|
+
expect(
|
|
278
|
+
hasAreaTrace([createTrace({ type: "scatter", fill: "" as "none" })]),
|
|
279
|
+
).toBe(false);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it("ignores non-scatter traces", () => {
|
|
283
|
+
expect(
|
|
284
|
+
hasAreaTrace([
|
|
285
|
+
createTrace({ type: "bar" }),
|
|
286
|
+
createTrace({ type: "heatmap" }),
|
|
287
|
+
]),
|
|
288
|
+
).toBe(false);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it("returns false for undefined data", () => {
|
|
292
|
+
expect(hasAreaTrace(undefined)).toBe(false);
|
|
293
|
+
});
|
|
294
|
+
});
|
|
@@ -141,13 +141,44 @@ export function hasPureLineTrace(
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
return data.some((trace) => {
|
|
144
|
-
const
|
|
144
|
+
const t = trace as Record<string, unknown>;
|
|
145
145
|
const isScatterLike =
|
|
146
|
-
|
|
146
|
+
t.type === undefined || LINE_CLICK_TRACE_TYPES.has(String(t.type));
|
|
147
147
|
if (!isScatterLike) {
|
|
148
148
|
return false;
|
|
149
149
|
}
|
|
150
|
-
return isPureLineMode(
|
|
150
|
+
return isPureLineMode(t.mode);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Return true when any scatter/scattergl trace has a non-empty fill or a
|
|
156
|
+
* stackgroup, i.e. it is an area chart.
|
|
157
|
+
*
|
|
158
|
+
* Area traces built with `mode="none"` have no visible line or markers, so
|
|
159
|
+
* `hasPureLineTrace` returns false for them even though they need select/lasso
|
|
160
|
+
* buttons just as much as `mode="lines"` area charts. This function covers
|
|
161
|
+
* that gap and is OR-ed with `hasPureLineTrace` in the config builder.
|
|
162
|
+
*/
|
|
163
|
+
export function hasAreaTrace(
|
|
164
|
+
data: readonly Plotly.Data[] | undefined,
|
|
165
|
+
): boolean {
|
|
166
|
+
if (!data) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return data.some((trace) => {
|
|
171
|
+
const t = trace as Record<string, unknown>;
|
|
172
|
+
// Only scatter/scattergl can be area traces.
|
|
173
|
+
if (t.type !== undefined && !LINE_CLICK_TRACE_TYPES.has(String(t.type))) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
// A trace is an area trace when fill is a non-empty string other than
|
|
177
|
+
// "none", OR it belongs to a stackgroup (px.area always sets stackgroup).
|
|
178
|
+
return (
|
|
179
|
+
(typeof t.fill === "string" && t.fill !== "" && t.fill !== "none") ||
|
|
180
|
+
t.stackgroup != null
|
|
181
|
+
);
|
|
151
182
|
});
|
|
152
183
|
}
|
|
153
184
|
|
|
@@ -228,6 +259,7 @@ export function shouldHandleClickSelection(
|
|
|
228
259
|
type === "heatmap" ||
|
|
229
260
|
type === "histogram" ||
|
|
230
261
|
type === "waterfall" ||
|
|
262
|
+
type === "violin" ||
|
|
231
263
|
isLinePoint(point)
|
|
232
264
|
);
|
|
233
265
|
});
|