JSFiddle - React, Tailwind, and code Playground

by doraeimo

HTML

<div>drag to rearrange these nodes,then click
    <button onclick="return refresh();">refresh data</button> Some nodes will be replaced.
</div>

CSS

.nodebox {
    fill: #fff;
    stroke: steelblue;
    stroke-width: 3.5px;
}
#node_PHYSICAL .nodebox {
    stroke: beige;
}
#node_PHYSICAL_HARD .nodebox {
    stroke: tan;
}
#node_PHYSICAL_SOFT .nodebox {
    stroke: yellow;
}
#node_BIOTA .nodebox {
    stroke: darkgreen;
}
#node_BIOTA_SPONGES .nodebox {
    stroke: orange;
}
#node_BIOTA_ALGAE .nodebox {
    stroke: green;
}
#node_BIOTA_ALGAE_CANOPY_ECK .nodebox {
    stroke: lightgreen;
}
#node_BIOTA_ALGAE_CRUSTOSE .nodebox {
    stroke: purple;
}
.nodeTitle {
    font: 8px sans-serif;
    font-weight: bold;
}
.nodeText {
    font: 8px sans-serif;
}
.f1Text {
    fill: orange;
    font-weight: bold;
}
.link {
    fill: none;
    stroke: #ccc;
    stroke-width: 3.5px;
}

JavaScript

/*

easy to show system performance and network flow
base on  http://blog.bitjuice.com.au/2013/02/using-d3-js-to-visualise-hierarchical-classification/

features:
1)tree and connectivity(network) are both supported.
2)draggable nodes.
3)able to custom the config and actions

bug fix:
change dom property to class instead of dumplicated id

*/
function graph(d3) {
    //step 0, new graph() ,import "http://d3js.org/d3.v3.min.js" to get d3

    //step 1, custom the config
    this.config = {
        bg_size: {
            width: 800,
            height: 600
        },
        edge_def_width: 5,
        edge_show_arrow: true,
        node_draggable: true,
        show_performance_bar: false,
    }

    var self = this;
    var cluster = d3.layout.cluster().size([self.config.bg_size.height, self.config.bg_size.width - 160]);


    /// step 2, custom the actions
    var showTitleAction;
    var showSubheadAction;
    var showPathDesc;

    this.showTitle = function (f) {
        showTitleAction = f;
    }

    this.showSubhead = function (f) {
        showSubheadAction = f;
    }

    this.showPathDesc = function (f) {
        showPathDesc = f;
    }


    /// final step , bind some data

    this.bind = function (data) {

        /**
        忽略连通图中的回路,产生一棵树。
        这棵树符合cluster.nodes(tree)的调用要求(参见:https://github.com/mbostock/d3/wiki/Cluster-Layout)    
        */
        var conv2tree = function (data) {
            var root = self.getRoot(data);
            var hasParentFlag = {}; //保证每个节点只有一个父节点,以便形成树状结构
            hasParentFlag[root.id] = true; //根节点不允许作为子节点
            self.traverseEdge(data, function (source, target) { //遍历每条边,即所有节点间关系
                if (!hasParentFlag[target.id] && source.id != target.id) { //首次被遍历到的target,作为source的子节点,后续将不被其它节点作为子节点
                    if (!source.children) {
                        source.children = [];
                    }
                    source.children.push(target);
                    hasParentFlag[target.id] =...