@hpcc-js/tree 3.2.15 → 3.2.17
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/LICENSE +43 -43
- package/README.md +454 -454
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +1 -1
- package/dist/index.umd.cjs.map +1 -1
- package/package.json +8 -6
- package/src/CirclePacking.css +15 -15
- package/src/CirclePacking.ts +152 -152
- package/src/Dendrogram.css +40 -40
- package/src/Dendrogram.ts +296 -296
- package/src/DirectoryTree.ts +306 -306
- package/src/Indented.ts +290 -290
- package/src/SunburstPartition.css +4 -4
- package/src/SunburstPartition.ts +157 -157
- package/src/Treemap.css +45 -45
- package/src/Treemap.ts +346 -346
- package/src/__package__.ts +3 -3
- package/src/index.ts +7 -7
package/src/Indented.ts
CHANGED
|
@@ -1,290 +1,290 @@
|
|
|
1
|
-
import { ITree } from "@hpcc-js/api";
|
|
2
|
-
import { PropertyExt, SVGZoomWidget, Utility } from "@hpcc-js/common";
|
|
3
|
-
import { hierarchy as d3Hierarchy, tree as d3Tree } from "d3-hierarchy";
|
|
4
|
-
import { select as d3Select } from "d3-selection";
|
|
5
|
-
|
|
6
|
-
import "../src/Indented.css";
|
|
7
|
-
|
|
8
|
-
export class IndentedColumn extends PropertyExt {
|
|
9
|
-
_owner: Indented;
|
|
10
|
-
|
|
11
|
-
constructor() {
|
|
12
|
-
super();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
owner(): Indented;
|
|
16
|
-
owner(_: Indented): this;
|
|
17
|
-
owner(_?: Indented): Indented | this {
|
|
18
|
-
if (!arguments.length) return this._owner;
|
|
19
|
-
this._owner = _;
|
|
20
|
-
return this;
|
|
21
|
-
}
|
|
22
|
-
valid(): boolean {
|
|
23
|
-
return !!this.column();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
column: (_?: string) => string | IndentedColumn;
|
|
27
|
-
}
|
|
28
|
-
IndentedColumn.prototype._class += " tree_Dendrogram.IndentedColumn";
|
|
29
|
-
|
|
30
|
-
IndentedColumn.prototype.publish("column", null, "set", "Field", function (this: IndentedColumn) { return this._owner ? this._owner.columns() : []; }, { optional: true });
|
|
31
|
-
|
|
32
|
-
// ===
|
|
33
|
-
export class Indented extends SVGZoomWidget {
|
|
34
|
-
Column;
|
|
35
|
-
_d3Tree;
|
|
36
|
-
_xml;
|
|
37
|
-
_svgLinks;
|
|
38
|
-
_svgNodes;
|
|
39
|
-
_treeData;
|
|
40
|
-
_collapsed: { [key: string]: boolean } = {};
|
|
41
|
-
|
|
42
|
-
constructor() {
|
|
43
|
-
super();
|
|
44
|
-
ITree.call(this);
|
|
45
|
-
Utility.SimpleSelectionMixin.call(this);
|
|
46
|
-
|
|
47
|
-
this._drawStartPos = "origin";
|
|
48
|
-
|
|
49
|
-
this._d3Tree = d3Tree();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
xmlToData(xml, id = "") {
|
|
53
|
-
if (DOMParser) {
|
|
54
|
-
const parser = new DOMParser();
|
|
55
|
-
const doc = parser.parseFromString(xml, "text/xml");
|
|
56
|
-
return xmlToJson(doc, id).children[0];
|
|
57
|
-
}
|
|
58
|
-
return [];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
xml(_) {
|
|
62
|
-
if (!arguments.length) return this._xml;
|
|
63
|
-
this._xml = _;
|
|
64
|
-
this.data(this.xmlToData(this._xml));
|
|
65
|
-
return this;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
IndentedData() {
|
|
69
|
-
if (this.data().length === 0) return [];
|
|
70
|
-
if (this.xmlColumn_exists()) {
|
|
71
|
-
const cellIdx = this.columns().indexOf(this.xmlColumn());
|
|
72
|
-
const retVal = {
|
|
73
|
-
label: this.xmlColumn(),
|
|
74
|
-
children: this.data().map(function (row, idx) {
|
|
75
|
-
return this.xmlToData(row[cellIdx], "[" + idx + "]");
|
|
76
|
-
}, this)
|
|
77
|
-
};
|
|
78
|
-
return retVal.children.length === 1 ? retVal.children[0] : retVal;
|
|
79
|
-
} else {
|
|
80
|
-
if (!this.mappings().filter(mapping => mapping.valid()).length) {
|
|
81
|
-
return this.data();
|
|
82
|
-
}
|
|
83
|
-
const view = this._db.rollupView(this.mappings().map(function (mapping) { return mapping.column(); }));
|
|
84
|
-
const root = {
|
|
85
|
-
key: "root",
|
|
86
|
-
values: view.entries()
|
|
87
|
-
};
|
|
88
|
-
return formatData(root);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function formatData(node): any {
|
|
92
|
-
if (node.values instanceof Array) {
|
|
93
|
-
const children = node.values.filter(function (value) {
|
|
94
|
-
return !(value instanceof Array);
|
|
95
|
-
}).map(function (value) {
|
|
96
|
-
return formatData(value);
|
|
97
|
-
});
|
|
98
|
-
const retVal: any = {
|
|
99
|
-
label: node.key
|
|
100
|
-
};
|
|
101
|
-
if (children.length) {
|
|
102
|
-
retVal.children = children;
|
|
103
|
-
} else {
|
|
104
|
-
retVal.size = 22;
|
|
105
|
-
}
|
|
106
|
-
return retVal;
|
|
107
|
-
}
|
|
108
|
-
return {
|
|
109
|
-
label: node.key,
|
|
110
|
-
size: node.values.aggregate,
|
|
111
|
-
origRows: node.values
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
enter(domNode, element) {
|
|
117
|
-
super.enter(domNode, element);
|
|
118
|
-
this._svgLinks = this._renderElement.append("g");
|
|
119
|
-
this._svgNodes = this._renderElement.append("g");
|
|
120
|
-
this._selection.widgetElement(this._svgNodes);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
protected _prevDataChecksum;
|
|
124
|
-
update(domNode, _element) {
|
|
125
|
-
super.update(domNode, _element);
|
|
126
|
-
const context = this;
|
|
127
|
-
|
|
128
|
-
this._d3Tree
|
|
129
|
-
.nodeSize([0, this.barHeight()])
|
|
130
|
-
;
|
|
131
|
-
const dataChecksum = this._db.dataChecksum();
|
|
132
|
-
if (this._prevDataChecksum !== dataChecksum) {
|
|
133
|
-
this._treeData = this.IndentedData();
|
|
134
|
-
this._prevDataChecksum = dataChecksum;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function getID(d) {
|
|
138
|
-
return (d.parent ? getID(d.parent) + "." : "") + d.data.label;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const root = d3Hierarchy(this.data())
|
|
142
|
-
.sum(function (d) {
|
|
143
|
-
return d.size || 50;
|
|
144
|
-
}).each((d) => {
|
|
145
|
-
if (this._collapsed[getID(d)]) {
|
|
146
|
-
delete (d.children);
|
|
147
|
-
}
|
|
148
|
-
})
|
|
149
|
-
;
|
|
150
|
-
|
|
151
|
-
const dataNodes = this._d3Tree(root).descendants();
|
|
152
|
-
const links = this._d3Tree(root).descendants().slice(1);
|
|
153
|
-
|
|
154
|
-
let nodeIdx = 0;
|
|
155
|
-
root.eachBefore((n: any) => {
|
|
156
|
-
n.x = nodeIdx * context.barHeight();
|
|
157
|
-
++nodeIdx;
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
const boxSize = this.barHeight() - 4;
|
|
161
|
-
const transitionDuration = this._renderCount ? 500 : 0;
|
|
162
|
-
|
|
163
|
-
// Lines ---
|
|
164
|
-
const lines = this._svgLinks.selectAll(".link").data(links, function (d) { return getID(d); });
|
|
165
|
-
lines.enter().append("path")
|
|
166
|
-
.attr("class", "link")
|
|
167
|
-
.attr("d", elbow)
|
|
168
|
-
;
|
|
169
|
-
lines.transition().duration(transitionDuration)
|
|
170
|
-
.attr("d", elbow)
|
|
171
|
-
;
|
|
172
|
-
lines.exit().remove();
|
|
173
|
-
|
|
174
|
-
function elbow(d) {
|
|
175
|
-
return "M" + d.parent.y + "," + d.parent.x
|
|
176
|
-
+ "V" + d.x + ", H" + d.y;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Nodes ---
|
|
180
|
-
const nodes = this._svgNodes.selectAll(".node").data(dataNodes, function (d) { return getID(d); });
|
|
181
|
-
nodes.transition().duration(transitionDuration)
|
|
182
|
-
.attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; })
|
|
183
|
-
;
|
|
184
|
-
const enterNodes = nodes.enter().append("g")
|
|
185
|
-
.attr("class", "node")
|
|
186
|
-
.attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; })
|
|
187
|
-
.call(this._selection.enter.bind(this._selection))
|
|
188
|
-
.each(function () {
|
|
189
|
-
const element = d3Select(this);
|
|
190
|
-
element.append("rect")
|
|
191
|
-
.attr("height", boxSize)
|
|
192
|
-
.attr("width", boxSize)
|
|
193
|
-
.on("click", function (d: any) {
|
|
194
|
-
if (context._collapsed[getID(d)]) {
|
|
195
|
-
delete context._collapsed[getID(d)];
|
|
196
|
-
} else if (d.children) {
|
|
197
|
-
context._collapsed[getID(d)] = true;
|
|
198
|
-
}
|
|
199
|
-
context.lazyRender();
|
|
200
|
-
})
|
|
201
|
-
;
|
|
202
|
-
element.append("text");
|
|
203
|
-
})
|
|
204
|
-
.style("opacity", 0)
|
|
205
|
-
;
|
|
206
|
-
enterNodes.transition()
|
|
207
|
-
.style("opacity", 1)
|
|
208
|
-
;
|
|
209
|
-
enterNodes.merge(nodes).select("rect")
|
|
210
|
-
.attr("x", -boxSize / 2)
|
|
211
|
-
.attr("y", -boxSize / 2)
|
|
212
|
-
.style("fill", color)
|
|
213
|
-
;
|
|
214
|
-
enterNodes.merge(nodes).select("text")
|
|
215
|
-
.attr("dx", boxSize / 2 + 4 + "px")
|
|
216
|
-
.attr("dy", "0.33em")
|
|
217
|
-
.text(function (d) { return d.data.label; })
|
|
218
|
-
;
|
|
219
|
-
nodes.exit().transition()
|
|
220
|
-
.style("opacity", 0)
|
|
221
|
-
.remove()
|
|
222
|
-
;
|
|
223
|
-
|
|
224
|
-
if (!this._renderCount) {
|
|
225
|
-
context.zoomToFit();
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function color(d) {
|
|
229
|
-
return context._collapsed[getID(d)] ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
Indented.prototype._class += " tree_Indented";
|
|
234
|
-
Indented.prototype.implements(ITree.prototype);
|
|
235
|
-
Indented.prototype.mixin(Utility.SimpleSelectionMixin);
|
|
236
|
-
Indented.prototype.Column = IndentedColumn;
|
|
237
|
-
|
|
238
|
-
export interface Indented {
|
|
239
|
-
_palette;
|
|
240
|
-
|
|
241
|
-
// ITree ---
|
|
242
|
-
click(row, column, selected): void;
|
|
243
|
-
dblclick(row, column, selected): void;
|
|
244
|
-
|
|
245
|
-
// SimpleSelectionMixin ---
|
|
246
|
-
_selection;
|
|
247
|
-
|
|
248
|
-
// Properties ---
|
|
249
|
-
xmlColumn(): string;
|
|
250
|
-
xmlColumn(_: string): this;
|
|
251
|
-
xmlColumn_exists(): boolean;
|
|
252
|
-
mappings(): IndentedColumn[];
|
|
253
|
-
mappings(_: IndentedColumn[]): this;
|
|
254
|
-
barHeight(): number;
|
|
255
|
-
barHeight(_: number): this;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
Indented.prototype.publish("xmlColumn", null, "set", "Field", function () { return this.columns(); }, { optional: true });
|
|
259
|
-
Indented.prototype.publish("mappings", [], "propertyArray", "Source Columns", null, { autoExpand: IndentedColumn, disable: (w) => w.xmlColumn_exists() });
|
|
260
|
-
Indented.prototype.publish("barHeight", 16, "number", "Bar height");
|
|
261
|
-
|
|
262
|
-
function xmlToJson(xml, id = "") {
|
|
263
|
-
const retVal = {
|
|
264
|
-
id,
|
|
265
|
-
label: "",
|
|
266
|
-
attributes: {},
|
|
267
|
-
children: []
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
retVal.label = xml.nodeName;
|
|
271
|
-
if (xml.nodeType === 1) { // element
|
|
272
|
-
if (xml.attributes.length > 0) {
|
|
273
|
-
for (let j = 0; j < xml.attributes.length; j++) {
|
|
274
|
-
const attribute = xml.attributes.item(j);
|
|
275
|
-
retVal.attributes[attribute.nodeName] = attribute.nodeValue;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
} else if (xml.nodeType === 3) { // text
|
|
279
|
-
retVal.label = xml.nodeValue;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (xml.hasChildNodes()) {
|
|
283
|
-
for (let i = 0; i < xml.childNodes.length; i++) {
|
|
284
|
-
const item = xml.childNodes.item(i);
|
|
285
|
-
const child = xmlToJson(item, id + "[" + retVal.children.length + "]");
|
|
286
|
-
retVal.children.push(child);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
return retVal;
|
|
290
|
-
}
|
|
1
|
+
import { ITree } from "@hpcc-js/api";
|
|
2
|
+
import { PropertyExt, SVGZoomWidget, Utility } from "@hpcc-js/common";
|
|
3
|
+
import { hierarchy as d3Hierarchy, tree as d3Tree } from "d3-hierarchy";
|
|
4
|
+
import { select as d3Select } from "d3-selection";
|
|
5
|
+
|
|
6
|
+
import "../src/Indented.css";
|
|
7
|
+
|
|
8
|
+
export class IndentedColumn extends PropertyExt {
|
|
9
|
+
_owner: Indented;
|
|
10
|
+
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
owner(): Indented;
|
|
16
|
+
owner(_: Indented): this;
|
|
17
|
+
owner(_?: Indented): Indented | this {
|
|
18
|
+
if (!arguments.length) return this._owner;
|
|
19
|
+
this._owner = _;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
valid(): boolean {
|
|
23
|
+
return !!this.column();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
column: (_?: string) => string | IndentedColumn;
|
|
27
|
+
}
|
|
28
|
+
IndentedColumn.prototype._class += " tree_Dendrogram.IndentedColumn";
|
|
29
|
+
|
|
30
|
+
IndentedColumn.prototype.publish("column", null, "set", "Field", function (this: IndentedColumn) { return this._owner ? this._owner.columns() : []; }, { optional: true });
|
|
31
|
+
|
|
32
|
+
// ===
|
|
33
|
+
export class Indented extends SVGZoomWidget {
|
|
34
|
+
Column;
|
|
35
|
+
_d3Tree;
|
|
36
|
+
_xml;
|
|
37
|
+
_svgLinks;
|
|
38
|
+
_svgNodes;
|
|
39
|
+
_treeData;
|
|
40
|
+
_collapsed: { [key: string]: boolean } = {};
|
|
41
|
+
|
|
42
|
+
constructor() {
|
|
43
|
+
super();
|
|
44
|
+
ITree.call(this);
|
|
45
|
+
Utility.SimpleSelectionMixin.call(this);
|
|
46
|
+
|
|
47
|
+
this._drawStartPos = "origin";
|
|
48
|
+
|
|
49
|
+
this._d3Tree = d3Tree();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
xmlToData(xml, id = "") {
|
|
53
|
+
if (DOMParser) {
|
|
54
|
+
const parser = new DOMParser();
|
|
55
|
+
const doc = parser.parseFromString(xml, "text/xml");
|
|
56
|
+
return xmlToJson(doc, id).children[0];
|
|
57
|
+
}
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
xml(_) {
|
|
62
|
+
if (!arguments.length) return this._xml;
|
|
63
|
+
this._xml = _;
|
|
64
|
+
this.data(this.xmlToData(this._xml));
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
IndentedData() {
|
|
69
|
+
if (this.data().length === 0) return [];
|
|
70
|
+
if (this.xmlColumn_exists()) {
|
|
71
|
+
const cellIdx = this.columns().indexOf(this.xmlColumn());
|
|
72
|
+
const retVal = {
|
|
73
|
+
label: this.xmlColumn(),
|
|
74
|
+
children: this.data().map(function (row, idx) {
|
|
75
|
+
return this.xmlToData(row[cellIdx], "[" + idx + "]");
|
|
76
|
+
}, this)
|
|
77
|
+
};
|
|
78
|
+
return retVal.children.length === 1 ? retVal.children[0] : retVal;
|
|
79
|
+
} else {
|
|
80
|
+
if (!this.mappings().filter(mapping => mapping.valid()).length) {
|
|
81
|
+
return this.data();
|
|
82
|
+
}
|
|
83
|
+
const view = this._db.rollupView(this.mappings().map(function (mapping) { return mapping.column(); }));
|
|
84
|
+
const root = {
|
|
85
|
+
key: "root",
|
|
86
|
+
values: view.entries()
|
|
87
|
+
};
|
|
88
|
+
return formatData(root);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function formatData(node): any {
|
|
92
|
+
if (node.values instanceof Array) {
|
|
93
|
+
const children = node.values.filter(function (value) {
|
|
94
|
+
return !(value instanceof Array);
|
|
95
|
+
}).map(function (value) {
|
|
96
|
+
return formatData(value);
|
|
97
|
+
});
|
|
98
|
+
const retVal: any = {
|
|
99
|
+
label: node.key
|
|
100
|
+
};
|
|
101
|
+
if (children.length) {
|
|
102
|
+
retVal.children = children;
|
|
103
|
+
} else {
|
|
104
|
+
retVal.size = 22;
|
|
105
|
+
}
|
|
106
|
+
return retVal;
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
label: node.key,
|
|
110
|
+
size: node.values.aggregate,
|
|
111
|
+
origRows: node.values
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
enter(domNode, element) {
|
|
117
|
+
super.enter(domNode, element);
|
|
118
|
+
this._svgLinks = this._renderElement.append("g");
|
|
119
|
+
this._svgNodes = this._renderElement.append("g");
|
|
120
|
+
this._selection.widgetElement(this._svgNodes);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
protected _prevDataChecksum;
|
|
124
|
+
update(domNode, _element) {
|
|
125
|
+
super.update(domNode, _element);
|
|
126
|
+
const context = this;
|
|
127
|
+
|
|
128
|
+
this._d3Tree
|
|
129
|
+
.nodeSize([0, this.barHeight()])
|
|
130
|
+
;
|
|
131
|
+
const dataChecksum = this._db.dataChecksum();
|
|
132
|
+
if (this._prevDataChecksum !== dataChecksum) {
|
|
133
|
+
this._treeData = this.IndentedData();
|
|
134
|
+
this._prevDataChecksum = dataChecksum;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function getID(d) {
|
|
138
|
+
return (d.parent ? getID(d.parent) + "." : "") + d.data.label;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const root = d3Hierarchy(this.data())
|
|
142
|
+
.sum(function (d) {
|
|
143
|
+
return d.size || 50;
|
|
144
|
+
}).each((d) => {
|
|
145
|
+
if (this._collapsed[getID(d)]) {
|
|
146
|
+
delete (d.children);
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
;
|
|
150
|
+
|
|
151
|
+
const dataNodes = this._d3Tree(root).descendants();
|
|
152
|
+
const links = this._d3Tree(root).descendants().slice(1);
|
|
153
|
+
|
|
154
|
+
let nodeIdx = 0;
|
|
155
|
+
root.eachBefore((n: any) => {
|
|
156
|
+
n.x = nodeIdx * context.barHeight();
|
|
157
|
+
++nodeIdx;
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const boxSize = this.barHeight() - 4;
|
|
161
|
+
const transitionDuration = this._renderCount ? 500 : 0;
|
|
162
|
+
|
|
163
|
+
// Lines ---
|
|
164
|
+
const lines = this._svgLinks.selectAll(".link").data(links, function (d) { return getID(d); });
|
|
165
|
+
lines.enter().append("path")
|
|
166
|
+
.attr("class", "link")
|
|
167
|
+
.attr("d", elbow)
|
|
168
|
+
;
|
|
169
|
+
lines.transition().duration(transitionDuration)
|
|
170
|
+
.attr("d", elbow)
|
|
171
|
+
;
|
|
172
|
+
lines.exit().remove();
|
|
173
|
+
|
|
174
|
+
function elbow(d) {
|
|
175
|
+
return "M" + d.parent.y + "," + d.parent.x
|
|
176
|
+
+ "V" + d.x + ", H" + d.y;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Nodes ---
|
|
180
|
+
const nodes = this._svgNodes.selectAll(".node").data(dataNodes, function (d) { return getID(d); });
|
|
181
|
+
nodes.transition().duration(transitionDuration)
|
|
182
|
+
.attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; })
|
|
183
|
+
;
|
|
184
|
+
const enterNodes = nodes.enter().append("g")
|
|
185
|
+
.attr("class", "node")
|
|
186
|
+
.attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; })
|
|
187
|
+
.call(this._selection.enter.bind(this._selection))
|
|
188
|
+
.each(function () {
|
|
189
|
+
const element = d3Select(this);
|
|
190
|
+
element.append("rect")
|
|
191
|
+
.attr("height", boxSize)
|
|
192
|
+
.attr("width", boxSize)
|
|
193
|
+
.on("click", function (d: any) {
|
|
194
|
+
if (context._collapsed[getID(d)]) {
|
|
195
|
+
delete context._collapsed[getID(d)];
|
|
196
|
+
} else if (d.children) {
|
|
197
|
+
context._collapsed[getID(d)] = true;
|
|
198
|
+
}
|
|
199
|
+
context.lazyRender();
|
|
200
|
+
})
|
|
201
|
+
;
|
|
202
|
+
element.append("text");
|
|
203
|
+
})
|
|
204
|
+
.style("opacity", 0)
|
|
205
|
+
;
|
|
206
|
+
enterNodes.transition()
|
|
207
|
+
.style("opacity", 1)
|
|
208
|
+
;
|
|
209
|
+
enterNodes.merge(nodes).select("rect")
|
|
210
|
+
.attr("x", -boxSize / 2)
|
|
211
|
+
.attr("y", -boxSize / 2)
|
|
212
|
+
.style("fill", color)
|
|
213
|
+
;
|
|
214
|
+
enterNodes.merge(nodes).select("text")
|
|
215
|
+
.attr("dx", boxSize / 2 + 4 + "px")
|
|
216
|
+
.attr("dy", "0.33em")
|
|
217
|
+
.text(function (d) { return d.data.label; })
|
|
218
|
+
;
|
|
219
|
+
nodes.exit().transition()
|
|
220
|
+
.style("opacity", 0)
|
|
221
|
+
.remove()
|
|
222
|
+
;
|
|
223
|
+
|
|
224
|
+
if (!this._renderCount) {
|
|
225
|
+
context.zoomToFit();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function color(d) {
|
|
229
|
+
return context._collapsed[getID(d)] ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
Indented.prototype._class += " tree_Indented";
|
|
234
|
+
Indented.prototype.implements(ITree.prototype);
|
|
235
|
+
Indented.prototype.mixin(Utility.SimpleSelectionMixin);
|
|
236
|
+
Indented.prototype.Column = IndentedColumn;
|
|
237
|
+
|
|
238
|
+
export interface Indented {
|
|
239
|
+
_palette;
|
|
240
|
+
|
|
241
|
+
// ITree ---
|
|
242
|
+
click(row, column, selected): void;
|
|
243
|
+
dblclick(row, column, selected): void;
|
|
244
|
+
|
|
245
|
+
// SimpleSelectionMixin ---
|
|
246
|
+
_selection;
|
|
247
|
+
|
|
248
|
+
// Properties ---
|
|
249
|
+
xmlColumn(): string;
|
|
250
|
+
xmlColumn(_: string): this;
|
|
251
|
+
xmlColumn_exists(): boolean;
|
|
252
|
+
mappings(): IndentedColumn[];
|
|
253
|
+
mappings(_: IndentedColumn[]): this;
|
|
254
|
+
barHeight(): number;
|
|
255
|
+
barHeight(_: number): this;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
Indented.prototype.publish("xmlColumn", null, "set", "Field", function () { return this.columns(); }, { optional: true });
|
|
259
|
+
Indented.prototype.publish("mappings", [], "propertyArray", "Source Columns", null, { autoExpand: IndentedColumn, disable: (w) => w.xmlColumn_exists() });
|
|
260
|
+
Indented.prototype.publish("barHeight", 16, "number", "Bar height");
|
|
261
|
+
|
|
262
|
+
function xmlToJson(xml, id = "") {
|
|
263
|
+
const retVal = {
|
|
264
|
+
id,
|
|
265
|
+
label: "",
|
|
266
|
+
attributes: {},
|
|
267
|
+
children: []
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
retVal.label = xml.nodeName;
|
|
271
|
+
if (xml.nodeType === 1) { // element
|
|
272
|
+
if (xml.attributes.length > 0) {
|
|
273
|
+
for (let j = 0; j < xml.attributes.length; j++) {
|
|
274
|
+
const attribute = xml.attributes.item(j);
|
|
275
|
+
retVal.attributes[attribute.nodeName] = attribute.nodeValue;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
} else if (xml.nodeType === 3) { // text
|
|
279
|
+
retVal.label = xml.nodeValue;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (xml.hasChildNodes()) {
|
|
283
|
+
for (let i = 0; i < xml.childNodes.length; i++) {
|
|
284
|
+
const item = xml.childNodes.item(i);
|
|
285
|
+
const child = xmlToJson(item, id + "[" + retVal.children.length + "]");
|
|
286
|
+
retVal.children.push(child);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return retVal;
|
|
290
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
.tree_Sunburst path {
|
|
2
|
-
stroke: #fff;
|
|
3
|
-
stroke-width: 0.5px;
|
|
4
|
-
fill-rule: evenodd;
|
|
1
|
+
.tree_Sunburst path {
|
|
2
|
+
stroke: #fff;
|
|
3
|
+
stroke-width: 0.5px;
|
|
4
|
+
fill-rule: evenodd;
|
|
5
5
|
}
|