Skip to content

Commit b0e968c

Browse files
committed
New widget: ScrollTable
1 parent 7524284 commit b0e968c

6 files changed

Lines changed: 208 additions & 22 deletions

File tree

src/main/resources/static/css/shared/components.css

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,47 @@ body.modal-open {
190190
.dv-dropdown.show {
191191
display: block;
192192
}
193+
194+
.dv-scroll-table {
195+
width: 100%;
196+
text-align: center;
197+
border-collapse: collapse;
198+
}
199+
200+
.dv-scroll-table > tbody tr:hover {
201+
background-color: var(--hover-color) !important;
202+
}
203+
204+
.dv-scroll-table > tbody tr:nth-of-type(2n + 1) {
205+
background-color: var(--bg-color-emphasis);
206+
}
207+
208+
.dv-scroll-table th {
209+
position: sticky;
210+
top: 0;
211+
background-color: var(--bg-color);
212+
box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.2);
213+
}
214+
215+
.dv-scroll-table th,
216+
.dv-scroll-table td {
217+
padding: 0.5rem;
218+
border: 1px solid var(--border-color);
219+
}
220+
221+
/* Remove top border */
222+
.dv-scroll-table tr:first-child th {
223+
border-top: none;
224+
}
225+
226+
/* Remove left border */
227+
.dv-scroll-table tr td:first-child,
228+
.dv-scroll-table tr th:first-child {
229+
border-left: none;
230+
}
231+
232+
/* Remove right border */
233+
.dv-scroll-table tr td:last-child,
234+
.dv-scroll-table tr th:last-child {
235+
border-right: none;
236+
}

src/main/resources/static/css/shared/globals.css

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -161,27 +161,6 @@
161161
}
162162
}
163163

