@matdata/yasgui-chart-plugin 1.0.0 → 1.2.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.
@@ -24982,9 +24982,9 @@ var ECharts = (
24982
24982
  var chartView = ecIns._chartsMap[seriesModel.__viewId];
24983
24983
  if (chartView.__alive) {
24984
24984
  chartView.eachRendered(function(el) {
24985
- var emphasis = el.states.emphasis;
24986
- if (emphasis && emphasis.hoverLayer !== HOVER_LAYER_FOR_INCREMENTAL) {
24987
- emphasis.hoverLayer = shouldUseHoverLayer2 ? HOVER_LAYER_FROM_THRESHOLD : HOVER_LAYER_NO;
24985
+ var emphasis2 = el.states.emphasis;
24986
+ if (emphasis2 && emphasis2.hoverLayer !== HOVER_LAYER_FOR_INCREMENTAL) {
24987
+ emphasis2.hoverLayer = shouldUseHoverLayer2 ? HOVER_LAYER_FROM_THRESHOLD : HOVER_LAYER_NO;
24988
24988
  }
24989
24989
  });
24990
24990
  }
@@ -42378,16 +42378,16 @@ function getLegendStyle(iconType, legendItemModel, lineVisualStyle, itemVisualSt
42378
42378
  }
42379
42379
  function getDefaultLegendIcon(opt) {
42380
42380
  var symboType = opt.icon || "roundRect";
42381
- var icon = createSymbol(symboType, 0, 0, opt.itemWidth, opt.itemHeight, opt.itemStyle.fill, opt.symbolKeepAspect);
42382
- icon.setStyle(opt.itemStyle);
42383
- icon.rotation = (opt.iconRotate || 0) * Math.PI / 180;
42384
- icon.setOrigin([opt.itemWidth / 2, opt.itemHeight / 2]);
42381
+ var icon2 = createSymbol(symboType, 0, 0, opt.itemWidth, opt.itemHeight, opt.itemStyle.fill, opt.symbolKeepAspect);
42382
+ icon2.setStyle(opt.itemStyle);
42383
+ icon2.rotation = (opt.iconRotate || 0) * Math.PI / 180;
42384
+ icon2.setOrigin([opt.itemWidth / 2, opt.itemHeight / 2]);
42385
42385
  if (symboType.indexOf("empty") > -1) {
42386
- icon.style.stroke = icon.style.fill;
42387
- icon.style.fill = tokens_default.color.neutral00;
42388
- icon.style.lineWidth = 2;
42386
+ icon2.style.stroke = icon2.style.fill;
42387
+ icon2.style.fill = tokens_default.color.neutral00;
42388
+ icon2.style.lineWidth = 2;
42389
42389
  }
42390
- return icon;
42390
+ return icon2;
42391
42391
  }
42392
42392
  function dispatchSelectAction(seriesName, dataName, api, excludeSeriesId) {
42393
42393
  dispatchDownplayAction(seriesName, dataName, api, excludeSeriesId);
@@ -42610,7 +42610,7 @@ var ScrollableLegendView = (
42610
42610
  createPageButton("pageNext", 1);
42611
42611
  function createPageButton(name, iconIdx) {
42612
42612
  var pageDataIndexName = name + "DataIndex";
42613
- var icon = createIcon(legendModel.get("pageIcons", true)[legendModel.getOrient().name][iconIdx], {
42613
+ var icon2 = createIcon(legendModel.get("pageIcons", true)[legendModel.getOrient().name][iconIdx], {
42614
42614
  // Buttons will be created in each render, so we do not need
42615
42615
  // to worry about avoiding using legendModel kept in scope.
42616
42616
  onclick: bind(self2._pageGo, self2, pageDataIndexName, legendModel, api)
@@ -42620,8 +42620,8 @@ var ScrollableLegendView = (
42620
42620
  width: pageIconSizeArr[0],
42621
42621
  height: pageIconSizeArr[1]
42622
42622
  });
42623
- icon.name = name;
42624
- controllerGroup.add(icon);
42623
+ icon2.name = name;
42624
+ controllerGroup.add(icon2);
42625
42625
  }
42626
42626
  };
42627
42627
  ScrollableLegendView2.prototype.layoutInner = function(legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition) {
@@ -42748,10 +42748,10 @@ var ScrollableLegendView = (
42748
42748
  each(["pagePrev", "pageNext"], function(name) {
42749
42749
  var key = name + "DataIndex";
42750
42750
  var canJump = pageInfo[key] != null;
42751
- var icon = controllerGroup.childOfName(name);
42752
- if (icon) {
42753
- icon.setStyle("fill", canJump ? legendModel.get("pageIconColor", true) : legendModel.get("pageIconInactiveColor", true));
42754
- icon.cursor = canJump ? "pointer" : "default";
42751
+ var icon2 = controllerGroup.childOfName(name);
42752
+ if (icon2) {
42753
+ icon2.setStyle("fill", canJump ? legendModel.get("pageIconColor", true) : legendModel.get("pageIconInactiveColor", true));
42754
+ icon2.cursor = canJump ? "pointer" : "default";
42755
42755
  }
42756
42756
  });
42757
42757
  var pageText = controllerGroup.childOfName("pageText");
@@ -46986,6 +46986,11 @@ function baseOption(colors, pointCount) {
46986
46986
  }
46987
46987
  };
46988
46988
  }
46989
+ function emphasis(colors, focusSeries) {
46990
+ const result = focusSeries ? { focus: "series" } : {};
46991
+ if (colors.highlight) result.itemStyle = { color: colors.highlight };
46992
+ return result;
46993
+ }
46989
46994
  function axisStyle(colors) {
46990
46995
  return {
46991
46996
  axisLine: { lineStyle: { color: colors.border } },
@@ -47027,6 +47032,7 @@ function categoryOption(data, settings, colors) {
47027
47032
  center: ["50%", "55%"],
47028
47033
  avoidLabelOverlap: true,
47029
47034
  itemStyle: { borderColor: colors.background, borderWidth: 1 },
47035
+ emphasis: emphasis(colors, false),
47030
47036
  label: { color: colors.text, formatter: "{b}: {d}%" },
47031
47037
  data: data.categories.map((c, i) => ({ name: c.label, value: values[i], categoryIndex: i })).filter((d) => d.value !== null && d.value !== void 0 && d.value > 0)
47032
47038
  }
@@ -47101,7 +47107,7 @@ function categoryOption(data, settings, colors) {
47101
47107
  areaStyle: settings.chartType === "area" ? { opacity: 0.25 } : void 0,
47102
47108
  connectNulls: isLine,
47103
47109
  showSymbol: isLine && labels.length <= 100,
47104
- emphasis: { focus: "series" },
47110
+ emphasis: isLine ? { focus: "series" } : emphasis(colors, true),
47105
47111
  large: !isLine && labels.length > 1e3
47106
47112
  }));
47107
47113
  return option;
@@ -47144,7 +47150,7 @@ function xyOption(data, settings, colors) {
47144
47150
  symbolSize: scatter ? 8 : 4,
47145
47151
  showSymbol: !scatter && s.points.length <= 100,
47146
47152
  areaStyle: settings.chartType === "area" ? { opacity: 0.25 } : void 0,
47147
- emphasis: { focus: "series" },
47153
+ emphasis: scatter ? emphasis(colors, true) : { focus: "series" },
47148
47154
  large: scatter && s.points.length > 2e3
47149
47155
  }));
47150
47156
  return option;
@@ -47176,7 +47182,13 @@ function histogramOption(data, colors) {
47176
47182
  return `${escapeHtml(data.column)}: ${escapeHtml(labels[p.dataIndex])}<br/>Count: <strong>${formatNumber(p.value)}</strong>`;
47177
47183
  };
47178
47184
  option.series = [
47179
- { type: "bar", name: "Count", data: data.bins.map((b) => b.count), barCategoryGap: "4%" }
47185
+ {
47186
+ type: "bar",
47187
+ name: "Count",
47188
+ data: data.bins.map((b) => b.count),
47189
+ barCategoryGap: "4%",
47190
+ emphasis: emphasis(colors, false)
47191
+ }
47180
47192
  ];
47181
47193
  return option;
47182
47194
  }
@@ -47201,6 +47213,29 @@ function iriForClick(data, params) {
47201
47213
  return void 0;
47202
47214
  }
47203
47215
 
47216
+ // src/icons.ts
47217
+ var ICON_PATHS = {
47218
+ "chart-column": '<path d="M3 3v16a2 2 0 0 0 2 2h16"/><path d="M18 17V9"/><path d="M13 17V5"/><path d="M8 17v-3"/>',
47219
+ "sliders-horizontal": '<line x1="21" x2="14" y1="4" y2="4"/><line x1="10" x2="3" y1="4" y2="4"/><line x1="21" x2="12" y1="12" y2="12"/><line x1="8" x2="3" y1="12" y2="12"/><line x1="21" x2="16" y1="20" y2="20"/><line x1="12" x2="3" y1="20" y2="20"/><line x1="14" x2="14" y1="2" y2="6"/><line x1="8" x2="8" y1="10" y2="14"/><line x1="16" x2="16" y1="18" y2="22"/>',
47220
+ "chevron-down": '<path d="m6 9 6 6 6-6"/>',
47221
+ "chevron-left": '<path d="m15 18-6-6 6-6"/>',
47222
+ "chevron-right": '<path d="m9 18 6-6-6-6"/>',
47223
+ "chevrons-left": '<path d="m11 17-5-5 5-5"/><path d="m18 17-5-5 5-5"/>',
47224
+ x: '<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',
47225
+ download: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',
47226
+ square: '<rect width="18" height="18" x="3" y="3" rx="2"/>',
47227
+ "square-check": '<rect width="18" height="18" x="3" y="3" rx="2"/><path d="m9 12 2 2 4-4"/>',
47228
+ "rotate-ccw": '<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/>'
47229
+ };
47230
+ function iconSvg(name, size = 16, strokeWidth = 1.75) {
47231
+ return `<svg xmlns="http://www.w3.org/2000/svg" class="chart-icon chart-icon-${name}" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="${strokeWidth}" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">${ICON_PATHS[name]}</svg>`;
47232
+ }
47233
+ function icon(name, size, strokeWidth) {
47234
+ const template = document.createElement("template");
47235
+ template.innerHTML = iconSvg(name, size, strokeWidth);
47236
+ return template.content.firstElementChild;
47237
+ }
47238
+
47204
47239
  // src/settings.ts
47205
47240
  var CHART_TYPES = [
47206
47241
  { value: "bar", label: "Bar" },
@@ -47229,12 +47264,19 @@ function sanitizeSettings(raw) {
47229
47264
  if (typeof r.series === "string") settings.series = r.series;
47230
47265
  if (Array.isArray(r.columns))
47231
47266
  settings.columns = r.columns.filter((v) => typeof v === "string");
47267
+ if (typeof r.shortenIris === "boolean") settings.shortenIris = r.shortenIris;
47232
47268
  return settings;
47233
47269
  }
47270
+ function isCustomised(saved) {
47271
+ return Object.keys(saved).some((key) => key !== "columns" && key !== "shortenIris");
47272
+ }
47273
+ function displayOptions(saved) {
47274
+ return saved.shortenIris === void 0 ? {} : { shortenIris: saved.shortenIris };
47275
+ }
47234
47276
  function settingsForColumns(saved, vars) {
47235
47277
  if (!saved.columns) return saved;
47236
47278
  const same = saved.columns.length === vars.length && saved.columns.every((v, i) => v === vars[i]);
47237
- return same ? saved : {};
47279
+ return same ? saved : displayOptions(saved);
47238
47280
  }
47239
47281
  function categoryCandidates(columns) {
47240
47282
  return columns.filter((c) => !c.isLabel && c.bound > 0);
@@ -47303,9 +47345,10 @@ var KIND_LABEL = {
47303
47345
  iri: "IRI",
47304
47346
  text: "text"
47305
47347
  };
47306
- function field(labelText, control) {
47307
- const wrapper = document.createElement("label");
47308
- wrapper.className = "chart-toolbar-field";
47348
+ var menuCounter = 0;
47349
+ function field(layout2, labelText, control, tag = "label") {
47350
+ const wrapper = document.createElement(tag);
47351
+ wrapper.className = layout2 === "host" ? "yasr_toolbarSelect chart-toolbar-field" : "chart-toolbar-field";
47309
47352
  const label = document.createElement("span");
47310
47353
  label.className = "chart-toolbar-label";
47311
47354
  label.textContent = labelText;
@@ -47313,9 +47356,9 @@ function field(labelText, control) {
47313
47356
  wrapper.appendChild(control);
47314
47357
  return wrapper;
47315
47358
  }
47316
- function select(className, options, value, onChange) {
47359
+ function select(layout2, className, options, value, onChange) {
47317
47360
  const el = document.createElement("select");
47318
- el.className = `chart-toolbar-select ${className}`;
47361
+ el.className = layout2 === "host" ? className : `chart-toolbar-select ${className}`;
47319
47362
  for (const o of options) {
47320
47363
  const option = document.createElement("option");
47321
47364
  option.value = o.value;
@@ -47339,11 +47382,10 @@ function button(className, text, title, onClick) {
47339
47382
  function columnLabel(c) {
47340
47383
  return `${c.name} (${KIND_LABEL[c.kind]})`;
47341
47384
  }
47342
- function renderToolbar(state, callbacks) {
47385
+ function renderPickers(layout2, state, callbacks) {
47343
47386
  var _a2, _b2;
47344
47387
  const { columns, resolved } = state;
47345
- const toolbar = document.createElement("div");
47346
- toolbar.className = "chart-toolbar";
47388
+ const fields = [];
47347
47389
  const current = () => {
47348
47390
  var _a3, _b3;
47349
47391
  return {
@@ -47355,10 +47397,12 @@ function renderToolbar(state, callbacks) {
47355
47397
  };
47356
47398
  const isHistogram = resolved.chartType === "histogram";
47357
47399
  const isPie = resolved.chartType === "pie" || resolved.chartType === "donut";
47358
- toolbar.appendChild(
47400
+ fields.push(
47359
47401
  field(
47360
- "Chart",
47402
+ layout2,
47403
+ layout2 === "host" ? "Type" : "Chart",
47361
47404
  select(
47405
+ layout2,
47362
47406
  "chart-type-select",
47363
47407
  CHART_TYPES,
47364
47408
  resolved.chartType,
@@ -47368,6 +47412,7 @@ function renderToolbar(state, callbacks) {
47368
47412
  );
47369
47413
  const candidates = categoryCandidates(columns);
47370
47414
  const categorySelect = select(
47415
+ layout2,
47371
47416
  "chart-category-select",
47372
47417
  candidates.map((c) => ({ value: c.name, label: columnLabel(c) })),
47373
47418
  (_a2 = resolved.category) != null ? _a2 : "",
@@ -47381,8 +47426,9 @@ function renderToolbar(state, callbacks) {
47381
47426
  }
47382
47427
  );
47383
47428
  categorySelect.disabled = isHistogram || candidates.length === 0;
47384
- toolbar.appendChild(
47429
+ fields.push(
47385
47430
  field(
47431
+ layout2,
47386
47432
  isPie ? "Slices" : resolved.chartType === "horizontal-bar" ? "Y axis" : "X axis",
47387
47433
  categorySelect
47388
47434
  )
@@ -47391,8 +47437,12 @@ function renderToolbar(state, callbacks) {
47391
47437
  const valuesPicker = document.createElement("details");
47392
47438
  valuesPicker.className = "chart-values-picker";
47393
47439
  const summary = document.createElement("summary");
47394
- summary.className = "chart-toolbar-select";
47395
- summary.textContent = resolved.values.length > 0 ? resolved.values.join(", ") : "None";
47440
+ summary.className = layout2 === "host" ? "chart-values-summary" : "chart-toolbar-select chart-values-summary";
47441
+ const summaryText = document.createElement("span");
47442
+ summaryText.className = "chart-values-summary-text";
47443
+ summaryText.textContent = resolved.values.length > 0 ? resolved.values.join(", ") : "None";
47444
+ summary.appendChild(summaryText);
47445
+ summary.appendChild(icon("chevron-down", 14));
47396
47446
  valuesPicker.appendChild(summary);
47397
47447
  const list = document.createElement("div");
47398
47448
  list.className = "chart-values-list";
@@ -47423,18 +47473,32 @@ function renderToolbar(state, callbacks) {
47423
47473
  list.appendChild(item);
47424
47474
  }
47425
47475
  valuesPicker.appendChild(list);
47426
- toolbar.appendChild(field(isHistogram ? "Value" : isPie ? "Size" : "Values", valuesPicker));
47476
+ fields.push(
47477
+ field(
47478
+ layout2,
47479
+ isHistogram ? "Value" : isPie ? "Size" : "Values",
47480
+ valuesPicker,
47481
+ layout2 === "host" ? "div" : "label"
47482
+ )
47483
+ );
47427
47484
  const seriesOptions = [{ value: "", label: "None" }].concat(
47428
47485
  candidates.filter((c) => c.name !== resolved.category && !resolved.values.includes(c.name)).map((c) => ({ value: c.name, label: columnLabel(c) }))
47429
47486
  );
47430
47487
  const seriesSelect = select(
47488
+ layout2,
47431
47489
  "chart-series-select",
47432
47490
  seriesOptions,
47433
47491
  (_b2 = resolved.series) != null ? _b2 : "",
47434
47492
  (value) => callbacks.onChange({ ...current(), series: value })
47435
47493
  );
47436
47494
  seriesSelect.disabled = isHistogram || isPie || seriesOptions.length <= 1;
47437
- toolbar.appendChild(field("Series", seriesSelect));
47495
+ fields.push(field(layout2, "Series", seriesSelect));
47496
+ return fields;
47497
+ }
47498
+ function renderToolbar(state, callbacks) {
47499
+ const toolbar = document.createElement("div");
47500
+ toolbar.className = "chart-toolbar";
47501
+ for (const el of renderPickers("own", state, callbacks)) toolbar.appendChild(el);
47438
47502
  if (state.customised) {
47439
47503
  toolbar.appendChild(
47440
47504
  button(
@@ -47448,6 +47512,14 @@ function renderToolbar(state, callbacks) {
47448
47512
  const spacer = document.createElement("div");
47449
47513
  spacer.className = "chart-toolbar-spacer";
47450
47514
  toolbar.appendChild(spacer);
47515
+ const shorten = button(
47516
+ "chart-shorten-iris",
47517
+ "Prefixes",
47518
+ "Show IRIs as prefixed names",
47519
+ () => callbacks.onShortenIris(!state.shortenIris)
47520
+ );
47521
+ shorten.setAttribute("aria-pressed", String(state.shortenIris));
47522
+ toolbar.appendChild(shorten);
47451
47523
  toolbar.appendChild(
47452
47524
  button(
47453
47525
  "chart-export-png",
@@ -47466,6 +47538,140 @@ function renderToolbar(state, callbacks) {
47466
47538
  );
47467
47539
  return toolbar;
47468
47540
  }
47541
+ function menuItem(className, iconName, text, title, onClick) {
47542
+ const el = document.createElement("button");
47543
+ el.type = "button";
47544
+ el.className = `chart-view-settings-item ${className}`;
47545
+ el.title = title;
47546
+ el.appendChild(icon(iconName));
47547
+ const label = document.createElement("span");
47548
+ label.textContent = text;
47549
+ el.appendChild(label);
47550
+ el.addEventListener("click", onClick);
47551
+ return el;
47552
+ }
47553
+ function renderViewSettings(state, callbacks) {
47554
+ const wrapper = document.createElement("div");
47555
+ wrapper.className = "chart-view-settings";
47556
+ const menuId = `chart-view-settings-menu-${++menuCounter}`;
47557
+ const toggle = document.createElement("button");
47558
+ toggle.type = "button";
47559
+ toggle.className = "yasr_toolbarButton chart-view-settings-button";
47560
+ toggle.setAttribute("aria-haspopup", "true");
47561
+ toggle.setAttribute("aria-expanded", "false");
47562
+ toggle.setAttribute("aria-controls", menuId);
47563
+ toggle.appendChild(icon("sliders-horizontal"));
47564
+ const text = document.createElement("span");
47565
+ text.textContent = "View settings";
47566
+ toggle.appendChild(text);
47567
+ const menu = document.createElement("div");
47568
+ menu.className = "chart-view-settings-menu";
47569
+ menu.id = menuId;
47570
+ menu.setAttribute("role", "group");
47571
+ menu.setAttribute("aria-label", "View settings");
47572
+ menu.hidden = true;
47573
+ const setOpen = (open) => {
47574
+ menu.hidden = !open;
47575
+ toggle.setAttribute("aria-expanded", String(open));
47576
+ toggle.classList.toggle("is-active", open);
47577
+ };
47578
+ const run = (action) => () => {
47579
+ setOpen(false);
47580
+ action();
47581
+ };
47582
+ const reset = menuItem(
47583
+ "chart-reset-button",
47584
+ "rotate-ccw",
47585
+ "Automatic chart",
47586
+ "Go back to the automatic chart for these results",
47587
+ run(callbacks.onReset)
47588
+ );
47589
+ reset.disabled = !state.customised;
47590
+ menu.appendChild(reset);
47591
+ const shorten = menuItem(
47592
+ "chart-shorten-iris",
47593
+ state.shortenIris ? "square-check" : "square",
47594
+ "Shorten IRIs with prefixes",
47595
+ "Show IRIs as prefixed names, such as ex:Germany",
47596
+ run(() => callbacks.onShortenIris(!state.shortenIris))
47597
+ );
47598
+ shorten.setAttribute("role", "menuitemcheckbox");
47599
+ shorten.setAttribute("aria-checked", String(state.shortenIris));
47600
+ menu.appendChild(shorten);
47601
+ const separator = document.createElement("div");
47602
+ separator.className = "chart-view-settings-separator";
47603
+ separator.setAttribute("role", "separator");
47604
+ menu.appendChild(separator);
47605
+ menu.appendChild(
47606
+ menuItem(
47607
+ "chart-export-png",
47608
+ "download",
47609
+ "Download PNG",
47610
+ "Download the chart as a PNG image",
47611
+ run(() => callbacks.onExport("png"))
47612
+ )
47613
+ );
47614
+ menu.appendChild(
47615
+ menuItem(
47616
+ "chart-export-svg",
47617
+ "download",
47618
+ "Download SVG",
47619
+ "Download the chart as an SVG image",
47620
+ run(() => callbacks.onExport("svg"))
47621
+ )
47622
+ );
47623
+ toggle.addEventListener("click", () => setOpen(menu.hidden));
47624
+ wrapper.addEventListener("keydown", (e2) => {
47625
+ if (e2.key === "Escape" && !menu.hidden) {
47626
+ e2.stopPropagation();
47627
+ setOpen(false);
47628
+ toggle.focus();
47629
+ }
47630
+ });
47631
+ wrapper.appendChild(toggle);
47632
+ wrapper.appendChild(menu);
47633
+ return wrapper;
47634
+ }
47635
+ function renderHostToolbar(slot, state, callbacks) {
47636
+ const group = document.createElement("div");
47637
+ group.className = "yasr_toolbarGroup chart-toolbar-pickers";
47638
+ for (const el of renderPickers("host", state, callbacks)) group.appendChild(el);
47639
+ const spacer = document.createElement("div");
47640
+ spacer.className = "yasr_toolbarSpacer";
47641
+ const nodes = [group, spacer, renderViewSettings(state, callbacks)];
47642
+ for (const node of nodes) slot.appendChild(node);
47643
+ return nodes;
47644
+ }
47645
+ function closeToolbarPopups(root, target) {
47646
+ root.querySelectorAll(".chart-values-picker[open]").forEach((picker) => {
47647
+ if (!target || !picker.contains(target)) picker.removeAttribute("open");
47648
+ });
47649
+ root.querySelectorAll(".chart-view-settings").forEach((wrapper) => {
47650
+ const menu = wrapper.querySelector(".chart-view-settings-menu");
47651
+ if (!menu || menu.hidden || target && wrapper.contains(target)) return;
47652
+ menu.hidden = true;
47653
+ const toggle = wrapper.querySelector(".chart-view-settings-button");
47654
+ toggle == null ? void 0 : toggle.setAttribute("aria-expanded", "false");
47655
+ toggle == null ? void 0 : toggle.classList.remove("is-active");
47656
+ });
47657
+ }
47658
+
47659
+ // src/host.ts
47660
+ function hasHostDescribe(yasr) {
47661
+ var _a2;
47662
+ return !!((_a2 = yasr == null ? void 0 : yasr.hostApi) == null ? void 0 : _a2.describe) && typeof yasr.describe === "function";
47663
+ }
47664
+ function getHostToolbar(yasr) {
47665
+ var _a2;
47666
+ if (!((_a2 = yasr == null ? void 0 : yasr.hostApi) == null ? void 0 : _a2.toolbar) || typeof yasr.getPluginToolbar !== "function") return null;
47667
+ try {
47668
+ const slot = yasr.getPluginToolbar();
47669
+ return slot instanceof HTMLElement ? slot : null;
47670
+ } catch (error2) {
47671
+ console.warn("yasgui-chart-plugin: could not get the plugin toolbar", error2);
47672
+ return null;
47673
+ }
47674
+ }
47469
47675
 
47470
47676
  // src/theme.ts
47471
47677
  var LIGHT_PALETTE = [
@@ -47492,6 +47698,10 @@ var DARK_PALETTE = [
47492
47698
  "#ef8cc8",
47493
47699
  "#9aa8bb"
47494
47700
  ];
47701
+ var BRAND_LIGHT = "#0563bb";
47702
+ var BRAND_DARK = "#5aa8f2";
47703
+ var HIGHLIGHT_LIGHT = "#f2b300";
47704
+ var HIGHLIGHT_DARK = "#f5c242";
47495
47705
  function getCurrentTheme() {
47496
47706
  if (typeof document === "undefined") return "light";
47497
47707
  return document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light";
@@ -47507,7 +47717,11 @@ function getThemeColors() {
47507
47717
  border: read("--yasgui-border-color", dark ? "#444444" : "#d0d0d0"),
47508
47718
  background: read("--yasgui-bg-primary", dark ? "#1e1e1e" : "#ffffff"),
47509
47719
  tooltipBackground: read("--yasgui-bg-secondary", dark ? "#2a2a2a" : "#ffffff"),
47510
- palette: dark ? DARK_PALETTE : LIGHT_PALETTE
47720
+ palette: [
47721
+ read("--yasgui-brand", dark ? BRAND_DARK : BRAND_LIGHT),
47722
+ ...(dark ? DARK_PALETTE : LIGHT_PALETTE).slice(1)
47723
+ ],
47724
+ highlight: read("--yasgui-highlight", dark ? HIGHLIGHT_DARK : HIGHLIGHT_LIGHT)
47511
47725
  };
47512
47726
  }
47513
47727
  function watchThemeChanges(callback) {
@@ -50387,7 +50601,8 @@ var DescribeModal = class {
50387
50601
  title.title = uri;
50388
50602
  const closeButton = document.createElement("button");
50389
50603
  closeButton.className = "chart-modal-close";
50390
- closeButton.innerHTML = "&times;";
50604
+ closeButton.type = "button";
50605
+ closeButton.appendChild(icon("x", 20));
50391
50606
  closeButton.setAttribute("aria-label", "Close modal");
50392
50607
  closeButton.addEventListener("click", () => this.close());
50393
50608
  header.appendChild(this.createNavigation());
@@ -50409,7 +50624,7 @@ var DescribeModal = class {
50409
50624
  hint.textContent = "Ctrl+click a URI to describe it, Ctrl+Shift+click for the triples where it is the object.";
50410
50625
  const copyButton = document.createElement("button");
50411
50626
  copyButton.className = "chart-modal-button";
50412
- copyButton.textContent = "Copy Raw";
50627
+ copyButton.textContent = "Copy raw";
50413
50628
  copyButton.addEventListener("click", () => {
50414
50629
  const rawText = payload.state === "results" ? payload.result.raw : payload.state === "error" ? payload.raw : "";
50415
50630
  this.copyToClipboard(rawText);
@@ -50448,11 +50663,11 @@ var DescribeModal = class {
50448
50663
  createNavigation() {
50449
50664
  const nav = document.createElement("div");
50450
50665
  nav.className = "chart-describe-modal-nav";
50451
- const button2 = (className, text, label, enabled, onClick) => {
50666
+ const button2 = (className, iconName, label, enabled, onClick) => {
50452
50667
  const btn = document.createElement("button");
50453
50668
  btn.type = "button";
50454
50669
  btn.className = `chart-describe-modal-nav-button ${className}`;
50455
- btn.textContent = text;
50670
+ btn.appendChild(icon(iconName));
50456
50671
  btn.title = label;
50457
50672
  btn.setAttribute("aria-label", label);
50458
50673
  btn.disabled = !enabled;
@@ -50462,19 +50677,25 @@ var DescribeModal = class {
50462
50677
  nav.appendChild(
50463
50678
  button2(
50464
50679
  "chart-describe-modal-start",
50465
- "\u23EE",
50680
+ "chevrons-left",
50466
50681
  "Back to start",
50467
50682
  this.canGoBack(),
50468
50683
  () => this.backToStart()
50469
50684
  )
50470
50685
  );
50471
50686
  nav.appendChild(
50472
- button2("chart-describe-modal-back", "\u25C0", "Back (Alt+\u2190)", this.canGoBack(), () => this.back())
50687
+ button2(
50688
+ "chart-describe-modal-back",
50689
+ "chevron-left",
50690
+ "Back (Alt+\u2190)",
50691
+ this.canGoBack(),
50692
+ () => this.back()
50693
+ )
50473
50694
  );
50474
50695
  nav.appendChild(
50475
50696
  button2(
50476
50697
  "chart-describe-modal-forward",
50477
- "\u25B6",
50698
+ "chevron-right",
50478
50699
  "Forward (Alt+\u2192)",
50479
50700
  this.canGoForward(),
50480
50701
  () => this.forward()
@@ -50683,6 +50904,18 @@ var DescribeModal = class {
50683
50904
  };
50684
50905
 
50685
50906
  // src/ChartPlugin.ts
50907
+ var COMMON_PREFIXES = {
50908
+ rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
50909
+ rdfs: "http://www.w3.org/2000/01/rdf-schema#",
50910
+ owl: "http://www.w3.org/2002/07/owl#",
50911
+ xsd: "http://www.w3.org/2001/XMLSchema#",
50912
+ foaf: "http://xmlns.com/foaf/0.1/",
50913
+ dc: "http://purl.org/dc/elements/1.1/",
50914
+ dcterms: "http://purl.org/dc/terms/",
50915
+ skos: "http://www.w3.org/2004/02/skos/core#",
50916
+ schema: "http://schema.org/",
50917
+ wd: "http://www.wikidata.org/entity/"
50918
+ };
50686
50919
  use([
50687
50920
  install2,
50688
50921
  install,
@@ -50697,7 +50930,7 @@ use([
50697
50930
  ]);
50698
50931
  var DEFAULT_MAX_ROWS = 5e3;
50699
50932
  var MIN_CHART_HEIGHT = 320;
50700
- var ICON_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path fill="currentColor" d="M3 3h2v16h16v2H3V3zm4 10h3v5H7v-5zm5-6h3v11h-3V7zm5 3h3v8h-3v-8z"/></svg>';
50933
+ var ICON_SVG = iconSvg("chart-column");
50701
50934
  var ChartPlugin = class {
50702
50935
  constructor(yasr, options = {}) {
50703
50936
  /** Below the table (10), so SELECT results still open in the table */
@@ -50717,6 +50950,9 @@ var ChartPlugin = class {
50717
50950
  this.outsideClickHandler = null;
50718
50951
  this.windowResizeHandler = null;
50719
50952
  this.fullscreenObserver = null;
50953
+ /** Elements this plugin put in the host's toolbar slot */
50954
+ this.hostToolbarNodes = [];
50955
+ /** @deprecated Own describe modal, used only when the host has no shared describe panel */
50720
50956
  this.describeModal = null;
50721
50957
  this.describeAbortController = null;
50722
50958
  var _a2, _b2, _c2;
@@ -50731,11 +50967,11 @@ var ChartPlugin = class {
50731
50967
  return 5;
50732
50968
  }
50733
50969
  getIcon() {
50734
- const icon = document.createElement("div");
50735
- icon.innerHTML = ICON_SVG;
50736
- icon.setAttribute("role", "img");
50737
- icon.setAttribute("aria-label", "Chart view");
50738
- return icon;
50970
+ const icon2 = document.createElement("div");
50971
+ icon2.innerHTML = ICON_SVG;
50972
+ icon2.setAttribute("role", "img");
50973
+ icon2.setAttribute("aria-label", "Chart view");
50974
+ return icon2;
50739
50975
  }
50740
50976
  /** Offered for SELECT results with at least one numeric column */
50741
50977
  canHandleResults() {
@@ -50799,6 +51035,14 @@ var ChartPlugin = class {
50799
51035
  }
50800
51036
  return prefixes;
50801
51037
  }
51038
+ /**
51039
+ * Prefixes used to show IRIs in the chart: well-known ones, then those of
51040
+ * Yasr and the query. None when the user turned shortening off.
51041
+ */
51042
+ getLabelPrefixes() {
51043
+ if (this.saved.shortenIris === false) return {};
51044
+ return { ...COMMON_PREFIXES, ...this.getPrefixes() };
51045
+ }
50802
51046
  /** Build the toolbar and chart for the current results and settings */
50803
51047
  render() {
50804
51048
  var _a2;
@@ -50809,23 +51053,28 @@ var ChartPlugin = class {
50809
51053
  const allRows = this.results.results.bindings;
50810
51054
  const rows = allRows.length > maxRows ? allRows.slice(0, maxRows) : allRows;
50811
51055
  this.resolved = resolveSettings(this.columns, this.saved, rows.length);
50812
- this.data = buildChartData(rows, this.columns, this.resolved, this.getPrefixes());
51056
+ this.data = buildChartData(rows, this.columns, this.resolved, this.getLabelPrefixes());
50813
51057
  const wrapper = document.createElement("div");
50814
51058
  wrapper.className = "yasgui-chart-plugin";
50815
- wrapper.appendChild(
50816
- renderToolbar(
50817
- {
50818
- columns: this.columns,
50819
- resolved: this.resolved,
50820
- customised: Object.keys(this.saved).length > 0
50821
- },
50822
- {
50823
- onChange: (settings) => this.updateSettings(settings),
50824
- onReset: () => this.updateSettings({}),
50825
- onExport: (format2) => this.exportImage(format2)
50826
- }
50827
- )
50828
- );
51059
+ const toolbarState = {
51060
+ columns: this.columns,
51061
+ resolved: this.resolved,
51062
+ customised: isCustomised(this.saved),
51063
+ shortenIris: this.saved.shortenIris !== false
51064
+ };
51065
+ const toolbarCallbacks = {
51066
+ onChange: (settings) => this.updateSettings({ ...displayOptions(this.saved), ...settings }),
51067
+ onReset: () => this.updateSettings(displayOptions(this.saved)),
51068
+ onShortenIris: (shortenIris) => this.updateSettings({ ...this.saved, shortenIris }),
51069
+ onExport: (format2) => this.exportImage(format2)
51070
+ };
51071
+ const slot = getHostToolbar(this.yasr);
51072
+ if (slot) {
51073
+ this.hostToolbarNodes = renderHostToolbar(slot, toolbarState, toolbarCallbacks);
51074
+ } else {
51075
+ wrapper.classList.add("chart-own-toolbar");
51076
+ wrapper.appendChild(renderToolbar(toolbarState, toolbarCallbacks));
51077
+ }
50829
51078
  const notes = [];
50830
51079
  if (allRows.length > maxRows) {
50831
51080
  notes.push(
@@ -50876,11 +51125,9 @@ var ChartPlugin = class {
50876
51125
  this.fullscreenObserver.observe(yasrRoot, { attributes: true, attributeFilter: ["class"] });
50877
51126
  }
50878
51127
  this.themeObserver = watchThemeChanges(() => this.applyOption());
51128
+ const popupRoot = slot || wrapper;
50879
51129
  this.outsideClickHandler = (e2) => {
50880
- const picker = wrapper.querySelector(".chart-values-picker");
50881
- if (picker && picker.hasAttribute("open") && !picker.contains(e2.target)) {
50882
- picker.removeAttribute("open");
50883
- }
51130
+ closeToolbarPopups(popupRoot, e2.target);
50884
51131
  };
50885
51132
  document.addEventListener("mousedown", this.outsideClickHandler);
50886
51133
  }
@@ -50903,8 +51150,7 @@ var ChartPlugin = class {
50903
51150
  }
50904
51151
  updateSettings(settings) {
50905
51152
  this.saved = sanitizeSettings(settings);
50906
- if (Object.keys(this.saved).length > 0 && this.results)
50907
- this.saved.columns = [...this.results.head.vars];
51153
+ if (isCustomised(this.saved) && this.results) this.saved.columns = [...this.results.head.vars];
50908
51154
  if (typeof this.yasr.storePluginConfig === "function") {
50909
51155
  try {
50910
51156
  this.yasr.storePluginConfig(this.getPluginName(), this.saved);
@@ -50922,15 +51168,37 @@ var ChartPlugin = class {
50922
51168
  if (!iri) return;
50923
51169
  this.runResourceQuery(iri, event.shiftKey ? "object" : "subject");
50924
51170
  }
51171
+ /**
51172
+ * Show the triples of `uri`: in the host's shared describe panel when YASR
51173
+ * offers one, otherwise in the plugin's own describe modal.
51174
+ */
51175
+ runResourceQuery(uri, direction) {
51176
+ if (hasHostDescribe(this.yasr)) {
51177
+ const hostDirection = direction === "object" ? "incoming" : "outgoing";
51178
+ const fail = (error2) => console.error("yasgui-chart-plugin: describe failed", uri, error2);
51179
+ try {
51180
+ Promise.resolve(
51181
+ this.yasr.describe(uri, { direction: hostDirection, source: "Chart" })
51182
+ ).catch(fail);
51183
+ } catch (error2) {
51184
+ fail(error2);
51185
+ }
51186
+ return;
51187
+ }
51188
+ void this.runOwnResourceQuery(uri, direction);
51189
+ }
50925
51190
  /**
50926
51191
  * Run a background query for the triples where `iri` is the subject (or
50927
- * object) and show them in the describe modal, as the table and geo plugins do.
51192
+ * object) and show them in the plugin's own describe modal.
51193
+ *
51194
+ * @deprecated Fallback for YASR versions without `yasr.describe()`; it will be
51195
+ * removed in the next major version.
50928
51196
  */
50929
- async runResourceQuery(uri, direction, newHistory = true) {
51197
+ async runOwnResourceQuery(uri, direction, newHistory = true) {
50930
51198
  var _a2, _b2, _c2, _d2;
50931
51199
  if (!this.describeModal) {
50932
51200
  this.describeModal = new DescribeModal({
50933
- onDescribe: (u, d) => this.runResourceQuery(u, d, false)
51201
+ onDescribe: (u, d) => this.runOwnResourceQuery(u, d, false)
50934
51202
  });
50935
51203
  }
50936
51204
  if (typeof this.yasr.executeQuery !== "function") {
@@ -51049,6 +51317,8 @@ var ChartPlugin = class {
51049
51317
  this.chart.dispose();
51050
51318
  this.chart = null;
51051
51319
  }
51320
+ for (const node of this.hostToolbarNodes) node.remove();
51321
+ this.hostToolbarNodes = [];
51052
51322
  this.chartEl = null;
51053
51323
  this.option = null;
51054
51324
  }