ShadowEditor/test/visual/old/ForceDirectedGraph.js
2019-12-08 19:29:42 +08:00

183 lines
4.7 KiB
JavaScript

import BaseComponent from '../BaseComponent';
/**
* 饼状图
* @author tengge / https://github.com/tengge1
*/
function ForceDirectedGraph() {
BaseComponent.call(this);
this.type = 'ForceDirectedGraph';
this.width = 500;
this.height = 500;
this.title = 'ForceDirectedGraph';
this.transform = null;
}
ForceDirectedGraph.prototype = Object.create(BaseComponent.prototype);
ForceDirectedGraph.prototype.constructor = ForceDirectedGraph;
ForceDirectedGraph.prototype.setTranslate = function (dx, dy) {
var xy = this.transform.split(',');
this.transform = `${parseFloat(xy[0]) + dx},${parseFloat(xy[1]) + dy}`;
this.dom.attr('transform', `translate(${this.transform})`);
};
ForceDirectedGraph.prototype.render = function (parent) {
if (d3.select(`#${this.id}`).size() > 0) {
return;
}
var g = d3.select(parent)
.append('g')
.attr('id', this.id)
.classed('Visual', true)
.classed('ScatterPlot', true)
.style('pointer-events', 'all');
var dataset = {
nodes: [
{ name: "Adam" },
{ name: "Bob" },
{ name: "Carrie" },
{ name: "Donovan" },
{ name: "Edward" },
{ name: "Felicity" },
{ name: "George" },
{ name: "Hannah" },
{ name: "Iris" },
{ name: "Jerry" }
],
links: [
{ source: 0, target: 1 },
{ source: 0, target: 2 },
{ source: 0, target: 3 },
{ source: 0, target: 4 },
{ source: 1, target: 5 },
{ source: 2, target: 5 },
{ source: 2, target: 5 },
{ source: 3, target: 4 },
{ source: 5, target: 8 },
{ source: 5, target: 9 },
{ source: 6, target: 7 },
{ source: 7, target: 8 },
{ source: 8, target: 9 }
]
};
var width = 500;
var height = 500;
var colors = d3.scaleOrdinal(d3.schemeCategory10);
var simulation = d3.forceSimulation(dataset.nodes)
.force('charge', d3.forceManyBody())
.force('link', d3.forceLink(dataset.links))
.force('center', d3.forceCenter(width / 2, height / 2));
var link = g.append('g')
.attr('class', 'links')
.selectAll('line')
.data(dataset.links)
.enter().append('line')
.attr('stroke', '#ccc')
.attr('stroke-width', 1);
var node = g.append('g')
.attr('class', 'nodes')
.selectAll('circle')
.data(dataset.nodes)
.enter().append('circle')
.attr('r', 10)
.attr('fill', function (d, i) {
return colors(i);
})
.call(d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended));
node.append('title')
.text(function (d) { return d.name; });
simulation
.nodes(dataset.nodes)
.on('tick', ticked);
simulation.force('link')
.links(dataset.links);
function ticked() {
link
.attr('x1', function (d) { return d.source.x; })
.attr('y1', function (d) { return d.source.y; })
.attr('x2', function (d) { return d.target.x; })
.attr('y2', function (d) { return d.target.y; });
node
.attr('cx', function (d) { return d.x; })
.attr('cy', function (d) { return d.y; });
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
if (!this.transform) {
var left = (parent.clientWidth - this.width) / 2;
var top = (parent.clientHeight - this.height) / 2;
this.transform = `${left},${top}`;
}
g.attr('transform', `translate(${this.transform})`);
this.dom = g;
};
ForceDirectedGraph.prototype.toJSON = function () {
var transform;
if (this.transform) {
transform = this.transform
.replace('translate(', '')
.replace(')', '');
}
return {
id: this.id,
type: this.type,
title: this.title,
transform
};
};
ForceDirectedGraph.prototype.fromJSON = function (json) {
this.id = json.id;
this.type = json.type;
this.title = json.title;
this.transform = json.transform || null;
};
ForceDirectedGraph.prototype.clear = function () {
this.title = 'ForceDirectedGraph';
this.transform = null;
delete this.dom;
};
export default ForceDirectedGraph;