@datawheel/bespoke 0.1.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/README.md +19 -0
- package/dist/Viz-41329377.js +368 -0
- package/dist/Viz-41329377.js.map +1 -0
- package/dist/Viz-ef983f01.js +368 -0
- package/dist/Viz-ef983f01.js.map +1 -0
- package/dist/index-9c337b90.js +6680 -0
- package/dist/index-9c337b90.js.map +1 -0
- package/dist/index-cf73f4fa.js +6680 -0
- package/dist/index-cf73f4fa.js.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/server.js +2944 -0
- package/dist/server.js.map +1 -0
- package/dist/style.css +765 -0
- package/package.json +125 -0
package/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Reports
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## EnvVars
|
|
5
|
+
```
|
|
6
|
+
REPORTS_DB_CONNECTION="postgres://user:@localhost:5432/database"
|
|
7
|
+
REPORTS_LOGGING=true
|
|
8
|
+
NEXT_PUBLIC_REPORTS_LOCALE_DEFAULT="en"
|
|
9
|
+
NEXT_PUBLIC_REPORTS_LOCALES="en,es"
|
|
10
|
+
REPORTS_DB_WIPE=false
|
|
11
|
+
|
|
12
|
+
#Images
|
|
13
|
+
NEXT_PUBLIC_IMAGE_SPLASH_WIDTH=1400
|
|
14
|
+
NEXT_PUBLIC_IMAGE_THUMB_WIDTH=400
|
|
15
|
+
|
|
16
|
+
#Providers
|
|
17
|
+
FLICKR_API_KEY="xxxx"
|
|
18
|
+
UNSPLASH_API_KEY="xxxx"
|
|
19
|
+
```
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { useState, useEffect, Component, useMemo } from "react";
|
|
3
|
+
import { Center, Badge } from "@mantine/core";
|
|
4
|
+
import * as d3plus from "d3plus-react";
|
|
5
|
+
import { S as StatPreview, l as libs, s as stripHTML, p as parse, g as getBlockContent, u as useFormatterFunctionsForLocale, v as varSwapRecursive, m as mortarEval } from "./index-9c337b90.js";
|
|
6
|
+
import axios from "axios";
|
|
7
|
+
import PropTypes from "prop-types";
|
|
8
|
+
import { dataLoad, dataConcat } from "d3plus-viz";
|
|
9
|
+
import { sum, max, min } from "d3-array";
|
|
10
|
+
import { scaleLinear } from "d3-scale";
|
|
11
|
+
import ReactTable from "react-table-6";
|
|
12
|
+
import "@mantine/hooks";
|
|
13
|
+
import "@tabler/icons";
|
|
14
|
+
import "next/link";
|
|
15
|
+
import "yn";
|
|
16
|
+
import "d3-collection";
|
|
17
|
+
import "d3-format";
|
|
18
|
+
import "d3-time-format";
|
|
19
|
+
import "d3plus-format";
|
|
20
|
+
import "d3plus-axis";
|
|
21
|
+
import "d3plus-common";
|
|
22
|
+
import "d3plus-text";
|
|
23
|
+
import "normalizr";
|
|
24
|
+
import "@mantine/notifications";
|
|
25
|
+
import "@reduxjs/toolkit";
|
|
26
|
+
import "next-redux-wrapper";
|
|
27
|
+
import "react-redux";
|
|
28
|
+
import "next/router";
|
|
29
|
+
import "react-router-dom";
|
|
30
|
+
import "react-beautiful-dnd";
|
|
31
|
+
import "slugify";
|
|
32
|
+
import "@mantine/prism";
|
|
33
|
+
import "@monaco-editor/react";
|
|
34
|
+
import "pretty-format";
|
|
35
|
+
import "next/dynamic";
|
|
36
|
+
import "@tinymce/tinymce-react";
|
|
37
|
+
import "jszip";
|
|
38
|
+
import "file-saver";
|
|
39
|
+
import "d3-dsv";
|
|
40
|
+
import "mantine-datatable";
|
|
41
|
+
import "d3-selection";
|
|
42
|
+
import "d3plus-export";
|
|
43
|
+
import "react-share";
|
|
44
|
+
import "@mantine/form";
|
|
45
|
+
var defaultConfig = {
|
|
46
|
+
loadingHTML: `<div style="left: 50%; top: 50%; position: absolute; transform: translate(-50%, -50%);">
|
|
47
|
+
<svg class="cp-viz-spinner" width="60px" height="60px" viewBox="0 0 317 317" xmlns="http://www.w3.org/2000/svg">
|
|
48
|
+
<path class="outer" d="M16.43 157.072c0 34.797 12.578 66.644 33.428 91.277l-11.144 11.141c-23.673-27.496-37.992-63.283-37.992-102.418 0-39.133 14.319-74.921 37.992-102.423l11.144 11.144c-20.85 24.63-33.428 56.481-33.428 91.279z"/>
|
|
49
|
+
<path class="outer" d="M157.793 15.708c34.798 0 66.648 12.58 91.28 33.427l11.143-11.144c-27.502-23.676-63.29-37.991-102.423-37.991-39.132 0-74.919 14.315-102.422 37.991l11.148 11.144c24.627-20.847 56.477-33.427 91.274-33.427"/>
|
|
50
|
+
<path class="outer" d="M299.159 157.072c0 34.797-12.578 66.644-33.43 91.277l11.145 11.141c23.674-27.496 37.992-63.283 37.992-102.418 0-39.133-14.318-74.921-37.992-102.423l-11.145 11.144c20.852 24.63 33.43 56.481 33.43 91.279"/>
|
|
51
|
+
<path class="outer" d="M157.793 298.432c-34.797 0-66.647-12.574-91.274-33.424l-11.148 11.138c27.503 23.682 63.29 37.997 102.422 37.997 39.133 0 74.921-14.315 102.423-37.997l-11.143-11.138c-24.632 20.85-56.482 33.424-91.28 33.424"/>
|
|
52
|
+
<path class="middle" d="M226.59 61.474l-7.889 13.659c24.997 18.61 41.184 48.382 41.184 81.94 0 33.555-16.187 63.329-41.184 81.936l7.889 13.664c29.674-21.394 49.004-56.23 49.004-95.6 0-39.373-19.33-74.21-49.004-95.599"/>
|
|
53
|
+
<path class="middle" d="M157.793 259.169c-52.398 0-95.553-39.485-101.399-90.317h-15.814c5.912 59.524 56.131 106.018 117.213 106.018 17.26 0 33.633-3.742 48.404-10.406l-7.893-13.672c-12.425 5.38-26.114 8.377-40.511 8.377"/>
|
|
54
|
+
<path class="middle" d="M157.793 54.976c14.397 0 28.086 2.993 40.511 8.371l7.893-13.667c-14.771-6.669-31.144-10.412-48.404-10.412-61.082 0-111.301 46.493-117.213 106.021h15.814c5.846-50.831 49.001-90.313 101.399-90.313"/>
|
|
55
|
+
<path class="inner" d="M95.371 164.193c-3.476-30.475 15.471-58.324 43.723-67.097l-1.804-15.842c-36.899 9.931-61.986 45.602-57.524 84.719 4.461 39.115 36.934 68.219 75.122 69.584l-1.806-15.838c-29.504-2.186-54.235-25.054-57.711-55.526"/>
|
|
56
|
+
<path class="inner" d="M162.504 94.425c29.508 2.185 54.235 25.053 57.711 55.529 3.476 30.469-15.466 58.319-43.724 67.096l1.806 15.834c36.898-9.927 61.986-45.598 57.525-84.712-4.461-39.117-36.936-68.223-75.125-69.588l1.807 15.841z"/>
|
|
57
|
+
</svg>
|
|
58
|
+
<strong>Loading</strong>
|
|
59
|
+
<sub style="bottom: 0; display: block; line-height: 1; margin-top: 5px;">
|
|
60
|
+
<a style="color: inherit;" href="https://www.datawheel.us/" target="_blank">
|
|
61
|
+
Built by Datawheel
|
|
62
|
+
</a>
|
|
63
|
+
</sub>
|
|
64
|
+
</div>`,
|
|
65
|
+
noDataHTML: `<div style="left: 50%; top: 50%; position: absolute; transform: translate(-50%, -50%);">
|
|
66
|
+
<strong>No Data Available</strong>
|
|
67
|
+
</div>`
|
|
68
|
+
}, __defProp$2 = Object.defineProperty, __getOwnPropSymbols$2 = Object.getOwnPropertySymbols, __hasOwnProp$2 = Object.prototype.hasOwnProperty, __propIsEnum$2 = Object.prototype.propertyIsEnumerable, __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$2 = (a, b) => {
|
|
69
|
+
for (var prop in b || (b = {}))
|
|
70
|
+
__hasOwnProp$2.call(b, prop) && __defNormalProp$2(a, prop, b[prop]);
|
|
71
|
+
if (__getOwnPropSymbols$2)
|
|
72
|
+
for (var prop of __getOwnPropSymbols$2(b))
|
|
73
|
+
__propIsEnum$2.call(b, prop) && __defNormalProp$2(a, prop, b[prop]);
|
|
74
|
+
return a;
|
|
75
|
+
};
|
|
76
|
+
function Graphic({ config, dataFormat }) {
|
|
77
|
+
const [builtConfig, setBuiltConfig] = useState();
|
|
78
|
+
return useEffect(() => {
|
|
79
|
+
let rebuiltConfig = __spreadValues$2(__spreadValues$2({}, {
|
|
80
|
+
numberFormat: (d, value, total) => {
|
|
81
|
+
const perc = Number(d[value] / total * 100);
|
|
82
|
+
return isNaN(perc) ? "No Data" : `${perc.toFixed(2)}%`;
|
|
83
|
+
}
|
|
84
|
+
}), config);
|
|
85
|
+
!rebuiltConfig || !rebuiltConfig.data ? console.log("no config/data") : typeof rebuiltConfig.data == "string" ? axios.get(rebuiltConfig.data).then((resp) => {
|
|
86
|
+
rebuiltConfig.data = dataFormat(resp.data), typeof rebuiltConfig.data == "object" && !(rebuiltConfig.data instanceof Array) && (rebuiltConfig = Object.assign(rebuiltConfig, rebuiltConfig.data)), rebuiltConfig.total || (rebuiltConfig.total = rebuiltConfig.data.reduce((acc, d) => isNaN(d[rebuiltConfig.value]) ? acc : acc + Number(d[rebuiltConfig.value]), 0)), setBuiltConfig(rebuiltConfig);
|
|
87
|
+
}) : (rebuiltConfig.data = dataFormat(rebuiltConfig.data), typeof rebuiltConfig.data == "object" && !(rebuiltConfig.data instanceof Array) && (rebuiltConfig = Object.assign(rebuiltConfig, rebuiltConfig.data)), rebuiltConfig.total || (rebuiltConfig.total = rebuiltConfig.data.reduce((acc, d) => isNaN(d[rebuiltConfig.value]) ? acc : acc + Number(d[rebuiltConfig.value]), 0)), setBuiltConfig(rebuiltConfig));
|
|
88
|
+
}, [config]), builtConfig ? /* @__PURE__ */ jsxs("div", { className: "cp-graphic", children: [
|
|
89
|
+
builtConfig.imageURL && /* @__PURE__ */ jsx("img", { src: builtConfig.imageURL, className: "cp-graphic-img", alt: "" }),
|
|
90
|
+
builtConfig.value && /* @__PURE__ */ jsx(
|
|
91
|
+
StatPreview,
|
|
92
|
+
{
|
|
93
|
+
title: builtConfig.label,
|
|
94
|
+
value: builtConfig.value,
|
|
95
|
+
subtitle: builtConfig.subtitle,
|
|
96
|
+
tooltip: builtConfig.tooltip
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
] }) : null;
|
|
100
|
+
}
|
|
101
|
+
function HTML({ config }) {
|
|
102
|
+
return !config || !config.html ? null : /* @__PURE__ */ jsx("div", { className: "cp-viz cp-html", dangerouslySetInnerHTML: { __html: config.html } });
|
|
103
|
+
}
|
|
104
|
+
function abbreviate(n) {
|
|
105
|
+
return libs.d3plus.formatAbbreviate(n);
|
|
106
|
+
}
|
|
107
|
+
var __defProp$1 = Object.defineProperty, __defProps = Object.defineProperties, __getOwnPropDescs = Object.getOwnPropertyDescriptors, __getOwnPropSymbols$1 = Object.getOwnPropertySymbols, __hasOwnProp$1 = Object.prototype.hasOwnProperty, __propIsEnum$1 = Object.prototype.propertyIsEnumerable, __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$1 = (a, b) => {
|
|
108
|
+
for (var prop in b || (b = {}))
|
|
109
|
+
__hasOwnProp$1.call(b, prop) && __defNormalProp$1(a, prop, b[prop]);
|
|
110
|
+
if (__getOwnPropSymbols$1)
|
|
111
|
+
for (var prop of __getOwnPropSymbols$1(b))
|
|
112
|
+
__propIsEnum$1.call(b, prop) && __defNormalProp$1(a, prop, b[prop]);
|
|
113
|
+
return a;
|
|
114
|
+
}, __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)), __publicField = (obj, key, value) => (__defNormalProp$1(obj, typeof key != "symbol" ? key + "" : key, value), value);
|
|
115
|
+
const letters = {
|
|
116
|
+
i: 2,
|
|
117
|
+
l: 2,
|
|
118
|
+
I: 2,
|
|
119
|
+
" ": 4
|
|
120
|
+
};
|
|
121
|
+
function spanify(html, cell, onClick) {
|
|
122
|
+
return /* @__PURE__ */ jsx("span", { className: `cp-table-cell-inner cp-table-cell-inner-${onClick ? "clickable" : "static"}`, onClick: onClick ? onClick.bind(this, cell.original) : void 0, dangerouslySetInnerHTML: { __html: html } });
|
|
123
|
+
}
|
|
124
|
+
const measureString = (str) => typeof str == "string" ? sum(str.split("").map((l) => letters[l] || l.toUpperCase() === l ? 8 : 6)) : 0, defaultCellFormat = (d, val) => isNaN(val) || d.column.id.includes("Year") || val === "" || val === " " ? val : abbreviate(val);
|
|
125
|
+
class Table extends Component {
|
|
126
|
+
constructor(props) {
|
|
127
|
+
super(props), __publicField(this, "renderGrouping", (currColumn, config) => {
|
|
128
|
+
const { headerFormat } = config;
|
|
129
|
+
let groupingTitle, nestedColumns;
|
|
130
|
+
if (currColumn[0] && typeof currColumn[0] == "string" && (groupingTitle = currColumn[0]), currColumn[1] && Array.isArray(currColumn[1]) && (nestedColumns = currColumn[1]), nestedColumns) {
|
|
131
|
+
if (typeof nestedColumns[0] == "string")
|
|
132
|
+
return {
|
|
133
|
+
Header: headerFormat(groupingTitle),
|
|
134
|
+
accessor: (d) => d[nestedColumns[0]],
|
|
135
|
+
id: groupingTitle,
|
|
136
|
+
columns: nestedColumns.map((col) => this.renderColumn(col))
|
|
137
|
+
};
|
|
138
|
+
if (Array.isArray(nestedColumns[0]))
|
|
139
|
+
return {
|
|
140
|
+
Header: headerFormat(groupingTitle),
|
|
141
|
+
id: groupingTitle,
|
|
142
|
+
columns: nestedColumns.map((col) => this.renderGrouping(col))
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
console.log("Invalid columns config passed to table viz; expected either an array of strings, or an array of arrays, each with a string first (table heading grouping title) and an array of strings.");
|
|
146
|
+
}), __publicField(this, "renderColumn", (obj, config) => {
|
|
147
|
+
const { data, headerFormat, cellFormat } = config, col = typeof obj == "string" ? obj : obj.accessor, onClick = typeof obj == "object" ? obj.onClick : void 0, header = obj.Header ? obj.Header : col, title = headerFormat ? headerFormat(header) : header, { print } = this.context;
|
|
148
|
+
function formatValue(cell, value) {
|
|
149
|
+
try {
|
|
150
|
+
return cellFormat ? cellFormat(cell, value) : defaultCellFormat(cell, value);
|
|
151
|
+
} catch (e) {
|
|
152
|
+
return console.log("Error in cellFormat: ", e), defaultCellFormat(cell, value);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const padding = 20, sortIconWidth = 30, values = data.reduce((arr, d) => {
|
|
156
|
+
const html = formatValue({ original: d, value: d[col], column: { id: col } }, d[col]), text = stripHTML(html);
|
|
157
|
+
if (text)
|
|
158
|
+
arr.push(measureString(text));
|
|
159
|
+
else {
|
|
160
|
+
const inlineWidth = html.match(/width[:="'\s]{1,}([0-9]{1,})px/);
|
|
161
|
+
arr.push(inlineWidth ? +inlineWidth[1] : 0);
|
|
162
|
+
}
|
|
163
|
+
return arr;
|
|
164
|
+
}, [measureString(title) + sortIconWidth]), columnWidth = max(values) + padding, calculatedMinWidth = min([200, max([padding * 2, columnWidth])]), minWidth = obj.minWidth !== void 0 ? obj.minWidth : calculatedMinWidth, maxWidth = obj.maxWidth !== void 0 ? obj.maxWidth : calculatedMinWidth < 100 ? calculatedMinWidth : void 0, { width } = obj;
|
|
165
|
+
return {
|
|
166
|
+
Header: print ? /* @__PURE__ */ jsx("button", { className: "cp-table-header-button", children: title }) : /* @__PURE__ */ jsxs("button", { className: "cp-table-header-button", children: [
|
|
167
|
+
title,
|
|
168
|
+
" ",
|
|
169
|
+
/* @__PURE__ */ jsx("span", { className: "u-visually-hidden", children: ", sort by column" }),
|
|
170
|
+
/* @__PURE__ */ jsx(Icon, { className: "cp-table-header-icon", icon: "caret-down" })
|
|
171
|
+
] }),
|
|
172
|
+
id: col,
|
|
173
|
+
accessor: (d) => d[col],
|
|
174
|
+
minWidth,
|
|
175
|
+
maxWidth,
|
|
176
|
+
width,
|
|
177
|
+
Cell: (cell) => {
|
|
178
|
+
if (obj.cellStyle)
|
|
179
|
+
try {
|
|
180
|
+
const newCell = obj.cellStyle(cell);
|
|
181
|
+
newCell && (cell = newCell);
|
|
182
|
+
} catch (e) {
|
|
183
|
+
console.error("Error in cellStyle");
|
|
184
|
+
}
|
|
185
|
+
const html = formatValue(cell, cell.value);
|
|
186
|
+
return spanify.bind(this)(html, cell, onClick);
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}), this.state = {
|
|
190
|
+
data: [],
|
|
191
|
+
error: !1,
|
|
192
|
+
loading: !1
|
|
193
|
+
}, this.viz = React.createRef();
|
|
194
|
+
}
|
|
195
|
+
componentDidMount() {
|
|
196
|
+
this.loadData.bind(this)();
|
|
197
|
+
}
|
|
198
|
+
loadData() {
|
|
199
|
+
const { config, dataFormat } = this.props, url = config.data;
|
|
200
|
+
if (url) {
|
|
201
|
+
const fetch = () => dataLoad.bind({})(url, dataFormat, void 0, (error, data) => {
|
|
202
|
+
this.state.loading === JSON.stringify(url) && (error ? (console.error(error), this.setState({ error, loading: !1 })) : this.setState({ data, loading: !1 }));
|
|
203
|
+
});
|
|
204
|
+
this.setState({ error: !1, loading: JSON.stringify(url) }, fetch.bind(this));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
componentDidUpdate(prevProps) {
|
|
208
|
+
const { data } = this.props.config, { loading } = this.state;
|
|
209
|
+
loading !== data && JSON.stringify(prevProps.config.data) !== JSON.stringify(data) && this.loadData.bind(this)();
|
|
210
|
+
}
|
|
211
|
+
render() {
|
|
212
|
+
const { data, loading } = this.state, { minRowsForPagination, size, t } = this.props, config = __spreadValues$1({}, this.props.config), { d3plus: d3plus2, print } = this.context;
|
|
213
|
+
config.data = data, config.column && delete config.column;
|
|
214
|
+
let columns = data.length ? Object.keys(data[0]) : [];
|
|
215
|
+
Array.isArray(config.columns) ? columns = config.columns : typeof config.columns == "string" ? columns = [config.columns] : typeof config.columns == "function" && (columns = config.columns(columns));
|
|
216
|
+
const tableStructure = columns.map((col) => typeof col == "string" || typeof col == "object" && col.accessor ? this.renderColumn(col, config) : Array.isArray(col) ? this.renderGrouping(col, config) : {}).filter(Boolean).map((d) => (d.cellStyle && delete d.cellStyle, d));
|
|
217
|
+
if (print && typeof window != "undefined") {
|
|
218
|
+
const totalWidth = sum(tableStructure, (d) => d.minWidth), widthScale = scaleLinear().domain([0, totalWidth]).range([0, size.width - 6]);
|
|
219
|
+
tableStructure.forEach((col) => {
|
|
220
|
+
col.maxWidth = void 0, col.minWidth = widthScale(col.minWidth);
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
return /* @__PURE__ */ jsxs("div", { className: "cp-table-wrapper", ref: this.viz, children: [
|
|
224
|
+
tableStructure.length ? /* @__PURE__ */ jsx(
|
|
225
|
+
ReactTable,
|
|
226
|
+
__spreadProps(__spreadValues$1({
|
|
227
|
+
resizable: !print,
|
|
228
|
+
sortable: !print,
|
|
229
|
+
loadingText: t("CMS.Table.Loading"),
|
|
230
|
+
nextText: t("CMS.Table.Next"),
|
|
231
|
+
noDataText: t("CMS.Table.No rows found"),
|
|
232
|
+
ofText: t("CMS.Table.of"),
|
|
233
|
+
pageText: t("CMS.Table.Page"),
|
|
234
|
+
previousText: t("CMS.Table.Previous"),
|
|
235
|
+
rowsText: t("CMS.Table.rows"),
|
|
236
|
+
showPagination: data.length >= minRowsForPagination
|
|
237
|
+
}, config), {
|
|
238
|
+
className: `cp-table ${loading ? "cp-table-loading" : ""}`,
|
|
239
|
+
columns: tableStructure
|
|
240
|
+
})
|
|
241
|
+
) : null,
|
|
242
|
+
loading && /* @__PURE__ */ jsx("div", { className: "cp-loading", dangerouslySetInnerHTML: { __html: config.loadingHTML || d3plus2.loadingHTML } })
|
|
243
|
+
] });
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
Table.contextTypes = {
|
|
247
|
+
d3plus: PropTypes.object,
|
|
248
|
+
print: PropTypes.bool
|
|
249
|
+
}, Table.defaultProps = {
|
|
250
|
+
minRowsForPagination: 15
|
|
251
|
+
};
|
|
252
|
+
const localeDefault = process.env.NEXT_PUBLIC_REPORTS_LOCALE_DEFAULT || "en", frontEndMessage = "Error Rendering Visualization", errorStub = {
|
|
253
|
+
data: [],
|
|
254
|
+
dataFormat: (d) => d,
|
|
255
|
+
type: "Treemap",
|
|
256
|
+
noDataHTML: `<p style="font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;">
|
|
257
|
+
<strong>${frontEndMessage}</strong>
|
|
258
|
+
</p>`
|
|
259
|
+
};
|
|
260
|
+
var d3plusPropify = (logic, formatters, variables = {}, locale = localeDefault, id = null, actions = {}) => {
|
|
261
|
+
let config;
|
|
262
|
+
try {
|
|
263
|
+
config = parse({ vars: ["variables"], logic }, formatters, locale, actions)(variables);
|
|
264
|
+
} catch (e) {
|
|
265
|
+
return console.error(`Parsing Error in propify (ID: ${id})`), console.error(`Error message: ${e.message}`), {
|
|
266
|
+
error: `${e}`,
|
|
267
|
+
config: errorStub
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
if (typeof config != "object")
|
|
271
|
+
return {
|
|
272
|
+
error: "Visualization JS code must return an object",
|
|
273
|
+
config: errorStub
|
|
274
|
+
};
|
|
275
|
+
const dataFormat = config.dataFormat ? config.dataFormat : (resp) => {
|
|
276
|
+
const sources = Array.isArray(config.data) && config.data.length > 1 && config.data.some((d) => typeof d == "string") ? resp : [resp];
|
|
277
|
+
return dataConcat(sources, "data");
|
|
278
|
+
};
|
|
279
|
+
delete config.dataFormat;
|
|
280
|
+
const linksFormat = config.linksFormat || void 0;
|
|
281
|
+
delete config.linksFormat;
|
|
282
|
+
const nodesFormat = config.nodesFormat || void 0;
|
|
283
|
+
delete config.nodesFormat;
|
|
284
|
+
const topojsonFormat = config.topojsonFormat || void 0;
|
|
285
|
+
return delete config.topojsonFormat, {
|
|
286
|
+
config,
|
|
287
|
+
dataFormat,
|
|
288
|
+
linksFormat,
|
|
289
|
+
nodesFormat,
|
|
290
|
+
topojsonFormat
|
|
291
|
+
};
|
|
292
|
+
}, __defProp = Object.defineProperty, __getOwnPropSymbols = Object.getOwnPropertySymbols, __hasOwnProp = Object.prototype.hasOwnProperty, __propIsEnum = Object.prototype.propertyIsEnumerable, __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues = (a, b) => {
|
|
293
|
+
for (var prop in b || (b = {}))
|
|
294
|
+
__hasOwnProp.call(b, prop) && __defNormalProp(a, prop, b[prop]);
|
|
295
|
+
if (__getOwnPropSymbols)
|
|
296
|
+
for (var prop of __getOwnPropSymbols(b))
|
|
297
|
+
__propIsEnum.call(b, prop) && __defNormalProp(a, prop, b[prop]);
|
|
298
|
+
return a;
|
|
299
|
+
};
|
|
300
|
+
const useAppContext = () => ({}), CustomVizzes = {}, vizTypes = __spreadValues(__spreadValues({
|
|
301
|
+
Table,
|
|
302
|
+
Graphic,
|
|
303
|
+
HTML
|
|
304
|
+
}, d3plus), CustomVizzes);
|
|
305
|
+
function Viz({
|
|
306
|
+
block,
|
|
307
|
+
active,
|
|
308
|
+
locale,
|
|
309
|
+
variables,
|
|
310
|
+
debug,
|
|
311
|
+
configOverride = {}
|
|
312
|
+
}) {
|
|
313
|
+
var _a;
|
|
314
|
+
const context = useAppContext(), content = getBlockContent(block), formatterFunctions = useFormatterFunctionsForLocale(locale), blockContext = { variables }, vizProps = useMemo(() => {
|
|
315
|
+
if (!active)
|
|
316
|
+
return { error: "Activate to View" };
|
|
317
|
+
if (!(content != null && content.logic))
|
|
318
|
+
return { error: "Add a Configuration" };
|
|
319
|
+
const transpiledLogic = varSwapRecursive({ logic: content.logic }, formatterFunctions, blockContext).logic;
|
|
320
|
+
return d3plusPropify(transpiledLogic, formatterFunctions, variables, locale, block.id, {});
|
|
321
|
+
}, [block, active, variables]);
|
|
322
|
+
useMemo(() => {
|
|
323
|
+
if (!active || !(content != null && content.logic))
|
|
324
|
+
return {};
|
|
325
|
+
const { logic } = content, { vars } = mortarEval("variables", variables, logic, formatterFunctions, void 0, blockContext);
|
|
326
|
+
return vars;
|
|
327
|
+
}, [block, active]);
|
|
328
|
+
const { type } = vizProps.config || {}, fallbackType = type && vizTypes[type] ? type : "Treemap";
|
|
329
|
+
type || (vizProps.config = { error: 'Visualization missing "type"' }), vizTypes[type] || (vizProps.config = { error: `"${type}" is not a valid Visualization Type` });
|
|
330
|
+
const Visualization = vizTypes[fallbackType], debugMessage = vizProps.error || ((_a = vizProps.config) == null ? void 0 : _a.error) || !1;
|
|
331
|
+
if (debugMessage)
|
|
332
|
+
return /* @__PURE__ */ jsx(Center, { style: { height: "100%" }, children: /* @__PURE__ */ jsx(Badge, { color: "gray", variant: "outline", children: debugMessage }, "type") });
|
|
333
|
+
vizProps.config = __spreadValues(__spreadValues({}, vizProps.config), configOverride);
|
|
334
|
+
const vizConfig = __spreadValues({ locale, variables }, vizProps.config);
|
|
335
|
+
return context.print && (vizConfig.detectVisible = !1), context.print, /* @__PURE__ */ jsx(
|
|
336
|
+
"div",
|
|
337
|
+
{
|
|
338
|
+
style: {
|
|
339
|
+
display: "flex",
|
|
340
|
+
flex: "1 1 100%"
|
|
341
|
+
},
|
|
342
|
+
children: /* @__PURE__ */ jsx(
|
|
343
|
+
Visualization,
|
|
344
|
+
{
|
|
345
|
+
style: { flex: 1 },
|
|
346
|
+
dataFormat: (resp) => {
|
|
347
|
+
vizProps.data && Array.isArray(vizProps.data) && vizProps.data.length > 1 && vizProps.data.some((d) => typeof d == "string");
|
|
348
|
+
let data;
|
|
349
|
+
try {
|
|
350
|
+
data = vizProps.dataFormat(resp);
|
|
351
|
+
} catch (e) {
|
|
352
|
+
console.log("Error in dataFormat: ", e), data = [];
|
|
353
|
+
}
|
|
354
|
+
return data;
|
|
355
|
+
},
|
|
356
|
+
linksFormat: vizProps.linksFormat,
|
|
357
|
+
nodesFormat: vizProps.nodesFormat,
|
|
358
|
+
topojsonFormat: vizProps.topojsonFormat,
|
|
359
|
+
config: __spreadValues(__spreadValues({}, defaultConfig), vizConfig)
|
|
360
|
+
},
|
|
361
|
+
"viz-key"
|
|
362
|
+
)
|
|
363
|
+
}
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
export {
|
|
367
|
+
Viz as default
|
|
368
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Viz-41329377.js","sources":["../libs/viz/defaultConfig.ts","../cms/components/reportVizes/Graphic.tsx","../cms/components/reportVizes/HTML.tsx","../libs/js/abbreviate.ts","../cms/components/reportVizes/Table.jsx","../libs/d3plusPropify.ts","../components/blocks/types/renderers/Viz.tsx"],"sourcesContent":["export default {\n loadingHTML: `<div style=\"left: 50%; top: 50%; position: absolute; transform: translate(-50%, -50%);\">\n <svg class=\"cp-viz-spinner\" width=\"60px\" height=\"60px\" viewBox=\"0 0 317 317\" xmlns=\"http://www.w3.org/2000/svg\">\n <path class=\"outer\" d=\"M16.43 157.072c0 34.797 12.578 66.644 33.428 91.277l-11.144 11.141c-23.673-27.496-37.992-63.283-37.992-102.418 0-39.133 14.319-74.921 37.992-102.423l11.144 11.144c-20.85 24.63-33.428 56.481-33.428 91.279z\"/>\n <path class=\"outer\" d=\"M157.793 15.708c34.798 0 66.648 12.58 91.28 33.427l11.143-11.144c-27.502-23.676-63.29-37.991-102.423-37.991-39.132 0-74.919 14.315-102.422 37.991l11.148 11.144c24.627-20.847 56.477-33.427 91.274-33.427\"/>\n <path class=\"outer\" d=\"M299.159 157.072c0 34.797-12.578 66.644-33.43 91.277l11.145 11.141c23.674-27.496 37.992-63.283 37.992-102.418 0-39.133-14.318-74.921-37.992-102.423l-11.145 11.144c20.852 24.63 33.43 56.481 33.43 91.279\"/>\n <path class=\"outer\" d=\"M157.793 298.432c-34.797 0-66.647-12.574-91.274-33.424l-11.148 11.138c27.503 23.682 63.29 37.997 102.422 37.997 39.133 0 74.921-14.315 102.423-37.997l-11.143-11.138c-24.632 20.85-56.482 33.424-91.28 33.424\"/>\n <path class=\"middle\" d=\"M226.59 61.474l-7.889 13.659c24.997 18.61 41.184 48.382 41.184 81.94 0 33.555-16.187 63.329-41.184 81.936l7.889 13.664c29.674-21.394 49.004-56.23 49.004-95.6 0-39.373-19.33-74.21-49.004-95.599\"/>\n <path class=\"middle\" d=\"M157.793 259.169c-52.398 0-95.553-39.485-101.399-90.317h-15.814c5.912 59.524 56.131 106.018 117.213 106.018 17.26 0 33.633-3.742 48.404-10.406l-7.893-13.672c-12.425 5.38-26.114 8.377-40.511 8.377\"/>\n <path class=\"middle\" d=\"M157.793 54.976c14.397 0 28.086 2.993 40.511 8.371l7.893-13.667c-14.771-6.669-31.144-10.412-48.404-10.412-61.082 0-111.301 46.493-117.213 106.021h15.814c5.846-50.831 49.001-90.313 101.399-90.313\"/>\n <path class=\"inner\" d=\"M95.371 164.193c-3.476-30.475 15.471-58.324 43.723-67.097l-1.804-15.842c-36.899 9.931-61.986 45.602-57.524 84.719 4.461 39.115 36.934 68.219 75.122 69.584l-1.806-15.838c-29.504-2.186-54.235-25.054-57.711-55.526\"/>\n <path class=\"inner\" d=\"M162.504 94.425c29.508 2.185 54.235 25.053 57.711 55.529 3.476 30.469-15.466 58.319-43.724 67.096l1.806 15.834c36.898-9.927 61.986-45.598 57.525-84.712-4.461-39.117-36.936-68.223-75.125-69.588l1.807 15.841z\"/>\n </svg>\n <strong>Loading</strong>\n <sub style=\"bottom: 0; display: block; line-height: 1; margin-top: 5px;\">\n <a style=\"color: inherit;\" href=\"https://www.datawheel.us/\" target=\"_blank\">\n Built by Datawheel\n </a>\n </sub>\n </div>`,\n noDataHTML: `<div style=\"left: 50%; top: 50%; position: absolute; transform: translate(-50%, -50%);\">\n <strong>No Data Available</strong>\n </div>`,\n};\n","import axios from \"axios\";\nimport React, {useState, useEffect} from \"react\";\nimport Stat from \"../../../components/blocks/types/renderers/Stat\";\nimport \"./Graphic.css\";\n\n/** */\nexport default function Graphic({config, dataFormat}) {\n const [builtConfig, setBuiltConfig] = useState<any>();\n\n useEffect(() => {\n const defaults = {\n numberFormat: (d, value, total) => {\n const perc = Number(d[value] / total * 100);\n return isNaN(perc) ? \"No Data\" : `${perc.toFixed(2)}%`;\n },\n };\n\n let rebuiltConfig = {...defaults, ...config};\n\n // prevent the page from white screening when config/data is malformed\n if (!rebuiltConfig || !rebuiltConfig.data) {\n console.log(\"no config/data\");\n }\n // If the data is an API call, run the axios get and replace .data with its results\n else if (typeof rebuiltConfig.data === \"string\") {\n axios.get(rebuiltConfig.data).then((resp) => {\n rebuiltConfig.data = dataFormat(resp.data);\n if (typeof rebuiltConfig.data === \"object\" && !(rebuiltConfig.data instanceof Array)) rebuiltConfig = Object.assign(rebuiltConfig, rebuiltConfig.data);\n if (!rebuiltConfig.total) rebuiltConfig.total = rebuiltConfig.data.reduce((acc, d) => (isNaN(d[rebuiltConfig.value]) ? acc : acc + Number(d[rebuiltConfig.value])), 0);\n setBuiltConfig(rebuiltConfig);\n });\n } else {\n rebuiltConfig.data = dataFormat(rebuiltConfig.data);\n if (typeof rebuiltConfig.data === \"object\" && !(rebuiltConfig.data instanceof Array)) rebuiltConfig = Object.assign(rebuiltConfig, rebuiltConfig.data);\n if (!rebuiltConfig.total) rebuiltConfig.total = rebuiltConfig.data.reduce((acc, d) => (isNaN(d[rebuiltConfig.value]) ? acc : acc + Number(d[rebuiltConfig.value])), 0);\n setBuiltConfig(rebuiltConfig);\n }\n }, [config]);\n\n if (!builtConfig) return null;\n\n return (\n <div className=\"cp-graphic\">\n {builtConfig.imageURL\n && <img src={builtConfig.imageURL} className=\"cp-graphic-img\" alt=\"\" />}\n {builtConfig.value\n && (\n <Stat\n title={builtConfig.label}\n value={builtConfig.value}\n subtitle={builtConfig.subtitle}\n tooltip={builtConfig.tooltip}\n />\n )}\n </div>\n );\n}\n","import React from \"react\";\n\n/** */\nexport default function HTML({config}) {\n if (!config || !config.html) return null;\n\n return <div className=\"cp-viz cp-html\" dangerouslySetInnerHTML={{__html: config.html}} />; // eslint-disable-line react/no-danger\n}\n","import libs from \"../libs\";\n\n/**\n * Abbreviates a number into a smaller more human-readible number.\n * @link https://github.com/d3plus/d3plus-format/blob/master/src/abbreviate.js#L44\n * @param {number} n 123456\n */\nexport default function abbreviate(n:number) {\n return libs.d3plus.formatAbbreviate(n);\n}","import React, {Component} from \"react\";\nimport PropTypes from \"prop-types\";\nimport {dataLoad} from \"d3plus-viz\";\nimport {max, min, sum} from \"d3-array\";\nimport {scaleLinear} from \"d3-scale\";\n\nimport ReactTable from \"react-table-6\";\nimport stripHTML from \"../../../libs/js/stripHTML\";\nimport abbreviate from \"../../../libs/js/abbreviate\";\n\nimport \"./Table.css\";\n\nconst letters = {\n i: 2,\n l: 2,\n I: 2,\n \" \": 4,\n};\n\n/** */\nfunction spanify(html, cell, onClick) {\n return <span className={`cp-table-cell-inner cp-table-cell-inner-${onClick ? \"clickable\" : \"static\"}`} onClick={onClick ? onClick.bind(this, cell.original) : undefined} dangerouslySetInnerHTML={{__html: html}} />;\n}\n\nconst measureString = (str) => (typeof str === \"string\" ? sum(str.split(\"\").map((l) => (letters[l] || l.toUpperCase() === l ? 8 : 6))) : 0);\n\nconst defaultCellFormat = (d, val) => (isNaN(val) || d.column.id.includes(\"Year\") || val === \"\" || val === \" \" ? val : abbreviate(val));\n\nclass Table extends Component {\n constructor(props) {\n super(props);\n this.state = {\n data: [],\n error: false,\n loading: false,\n };\n\n this.viz = React.createRef();\n }\n\n componentDidMount() {\n this.loadData.bind(this)();\n }\n\n loadData() {\n const {config, dataFormat} = this.props;\n const url = config.data;\n\n if (url) {\n // When the user provides immediate data in-line (not a remote call), dataLoad actually returns *before* the\n // loading state has changed.\n const fetch = () => dataLoad.bind({})(url, dataFormat, undefined, (error, data) => {\n // The quickness of that local load means that this comparison still has loading set to \"false\"\n if (this.state.loading === JSON.stringify(url)) {\n if (error) {\n console.error(error);\n this.setState({error, loading: false});\n } else this.setState({data, loading: false});\n }\n });\n // Therefore, run the datafetch AFTER the setstate has completed, so when the fetch callback runs, this.state.loading\n // is set to a value that has meaning for the comparison.\n this.setState({error: false, loading: JSON.stringify(url)}, fetch.bind(this));\n }\n }\n\n componentDidUpdate(prevProps) {\n const {data} = this.props.config;\n const {loading} = this.state;\n if (loading !== data && JSON.stringify(prevProps.config.data) !== JSON.stringify(data)) {\n this.loadData.bind(this)();\n }\n }\n\n // render parent header grouping\n // assumes an array with string followed by an array of columns\n renderGrouping = (currColumn, config) => {\n const {headerFormat} = config;\n\n let groupingTitle; let\n nestedColumns;\n if (currColumn[0] && typeof currColumn[0] === \"string\") groupingTitle = currColumn[0];\n if (currColumn[1] && Array.isArray(currColumn[1])) nestedColumns = currColumn[1];\n\n if (nestedColumns) {\n if (typeof nestedColumns[0] === \"string\") {\n return {\n Header: headerFormat(groupingTitle),\n accessor: (d) => d[nestedColumns[0]],\n id: groupingTitle,\n columns: nestedColumns.map((col) => this.renderColumn(col)),\n };\n }\n if (Array.isArray(nestedColumns[0])) {\n return {\n Header: headerFormat(groupingTitle),\n id: groupingTitle,\n columns: nestedColumns.map((col) => this.renderGrouping(col)),\n };\n }\n }\n\n console.log(\"Invalid columns config passed to table viz; expected either an array of strings, or an array of arrays, each with a string first (table heading grouping title) and an array of strings.\");\n return undefined;\n };\n\n // render ungrouped column\n renderColumn = (obj, config) => {\n const {data, headerFormat, cellFormat} = config;\n const col = typeof obj === \"string\" ? obj : obj.accessor;\n const onClick = typeof obj === \"object\" ? obj.onClick : undefined;\n const header = obj.Header ? obj.Header : col;\n const title = headerFormat ? headerFormat(header) : header;\n const {print} = this.context;\n\n /** */\n function formatValue(cell, value) {\n try {\n return cellFormat ? cellFormat(cell, value) : defaultCellFormat(cell, value);\n } catch (e) {\n console.log(\"Error in cellFormat: \", e);\n return defaultCellFormat(cell, value);\n }\n }\n\n const padding = 20;\n const sortIconWidth = 30;\n\n const values = data.reduce((arr, d) => {\n const html = formatValue({original: d, value: d[col], column: {id: col}}, d[col]);\n const text = stripHTML(html);\n if (!text) {\n const inlineWidth = html.match(/width[:=\"'\\s]{1,}([0-9]{1,})px/);\n arr.push(inlineWidth ? +inlineWidth[1] : 0);\n } else {\n arr.push(measureString(text));\n }\n return arr;\n }, [measureString(title) + sortIconWidth]);\n\n const columnWidth = max(values) + padding;\n const calculatedMinWidth = min([200, max([padding * 2, columnWidth])]);\n const minWidth = obj.minWidth !== undefined ? obj.minWidth : calculatedMinWidth;\n const maxWidth = obj.maxWidth !== undefined ? obj.maxWidth : calculatedMinWidth < 100 ? calculatedMinWidth : undefined;\n const {width} = obj;\n\n return {\n Header: print\n ? (\n <button className=\"cp-table-header-button\">\n {title}\n </button>\n )\n : (\n <button className=\"cp-table-header-button\">\n {title}\n {\" \"}\n <span className=\"u-visually-hidden\">, sort by column</span>\n <Icon className=\"cp-table-header-icon\" icon=\"caret-down\" />\n </button>\n ),\n id: col,\n accessor: (d) => d[col],\n minWidth,\n maxWidth,\n width,\n\n /** react-table v6 has extremely strange behavior in this Cell callback - it attempts to choose between two options:\n * 1. if Cell is a purely functional component, run Cell(props), i.e., execute the function.\n * 2. if Cell is a react component, run React.createElement(comp, props), i.e. instantiate a component and pass it props\n * The problem is: react-table uses String(component).includes('.createElement') to determine which one Cell is.\n * On Dev, it is 1 - because there is no \"createElement\" in this function.\n * On Prod, it can be 2! - if \"return <span>\" is run here, the transpiling creates a React.createElement, and switches it to type 2.\n * The result is that the cell function isn't run - but this Cell callback must be run for cellStyles to be applied.\n * To get around this - move a spanify function out of scope to trick react-table into using #1 for rendering.\n * */\n\n Cell: (cell) => {\n if (obj.cellStyle) {\n try {\n const newCell = obj.cellStyle(cell);\n if (newCell) cell = newCell; // the spec asks for a return value, but support editing by reference as well.\n } catch (e) {\n console.error(\"Error in cellStyle\");\n }\n }\n const html = formatValue(cell, cell.value);\n const span = spanify.bind(this)(html, cell, onClick);\n return span;\n },\n };\n };\n\n render() {\n const {data, loading} = this.state;\n const {minRowsForPagination, size, t} = this.props;\n const config = {...this.props.config};\n const {d3plus, print} = this.context;\n config.data = data;\n\n // removes erronous \"column\" key from Matrix chart configs\n if (config.column) delete config.column;\n\n let columns = data.length ? Object.keys(data[0]) : [];\n if (Array.isArray(config.columns)) columns = config.columns;\n else if (typeof config.columns === \"string\") columns = [config.columns];\n else if (typeof config.columns === \"function\") columns = config.columns(columns);\n\n const tableStructure = columns.map((col) => {\n // if the current column is a string alone, render the column\n if (typeof col === \"string\" || typeof col === \"object\" && col.accessor) {\n return this.renderColumn(col, config);\n } if (Array.isArray(col)) {\n return this.renderGrouping(col, config);\n } return {};\n }).filter(Boolean) // handle malformed tables\n .map((d) => { // remove front-end styling method (irrelevant to react-table)\n if (d.cellStyle) delete d.cellStyle;\n return d;\n });\n\n if (print && typeof window !== \"undefined\") {\n const totalWidth = sum(tableStructure, (d) => d.minWidth);\n const widthScale = scaleLinear()\n .domain([0, totalWidth])\n .range([0, size.width - 6]);\n tableStructure\n .forEach((col) => {\n col.maxWidth = undefined;\n col.minWidth = widthScale(col.minWidth);\n });\n }\n\n return (\n <div className=\"cp-table-wrapper\" ref={this.viz}>\n {tableStructure.length\n ? (\n <ReactTable\n resizable={!print}\n sortable={!print}\n loadingText={t(\"CMS.Table.Loading\")}\n nextText={t(\"CMS.Table.Next\")}\n noDataText={t(\"CMS.Table.No rows found\")}\n ofText={t(\"CMS.Table.of\")}\n pageText={t(\"CMS.Table.Page\")}\n previousText={t(\"CMS.Table.Previous\")}\n rowsText={t(\"CMS.Table.rows\")}\n showPagination={data.length >= minRowsForPagination}\n {...config}\n className={`cp-table ${loading ? \"cp-table-loading\" : \"\"}`}\n columns={tableStructure}\n />\n )\n : null}\n {loading && <div className=\"cp-loading\" dangerouslySetInnerHTML={{__html: config.loadingHTML || d3plus.loadingHTML}} />}\n </div>\n );\n }\n}\n\nTable.contextTypes = {\n d3plus: PropTypes.object,\n print: PropTypes.bool,\n};\n\nTable.defaultProps = {\n minRowsForPagination: 15,\n};\n\nexport default Table;\n","import {dataConcat} from \"d3plus-viz\";\nimport {parse} from \"./FUNC\";\n\nconst localeDefault = process.env.NEXT_PUBLIC_REPORTS_LOCALE_DEFAULT || \"en\";\n\nconst frontEndMessage = \"Error Rendering Visualization\";\n\nconst errorStub = {\n data: [],\n dataFormat: (d) => d,\n type: \"Treemap\",\n noDataHTML:\n `<p style=\"font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;\">\n <strong>${frontEndMessage}</strong>\n </p>`,\n};\n\nexport default (logic, formatters, variables = {}, locale = localeDefault, id = null, actions = {}) => {\n let config;\n\n // The logic provided might be malformed. Wrap it in a try/catch to be sure we don't\n // crash / RSOD whatever page is making use of propify.\n try {\n config = parse({vars: [\"variables\"], logic}, formatters, locale, actions)(variables);\n } catch (e) {\n // If the javascript fails, return a special error object for the front-end to use.\n console.error(`Parsing Error in propify (ID: ${id})`);\n console.error(`Error message: ${e.message}`);\n return {\n error: `${e}`,\n config: errorStub,\n };\n }\n // If the user added correct javascript, but it doesn't return an object, don't attempt to render.\n if (typeof config !== \"object\") {\n return {\n error: \"Visualization JS code must return an object\",\n config: errorStub,\n };\n }\n\n // strip out the \"dataFormat\" from config\n const dataFormat = config.dataFormat ? config.dataFormat : (resp) => {\n const hasMultiples = Array.isArray(config.data)\n && config.data.length > 1\n && config.data.some((d) => typeof d === \"string\");\n const sources = hasMultiples ? resp : [resp];\n return dataConcat(sources, \"data\");\n };\n delete config.dataFormat;\n\n const linksFormat = config.linksFormat || undefined;\n delete config.linksFormat;\n\n const nodesFormat = config.nodesFormat || undefined;\n delete config.nodesFormat;\n\n const topojsonFormat = config.topojsonFormat || undefined;\n delete config.topojsonFormat;\n\n return {\n config, dataFormat, linksFormat, nodesFormat, topojsonFormat,\n };\n};\n","/* react */\nimport React, {useMemo, useContext} from \"react\";\nimport {Badge, Center} from \"@mantine/core\";\n\n/* utils */\nimport * as d3plus from \"d3plus-react\";\n\nimport varSwapRecursive from \"../../../../libs/variables/varSwapRecursive\";\nimport mortarEval from \"../../../../libs/variables/mortarEval\";\nimport defaultConfig from \"../../../../libs/viz/defaultConfig\";\n\n/* vizes */\nimport Graphic from \"../../../../cms/components/reportVizes/Graphic\";\nimport HTML from \"../../../../cms/components/reportVizes/HTML\";\nimport Table from \"../../../../cms/components/reportVizes/Table\";\n\nimport d3plusPropify from \"../../../../libs/d3plusPropify\";\nimport {getBlockContent} from \"../../../../libs/blocks/getBlockContent\";\nimport {ResourceContext} from \"../../../../context/ResourceProvider\";\nimport {useFormatterFunctionsForLocale} from \"../../../../store/hooks\";\n\n/* context */\n// import useAppContext from \"../../../hooks/context/useAppContext\";\n// todo1.0 fix context\nconst useAppContext = () => ({});\n\n// User must define custom sections in app/reports/sections,\n// and export them from an index.js in that folder.\n// import * as CustomVizzes from \"CustomVizzes\";\nconst CustomVizzes = {};\n\nconst vizTypes = {\n Table, Graphic, HTML, ...d3plus, ...CustomVizzes,\n};\n\n/**\n * Viz Renderer\n*/\nexport default function Viz({\n block, active, locale, variables, debug, configOverride = {},\n}) {\n const context:any = useAppContext();\n const content = getBlockContent(block);\n const formatterFunctions = useFormatterFunctionsForLocale(locale);\n const blockContext = {variables};\n\n // todo1.0 - There is a ton of missing functionality here. updateSources, getChildContext, various context interactions.\n // This will all need to be brought in, to play nice with legacy context.\n\n const vizProps:any = useMemo(() => {\n if (!active) return {error: \"Activate to View\"};\n if (!content?.logic) return {error: \"Add a Configuration\"};\n // todo1.0 fix all these arguments!\n const transpiledLogic = varSwapRecursive({logic: content.logic}, formatterFunctions, blockContext).logic;\n return d3plusPropify(transpiledLogic, formatterFunctions, variables, locale, block.id, {});\n }, [block, active, variables]);\n\n // todo1.0 - these vizSettings should be used to implement tabs, mini, options, etc on the front end\n const vizSettings = useMemo(() => {\n if (!active || !content?.logic) return {};\n const {logic} = content;\n const {vars} = mortarEval(\"variables\", variables, logic, formatterFunctions, undefined, blockContext);\n return vars;\n }, [block, active]);\n\n // strip out the \"type\" from config\n const {type} = vizProps.config || {};\n const fallbackType = type && vizTypes[type] ? type : \"Treemap\";\n if (!type) vizProps.config = {error: \"Visualization missing \\\"type\\\"\"};\n if (!vizTypes[type]) vizProps.config = {error: `\"${type}\" is not a valid Visualization Type`};\n const Visualization = vizTypes[fallbackType];\n\n // If the result of propify has an \"error\" property, then the provided javascript was malformed and propify\n // caught an error. Instead of attempting to render the viz, simply show the error to the user.\n // If \"debug\" is set to true, this viz is being rendered in the CMS, and we can show the stacktrace directly.\n const debugMessage = vizProps.error || vizProps.config?.error || false;\n if (debugMessage) {\n return (\n <Center style={{height: \"100%\"}}>\n <Badge key=\"type\" color=\"gray\" variant=\"outline\">{debugMessage}</Badge>\n </Center>\n );\n }\n\n vizProps.config = {...vizProps.config, ...configOverride};\n\n const vizConfig = {locale, variables, ...vizProps.config};\n\n // todo1.0 this probably doesn't work as print is added to context later, come back for this\n if (context.print) vizConfig.detectVisible = false;\n // whether to show the title and/or visualization options\n const showHeader = !context.print && type !== \"Graphic\" && type !== \"HTML\";\n\n // todo1.0 this is temporary, to get the buttons out of the way\n const showOptions = false;\n\n return (\n <div\n style={{\n display: \"flex\",\n flex: \"1 1 100%\",\n }}\n >\n <Visualization\n style={{flex: 1}}\n key=\"viz-key\"\n dataFormat={(resp) => {\n const hasMultiples = vizProps.data\n && Array.isArray(vizProps.data)\n && vizProps.data.length > 1\n && vizProps.data.some((d) => typeof d === \"string\");\n const sources = hasMultiples ? resp : [resp];\n // sources.forEach(r => this.analyzeData.bind(this)(r));\n let data;\n try {\n data = vizProps.dataFormat(resp);\n } catch (e) {\n console.log(\"Error in dataFormat: \", e);\n data = [];\n }\n return data;\n }}\n linksFormat={vizProps.linksFormat}\n nodesFormat={vizProps.nodesFormat}\n topojsonFormat={vizProps.topojsonFormat}\n config={{...defaultConfig, ...vizConfig}}\n />\n </div>\n );\n}\n"],"names":["__spreadValues","Stat","d3plus"],"mappings":"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"}
|