-
Notifications
You must be signed in to change notification settings - Fork 2
/
SomeD3Viz.js
123 lines (103 loc) · 3.51 KB
/
SomeD3Viz.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
sap.ui.define([
'sap/ui/core/Control',
'sap/ui/core/HTML',
'sap/ui/core/ResizeHandler',
'./../thirdparty/d3.v5.min'
], function(Control, HTML, ResizeHandler) {
'use strict';
return Control.extend('sap.ui5con2019.d3js.controls.SomeD3Viz', {
metadata: {
aggregations: {
_html: {
type: 'sap.ui.core.HTML',
multiple: false,
visibility: 'hidden'
},
data: {
type: 'sap.ui.base.ManagedObject'
}
}
},
init: function() {
this._sContainerId = this.getId() + '--container'
this.setAggregation('_html', new HTML({
content: `<svg id="${this._sContainerId}"></svg>`
}))
},
exit: function() {
ResizeHandler.deregister(this._sResizeHandlerId);
},
renderer: {
apiVersion: 2,
render: function(oRm, oControl) {
oRm.openStart('div', oControl);
oRm.class('someViz');
oRm.openEnd();
oRm.openStart('p').openEnd();
oRm.text('Custom controls are great 🎉');
oRm.close('p');
oRm.renderControl(oControl.getAggregation('_html'));
oRm.close('div');
}
},
_onResize: function() {
console.log('resize to width:', this.$().width());
this._renderViz();
},
onBeforeRendering: function() {
ResizeHandler.deregister(this._sResizeHandlerId);
},
onAfterRendering: function() {
this._sResizeHandlerId = ResizeHandler.register(this, this._onResize.bind(this));
this._renderViz();
},
_renderViz: function() {
const height = 500;
const width = this.$().width();
console.log('rendering with width', width);
const svg = d3.select('#' + this._sContainerId)
svg.attr("height", height).attr("width", width)
const data = this.getBinding("data").getContexts()
.map(oContext => oContext.getObject());
/**
* The following snippet is based on the Bubble Chart of Mike Bostock
* https://observablehq.com/@d3/bubble-chart
*/
const format = d3.format(",d")
const color = d3.scaleOrdinal(data.map(d => d.group), d3.schemeCategory10)
const pack = data => d3.pack()
.size([width - 2, height - 2])
.padding(3)
(d3.hierarchy({children: data})
.sum(d => d.value))
const root = pack(data);
svg.attr("viewBox", [0, 0, width, height])
.attr("font-size", 10)
.attr("font-family", "sans-serif")
.attr("text-anchor", "middle");
const leaf = svg.selectAll("g")
.data(root.leaves())
.join("g")
.attr("transform", d => `translate(${d.x + 1},${d.y + 1})`);
leaf.append("circle")
.attr("id", d => (d.leafUid = "leaf" /*DOM.uid*/).id)
.attr("r", d => d.r)
.attr("fill-opacity", 0.7)
.attr("fill", d => color(d.data.group));
leaf.append("clipPath")
.attr("id", d => (d.clipUid = "clip" /*DOM.uid*/).id)
.append("use")
.attr("xlink:href", d => d.leafUid.href);
leaf.append("text")
.attr("clip-path", d => d.clipUid)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g))
.join("tspan")
.attr("x", 0)
.attr("y", (d, i, nodes) => `${i - nodes.length / 2 + 0.8}em`)
.text(d => d);
leaf.append("title")
.text(d => `${d.data.title}\n${format(d.value)}`);
} // end of onAfterRendering
});
});