@malloydata/render 0.0.1
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 +7 -0
- package/dist/data_styles.d.ts +181 -0
- package/dist/data_styles.js +15 -0
- package/dist/drill.d.ts +10 -0
- package/dist/drill.js +103 -0
- package/dist/html/bar_chart.d.ts +7 -0
- package/dist/html/bar_chart.js +48 -0
- package/dist/html/boolean.d.ts +5 -0
- package/dist/html/boolean.js +26 -0
- package/dist/html/bytes.d.ts +5 -0
- package/dist/html/bytes.js +26 -0
- package/dist/html/cartesian_chart.d.ts +7 -0
- package/dist/html/cartesian_chart.js +88 -0
- package/dist/html/chart.d.ts +21 -0
- package/dist/html/chart.js +105 -0
- package/dist/html/container.d.ts +21 -0
- package/dist/html/container.js +43 -0
- package/dist/html/currency.d.ts +5 -0
- package/dist/html/currency.js +32 -0
- package/dist/html/dashboard.d.ts +7 -0
- package/dist/html/dashboard.js +224 -0
- package/dist/html/date.d.ts +7 -0
- package/dist/html/date.js +38 -0
- package/dist/html/html_view.d.ts +23 -0
- package/dist/html/html_view.js +217 -0
- package/dist/html/image.d.ts +7 -0
- package/dist/html/image.js +34 -0
- package/dist/html/index.d.ts +1 -0
- package/dist/html/index.js +18 -0
- package/dist/html/json.d.ts +7 -0
- package/dist/html/json.js +31 -0
- package/dist/html/line_chart.d.ts +7 -0
- package/dist/html/line_chart.js +51 -0
- package/dist/html/link.d.ts +7 -0
- package/dist/html/link.js +35 -0
- package/dist/html/list.d.ts +9 -0
- package/dist/html/list.js +63 -0
- package/dist/html/list_detail.d.ts +5 -0
- package/dist/html/list_detail.js +23 -0
- package/dist/html/number.d.ts +6 -0
- package/dist/html/number.js +30 -0
- package/dist/html/percent.d.ts +5 -0
- package/dist/html/percent.js +26 -0
- package/dist/html/point_map.d.ts +8 -0
- package/dist/html/point_map.js +147 -0
- package/dist/html/scatter_chart.d.ts +7 -0
- package/dist/html/scatter_chart.js +51 -0
- package/dist/html/segment_map.d.ts +8 -0
- package/dist/html/segment_map.js +128 -0
- package/dist/html/shape_map.d.ts +10 -0
- package/dist/html/shape_map.js +171 -0
- package/dist/html/state_codes.d.ts +3 -0
- package/dist/html/state_codes.js +127 -0
- package/dist/html/table.d.ts +7 -0
- package/dist/html/table.js +111 -0
- package/dist/html/text.d.ts +8 -0
- package/dist/html/text.js +35 -0
- package/dist/html/utils.d.ts +18 -0
- package/dist/html/utils.js +175 -0
- package/dist/html/vega_spec.d.ts +18 -0
- package/dist/html/vega_spec.js +499 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +19 -0
- package/dist/renderer.d.ts +21 -0
- package/dist/renderer.js +23 -0
- package/package.json +17 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Explore } from "@malloydata/malloy";
|
|
2
|
+
import { DataStyles, StyleDefaults } from "../data_styles";
|
|
3
|
+
import { DrillFunction } from "../drill";
|
|
4
|
+
import { ChildRenderers, RenderTree } from "../renderer";
|
|
5
|
+
export declare abstract class ContainerRenderer extends RenderTree {
|
|
6
|
+
childRenderers: ChildRenderers;
|
|
7
|
+
protected abstract childrenStyleDefaults: StyleDefaults;
|
|
8
|
+
makeChildRenderers(explore: Explore, document: Document, options: {
|
|
9
|
+
dataStyles: DataStyles;
|
|
10
|
+
isDrillingEnabled?: boolean;
|
|
11
|
+
onDrill?: DrillFunction;
|
|
12
|
+
}): void;
|
|
13
|
+
static make<Type extends ContainerRenderer>(c: new (document: Document, options: {
|
|
14
|
+
isDrillingEnabled?: boolean;
|
|
15
|
+
onDrill?: DrillFunction;
|
|
16
|
+
}) => Type, document: Document, exploreField: Explore, options: {
|
|
17
|
+
dataStyles: DataStyles;
|
|
18
|
+
isDrillingEnabled?: boolean;
|
|
19
|
+
onDrill?: DrillFunction;
|
|
20
|
+
}): Type;
|
|
21
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2021 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* This program is free software; you can redistribute it and/or
|
|
6
|
+
* modify it under the terms of the GNU General Public License
|
|
7
|
+
* version 2 as published by the Free Software Foundation.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU General Public License for more details.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ContainerRenderer = void 0;
|
|
16
|
+
const renderer_1 = require("../renderer");
|
|
17
|
+
const html_view_1 = require("./html_view");
|
|
18
|
+
class ContainerRenderer extends renderer_1.RenderTree {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments);
|
|
21
|
+
this.childRenderers = {};
|
|
22
|
+
}
|
|
23
|
+
makeChildRenderers(explore, document, options) {
|
|
24
|
+
const result = {};
|
|
25
|
+
explore.intrinsicFields.forEach((field) => {
|
|
26
|
+
result[field.name] = (0, html_view_1.makeRenderer)(field, document, options, this.childrenStyleDefaults);
|
|
27
|
+
});
|
|
28
|
+
this.childRenderers = result;
|
|
29
|
+
}
|
|
30
|
+
// We can't use a normal constructor here because we need
|
|
31
|
+
// we need to be fully constructed before we construct
|
|
32
|
+
// our children.
|
|
33
|
+
static make(c, document, exploreField, options) {
|
|
34
|
+
const n = new c(document, {
|
|
35
|
+
isDrillingEnabled: options.isDrillingEnabled,
|
|
36
|
+
onDrill: options.onDrill,
|
|
37
|
+
});
|
|
38
|
+
n.makeChildRenderers(exploreField, document, options);
|
|
39
|
+
return n;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.ContainerRenderer = ContainerRenderer;
|
|
43
|
+
//# sourceMappingURL=container.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2021 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* This program is free software; you can redistribute it and/or
|
|
6
|
+
* modify it under the terms of the GNU General Public License
|
|
7
|
+
* version 2 as published by the Free Software Foundation.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU General Public License for more details.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.HTMLCurrencyRenderer = void 0;
|
|
16
|
+
const text_1 = require("./text");
|
|
17
|
+
class HTMLCurrencyRenderer extends text_1.HTMLTextRenderer {
|
|
18
|
+
getText(data) {
|
|
19
|
+
if (data.isNull()) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
// TODO get this from renderer options
|
|
23
|
+
const unitText = "$";
|
|
24
|
+
const numText = data.number.value.toLocaleString("en-US", {
|
|
25
|
+
minimumFractionDigits: 2,
|
|
26
|
+
maximumFractionDigits: 2,
|
|
27
|
+
});
|
|
28
|
+
return `${unitText}${numText}`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.HTMLCurrencyRenderer = HTMLCurrencyRenderer;
|
|
32
|
+
//# sourceMappingURL=currency.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DataArrayOrRecord } from "@malloydata/malloy";
|
|
2
|
+
import { StyleDefaults } from "../data_styles";
|
|
3
|
+
import { ContainerRenderer } from "./container";
|
|
4
|
+
export declare class HTMLDashboardRenderer extends ContainerRenderer {
|
|
5
|
+
protected childrenStyleDefaults: StyleDefaults;
|
|
6
|
+
render(table: DataArrayOrRecord): Promise<HTMLElement>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2021 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* This program is free software; you can redistribute it and/or
|
|
6
|
+
* modify it under the terms of the GNU General Public License
|
|
7
|
+
* version 2 as published by the Free Software Foundation.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU General Public License for more details.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.HTMLDashboardRenderer = void 0;
|
|
16
|
+
const drill_1 = require("../drill");
|
|
17
|
+
const container_1 = require("./container");
|
|
18
|
+
const text_1 = require("./text");
|
|
19
|
+
const utils_1 = require("./utils");
|
|
20
|
+
class HTMLDashboardRenderer extends container_1.ContainerRenderer {
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments);
|
|
23
|
+
this.childrenStyleDefaults = {
|
|
24
|
+
size: "medium",
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
async render(table) {
|
|
28
|
+
if (!table.isArrayOrRecord()) {
|
|
29
|
+
return (0, utils_1.createErrorElement)(this.document, "Invalid data for dashboard renderer.");
|
|
30
|
+
}
|
|
31
|
+
const fields = table.field.intrinsicFields;
|
|
32
|
+
const dimensions = fields.filter((field) => field.isAtomicField() && field.sourceWasDimension());
|
|
33
|
+
const measures = fields.filter((field) => !field.isAtomicField() || field.sourceWasMeasureLike());
|
|
34
|
+
const body = this.document.createElement("div");
|
|
35
|
+
for (const row of table) {
|
|
36
|
+
const dimensionsContainer = this.document.createElement("div");
|
|
37
|
+
dimensionsContainer.classList.add("dimensions");
|
|
38
|
+
dimensionsContainer.style.display = "flex";
|
|
39
|
+
dimensionsContainer.style.flexWrap = "wrap";
|
|
40
|
+
const rowElement = this.document.createElement("div");
|
|
41
|
+
rowElement.style.position = "relative";
|
|
42
|
+
for (const field of dimensions) {
|
|
43
|
+
const renderer = this.childRenderers[field.name];
|
|
44
|
+
const rendered = await renderer.render(row.cell(field));
|
|
45
|
+
const renderedDimension = this.document.createElement("div");
|
|
46
|
+
renderedDimension.style.cssText = DIMENSION_BOX;
|
|
47
|
+
const dimensionTitle = this.document.createElement("div");
|
|
48
|
+
dimensionTitle.style.cssText = DIMENSION_TITLE;
|
|
49
|
+
dimensionTitle.appendChild(this.document.createTextNode(field.name));
|
|
50
|
+
const dimensionInner = this.document.createElement("div");
|
|
51
|
+
dimensionInner.style.cssText = VERTICAL_CENTER;
|
|
52
|
+
dimensionInner.appendChild(rendered);
|
|
53
|
+
renderedDimension.appendChild(dimensionTitle);
|
|
54
|
+
renderedDimension.appendChild(dimensionInner);
|
|
55
|
+
dimensionsContainer.appendChild(renderedDimension);
|
|
56
|
+
}
|
|
57
|
+
if (dimensions.length > 0) {
|
|
58
|
+
const rowSeparatorOuter = this.document.createElement("div");
|
|
59
|
+
rowSeparatorOuter.classList.add("row-separator-outer");
|
|
60
|
+
rowSeparatorOuter.style.cssText = ROW_SEPARATOR_OUTER;
|
|
61
|
+
const rowSeparator = this.document.createElement("div");
|
|
62
|
+
rowSeparator.style.cssText = ROW_SEPARATOR;
|
|
63
|
+
rowSeparatorOuter.appendChild(rowSeparator);
|
|
64
|
+
dimensionsContainer.appendChild(rowSeparatorOuter);
|
|
65
|
+
}
|
|
66
|
+
const measuresContainer = this.document.createElement("div");
|
|
67
|
+
measuresContainer.style.cssText = MEASURE_BOXES;
|
|
68
|
+
for (const field of measures) {
|
|
69
|
+
const childRenderer = this.childRenderers[field.name];
|
|
70
|
+
await (0, utils_1.yieldTask)();
|
|
71
|
+
const rendered = await childRenderer.render(row.cell(field));
|
|
72
|
+
if (childRenderer instanceof HTMLDashboardRenderer) {
|
|
73
|
+
measuresContainer.appendChild(rendered);
|
|
74
|
+
}
|
|
75
|
+
else if (childRenderer instanceof text_1.HTMLTextRenderer) {
|
|
76
|
+
const measureBox = this.document.createElement("div");
|
|
77
|
+
measureBox.style.cssText = MEASURE_BOX;
|
|
78
|
+
const measureTitle = this.document.createElement("div");
|
|
79
|
+
measureTitle.style.cssText = TITLE;
|
|
80
|
+
measureTitle.appendChild(this.document.createTextNode(field.name));
|
|
81
|
+
const measureInner = this.document.createElement("div");
|
|
82
|
+
measureInner.style.cssText = VERTICAL_CENTER;
|
|
83
|
+
const innerInner = this.document.createElement("div");
|
|
84
|
+
innerInner.style.cssText = SINGLE_VALUE;
|
|
85
|
+
innerInner.appendChild(rendered);
|
|
86
|
+
measureInner.appendChild(innerInner);
|
|
87
|
+
measureBox.appendChild(measureTitle);
|
|
88
|
+
measureBox.appendChild(measureInner);
|
|
89
|
+
measuresContainer.appendChild(measureBox);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const measureBox = this.document.createElement("div");
|
|
93
|
+
measureBox.style.cssText = MEASURE_BOX;
|
|
94
|
+
const measureTitle = this.document.createElement("div");
|
|
95
|
+
measureTitle.style.cssText = TITLE;
|
|
96
|
+
measureTitle.appendChild(this.document.createTextNode(field.name));
|
|
97
|
+
const measureInner = this.document.createElement("div");
|
|
98
|
+
measureInner.style.cssText = VERTICAL_CENTER;
|
|
99
|
+
const innerInner = this.document.createElement("div");
|
|
100
|
+
innerInner.style.cssText = HORIZONTAL_CENTER;
|
|
101
|
+
innerInner.appendChild(rendered);
|
|
102
|
+
measureInner.appendChild(innerInner);
|
|
103
|
+
measureBox.appendChild(measureTitle);
|
|
104
|
+
measureBox.appendChild(measureInner);
|
|
105
|
+
measuresContainer.appendChild(measureBox);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
rowElement.appendChild(dimensionsContainer);
|
|
109
|
+
if (dimensions.length > 0 && this.options.isDrillingEnabled) {
|
|
110
|
+
const drillElement = this.document.createElement("span");
|
|
111
|
+
const drillIcon = (0, utils_1.createDrillIcon)(this.document);
|
|
112
|
+
drillElement.appendChild(drillIcon);
|
|
113
|
+
drillElement.style.cssText = `padding: 8px; vertical-align: top; width: 25px; cursor: pointer; position: absolute; top: 5px; right: 5px;`;
|
|
114
|
+
drillElement.onclick = () => {
|
|
115
|
+
if (this.options.onDrill) {
|
|
116
|
+
const { drillQuery, drillFilters } = (0, drill_1.getDrillQuery)(row);
|
|
117
|
+
this.options.onDrill(drillQuery, drillIcon, drillFilters);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
rowElement.appendChild(drillElement);
|
|
121
|
+
}
|
|
122
|
+
const dashboardOuter = this.document.createElement("div");
|
|
123
|
+
dashboardOuter.classList.add("dashboard-outer");
|
|
124
|
+
dashboardOuter.style.cssText = DASHBOARD_OUTER;
|
|
125
|
+
if (dimensions.length > 0) {
|
|
126
|
+
const nestIndicator = this.document.createElement("div");
|
|
127
|
+
nestIndicator.style.cssText = NEST_INDICATOR;
|
|
128
|
+
dashboardOuter.appendChild(nestIndicator);
|
|
129
|
+
}
|
|
130
|
+
dashboardOuter.appendChild(measuresContainer);
|
|
131
|
+
rowElement.appendChild(dashboardOuter);
|
|
132
|
+
body.appendChild(rowElement);
|
|
133
|
+
}
|
|
134
|
+
return body;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
exports.HTMLDashboardRenderer = HTMLDashboardRenderer;
|
|
138
|
+
const ROW_SEPARATOR_OUTER = `
|
|
139
|
+
display: flex;
|
|
140
|
+
flex-direction: column;
|
|
141
|
+
justify-content: flex-end;
|
|
142
|
+
flex: 1 0 auto;
|
|
143
|
+
`;
|
|
144
|
+
const DASHBOARD_OUTER = `
|
|
145
|
+
display: flex;
|
|
146
|
+
flex-direction: row;
|
|
147
|
+
font-size: 11px;
|
|
148
|
+
`;
|
|
149
|
+
const NESTING_DIV = `
|
|
150
|
+
background-color: var(--malloy-tile-background-color, #f7f7f7);
|
|
151
|
+
border: 1px solid var(--malloy-border-color, #e9e9e9);
|
|
152
|
+
`;
|
|
153
|
+
const NEST_INDICATOR = `
|
|
154
|
+
${NESTING_DIV}
|
|
155
|
+
min-height: 100%;
|
|
156
|
+
min-width: 11px;
|
|
157
|
+
margin: 6px;
|
|
158
|
+
border-radius: 4px;
|
|
159
|
+
`;
|
|
160
|
+
const ROW_SEPARATOR = `
|
|
161
|
+
${NESTING_DIV}
|
|
162
|
+
min-height: 11px;
|
|
163
|
+
max-height: 11px;
|
|
164
|
+
margin: 6px;
|
|
165
|
+
flex: 1 0 auto;
|
|
166
|
+
border-radius: 4px;
|
|
167
|
+
`;
|
|
168
|
+
const MEASURE_BOXES = `
|
|
169
|
+
display: flex;
|
|
170
|
+
flex-wrap: wrap;
|
|
171
|
+
`;
|
|
172
|
+
const DIMENSION_BOX = `
|
|
173
|
+
background-color: var(--malloy-tile-background-color, #f7f7f7);
|
|
174
|
+
border: 1px solid var(--malloy-border-color, #e9e9e9);
|
|
175
|
+
margin: 6px;
|
|
176
|
+
border-radius: 5px;
|
|
177
|
+
padding: 10px;
|
|
178
|
+
box-shadow: 0 1px 5px 0 var(--malloy-border-color, #f3f3f3);
|
|
179
|
+
`;
|
|
180
|
+
const MEASURE_BOX = `
|
|
181
|
+
margin: 6px;
|
|
182
|
+
border-radius: 5px;
|
|
183
|
+
border: 1px solid var(--malloy-border-color, #e9e9e9);
|
|
184
|
+
padding: 10px;
|
|
185
|
+
flex: 1 0 auto;
|
|
186
|
+
box-shadow: 0 1px 5px 0 var(--malloy-tile-background-color, #f3f3f3);
|
|
187
|
+
max-width: calc(100% - 11px);
|
|
188
|
+
display: flex;
|
|
189
|
+
flex-direction: column;
|
|
190
|
+
overflow: hidden;
|
|
191
|
+
`;
|
|
192
|
+
const DIMENSION_TITLE = `
|
|
193
|
+
font-size: 12px;
|
|
194
|
+
font-weight: 500;
|
|
195
|
+
color: var(--malloy-title-color, #505050);
|
|
196
|
+
margin-bottom: 5px;
|
|
197
|
+
font-family: var(--malloy-font-family, "Roboto");
|
|
198
|
+
`;
|
|
199
|
+
const TITLE = `
|
|
200
|
+
font-size: 11px;
|
|
201
|
+
font-family: var(--malloy-font-family, "Roboto");
|
|
202
|
+
font-weight: 500;
|
|
203
|
+
color: #var(--malloy-title-color, #505050);
|
|
204
|
+
`;
|
|
205
|
+
const SINGLE_VALUE = `
|
|
206
|
+
font-size: 20px;
|
|
207
|
+
display: flex;
|
|
208
|
+
justify-content: center;
|
|
209
|
+
align-items: center;
|
|
210
|
+
margin-top: 5px;
|
|
211
|
+
`;
|
|
212
|
+
const VERTICAL_CENTER = `
|
|
213
|
+
display: flex;
|
|
214
|
+
flex-direction: column;
|
|
215
|
+
justify-content: center;
|
|
216
|
+
flex: 1 0 auto;
|
|
217
|
+
`;
|
|
218
|
+
const HORIZONTAL_CENTER = `
|
|
219
|
+
display: flex;
|
|
220
|
+
justify-content: center;
|
|
221
|
+
align-items: center;
|
|
222
|
+
flex-direction: column;
|
|
223
|
+
`;
|
|
224
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DataColumn } from "@malloydata/malloy";
|
|
2
|
+
import { Renderer } from "../renderer";
|
|
3
|
+
export declare class HTMLDateRenderer implements Renderer {
|
|
4
|
+
private readonly document;
|
|
5
|
+
constructor(document: Document);
|
|
6
|
+
render(data: DataColumn): Promise<HTMLElement>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2021 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* This program is free software; you can redistribute it and/or
|
|
6
|
+
* modify it under the terms of the GNU General Public License
|
|
7
|
+
* version 2 as published by the Free Software Foundation.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU General Public License for more details.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.HTMLDateRenderer = void 0;
|
|
16
|
+
const malloy_1 = require("@malloydata/malloy");
|
|
17
|
+
const utils_1 = require("./utils");
|
|
18
|
+
class HTMLDateRenderer {
|
|
19
|
+
constructor(document) {
|
|
20
|
+
this.document = document;
|
|
21
|
+
}
|
|
22
|
+
async render(data) {
|
|
23
|
+
if (data.isNull()) {
|
|
24
|
+
return (0, utils_1.createNullElement)(this.document);
|
|
25
|
+
}
|
|
26
|
+
if (!data.isDate() && !data.isTimestamp()) {
|
|
27
|
+
return (0, utils_1.createErrorElement)(this.document, "Invalid field for date renderer");
|
|
28
|
+
}
|
|
29
|
+
const timeframe = data.field.timeframe ||
|
|
30
|
+
(data.isTimestamp() ? malloy_1.TimestampTimeframe.Second : malloy_1.DateTimeframe.Day);
|
|
31
|
+
const timestring = (0, utils_1.timeToString)(data.value, timeframe);
|
|
32
|
+
const element = this.document.createElement("span");
|
|
33
|
+
element.appendChild(this.document.createTextNode(timestring));
|
|
34
|
+
return element;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.HTMLDateRenderer = HTMLDateRenderer;
|
|
38
|
+
//# sourceMappingURL=date.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DataArray, Field, Explore } from "@malloydata/malloy";
|
|
2
|
+
import { DataStyles, StyleDefaults } from "../data_styles";
|
|
3
|
+
import { Renderer } from "../renderer";
|
|
4
|
+
import { DrillFunction } from "../drill";
|
|
5
|
+
export declare class HTMLView {
|
|
6
|
+
private readonly document;
|
|
7
|
+
constructor(document: Document);
|
|
8
|
+
render(table: DataArray, options: {
|
|
9
|
+
dataStyles: DataStyles;
|
|
10
|
+
isDrillingEnabled?: boolean;
|
|
11
|
+
onDrill?: DrillFunction;
|
|
12
|
+
}): Promise<HTMLElement>;
|
|
13
|
+
}
|
|
14
|
+
export declare class JSONView {
|
|
15
|
+
private readonly document;
|
|
16
|
+
constructor(document: Document);
|
|
17
|
+
render(table: DataArray): Promise<HTMLElement>;
|
|
18
|
+
}
|
|
19
|
+
export declare function makeRenderer(field: Explore | Field, document: Document, options: {
|
|
20
|
+
dataStyles: DataStyles;
|
|
21
|
+
isDrillingEnabled?: boolean;
|
|
22
|
+
onDrill?: DrillFunction;
|
|
23
|
+
}, styleDefaults: StyleDefaults): Renderer;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2021 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* This program is free software; you can redistribute it and/or
|
|
6
|
+
* modify it under the terms of the GNU General Public License
|
|
7
|
+
* version 2 as published by the Free Software Foundation.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU General Public License for more details.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.makeRenderer = exports.JSONView = exports.HTMLView = void 0;
|
|
16
|
+
const bar_chart_1 = require("./bar_chart");
|
|
17
|
+
const boolean_1 = require("./boolean");
|
|
18
|
+
const json_1 = require("./json");
|
|
19
|
+
const bytes_1 = require("./bytes");
|
|
20
|
+
const currency_1 = require("./currency");
|
|
21
|
+
const percent_1 = require("./percent");
|
|
22
|
+
const dashboard_1 = require("./dashboard");
|
|
23
|
+
const image_1 = require("./image");
|
|
24
|
+
const date_1 = require("./date");
|
|
25
|
+
const line_chart_1 = require("./line_chart");
|
|
26
|
+
const link_1 = require("./link");
|
|
27
|
+
const list_1 = require("./list");
|
|
28
|
+
const list_detail_1 = require("./list_detail");
|
|
29
|
+
const number_1 = require("./number");
|
|
30
|
+
const point_map_1 = require("./point_map");
|
|
31
|
+
const scatter_chart_1 = require("./scatter_chart");
|
|
32
|
+
const segment_map_1 = require("./segment_map");
|
|
33
|
+
const shape_map_1 = require("./shape_map");
|
|
34
|
+
const table_1 = require("./table");
|
|
35
|
+
const text_1 = require("./text");
|
|
36
|
+
const vega_spec_1 = require("./vega_spec");
|
|
37
|
+
const container_1 = require("./container");
|
|
38
|
+
const malloy_1 = require("@malloydata/malloy");
|
|
39
|
+
const utils_1 = require("./utils");
|
|
40
|
+
class HTMLView {
|
|
41
|
+
constructor(document) {
|
|
42
|
+
this.document = document;
|
|
43
|
+
}
|
|
44
|
+
async render(table, options) {
|
|
45
|
+
const renderer = makeRenderer(table.field, this.document, options, {
|
|
46
|
+
size: "large",
|
|
47
|
+
});
|
|
48
|
+
try {
|
|
49
|
+
// TODO Implement row streaming capability for some renderers: some renderers should be usable
|
|
50
|
+
// as a builder with `begin(field: StructDef)`, `row(field: StructDef, row: QueryDataRow)`,
|
|
51
|
+
// and `end(field: StructDef)` methods.
|
|
52
|
+
// Primarily, this should be possible for the `table` and `dashboard` renderers.
|
|
53
|
+
// This would only be used at this top level (and HTML view should support `begin`,
|
|
54
|
+
// `row`, and `end` as well).
|
|
55
|
+
return await renderer.render(table);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
if (error instanceof Error) {
|
|
59
|
+
return (0, utils_1.createErrorElement)(this.document, error);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
return (0, utils_1.createErrorElement)(this.document, "Internal error - Exception not an Error object.");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.HTMLView = HTMLView;
|
|
68
|
+
class JSONView {
|
|
69
|
+
constructor(document) {
|
|
70
|
+
this.document = document;
|
|
71
|
+
}
|
|
72
|
+
async render(table) {
|
|
73
|
+
const renderer = new json_1.HTMLJSONRenderer(this.document);
|
|
74
|
+
try {
|
|
75
|
+
return await renderer.render(table);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (error instanceof Error) {
|
|
79
|
+
return (0, utils_1.createErrorElement)(this.document, error);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
return (0, utils_1.createErrorElement)(this.document, "Internal error - Exception not an Error object.");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.JSONView = JSONView;
|
|
88
|
+
function getRendererOptions(field, dataStyles) {
|
|
89
|
+
let renderer = dataStyles[field.name];
|
|
90
|
+
if (!renderer) {
|
|
91
|
+
for (const sourceClass of field.sourceClasses) {
|
|
92
|
+
if (!renderer) {
|
|
93
|
+
renderer = dataStyles[sourceClass];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return renderer;
|
|
98
|
+
}
|
|
99
|
+
function isContainer(field) {
|
|
100
|
+
if (field.isExplore()) {
|
|
101
|
+
return field;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
throw new Error(`${field.name} does not contain fields and cannot be rendered this way`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function makeRenderer(field, document, options, styleDefaults) {
|
|
108
|
+
const renderDef = getRendererOptions(field, options.dataStyles) || {};
|
|
109
|
+
if (renderDef.renderer === "shape_map" || field.name.endsWith("_shape_map")) {
|
|
110
|
+
return new shape_map_1.HTMLShapeMapRenderer(document, styleDefaults, renderDef);
|
|
111
|
+
}
|
|
112
|
+
else if (renderDef.renderer === "point_map" ||
|
|
113
|
+
field.name.endsWith("_point_map")) {
|
|
114
|
+
return new point_map_1.HTMLPointMapRenderer(document, styleDefaults);
|
|
115
|
+
}
|
|
116
|
+
else if (renderDef.renderer === "image" || field.name.endsWith("_image")) {
|
|
117
|
+
return new image_1.HTMLImageRenderer(document);
|
|
118
|
+
}
|
|
119
|
+
else if (renderDef.renderer === "segment_map" ||
|
|
120
|
+
field.name.endsWith("_segment_map")) {
|
|
121
|
+
return new segment_map_1.HTMLSegmentMapRenderer(document, styleDefaults, renderDef);
|
|
122
|
+
}
|
|
123
|
+
else if (renderDef.renderer === "dashboard" ||
|
|
124
|
+
field.name.endsWith("_dashboard")) {
|
|
125
|
+
return container_1.ContainerRenderer.make(dashboard_1.HTMLDashboardRenderer, document, isContainer(field), options);
|
|
126
|
+
}
|
|
127
|
+
else if (renderDef.renderer === "json" || field.name.endsWith("_json")) {
|
|
128
|
+
return new json_1.HTMLJSONRenderer(document);
|
|
129
|
+
}
|
|
130
|
+
else if (renderDef.renderer === "line_chart" ||
|
|
131
|
+
field.name.endsWith("_line_chart")) {
|
|
132
|
+
return new line_chart_1.HTMLLineChartRenderer(document, styleDefaults, renderDef);
|
|
133
|
+
}
|
|
134
|
+
else if (renderDef.renderer === "scatter_chart" ||
|
|
135
|
+
field.name.endsWith("_scatter_chart")) {
|
|
136
|
+
return new scatter_chart_1.HTMLScatterChartRenderer(document, styleDefaults);
|
|
137
|
+
}
|
|
138
|
+
else if (renderDef.renderer === "bar_chart") {
|
|
139
|
+
return new bar_chart_1.HTMLBarChartRenderer(document, styleDefaults, renderDef);
|
|
140
|
+
}
|
|
141
|
+
else if (field.name.endsWith("_bar_chart")) {
|
|
142
|
+
return new bar_chart_1.HTMLBarChartRenderer(document, styleDefaults, {});
|
|
143
|
+
}
|
|
144
|
+
else if (renderDef.renderer === "vega") {
|
|
145
|
+
const spec = renderDef.spec;
|
|
146
|
+
if (spec) {
|
|
147
|
+
return new vega_spec_1.HTMLVegaSpecRenderer(document, styleDefaults, spec);
|
|
148
|
+
}
|
|
149
|
+
else if (renderDef.spec_name) {
|
|
150
|
+
const vegaRenderer = options.dataStyles[renderDef.spec_name];
|
|
151
|
+
if (vegaRenderer !== undefined && vegaRenderer.renderer === "vega") {
|
|
152
|
+
if (vegaRenderer.spec) {
|
|
153
|
+
return new vega_spec_1.HTMLVegaSpecRenderer(document, styleDefaults, vegaRenderer.spec);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
throw new Error(`No spec defined on ${renderDef.spec_name}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
throw new Error(`No Vega renderer named ${renderDef.spec_name}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
throw new Error(`No top level vega spec defined for ${field.name}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
if (renderDef.renderer === "time" ||
|
|
169
|
+
(field.hasParentExplore() &&
|
|
170
|
+
field.isAtomicField() &&
|
|
171
|
+
(field.type === malloy_1.AtomicFieldType.Date ||
|
|
172
|
+
field.type === malloy_1.AtomicFieldType.Timestamp))) {
|
|
173
|
+
return new date_1.HTMLDateRenderer(document);
|
|
174
|
+
}
|
|
175
|
+
else if (renderDef.renderer === "currency") {
|
|
176
|
+
return new currency_1.HTMLCurrencyRenderer(document);
|
|
177
|
+
}
|
|
178
|
+
else if (renderDef.renderer === "percent") {
|
|
179
|
+
return new percent_1.HTMLPercentRenderer(document);
|
|
180
|
+
}
|
|
181
|
+
else if (renderDef.renderer === "number" ||
|
|
182
|
+
(field.hasParentExplore() &&
|
|
183
|
+
field.isAtomicField() &&
|
|
184
|
+
field.type === malloy_1.AtomicFieldType.Number)) {
|
|
185
|
+
return new number_1.HTMLNumberRenderer(document);
|
|
186
|
+
}
|
|
187
|
+
else if (renderDef.renderer === "bytes") {
|
|
188
|
+
return new bytes_1.HTMLBytesRenderer(document);
|
|
189
|
+
}
|
|
190
|
+
else if (renderDef.renderer === "boolean" ||
|
|
191
|
+
(field.hasParentExplore() &&
|
|
192
|
+
field.isAtomicField() &&
|
|
193
|
+
field.type === malloy_1.AtomicFieldType.Boolean)) {
|
|
194
|
+
return new boolean_1.HTMLBooleanRenderer(document);
|
|
195
|
+
}
|
|
196
|
+
else if (renderDef.renderer === "link" || field.name.endsWith("_url")) {
|
|
197
|
+
return new link_1.HTMLLinkRenderer(document);
|
|
198
|
+
}
|
|
199
|
+
else if (renderDef.renderer === "list" || field.name.endsWith("_list")) {
|
|
200
|
+
return container_1.ContainerRenderer.make(list_1.HTMLListRenderer, document, isContainer(field), options);
|
|
201
|
+
}
|
|
202
|
+
else if (renderDef.renderer === "list_detail" ||
|
|
203
|
+
field.name.endsWith("_list_detail")) {
|
|
204
|
+
return container_1.ContainerRenderer.make(list_detail_1.HTMLListDetailRenderer, document, isContainer(field), options);
|
|
205
|
+
}
|
|
206
|
+
else if (renderDef.renderer === "table" ||
|
|
207
|
+
!field.hasParentExplore() ||
|
|
208
|
+
field.isExploreField()) {
|
|
209
|
+
return container_1.ContainerRenderer.make(table_1.HTMLTableRenderer, document, isContainer(field), options);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
return new text_1.HTMLTextRenderer(document);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
exports.makeRenderer = makeRenderer;
|
|
217
|
+
//# sourceMappingURL=html_view.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DataColumn } from "@malloydata/malloy";
|
|
2
|
+
import { Renderer } from "../renderer";
|
|
3
|
+
export declare class HTMLImageRenderer implements Renderer {
|
|
4
|
+
private readonly document;
|
|
5
|
+
constructor(document: Document);
|
|
6
|
+
render(data: DataColumn): Promise<HTMLElement>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2021 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* This program is free software; you can redistribute it and/or
|
|
6
|
+
* modify it under the terms of the GNU General Public License
|
|
7
|
+
* version 2 as published by the Free Software Foundation.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU General Public License for more details.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.HTMLImageRenderer = void 0;
|
|
16
|
+
const utils_1 = require("./utils");
|
|
17
|
+
class HTMLImageRenderer {
|
|
18
|
+
constructor(document) {
|
|
19
|
+
this.document = document;
|
|
20
|
+
}
|
|
21
|
+
async render(data) {
|
|
22
|
+
if (!data.isString()) {
|
|
23
|
+
return (0, utils_1.createErrorElement)(this.document, "Invalid field for Image renderer");
|
|
24
|
+
}
|
|
25
|
+
if (data.isNull()) {
|
|
26
|
+
return (0, utils_1.createNullElement)(this.document);
|
|
27
|
+
}
|
|
28
|
+
const element = this.document.createElement("img");
|
|
29
|
+
element.src = data.value;
|
|
30
|
+
return element;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.HTMLImageRenderer = HTMLImageRenderer;
|
|
34
|
+
//# sourceMappingURL=image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { HTMLView } from "./html_view";
|