164-
.dv-scrollable-table {
165-
width: 100%;
166-
text-align: center;
167-
border: 1px solid var(--border-color);
168-
border-collapse: collapse;
169-
}
170-
171-
.dv-scrollable-table tr {
172-
border: 1px solid var(--border-color);
173-
}
174-
175-
.dv-scrollable-table > tbody tr:nth-of-type(2n + 1) {
176-
background-color: var(--bg-color-emphasis);
177-
}
178-
179-
.dv-scrollable-table th,
180-
.dv-scrollable-table td {
181-
padding: 0.5rem;
182-
border: 1px solid var(--border-color);
183-
}
184-
185164
.dv-error {
186165
height: 100vh;
187166
width: 100vw;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[
2+
["Heading 1", "Heading 2", "Heading 3"],
3+
["Cell 4", "Cell 5", "Cell 6"],
4+
["Cell 7", "Cell 8", "Cell 9"],
5+
["Cell 10", "Cell 11", "Cell 12"],
6+
["Cell 13", "Cell 14", "Cell 15"],
7+
["Cell 16", "Cell 17", "Cell 18"],
8+
["Cell 19", "Cell 20", "Cell 21"],
9+
["Cell 22", "Cell 23", "Cell 24"],
10+
["Cell 25", "Cell 26", "Cell 27"],
11+
["Cell 28", "Cell 29", "Cell 30"],
12+
["Cell 31", "Cell 32", "Cell 33"]
13+
]
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import ControlsHandler from "../../pages/view/toolbar/ControlsHandler.js";
2+
import ExportHandler from "../../pages/view/toolbar/ExportHandler.js";
3+
import { getGeneratorOptions } from "../../pages/editor/utils/editorActions.js";
4+
5+
export default class ScrollTable {
6+
static defaultConfig = {
7+
type: "ScrollTable",
8+
title: "Table",
9+
generator: { id: "" },
10+
options: {
11+
numbers: true,
12+
},
13+
icon: "bi bi-table",
14+
w: 6,
15+
h: 6,
16+
};
17+
static formConfig = {
18+
title: {
19+
type: "text",
20+
label: "Title",
21+
},
22+
"generator.id": {
23+
type: "select",
24+
label: "Generator",
25+
options: () => getGeneratorOptions("CategoryNumber"),
26+
},
27+
"options.numbers": {
28+
type: "switch",
29+
label: "Row numbers",
30+
},
31+
};
32+
static previewData = [
33+
["Heading 1", "Heading 2", "Heading 3"],
34+
["Cell 4", "Cell 5", "Cell 6"],
35+
["Cell 7", "Cell 8", "Cell 9"],
36+
["Cell 10", "Cell 11", "Cell 12"],
37+
["Cell 13", "Cell 14", "Cell 15"],
38+
["Cell 16", "Cell 17", "Cell 18"],
39+
["Cell 19", "Cell 20", "Cell 21"],
40+
["Cell 22", "Cell 23", "Cell 24"],
41+
["Cell 25", "Cell 26", "Cell 27"],
42+
["Cell 28", "Cell 29", "Cell 30"],
43+
["Cell 31", "Cell 32", "Cell 33"],
44+
];
45+
46+
constructor(root, config) {
47+
this.root = d3.select(root);
48+
this.config = config;
49+
50+
this.setTitle(this.config.title);
51+
52+
this.div = this.root.select(".dv-chart-area").append("div");
53+
this.data = null;
54+
55+
this.filter = {};
56+
this.controls = new ControlsHandler(this);
57+
this.exports = new ExportHandler(this);
58+
59+
this.numbers = config.options.numbers || true;
60+
}
61+
62+
setTitle(title) {
63+
this.root.select(".dv-toolbar-title").attr("title", title).text(title);
64+
}
65+
66+
async fetch() {
67+
return await d3.json("/data/table.json");
68+
}
69+
70+
clear() {
71+
this.div.selectAll("*").remove();
72+
this.div
73+
.style("width", "100%")
74+
.style("height", "100%")
75+
.style("overflow-y", "auto");
76+
}
77+
78+
async init() {
79+
const data = await this.fetch();
80+
this.render(data);
81+
82+
this.filter = {
83+
sort: data[0][0],
84+
desc: true,
85+
};
86+
this.controls.append([
87+
{
88+
type: "select",
89+
label: "Sort by",
90+
value: this.filter.sort,
91+
options: data[0],
92+
onchange: (event) => {
93+
this.filter.sort = event.target.value;
94+
this.fetch().then((data) => this.render(data));
95+
},
96+
},
97+
{
98+
type: "switch",
99+
label: "Desc",
100+
value: this.filter.desc,
101+
onchange: (event) => {
102+
this.filter.desc = event.target.checked;
103+
this.fetch().then((data) => this.render(data));
104+
},
105+
},
106+
]);
107+
}
108+
109+
render(data) {
110+
this.clear();
111+
112+
let rows = data;
113+
if (this.numbers) {
114+
rows = data.map((row, i) => [i, ...row]);
115+
rows[0][0] = "#";
116+
}
117+
118+
const table = this.div.append("table").attr("class", "dv-scroll-table");
119+
120+
// Append table head (first row)
121+
table
122+
.append("thead")
123+
.append("tr")
124+
.selectAll("th")
125+
.data(rows[0])
126+
.join("th")
127+
.text((d) => d);
128+
129+
// Append table body (remaining rows)
130+
table
131+
.append("tbody")
132+
.selectAll("tr")
133+
.data(rows.slice(1)) // skip header
134+
.join("tr")
135+
.selectAll("td")
136+
.data((d) => d)
137+
.join("td")
138+
.text((d) => d);
139+
140+
// Cache rendered data
141+
this.data = data;
142+
}
143+
}

src/main/resources/static/js/widgets/static/StaticIFrame.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,17 @@ export default class StaticIFrame {
3737
render(data) {
3838
this.clear();
3939

40-
this.root
40+
const frame = this.root
4141
.append("iframe")
4242
.attr("src", data)
4343
.attr("width", "100%")
4444
.attr("height", "100%");
4545

46+
// Disable pointer events for dragging in editor
47+
if (d3.select(".dv-chart-tooltip").empty()) {
48+
frame.style("pointer-events", "none");
49+
}
50+
4651
this.root.classed("overflow-hidden", true);
4752
}
4853
}

src/main/resources/static/js/widgets/widgets.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import StaticText from "./static/StaticText.js";
33
import StaticVideo from "./static/StaticVideo.js";
44
import StaticIFrame from "./static/StaticIFrame.js";
55

6+
import ScrollTable from "./charts/ScrollTable.js";
67
import BarChart from "./charts/BarChart.js";
78
import LineChart from "./charts/LineChart.js";
89
import PieChart from "./charts/PieChart.js";
@@ -19,6 +20,7 @@ export default {
1920
StaticVideo,
2021
StaticIFrame,
2122

23+
ScrollTable,
2224
BarChart,
2325
PieChart,
2426
LineChart,

0 commit comments

Comments
 (0)