@datawheel/data-explorer 1.1.7 → 1.1.9

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.
Files changed (2) hide show
  1. package/dist/main.mjs +120 -22
  2. package/package.json +3 -2
package/dist/main.mjs CHANGED
@@ -21,6 +21,7 @@ import { saveElement } from 'd3plus-export';
21
21
  import { d3plusConfigBuilder } from '@datawheel/vizbuilder/react';
22
22
  import { assign } from 'd3plus-common';
23
23
  import { BarChart, Geomap, Donut, LinePlot, StackedArea, Treemap } from 'd3plus-react';
24
+ import { useInView } from 'react-intersection-observer';
24
25
 
25
26
  // src/components/DebugView.tsx
26
27
  var explorerTranslation = {
@@ -1847,16 +1848,58 @@ var useDimensionItems = () => {
1847
1848
  (a, b) => getOrderValue(a.item) - getOrderValue(b.item) || b.count - a.count || a.alpha.localeCompare(b.alpha)
1848
1849
  ).map((i) => i.item);
1849
1850
  };
1851
+ function getISO3Drilldowns({ cube, search }) {
1852
+ const ISO_3_CODE = "ISO 3";
1853
+ if (!cube) return false;
1854
+ function getList(search2, key, separator) {
1855
+ return search2.getAll(key).join(separator).split(separator).filter((token) => token);
1856
+ }
1857
+ const dimensions = {};
1858
+ const hierarchies = {};
1859
+ const levels = Object.fromEntries(
1860
+ cube.dimensions.flatMap(
1861
+ (dim) => dim.hierarchies.flatMap(
1862
+ (hie) => hie.levels.map((lvl) => {
1863
+ dimensions[lvl.name] = dim.name;
1864
+ hierarchies[lvl.name] = hie.name;
1865
+ return [lvl.name, lvl];
1866
+ })
1867
+ )
1868
+ )
1869
+ );
1870
+ const properties = [ISO_3_CODE];
1871
+ const drilldowns = getList(search, "drilldowns", ",").map((name4) => {
1872
+ const lvl = levels[name4];
1873
+ return buildDrilldown({
1874
+ active: true,
1875
+ key: lvl.name,
1876
+ dimension: dimensions[name4],
1877
+ hierarchy: hierarchies[name4],
1878
+ level: name4,
1879
+ properties: filterMap(
1880
+ lvl.properties,
1881
+ (prop) => properties.includes(prop.name) ? buildProperty({ name: prop.name, level: name4, active: true }) : null
1882
+ )
1883
+ });
1884
+ });
1885
+ return keyBy(drilldowns, "key");
1886
+ }
1850
1887
  function useDownloadQuery() {
1851
1888
  const { tesseract } = useLogicLayer();
1852
1889
  const { params } = useSelector(selectCurrentQueryItem);
1890
+ const { data: schema } = useServerSchema();
1853
1891
  return useMutation({
1854
1892
  mutationFn: async ({ format: format2 }) => {
1855
1893
  if (!isValidQuery(params)) {
1856
1894
  throw new Error("The current query is not valid.");
1857
1895
  }
1858
1896
  const queryParams = { ...params, pagiLimit: 0, pagiOffset: 0 };
1859
- const request = queryParamsToRequest(queryParams);
1897
+ const drilldowns = getISO3Drilldowns({
1898
+ cube: schema == null ? void 0 : schema.cubeMap[params.cube],
1899
+ search: new URLSearchParams(location.search)
1900
+ });
1901
+ const paramsUpdated = drilldowns ? { ...queryParams, drilldowns } : queryParams;
1902
+ const request = queryParamsToRequest(paramsUpdated);
1860
1903
  const response = await tesseract.fetchData({
1861
1904
  request,
1862
1905
  format: format2
@@ -6342,9 +6385,20 @@ var iconByFormat = {
6342
6385
  svg: IconVectorTriangle
6343
6386
  };
6344
6387
  function ChartCard(props) {
6345
- const { chart, downloadFormats, isFullMode, onFocus, showConfidenceInt } = props;
6388
+ const { chart, downloadFormats, isFullMode, onFocus, showConfidenceInt, height } = props;
6346
6389
  const { translate } = useTranslation();
6347
6390
  const nodeRef = useRef(null);
6391
+ const { ref: inViewRef, inView } = useInView({ triggerOnce: false, threshold: 0 });
6392
+ const [hasBeenInView, setHasBeenInView] = useState(false);
6393
+ React13__default.useEffect(() => {
6394
+ if (inView && !hasBeenInView) {
6395
+ setHasBeenInView(true);
6396
+ }
6397
+ }, [inView, hasBeenInView]);
6398
+ const setRefs = (el) => {
6399
+ nodeRef.current = el;
6400
+ inViewRef(el);
6401
+ };
6348
6402
  const [ChartComponent, config] = useD3plusConfig(chart, {
6349
6403
  fullMode: !!isFullMode,
6350
6404
  showConfidenceInt: !!showConfidenceInt,
@@ -6413,9 +6467,9 @@ function ChartCard(props) {
6413
6467
  isShared ? translate("vizbuilder.share_copied") : translate("vizbuilder.action_share")
6414
6468
  );
6415
6469
  }, [clipboard, translate, isShared]);
6416
- const height = isFullMode ? "calc(100vh - 3rem)" : 300;
6470
+ const resolvedHeight = height ? height : isFullMode ? "calc(100vh - 3rem)" : 400;
6417
6471
  if (!ChartComponent) return null;
6418
- return /* @__PURE__ */ React13__default.createElement(Paper, { h: height, w: "100%", style: { overflow: "hidden" } }, /* @__PURE__ */ React13__default.createElement(ErrorBoundary, null, /* @__PURE__ */ React13__default.createElement(Stack, { spacing: 0, h: height, style: { position: "relative" }, w: "100%" }, /* @__PURE__ */ React13__default.createElement(Group, { position: "right", p: "xs", spacing: "xs", align: "center" }, isFullMode && shareButton, downloadButtons, onFocus && focusButton), /* @__PURE__ */ React13__default.createElement(Box, { style: { flex: "1 1 auto" }, ref: nodeRef, pb: "xs", px: "xs" }, /* @__PURE__ */ React13__default.createElement(ChartComponent, { config })))));
6472
+ return /* @__PURE__ */ React13__default.createElement(Paper, { h: resolvedHeight, w: "100%", style: { overflow: "hidden" } }, /* @__PURE__ */ React13__default.createElement(ErrorBoundary, null, /* @__PURE__ */ React13__default.createElement(Stack, { spacing: 0, h: resolvedHeight, style: { position: "relative" }, w: "100%" }, /* @__PURE__ */ React13__default.createElement(Group, { position: "center", p: "xs", spacing: "xs", align: "center" }, isFullMode && shareButton, downloadButtons, onFocus && focusButton), /* @__PURE__ */ React13__default.createElement(Box, { style: { flex: "1 1 auto" }, ref: setRefs, pb: "xs", px: "xs" }, ChartComponent && (inView || hasBeenInView) ? /* @__PURE__ */ React13__default.createElement(ChartComponent, { config }) : /* @__PURE__ */ React13__default.createElement("div", { style: { height: "100%", width: "100%" } })))));
6419
6473
  }
6420
6474
  var getBackground = (node) => {
6421
6475
  if (node.nodeType !== Node.ELEMENT_NODE) return "white";
@@ -6453,6 +6507,42 @@ function Vizbuilder(props) {
6453
6507
  const queryItem = useSelector$1(selectCurrentQueryItem);
6454
6508
  const currentChart = (queryItem == null ? void 0 : queryItem.chart) || "";
6455
6509
  const { actions: actions2 } = useSettings();
6510
+ const useStyles6 = createStyles((theme) => ({
6511
+ grid: {
6512
+ padding: theme.spacing.xl,
6513
+ display: "grid",
6514
+ gridAutoRows: "minmax(200px, auto)",
6515
+ gap: theme.spacing.xl,
6516
+ gridTemplateColumns: "1fr 1fr",
6517
+ [theme.fn.smallerThan("md")]: {
6518
+ gridTemplateColumns: "1fr"
6519
+ }
6520
+ },
6521
+ itemLarge: {
6522
+ gridRow: "auto",
6523
+ gridColumn: "auto"
6524
+ },
6525
+ itemSmallTop: {
6526
+ gridRow: "auto",
6527
+ gridColumn: "auto"
6528
+ },
6529
+ itemSmallBottom: {
6530
+ gridRow: "auto",
6531
+ gridColumn: "auto"
6532
+ },
6533
+ // for single chart
6534
+ fill: {
6535
+ gridColumn: "1",
6536
+ gridRow: "1",
6537
+ height: "100%",
6538
+ width: "100%",
6539
+ [theme.fn.largerThan("md")]: {
6540
+ gridColumn: "1 / span 2",
6541
+ gridRow: "1 / span 2"
6542
+ }
6543
+ }
6544
+ }));
6545
+ const { classes, cx } = useStyles6();
6456
6546
  const setCurrentChart = useCallback(
6457
6547
  (chart) => {
6458
6548
  actions2.updateChart(chart);
@@ -6489,34 +6579,40 @@ function Vizbuilder(props) {
6489
6579
  if (chartList.length === 0 && !Array.isArray(datasets) && datasets.data.length === 1)
6490
6580
  return /* @__PURE__ */ React13__default.createElement(Notice, { status: "one-row" });
6491
6581
  if (chartList.length === 0) return /* @__PURE__ */ React13__default.createElement(Notice, { status: "empty" });
6492
- const isSingleChart = chartList.length === 1;
6493
6582
  if (chartList.length > 10) {
6494
6583
  chartList = chartList.slice(0, 10);
6495
6584
  }
6496
- return /* @__PURE__ */ React13__default.createElement(ErrorBoundary, null, /* @__PURE__ */ React13__default.createElement(
6497
- SimpleGrid,
6498
- {
6499
- breakpoints: [
6500
- { minWidth: "xs", cols: 1 },
6501
- { minWidth: "md", cols: 2 },
6502
- { minWidth: "lg", cols: 3 },
6503
- { minWidth: "xl", cols: 4 }
6504
- ],
6505
- className: cls({ unique: isSingleChart })
6506
- },
6507
- chartList.map((chart) => /* @__PURE__ */ React13__default.createElement(
6585
+ const isSingleChart = chartList.length === 1;
6586
+ return /* @__PURE__ */ React13__default.createElement(ErrorBoundary, null, /* @__PURE__ */ React13__default.createElement("div", { className: cx(classes.grid, { [classes.fill]: isSingleChart }) }, chartList.map((chart, idx) => {
6587
+ const pos = idx % 3;
6588
+ let style = {};
6589
+ let className = "";
6590
+ let height;
6591
+ if (isSingleChart) {
6592
+ className = classes.fill;
6593
+ height = 600;
6594
+ } else {
6595
+ if (pos === 0) {
6596
+ className = classes.itemLarge;
6597
+ } else if (pos === 1) {
6598
+ className = classes.itemSmallTop;
6599
+ } else if (pos === 2) {
6600
+ className = classes.itemSmallBottom;
6601
+ }
6602
+ }
6603
+ return /* @__PURE__ */ React13__default.createElement("div", { key: chart.key, className, style }, /* @__PURE__ */ React13__default.createElement(
6508
6604
  ChartCard,
6509
6605
  {
6510
- key: chart.key,
6511
6606
  chart,
6512
6607
  downloadFormats,
6513
6608
  measureConfig: getMeasureConfig,
6514
6609
  onFocus: () => setCurrentChart(chart.key),
6515
6610
  showConfidenceInt,
6516
- userConfig
6611
+ userConfig,
6612
+ ...height ? { height } : {}
6517
6613
  }
6518
- ))
6519
- ));
6614
+ ));
6615
+ })));
6520
6616
  }, [
6521
6617
  charts,
6522
6618
  datasets,
@@ -6524,7 +6620,9 @@ function Vizbuilder(props) {
6524
6620
  getMeasureConfig,
6525
6621
  nonIdealState,
6526
6622
  showConfidenceInt,
6527
- userConfig
6623
+ userConfig,
6624
+ classes,
6625
+ cx
6528
6626
  ]);
6529
6627
  const focusContent = useMemo(() => {
6530
6628
  const chart = charts[currentChart];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datawheel/data-explorer",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "main": "./dist/main.mjs",
5
5
  "types": "./dist/main.d.mts",
6
6
  "files": [
@@ -39,6 +39,7 @@
39
39
  "mantine-react-table": "^1.3.0",
40
40
  "match-sorter": "^6.3.4",
41
41
  "postcss-modules": "^6.0.0",
42
+ "react-intersection-observer": "^9.16.0",
42
43
  "react-redux": "^7.0.0",
43
44
  "react-router-dom": "^6.30.0",
44
45
  "react-viewport-list": "^3.0.0",
@@ -47,8 +48,8 @@
47
48
  "yn": "^5.0.0"
48
49
  },
49
50
  "peerDependencies": {
50
- "@emotion/react": "^11.0.0",
51
51
  "@datawheel/vizbuilder": "^0.6.0",
52
+ "@emotion/react": "^11.0.0",
52
53
  "@mantine/core": "^6.0.0",
53
54
  "@mantine/dates": "^6.0.0",
54
55
  "@mantine/hooks": "^6.0.0",