Implemented collisions on nodes
Also included in this is the implementation of stats as html foreign objects in svgs.
This commit is contained in:
parent
62aef3eec6
commit
d82a43d1e3
@ -66,7 +66,7 @@ var color = d3.scaleOrdinal(d3.schemeCategory20);
|
|||||||
var simulation = d3.forceSimulation()
|
var simulation = d3.forceSimulation()
|
||||||
.force('charge', d3.forceManyBody().strength(() => -50).distanceMin(() => 30))
|
.force('charge', d3.forceManyBody().strength(() => -50).distanceMin(() => 30))
|
||||||
.force('link', d3.forceLink().distance(() => 200).id(function(d) { return d.id; }))
|
.force('link', d3.forceLink().distance(() => 200).id(function(d) { return d.id; }))
|
||||||
.force('collide', d3.forceCollide().radius(function(d) { return 128 + 0.5; }).iterations(2))
|
.force('collide', d3.forceCollide().radius(function(d) { return 200 + 0.5; }).iterations(2))
|
||||||
.force('center', d3.forceCenter(width * 1/3, height * 1/3))
|
.force('center', d3.forceCenter(width * 1/3, height * 1/3))
|
||||||
|
|
||||||
function rightRoundedRect(x, y, width, height, radius) {
|
function rightRoundedRect(x, y, width, height, radius) {
|
||||||
@ -171,35 +171,26 @@ d3.json('services.json', function(error, graph) {
|
|||||||
.attr('stroke-width', '1px')
|
.attr('stroke-width', '1px')
|
||||||
.attr('fill', '#464646')
|
.attr('fill', '#464646')
|
||||||
|
|
||||||
// An icon or label that exists within the circle, inside the infobox
|
var html = stats
|
||||||
stats.append('text')
|
.append('switch')
|
||||||
.attr('class', 'cpu')
|
.append('foreignObject')
|
||||||
.attr('class', 'stat')
|
.attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility')
|
||||||
.attr('x', '12')
|
.attr('x', 12)
|
||||||
.attr('y', '65')
|
.attr('y', 57)
|
||||||
.attr('text-anchor', 'start')
|
.attr('width', 160)
|
||||||
.attr('fill', 'rgba(255, 255, 255, 0.8)')
|
.attr('height', 70)
|
||||||
.text('CPU: 63%')
|
// From here everything will be rendered with react using a ref.
|
||||||
|
// However for now these values are hard-coded.
|
||||||
|
.append('xhtml:div')
|
||||||
|
.attr('class', 'node_statistics')
|
||||||
|
|
||||||
// An icon or label that exists within the circle, inside the infobox
|
// Remove with react + dyanmic data.
|
||||||
stats.append('text')
|
html.append('p')
|
||||||
.attr('class', 'memory')
|
.text('CPU: 48%')
|
||||||
.attr('class', 'stat')
|
html.append('p')
|
||||||
.attr('x', '12')
|
.text('Memory: 54%')
|
||||||
.attr('y', '85')
|
html.append('p')
|
||||||
.attr('text-anchor', 'start')
|
.text('Network: 1.75kb/sec')
|
||||||
.attr('fill', 'rgba(255, 255, 255, 0.8)')
|
|
||||||
.text('Memory: 50%')
|
|
||||||
|
|
||||||
// An icon or label that exists within the circle, inside the infobox
|
|
||||||
stats.append('text')
|
|
||||||
.attr('class', 'network')
|
|
||||||
.attr('class', 'stat')
|
|
||||||
.attr('x', '12')
|
|
||||||
.attr('y', '105')
|
|
||||||
.attr('text-anchor', 'start')
|
|
||||||
.attr('fill', 'rgba(255, 255, 255, 0.8)')
|
|
||||||
.text('Network: 1.23kb/sec')
|
|
||||||
|
|
||||||
|
|
||||||
elm.call(d3.drag()
|
elm.call(d3.drag()
|
||||||
@ -237,7 +228,7 @@ d3.json('services.json', function(error, graph) {
|
|||||||
|
|
||||||
primary.append('path')
|
primary.append('path')
|
||||||
.attr('class', 'node')
|
.attr('class', 'node')
|
||||||
.attr('d', rect('0', '-39', 170, 78, 2))
|
.attr('d', rect('0', '-39', 170, 114, 2))
|
||||||
.attr('stroke', '#343434')
|
.attr('stroke', '#343434')
|
||||||
.attr('stroke-width', '1px')
|
.attr('stroke-width', '1px')
|
||||||
.attr('fill', '#464646')
|
.attr('fill', '#464646')
|
||||||
@ -267,11 +258,32 @@ d3.json('services.json', function(error, graph) {
|
|||||||
.attr('fill', '#fff')
|
.attr('fill', '#fff')
|
||||||
.text('☇')
|
.text('☇')
|
||||||
|
|
||||||
|
var html = primary
|
||||||
|
.append('switch')
|
||||||
|
.append('foreignObject')
|
||||||
|
.attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility')
|
||||||
|
.attr('x', 12)
|
||||||
|
.attr('y', 87)
|
||||||
|
.attr('width', 160)
|
||||||
|
.attr('height', 70)
|
||||||
|
// From here everything will be rendered with react using a ref.
|
||||||
|
// However for now these values are hard-coded.
|
||||||
|
.append('xhtml:div')
|
||||||
|
.attr('class', 'node_statistics')
|
||||||
|
|
||||||
|
// Remove with react + dyanmic data.
|
||||||
|
html.append('p')
|
||||||
|
.text('CPU: 48%')
|
||||||
|
html.append('p')
|
||||||
|
.text('Memory: 54%')
|
||||||
|
html.append('p')
|
||||||
|
.text('Network: 1.75kb/sec')
|
||||||
|
|
||||||
var secondary = stats.append('g');
|
var secondary = stats.append('g');
|
||||||
|
|
||||||
secondary.append('path')
|
secondary.append('path')
|
||||||
.attr('class', 'node')
|
.attr('class', 'node')
|
||||||
.attr('d', bottomRoundedRect('0', '-113', 170, 114, 4))
|
.attr('d', bottomRoundedRect('0', '-149', 170, 114, 4))
|
||||||
.attr('stroke', '#343434')
|
.attr('stroke', '#343434')
|
||||||
.attr('stroke-width', '1px')
|
.attr('stroke-width', '1px')
|
||||||
.attr('fill', '#464646')
|
.attr('fill', '#464646')
|
||||||
@ -279,7 +291,7 @@ d3.json('services.json', function(error, graph) {
|
|||||||
secondary.append('text')
|
secondary.append('text')
|
||||||
.attr('class', 'secondary')
|
.attr('class', 'secondary')
|
||||||
.attr('x', '12')
|
.attr('x', '12')
|
||||||
.attr('y', '150')
|
.attr('y', '183')
|
||||||
.attr('text-anchor', 'start')
|
.attr('text-anchor', 'start')
|
||||||
.attr('fill', '#fff')
|
.attr('fill', '#fff')
|
||||||
.text('Secondary')
|
.text('Secondary')
|
||||||
@ -287,7 +299,7 @@ d3.json('services.json', function(error, graph) {
|
|||||||
secondary.append('circle')
|
secondary.append('circle')
|
||||||
.attr('class', 'alert')
|
.attr('class', 'alert')
|
||||||
.attr('cx', function () { return d3.select(this.parentNode).select('.secondary').node().getBBox().width + 30 })
|
.attr('cx', function () { return d3.select(this.parentNode).select('.secondary').node().getBBox().width + 30 })
|
||||||
.attr('cy', '144')
|
.attr('cy', '177')
|
||||||
.attr('stroke-width', '0px')
|
.attr('stroke-width', '0px')
|
||||||
.attr('fill', 'rgb(0,175,102)')
|
.attr('fill', 'rgb(0,175,102)')
|
||||||
.attr('r', '9px')
|
.attr('r', '9px')
|
||||||
@ -296,7 +308,7 @@ d3.json('services.json', function(error, graph) {
|
|||||||
secondary.append('text')
|
secondary.append('text')
|
||||||
.attr('class', 'health')
|
.attr('class', 'health')
|
||||||
.attr('x', function () { return d3.select(this.parentNode).select('.secondary').node().getBBox().width + 30 })
|
.attr('x', function () { return d3.select(this.parentNode).select('.secondary').node().getBBox().width + 30 })
|
||||||
.attr('y', '149')
|
.attr('y', '182')
|
||||||
.attr('text-anchor', 'middle')
|
.attr('text-anchor', 'middle')
|
||||||
.attr('fill', '#fff')
|
.attr('fill', '#fff')
|
||||||
.text('❤')
|
.text('❤')
|
||||||
@ -306,9 +318,9 @@ d3.json('services.json', function(error, graph) {
|
|||||||
.append('foreignObject')
|
.append('foreignObject')
|
||||||
.attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility')
|
.attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility')
|
||||||
.attr('x', 12)
|
.attr('x', 12)
|
||||||
.attr('y', 160)
|
.attr('y', 200)
|
||||||
.attr('width', 160)
|
.attr('width', 160)
|
||||||
.attr('height', 100)
|
.attr('height', 70)
|
||||||
// From here everything will be rendered with react using a ref.
|
// From here everything will be rendered with react using a ref.
|
||||||
// However for now these values are hard-coded.
|
// However for now these values are hard-coded.
|
||||||
.append('xhtml:div')
|
.append('xhtml:div')
|
||||||
@ -369,18 +381,49 @@ d3.json('services.json', function(error, graph) {
|
|||||||
function ticked() {
|
function ticked() {
|
||||||
// TODO: Remove these values and pull them out of the height of the boxes
|
// TODO: Remove these values and pull them out of the height of the boxes
|
||||||
// that the constraints belong to.
|
// that the constraints belong to.
|
||||||
r=180
|
r=174
|
||||||
r2=130
|
r2=270
|
||||||
|
|
||||||
link
|
link
|
||||||
.attr('x1', function(d) { return contrain(width, r, d.source.x) + 80; })
|
.attr('x1', function(d) {
|
||||||
.attr('y1', function(d) { return contrain(height, r2, d.source.y) + 24; })
|
let x;
|
||||||
.attr('x2', function(d) { return contrain(width, r, d.target.x) + 80; })
|
svg.selectAll('.node_group').each(function (_, i) {
|
||||||
.attr('y2', function(d) { return contrain(height, r2, d.target.y) + 24; });
|
if (i !== d.source.index) return;
|
||||||
|
x = d3.select(this).node().getBBox().width;
|
||||||
|
});
|
||||||
|
|
||||||
|
return contrain(width, x, d.source.x) + 80;
|
||||||
|
})
|
||||||
|
.attr('y1', function(d) {
|
||||||
|
let y;
|
||||||
|
svg.selectAll('.node_group').each(function (_, i) {
|
||||||
|
if (i !== d.source.index) return;
|
||||||
|
y = d3.select(this).node().getBBox().height;
|
||||||
|
});
|
||||||
|
return contrain(height, y, d.source.y) + 24;
|
||||||
|
})
|
||||||
|
.attr('x2', function(d) {
|
||||||
|
let x;
|
||||||
|
svg.selectAll('.node_group').each(function (_, i) {
|
||||||
|
if (i !== d.target.index) return;
|
||||||
|
x = d3.select(this).node().getBBox().width;
|
||||||
|
});
|
||||||
|
return contrain(width, x, d.target.x) + 80;
|
||||||
|
})
|
||||||
|
.attr('y2', function(d) {
|
||||||
|
let y;
|
||||||
|
svg.selectAll('.node_group').each(function (_, i) {
|
||||||
|
if (i !== d.target.index) return;
|
||||||
|
y = d3.select(this).node().getBBox().height;
|
||||||
|
});
|
||||||
|
return contrain(height, y, d.target.y) + 24;
|
||||||
|
});
|
||||||
|
|
||||||
svg.selectAll('.node_group')
|
svg.selectAll('.node_group')
|
||||||
.attr('transform', function(d) {
|
.attr('transform', function(d) {
|
||||||
return 'translate(' + contrain(width, r, d.x) + ',' + contrain(height, r2, d.y) + ')';
|
let x = d3.select(this).node().getBBox().width;
|
||||||
|
let y = d3.select(this).node().getBBox().height;
|
||||||
|
return 'translate(' + contrain(width, x, d.x) + ',' + contrain(height, y, d.y) + ')';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user