@liiift-studio/sanity-visitor-insights 0.53.0 → 0.55.0
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/index.js +35 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +35 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/studio/CrossSourceTimeline.tsx +36 -11
- package/src/studio/panels.test.tsx +95 -1
- package/src/studio/panels.tsx +43 -13
package/dist/index.js
CHANGED
|
@@ -1461,9 +1461,8 @@ function CrossSourceTimeline({ series, markers = [], currency, onBrush }) {
|
|
|
1461
1461
|
x2: at,
|
|
1462
1462
|
y1: TOP_PAD,
|
|
1463
1463
|
y2: height - AXIS_HEIGHT + 4,
|
|
1464
|
-
stroke: "
|
|
1465
|
-
strokeWidth: 1
|
|
1466
|
-
opacity: 0.18
|
|
1464
|
+
stroke: mark("chart.grid"),
|
|
1465
|
+
strokeWidth: 1
|
|
1467
1466
|
},
|
|
1468
1467
|
`grid-${date}`
|
|
1469
1468
|
);
|
|
@@ -1495,7 +1494,7 @@ function CrossSourceTimeline({ series, markers = [], currency, onBrush }) {
|
|
|
1495
1494
|
const stems = row.mark === "events" ? row.points.filter((p) => p.value !== null && p.value !== 0) : [];
|
|
1496
1495
|
const zeroes = row.mark === "events" && pitch >= 6 ? row.points.filter((p) => p.value === 0) : [];
|
|
1497
1496
|
const gap = row.shortfall ? gapGen(row.points) ?? "" : "";
|
|
1498
|
-
const shortfallLine = row.shortfall
|
|
1497
|
+
const shortfallLine = row.shortfall ? lineGen(shortfallPoints) ?? "" : "";
|
|
1499
1498
|
const clipId = `${instanceId}-row-${rowIndex}`;
|
|
1500
1499
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { children: [
|
|
1501
1500
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("clipPath", { id: clipId, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: GUTTER, y: plotTop, width: plotWidth, height: Math.max(1, bottom - plotTop) }) }) }),
|
|
@@ -1514,21 +1513,29 @@ function CrossSourceTimeline({ series, markers = [], currency, onBrush }) {
|
|
|
1514
1513
|
{
|
|
1515
1514
|
d: ghost,
|
|
1516
1515
|
fill: "none",
|
|
1517
|
-
stroke: "
|
|
1516
|
+
stroke: mark("chart.ghost"),
|
|
1518
1517
|
strokeWidth: 1,
|
|
1519
|
-
strokeDasharray: "2 3"
|
|
1520
|
-
opacity: 0.35
|
|
1518
|
+
strokeDasharray: "2 3"
|
|
1521
1519
|
}
|
|
1522
1520
|
),
|
|
1523
1521
|
gap && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1524
1522
|
"path",
|
|
1525
1523
|
{
|
|
1526
1524
|
d: gap,
|
|
1527
|
-
fill: shortfallStroke ? seriesFill(colorFor(row.shortfall.source, row.unit, row.shortfall.color),
|
|
1525
|
+
fill: shortfallStroke ? seriesFill(colorFor(row.shortfall.source, row.unit, row.shortfall.color), MARKS["chart.region"].alpha) : "currentColor",
|
|
1528
1526
|
opacity: shortfallStroke ? 1 : 0.48
|
|
1529
1527
|
}
|
|
1530
1528
|
),
|
|
1531
|
-
shortfallLine && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1529
|
+
shortfallLine && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1530
|
+
"path",
|
|
1531
|
+
{
|
|
1532
|
+
d: shortfallLine,
|
|
1533
|
+
fill: "none",
|
|
1534
|
+
stroke: mark("chart.regionEdge"),
|
|
1535
|
+
strokeWidth: 1.5,
|
|
1536
|
+
strokeDasharray: "6 4"
|
|
1537
|
+
}
|
|
1538
|
+
),
|
|
1532
1539
|
zeroes.map((p) => {
|
|
1533
1540
|
const cx = at(p);
|
|
1534
1541
|
if (!Number.isFinite(cx)) return null;
|
|
@@ -1539,8 +1546,7 @@ function CrossSourceTimeline({ series, markers = [], currency, onBrush }) {
|
|
|
1539
1546
|
y: zeroY - 3,
|
|
1540
1547
|
width: stemWidth,
|
|
1541
1548
|
height: 3,
|
|
1542
|
-
fill: stroke
|
|
1543
|
-
opacity: 0.7
|
|
1549
|
+
fill: stroke
|
|
1544
1550
|
},
|
|
1545
1551
|
`zero-${p.date}`
|
|
1546
1552
|
);
|
|
@@ -1556,8 +1562,7 @@ function CrossSourceTimeline({ series, markers = [], currency, onBrush }) {
|
|
|
1556
1562
|
y: Math.min(headY, zeroY),
|
|
1557
1563
|
width: stemWidth,
|
|
1558
1564
|
height: Math.max(1.5, Math.abs(zeroY - headY)),
|
|
1559
|
-
fill: stroke
|
|
1560
|
-
opacity: 0.9
|
|
1565
|
+
fill: stroke
|
|
1561
1566
|
},
|
|
1562
1567
|
p.date
|
|
1563
1568
|
);
|
|
@@ -1569,8 +1574,7 @@ function CrossSourceTimeline({ series, markers = [], currency, onBrush }) {
|
|
|
1569
1574
|
fill: "none",
|
|
1570
1575
|
stroke,
|
|
1571
1576
|
strokeWidth: 2,
|
|
1572
|
-
strokeDasharray: row.complete ? void 0 : "6 4"
|
|
1573
|
-
opacity: row.complete ? 0.95 : 0.7
|
|
1577
|
+
strokeDasharray: row.complete ? void 0 : "6 4"
|
|
1574
1578
|
}
|
|
1575
1579
|
)
|
|
1576
1580
|
] })
|
|
@@ -2040,7 +2044,6 @@ function OverviewPanel({ data, previous, onBrush }) {
|
|
|
2040
2044
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
2041
2045
|
ChartData,
|
|
2042
2046
|
{
|
|
2043
|
-
note: "A negative miss means GA4 counted more than Vercel that day \u2014 usually a tag firing twice, not extra traffic.",
|
|
2044
2047
|
label: "Show these figures as a table",
|
|
2045
2048
|
rows: data.crossSource ?? [],
|
|
2046
2049
|
rowKey: (d) => d.date,
|
|
@@ -2384,7 +2387,11 @@ function AcquisitionPanel({ data, previous }) {
|
|
|
2384
2387
|
filterOn: (row) => `${row.source} ${row.channel} ${row.medium ?? ""} ${row.campaign ?? ""}`,
|
|
2385
2388
|
filterPlaceholder: "Filter sources",
|
|
2386
2389
|
exportName: "traffic-sources",
|
|
2387
|
-
truncatedNote:
|
|
2390
|
+
truncatedNote: shortListNote(
|
|
2391
|
+
Boolean(data.rowsTruncated),
|
|
2392
|
+
Boolean(data.rowsWithheld),
|
|
2393
|
+
"For a foundry the tail of small design blogs is often the referral story."
|
|
2394
|
+
),
|
|
2388
2395
|
columns: [
|
|
2389
2396
|
{
|
|
2390
2397
|
key: "source",
|
|
@@ -2500,8 +2507,7 @@ function AcquisitionPanel({ data, previous }) {
|
|
|
2500
2507
|
" of those sales; the rest came from sources outside this list, so this column does not add up to the whole."
|
|
2501
2508
|
] })
|
|
2502
2509
|
] })
|
|
2503
|
-
] })
|
|
2504
|
-
data.rowsWithheld && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NoticeList, { notices: ["GA4 withheld some low-traffic rows for privacy, so this list is shorter than reality."] })
|
|
2510
|
+
] })
|
|
2505
2511
|
] });
|
|
2506
2512
|
}
|
|
2507
2513
|
function firstStepRate(steps) {
|
|
@@ -2526,6 +2532,11 @@ function spread(segments) {
|
|
|
2526
2532
|
if (ratio < RATIO) return null;
|
|
2527
2533
|
return `${worst.label} reaches the second step at ${formatPercent(worst.rate, 2)} against ${best.label}'s ${formatPercent(best.rate, 2)} \u2014 about ${Math.round(ratio)} times worse, on ${formatCount(worst.users)} visitors. The combined funnel above averages the two and describes neither.`;
|
|
2528
2534
|
}
|
|
2535
|
+
function shortListNote(truncated, withheld, tail) {
|
|
2536
|
+
if (!truncated && !withheld) return void 0;
|
|
2537
|
+
const cause = truncated && withheld ? "GA4 returned only its top rows, and withheld others with too few people to report" : truncated ? "GA4 returned only its top rows" : "GA4 withheld rows with too few people to report";
|
|
2538
|
+
return `${cause}, so this list is shorter than reality. ${tail}`;
|
|
2539
|
+
}
|
|
2529
2540
|
function JourneyPanel({ data }) {
|
|
2530
2541
|
const [segmentKey, setSegmentKey] = import_react4.default.useState(null);
|
|
2531
2542
|
const segments = data.segments ?? [];
|
|
@@ -2723,7 +2734,11 @@ function TypefaceInterestPanel({ data }) {
|
|
|
2723
2734
|
filterOn: (row) => row.typeface,
|
|
2724
2735
|
filterPlaceholder: "Filter typefaces",
|
|
2725
2736
|
exportName: "typeface-interest",
|
|
2726
|
-
truncatedNote:
|
|
2737
|
+
truncatedNote: shortListNote(
|
|
2738
|
+
Boolean(data.rowsTruncated),
|
|
2739
|
+
Boolean(data.rowsWithheld),
|
|
2740
|
+
"A family missing from this table has not necessarily gone quiet \u2014 and for a foundry the long tail is most of the catalogue."
|
|
2741
|
+
),
|
|
2727
2742
|
columns: [
|
|
2728
2743
|
{
|
|
2729
2744
|
key: "typeface",
|
|
@@ -2858,7 +2873,6 @@ function TypefaceInterestPanel({ data }) {
|
|
|
2858
2873
|
}
|
|
2859
2874
|
)
|
|
2860
2875
|
] }),
|
|
2861
|
-
data.rowsWithheld && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NoticeList, { notices: ["GA4 withheld some low-count rows for privacy. A family missing from this table has not necessarily gone quiet."] }),
|
|
2862
2876
|
data.revenueIsApportioned && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Text, { size: 0, muted: true, children: "Revenue is apportioned: an order covering several families or licences is split evenly between them, because the order documents carry no per-line value." })
|
|
2863
2877
|
] });
|
|
2864
2878
|
}
|