This commit is contained in:
Aleksey Chichenkov 2018-12-10 11:04:43 +03:00
parent e9d3bb0b61
commit 776e9acd03
10 changed files with 1214 additions and 6 deletions

View File

@ -5,6 +5,9 @@
"recurseDepth": 10,
"source": {
"include": ["docfiles"],
"include_2": ["../develop/first/gui/js/providers"],
"include_3": ["../develop/first/gui/js"],
"core": ["../develop/first/core"],
"includePattern": ".+\\.js(doc|x)?$",
"excludePattern": "(^|\\/|\\\\)_"
},

View File

@ -23,6 +23,11 @@
/**
* ### Содержание:
* - #### [Архитектура](./arch.html)
* - #### [Наследование](./inheritance.html)
* - #### [Наследование GUI(деревом)](./gui_tree.html)
* - #### [Наследование GUI(графом)](./gui_graph.html)
* - #### [Наследование CORE(деревом)](./core_tree.html)
* - #### [Наследование CORE(графом)](./core_graph.html)
* - #### Виджеты
* - #### Датасорсы
* - #### Сигнал-Слоты

View File

@ -1,5 +1,4 @@
'use strict';
var doop = require('jsdoc/util/doop');
var env = require('jsdoc/env');
var fs = require('jsdoc/fs');
@ -19,7 +18,14 @@ var replace_enters_to_br = pct.replace_enters_to_br;
var resolveAuthorLinks = helper.resolveAuthorLinks;
var hasOwnProp = Object.prototype.hasOwnProperty;
var sih = require("./search_inheritance.js");
var inh_struct = sih.find(env.conf);
var sih2 = require("./search_inheritance2.js");
var inh_struct2 = sih2.find(env.conf);
var sih_core = require("./search_inheritance_core.js");
var inh_struct_core = sih_core.find(env.conf);
var data;
@ -919,6 +925,61 @@ exports.publish = function(taffyData, opts, tutorials) {
fs.writeFileSync(outdir + "/arch.html", html, 'utf8');
// providers tree
var html = view.render('inheritance.tmpl', {
inheritance: inh_struct,
env: env,
title: "",
});
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a>
// fs.createFileSync("/arch.html", html, 'utf8');
fs.writeFileSync(outdir + "/inheritance.html", html, 'utf8');
// gui tree
html = view.render('inheritance2.tmpl', {
inheritance: inh_struct2,
height: 15100,
env: env,
title: "",
});
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a>
// fs.createFileSync("/arch.html", html, 'utf8');
fs.writeFileSync(outdir + "/gui_tree.html", html, 'utf8');
// gui graph
html = view.render('inheritance3.tmpl', {
inheritance: inh_struct2,
height: 1600,
env: env,
title: "",
});
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a>
// fs.createFileSync("/arch.html", html, 'utf8');
fs.writeFileSync(outdir + "/gui_graph.html", html, 'utf8');
// core tree
html = view.render('inheritance2.tmpl', {
inheritance: inh_struct_core,
height: 10000,
env: env,
title: "",
});
html = helper.resolveLinks(html);
fs.writeFileSync(outdir + "/core_tree.html", html, 'utf8');
// core graph
html = view.render('inheritance3.tmpl', {
inheritance: inh_struct_core,
height: 800,
env: env,
title: "",
});
html = helper.resolveLinks(html);
fs.writeFileSync(outdir + "/core_graph.html", html, 'utf8');
// set up the lists that we'll use to generate pages
classes = taffy(members.classes);
modules = taffy(members.modules);

View File

@ -0,0 +1,175 @@
/**
* Created by Aleksey Chichenkov <a.chichenkov@initi.ru> on 12/6/18.
*/
var fs = require("fs");
var path = require('jsdoc/path');
var rx_class_declarator_std = /var *(.*?)(?:| )=(?:| ) std.class\(\[(.*?)\]/im;
var rx_requires = /var {1,}?(.*?) {1,}?= {1,}?require\("(.*?)"\)/i;
var __tree_list = Object.create(null);
var __root;
var map = {};
var destination;
var find = function (_conf) {
__root = new Node();
// console.log("start find");
destination = path.normalize(_conf.source.include_2[0]);
recursive(destination);
generate_tree();
return __root.get_struct();
};
var recursive = function(_path){
if(fs.lstatSync(_path).isDirectory()) {
// console.log("DIRECTORY: ",_path);
var arr = fs.readdirSync(_path);
for (var a = 0; a < arr.length; a++) {
var name = arr[a];
recursive(_path + "/" + name);
}
} else {
// console.log("FILE: ", _path);
parse_file(_path);
}
};
var parse_file = function(_path){
let info = Object.create(null);
info.requires = Object.create(null);
info.classes = Object.create(null);
var file = fs.readFileSync(_path, "utf8");
var requires = exec_all(rx_requires, file);
if(requires.length > 0) {
for(var a = 0; a < requires.length; a++){
info.requires[requires[a].subs[0]] = update_link_file(requires[a].subs[1])
}
}
var classes = exec_all(rx_class_declarator_std, file);
if(classes.length > 0) {
for(var a = 0; a < classes.length; a++){
info.classes[classes[a].subs[0]] = classes[a].subs[1]
}
}
map[_path] = info;
};
var exec_all = function(_rx, _string){
var out = [];
var result;
while(result = _string.match(_rx)){
result = convert_result(result);
// console.log("result", result);
_string = _string.substring(result.index + result.match.length, _string.length);
out.push(result);
}
return out
};
var convert_result = function(_exec_result) {
var info = Object.create(null);
info.index = _exec_result.index;
info.match = _exec_result[0];
info.subs = [];
for (var a = 1; a < _exec_result.length; a++) {
info.subs.push(_exec_result[a]);
}
return info;
};
var update_link_file = function (_path) {
var arr = destination.split("/");
arr.pop();
return arr.join("/") + "/" + _path + ".js"
};
var generate_tree = function() {
__root.name = "std.base";
for (var path in map) {
var file_info = map[path];
recursive_tree(path, file_info);
}
for(var name in __tree_list){
var n = __tree_list[name];
if(n.inherit === "base_class"){
__root.children.push(n);
}
}
};
var recursive_tree = function (_file_name, _file_info, _child) {
if(!_file_info){
console.log("ERROR: ", _file_name);
return;
}
var classes = _file_info.classes;
var requires = _file_info.requires;
for(var name in classes){
var path = _file_name + ":" + name;
var node = __tree_list[path];
if(!node){
node = new Node();
if(name == "data"){
// console.log(_file_name);
}
node.name = name;
__tree_list[path] = node;
}
var inheritance = classes[name];
var req = requires[inheritance];
if(req){
if(_child && node.children.indexOf(_child) === -1){
_child.inherit = name;
node.children.push(_child);
}
var fi = map[req];
recursive_tree(req, fi, node);
}
}
};
var Node = function(){
this.children = [];
this.name = "";
this.inherit = "base_class";
};
Node.prototype = {
get_struct: function () {
var children = [];
for(var a = 0; a < this.children.length; a++){
children.push(this.children[a].get_struct());
}
return {
name: this.name,
children: children
}
}
};
module.exports.find = find;

View File

@ -0,0 +1,194 @@
/**
* Created by Aleksey Chichenkov <a.chichenkov@initi.ru> on 12/6/18.
*/
var fs = require("fs");
var path = require('jsdoc/path');
var rx_class_declarator_std = /var {1,}?(.*?) {1,}?= {1,}?(.*?)\.inherit\(\{/i;
var rx_requires = /var {1,}?(.*?) {1,}?= {1,}?require\("(.*?)"\)/i;
var __tree_list = Object.create(null);
var __root;
var map = {};
var destination;
var find = function (_conf) {
__root = new Node();
// console.log("start find");
destination = path.normalize(_conf.source.include_3[0]);
// console.log("=================");
// console.log("===== START =====");
// console.log("=================");
// console.log("=================");
// console.log("====== END ======");
// console.log("=================");
recursive(destination);
// console.log("=================================================");
// console.log("var map = JSON.parse('%s');", JSON.stringify(map));
// console.log("=================================================");
generate_tree();
// console.log("=================================================");
// console.log("JSON.parse('%s');", JSON.stringify(__tree_list));
// console.log("=================================================");
return __root.get_struct();
};
var recursive = function(_path){
if(fs.lstatSync(_path).isDirectory()) {
// console.log("DIRECTORY: ",_path);
var arr = fs.readdirSync(_path);
for (var a = 0; a < arr.length; a++) {
var name = arr[a];
recursive(_path + "/" + name);
}
} else {
// console.log("FILE: ", _path);
parse_file(_path);
}
};
var parse_file = function(_path){
let info = Object.create(null);
info.requires = Object.create(null);
info.classes = Object.create(null);
var file = fs.readFileSync(_path, "utf8");
var requires = exec_all(rx_requires, file);
if(requires.length > 0) {
for(var a = 0; a < requires.length; a++){
info.requires[requires[a].subs[0]] = update_link_file(requires[a].subs[1])
}
}
var classes = exec_all(rx_class_declarator_std, file);
if(classes.length > 0) {
for(var a = 0; a < classes.length; a++){
info.classes[classes[a].subs[0]] = classes[a].subs[1]
}
}
map[_path] = info;
};
var exec_all = function(_rx, _string){
var out = [];
var result;
while(result = _string.match(_rx)){
result = convert_result(result);
// console.log("result", result);
_string = _string.substring(result.index + result.match.length, _string.length);
out.push(result);
}
return out
};
var convert_result = function(_exec_result) {
var info = Object.create(null);
info.index = _exec_result.index;
info.match = _exec_result[0];
info.subs = [];
for (var a = 1; a < _exec_result.length; a++) {
info.subs.push(_exec_result[a]);
}
return info;
};
var update_link_file = function (_path) {
var arr = destination.split("/");
// arr.pop();
return arr.join("/") + "/" + _path + ".js"
};
var generate_tree = function() {
__root.name = "BaseClass";
for (var path in map) {
var file_info = map[path];
recursive_tree(path, file_info);
}
for(var name in __tree_list){
var n = __tree_list[name];
if(n.inherit === "base_class"){
__root.children.push(n);
}
}
};
var recursive_tree = function (_file_name, _file_info, _child) {
if(!_file_info){
// console.log("ERROR: ", _file_name);
return;
}
var classes = _file_info.classes;
var requires = _file_info.requires;
for(var name in classes){
var path = _file_name + ":" + name;
var node = __tree_list[path];
if(!node){
node = new Node();
node.name = name;
__tree_list[path] = node;
}
var inheritance = classes[name];
var req = requires[inheritance];
// console.log("CLASS: %s, REQUIRE: %s", name, req);
if(req){
if(_child && node.children.indexOf(_child) === -1){
_child.inherit = name;
node.children.push(_child);
}
var fi = map[req];
recursive_tree(req, fi, node);
}
}
};
var Node = function(){
this.children = [];
this.name = "";
this.inherit = "base_class";
};
Node.prototype = {
get_struct: function () {
var children = [];
for(var a = 0; a < this.children.length; a++){
children.push(this.children[a].get_struct());
}
return {
name: this.name,
children: children
}
}
};
module.exports.find = find;

View File

@ -0,0 +1,172 @@
/**
* Created by Aleksey Chichenkov <a.chichenkov@initi.ru> on 12/6/18.
*/
var fs = require("fs");
var path = require('jsdoc/path');
var rx_match_modelType = /ModelType {1,}?([A-Za-z]{1,}?)\(@(.*)?\)/i;
var __tree_list = Object.create(null);
var __root;
var map = {
"mObject": ""
};
var destination;
var ignore = {
".git": true
};
var avail_format = {
"xxc": true
};
var find = function (_conf) {
__root = new Node();
destination = path.normalize(_conf.source.core[0]);
recursive(destination);
generate_tree();
return __root.get_struct();
};
var recursive = function(_path){
if(fs.lstatSync(_path).isDirectory()) {
// console.log("DIRECTORY: ",_path);
var arr = fs.readdirSync(_path);
for (var a = 0; a < arr.length; a++) {
var name = arr[a];
if (!ignore[name]) {
recursive(_path + "/" + name);
}
}
} else {
console.log("FILE: ", _path);
var extenstion = _path.split(".").pop();
if (avail_format[extenstion]) {
parse_file(_path);
}
}
};
var parse_file = function(_path){
let info = Object.create(null);
info.requires = Object.create(null);
info.classes = Object.create(null);
var file = fs.readFileSync(_path, "utf8");
var classes = exec_all(rx_match_modelType, file);
if(classes.length > 0) {
for(var a = 0; a < classes.length; a++){
map[classes[a].subs[0]] = classes[a].subs[1];
}
}
};
var exec_all = function(_rx, _string){
var out = [];
var result;
while(result = _string.match(_rx)){
result = convert_result(result);
_string = _string.substring(result.index + result.match.length, _string.length);
out.push(result);
}
return out
};
var convert_result = function(_exec_result) {
var info = Object.create(null);
info.index = _exec_result.index;
info.match = _exec_result[0];
info.subs = [];
for (var a = 1; a < _exec_result.length; a++) {
info.subs.push(_exec_result[a]);
}
return info;
};
var generate_tree = function() {
__root.name = "BaseClass";
for (var type in map) {
var inherit = map[type];
recursive_tree(type, inherit);
}
};
var recursive_tree = function (_type_name, _inherit, _child) {
if(_type_name === "mObject"){
console.log("create mObject");
var n = new Node();
n.name = _type_name;
n.inherit = __root.name;
__root.children.push(n);
__tree_list[_type_name] = n;
return;
}
if(_type_name !== "mObject" && !_type_name){
console.log("ERROR: TYPE %s, INHERIT: %s, ChildName: %s", _type_name, _inherit, _child.name);
process.exit(1);
} else {
console.log("CLASS: %s, INHERIT: %s", _type_name, _inherit);
}
var node = __tree_list[_type_name];
if(!node){
node = new Node();
node.name = _type_name;
__tree_list[_type_name] = node;
if(_child && node.children.indexOf(_child) === -1){
_child.inherit = _type_name;
node.children.push(_child);
}
}
var parent = __tree_list[_inherit];
if(parent){
if(parent.children.indexOf(node) === -1) {
node.inherit = _inherit;
parent.children.push(node);
}
} else {
var inh = map[_inherit];
if(inh) {
recursive_tree(_inherit, inh, node);
} else {
if(__root.children.indexOf(node) === -1) {
__root.children.push(node);
node.inherit = __root.name;
}
}
}
};
var Node = function(){
this.children = [];
this.name = "";
this.inherit = "base_class";
};
Node.prototype = {
get_struct: function () {
var children = [];
for(var a = 0; a < this.children.length; a++){
children.push(this.children[a].get_struct());
}
return {
name: this.name,
children: children
}
}
};
module.exports.find = find;

View File

@ -80,9 +80,6 @@
{
name: "Node",
children: [
{
name: "Children",
},
{
name: "Scheme",
children: [
@ -125,10 +122,15 @@
]
},
{
name: "global_tree",
name: "GlobalTree",
children: [
{
name: "Node"
name: "Node",
children: [
{
name: "Children",
}
]
},
{
name: "NodeTypes",

View File

@ -0,0 +1,182 @@
<?js
var data = obj;
var self = this;
var str = JSON.stringify(inheritance);
?>
<style>
.node {
cursor: pointer;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 3px;
}
.node text {
font: 12px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 2px;
}
</style>
<div class="oa fs" id="arch-scroll" style="max-width: 100%">
<div id="arch-content" class=""></div>
</div>
<!-- load the d3.js library -->
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var as = document.getElementById("arch-scroll");
as.style.height = (screen.availHeight - 143) + "px";
var sstr = '<?js= str ?>';
treeData = [JSON.parse(sstr)];
// ************** Generate the tree diagram *****************
var margin = {top: 20, right: 120, bottom: 20, left: 120},
width = 3260 - margin.right - margin.left,
height = 2100 - margin.top - margin.bottom;
var i = 0,
duration = 350,
root;
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
var svg = d3.select("div#arch-content").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
root = treeData[0];
root.x0 = height / 2;
root.y0 = 0;
update(root);
d3.select(self.frameElement).style("height", "500px");
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 180; });
// Update the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.on("click", click);
nodeEnter.append("circle")
.attr("r", 1e-6)
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
nodeEnter.append("text")
.attr("x", function(d) { return 13; })
.attr("y", function(d) { return -6; })
.attr("dy", ".35em")
.attr("text-anchor", function(d) { return "start" })
.text(function(d) { return d.name; })
.style("fill-opacity", 1e-6);
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
nodeUpdate.select("circle")
.attr("r", 10)
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
nodeUpdate.select("text")
.style("fill-opacity", 1);
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
.remove();
nodeExit.select("circle")
.attr("r", 1e-6);
nodeExit.select("text")
.style("fill-opacity", 1e-6);
// Update the links…
var link = svg.selectAll("path.link")
.data(links, function(d) { return d.target.id; });
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {x: source.x0, y: source.y0};
return diagonal({source: o, target: o});
});
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function(d) {
var o = {x: source.x, y: source.y};
return diagonal({source: o, target: o});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
</script>

View File

@ -0,0 +1,183 @@
<?js
var data = obj;
var self = this;
var str = JSON.stringify(inheritance);
?>
<style>
.node {
cursor: pointer;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 3px;
}
.node text {
font: 12px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 2px;
}
</style>
<div class="oa fs" id="arch-scroll" style="max-width: 100%">
<div id="arch-content" class=""></div>
</div>
<!-- load the d3.js library -->
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var as = document.getElementById("arch-scroll");
as.style.height = (screen.availHeight - 243) + "px";
var sstr = '<?js= str ?>';
var hheight = '<?js= height ?>';
treeData = [JSON.parse(sstr)];
// ************** Generate the tree diagram *****************
var margin = {top: 20, right: 120, bottom: 20, left: 120},
width = 3260 - margin.right - margin.left,
height = hheight - margin.top - margin.bottom;
var i = 0,
duration = 350,
root;
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
var svg = d3.select("div#arch-content").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
root = treeData[0];
root.x0 = height / 2;
root.y0 = 0;
update(root);
d3.select(self.frameElement).style("height", "500px");
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 180; });
// Update the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.on("click", click);
nodeEnter.append("circle")
.attr("r", 1e-6)
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
nodeEnter.append("text")
.attr("x", function(d) { return 13; })
.attr("y", function(d) { return -6; })
.attr("dy", ".35em")
.attr("text-anchor", function(d) { return "start" })
.text(function(d) { return d.name; })
.style("fill-opacity", 1e-6);
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
nodeUpdate.select("circle")
.attr("r", 10)
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
nodeUpdate.select("text")
.style("fill-opacity", 1);
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
.remove();
nodeExit.select("circle")
.attr("r", 1e-6);
nodeExit.select("text")
.style("fill-opacity", 1e-6);
// Update the links…
var link = svg.selectAll("path.link")
.data(links, function(d) { return d.target.id; });
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {x: source.x0, y: source.y0};
return diagonal({source: o, target: o});
});
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function(d) {
var o = {x: source.x, y: source.y};
return diagonal({source: o, target: o});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
</script>

View File

@ -0,0 +1,231 @@
<?js
var data = obj;
var self = this;
var str = JSON.stringify(inheritance);
?>
<style>
.node {
cursor: pointer;
stroke: #3182bd;
stroke-width: 1.5px;
}
.link {
fill: none;
stroke: #9ecae1;
stroke-width: 1.5px;
}
</style>
<div class="oa fs" id="arch-scroll" style="max-width: 100%">
<div id="arch-content" class=""></div>
</div>
<!-- load the d3.js library -->
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var as = document.getElementById("arch-scroll");
as.style.height = (screen.availHeight - 243) + "px";
var sstr = '<?js= str ?>';
var hheight = '<?js= height ?>';
var treeData = [JSON.parse(sstr)];
// ------------
var __updatelinks = function (links) {
for (var a = 0; a < links.length; a++) {
var link = links[a];
var minsize = 2150;
var max = Math.max(link.source.children.length, link.target.children.length);
// link.strange = 2;
}
};
// ************** Generate the tree diagram *****************
var width = 2000,
height = hheight,
root;
var force = d3.layout.force()
.size([width, height])
.on("tick", tick)
.linkDistance(function(link){
var max = Math.sqrt(Math.max(link.source.children.length, link.target.children.length) * 20);
return max < 20 ? 20 : max;
})
.charge(function () {
return -50;
});
var svg = d3.select("#arch-content").append("svg")
.attr("width", width)
.attr("height", height);
var link = svg.selectAll(".link"),
node = svg.selectAll(".node");
root = treeData[0];
update();
function update() {
var nodes = window.nodes = flatten(root);
var links = window.links = d3.layout.tree().links(nodes);
// __updatelinks(links);
// Restart the force layout.
force
.nodes(nodes)
.links(links)
.start();
// Update the links…
link = link.data(links, function(d) { return d.target.id; });
// Exit any old links.
link.exit().remove();
// Enter any new links.
link.enter().insert("line", ".node")
.attr("class", "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; });
// Update the nodes…
node = node.data(nodes, function(d) { return d.id; }).style("fill", color);
// Exit any old nodes.
node.exit().remove();
// Enter any new nodes.
node.enter().append("circle")
.attr("class", "node")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", function(d) {
var size = 4.5;
var res = Math.sqrt(d.children.length * size);
return res < size ? size : res;
})
.style("fill", color)
.on("click", click)
.on("mouseover", handleMouseOver)
.on("mouseout", handleMouseOut)
.call(force.drag);
// node.enter().append("text")
// .attr("dx", function(d){return d.x; })
// .attr("dy", function(d){return d.y; })
// .text(function(d){return d.name});
}
function tick() {
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; });
}
// Color leaf nodes orange, and packages white or blue.
function color(d) {
return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
}
// Toggle children on click.
function click(d) {
if (!d3.event.defaultPrevented) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update();
}
}
var currentNode;
// Create Event Handlers for mouse
function handleMouseOver(d, i) { // Add interactivity
if(currentNode){
currentNode.remove(); // Remove text location
}
// Use D3 to select element, change color and size
d3.select(this).attr({
fill: "orange",
// r: 15
});
// Specify where to put label of text
currentNode = svg.append("text").attr({
id: d.name, // Create an id for text so we can select it later for removing on mouseout
x: function() { return d.x + 10; },
y: function() { return d.y - 15; }
})
.text(d.name);
}
function handleMouseOut(d, i) {
// Use D3 to select element, change color back to normal
d3.select(this).attr({
fill: "black",
r: function(d) {
var size = 4.5;
var res = Math.sqrt(d.children.length * size);
return res < size ? size : res;
}
});
// Select text by id and then remove
currentNode.remove(); // Remove text location
currentNode = null;
}
// Returns a list of all nodes under the root.
function flatten(root) {
var nodes = [], i = 0;
function recurse(node) {
if (node.children) node.children.forEach(recurse);
if (!node.id) node.id = ++i;
nodes.push(node);
}
recurse(root);
return nodes;
}
</script>