0

我正在尝试使用 d3.js 渲染树图(我很新)。所以我不知道如何使从下到上的方向。我在这里参考了这个例子

我还希望每个节点单击节点属性都会显示(单击函数调用)。

有人可以启发我吗?谢谢

到目前为止,这是我的代码。

var orientation = {
"": {
       size: [width, height],
       x: function(node) { return node.x; },
       y: function(node) { return height - node.y; }
    }, 
};

var data = (function () {
   var jason = null;
   $.ajax({
      'async': false,
      'global': false,
      'url': "/../GMGR_restructure/json/tree6.json",
      'dataType': "json",
      'success': function (data) {
        jason = data;
      }
    });
   return jason;
})(); 


var realWidth = window.innerWidth;
var realHeight = window.innerHeight;
var margin = {top: 140, right: 10, bottom: 140, left: 10},
m = [0, 1000, 0, 100],     
width = 1500 - margin.left - margin.right,
height = 1000 - margin.top - margin.bottom
h = realHeight -m[0] -m[2],
rectW = 200;
rectH = 30;
w = realWidth -m[0] -m[0];  

var customNodes = new Array(),
    tmpNodes,
    label_w = 70,
    branch_w = 70,
    layer_wider_label = new Array(),
    depencencyChart;



function graph2() {
var ms = document.getElementById('maxStep').value;

    tmpNodes = d3.layout.tree().size([600, 1000]).nodes(data);//.on("click", click);
//Create a svg canvas
    depencencyChart = d3.select("#graphDiv").append("svg:svg")
        .data(d3.entries(orientation))
        .attr("width", 2000)
        .attr("height", 1000)
        .append("svg:g")
        .attr("class","drawarea")
        .attr("transform", "translate(80, 80)") // shift everything to the right
        //.on("click", click);  
 var fakeTxtBox = depencencyChart.append("svg:text")
        .attr("id", "fakeTXT")
        .attr("text-anchor", "right")
        .text(data.name + "(" + data.gid + ")");
        //.on("click", click);
layer_wider_label[0] = fakeTxtBox.node().getComputedTextLength();
depencencyChart.select("#fakeTXT").remove();
data.y = getNodeY(data.id);
data.x = 0;

data.depth = parseInt(data.layer);
customNodes.push(data);//.on("click", click);   
prepareNodes(data.children);//.on("click", click(data));
//align nodes.
updateNodesXOffset()

if(ms==""||ms==" "||ms=="All")
    drawChart2();
else
    drawChart(ms);

d3.select("g")
    .call(d3.behavior.zoom()
          .scaleExtent([0.1,5])
          .on("zoom", zoom));
}

function updateNodesXOffset(){
    var x_offsets = new Array();
    x_offsets[0] = 0;
    customNodes.forEach(function(node) {
        node.x = 0;
        if (node.layer > 0) {
            node.x = x_offsets[node.layer - 1] + layer_wider_label[node.layer - 1] +       branch_w;
            x_offsets[node.layer] = node.x;
        }
    });
}

function getNodeY(id) {
    var ret = 0;
    tmpNodes.some(function(node) {
        if (node.id === id) {
            //return x:d3.tree has a vertical layout by default.
            ret = node.x;
            return;
        } 
    })
    return ret;
}

function prepareNodes(nodes) {
    nodes.forEach(function(node) {

        prepareNode(node);
    if (node.children) {
        prepareNodes(node.children);
    }
});
}

function prepareNode(node) {
node.y = getNodeY(node.id);
    //.on("click", click);
//fake element to calculate labels area width.
var fakeTxtBox = depencencyChart.append("svg:text")
        .attr("id", "fakeTXT")
        .attr("text-anchor", "right")
        .text(node.name + " : " + node.gid)
        //.on("click", click(node));
var this_label_w = fakeTxtBox.node().getComputedTextLength();
depencencyChart.select("#fakeTXT").remove();
if (layer_wider_label[node.layer] == null) {
    layer_wider_label[node.layer] = this_label_w;
} else {
    if (this_label_w > layer_wider_label[node.layer]) {
        layer_wider_label[node.layer] = this_label_w;
    }
}

    //x will be set
    node.depth = parseInt(node.layer);
    customNodes.push(node);
    //node.on("click", click(node));
}


function customSpline(d) {
  var p = new Array();
  p[0] = d.source.x + "," + d.source.y;
  p[3] = d.target.x + "," + d.target.y;
  var m = (d.source.x + d.target.x) / 2
  p[1] = m + "," + d.source.y;
  p[2] = m + "," + d.target.y;
  //This is to change the points where the spline is anchored
  //from [source.right,target.left] to [source.top,target.bottom]
  //            var m = (d.source.y + d.target.y)/2
  //            p[1] = d.source.x + "," + m;
  //            p[2] = d.target.x + "," + m;
  return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
}

function drawChart(ms) {
var cnt=0;

  customNodes.forEach(function(node) { //alert(node.layer);
    if(node.depth <= ms){
    cnt++;
    var nodeSVG = depencencyChart.append("svg:g")
            .attr("transform", "translate(" + node.x + "," + node.y + ")")
    //alert(node.depth);        
    if (node.depth > 0) {
        nodeSVG.append("svg:circle")
                .attr("stroke", node.children ? "#3191c1" : "#269926")
                .attr("fill", "#fff")
                .attr("r", 3)

    }
    var txtBox = nodeSVG.append("svg:text")
            .on("click", click)
            .attr("class", "name")
            .attr("dx", 8)
            .attr("dy", 4)
            //.attr("fill", node.current ? "#ffffff" : node.children ? "#226586" : "#269926")
            .attr("fill", node.current ? "#ffffff" : node.children ? "#ffffff" : "#ffffff")
            .text(node.name)

            //.text(node.name + " \n (" + node.gid + ") ")
            //.attr("dx", 8)
            //.attr("dy", 8)
            //.text(node.gid)

            var txtW = txtBox.node().getComputedTextLength();
            nodeSVG.insert("rect", "text")
                .attr("fill", node.children ? "#3191c1" : "#3191c1")
                .attr("stroke", "black")
                .attr("width", txtW + 8)
                .attr("height", "20")
                .attr("y", "-12")
                .attr("x", "5")
                .attr("rx", 4)
                .attr("ry", 4)

            //.on("click", click(node))

    if (node.current) {
        nodeSVG.insert("rect", "text")
                .attr("fill", node.children ? "#FF4D4D" : "#269926")
                .attr("width", txtW + 8)
                .attr("height", "20")
                .attr("y", "-12")
                .attr("x", "5")
                .attr("rx", 4)
                .attr("ry", 4)
    }
    //if(cnt <= ms){
    if (node.children) {
        node.x = node.x + txtW + 20;
        //prepare links;
        var links = new Array();
        node.children.forEach(function(child) {
            var st = new Object();
            st.source = node;
//                        st.parent = node;
            st.target = child;
            st.warning = child.warning;
            links.push(st);
        })
        //.on("click", click(node));


        //draw links (under nodes)
        depencencyChart.selectAll("pathlink")
                .data(links)
                .enter().insert("svg:path", "g")
                .attr("class", function(d) {
            return d.warning === "true" ? "link warning" : "link"
        })
                .attr("d", customSpline)


        //draw a node at the end of the link
        nodeSVG.append("svg:circle")
                .attr("stroke", "#3191c1")
                .attr("fill", "#fff")
                .attr("r", 5.5)
                //.on("click", click(node))
                .attr("transform", "translate(" + (txtW + 20) + ",0)");
    //}
    }
    //node.on("click", click(node));

    }

});

d3.select("svg")
    .call(d3.behavior.zoom()
          .scaleExtent([0.5, 10])
          .on("zoom", zoom));
    //update(data);
}

function drawChart2() {
var cnt=0;
customNodes.forEach(function(node) {
    //if(node.depth <= ms){
    cnt++;
    var nodeSVG = depencencyChart.append("svg:g")
            .attr("transform", "translate(" + node.x + "," + node.y + ")")
    //alert(node.depth);        
    if (node.depth > 0) {
        nodeSVG.append("svg:circle")
                .attr("stroke", node.children ? "#3191c1" : "#269926")
                .attr("fill", "#fff")
                .attr("r", 3)
                //.attr("x",(node.x-5))
                //.attr("y",(node.y-8))


    }
    var txtBox = nodeSVG.append("svg:text")
            //.on("click", click(node))
            .attr("class", "name")
            .attr("dx", 8)
            .attr("dy", 4)
            //.attr("fill", node.current ? "#ffffff" : node.children ? "#226586" : "#269926")
            .attr("fill", node.current ? "#ffffff" : node.children ? "#ffffff" : "#ffffff")
            .text(node.name)
            /*.html(function(node){
              var str=node.name;
              if(str.length>10){
                    var txt1=str.slice(0,10);
                txt1+="<br/>";
                txt2=str.slice(10,str.length);
                return txt1+txt2;
               }
              return node.name;
            });*/
            //.text(node.name + " \n (" + node.gid + ") ")
            //.attr("dx", 8)
            //.attr("dy", 8)
            //.text(node.gid)

            var txtW = txtBox.node().getComputedTextLength();
            nodeSVG.insert("rect", "text")
                .attr("fill", node.children ? "#3191c1" : "#3191c1")
                .attr("stroke", "black")
                .attr("width", txtW + 8)
                .attr("height", "20")
                .attr("y", "-12")
                .attr("x", "5")
                .attr("rx", 4)
                .attr("ry", 4)

            //.on("click", click(node))

    if (node.current) {
        nodeSVG.insert("rect", "text")
                .attr("fill", node.children ? "#FF4D4D" : "#269926")
                .attr("width", txtW + 8)
                .attr("height", "20")
                .attr("y", "-12")
                .attr("x", "5")
                .attr("rx", 4)
                .attr("ry", 4)
    }
    //if(cnt <= ms){
    if (node.children) {
        node.x = node.x + txtW + 20;
        //prepare links;
        var links = new Array();
        node.children.forEach(function(child) {
            var st = new Object();
            st.source = node;
//                        st.parent = node;
            st.target = child;
            st.warning = child.warning;
            links.push(st);
        })
        //.on("click", click(node));


        //draw links (under nodes)
        depencencyChart.selectAll("pathlink")
                .data(links)
                .enter().insert("svg:path", "g")
                .attr("class", function(d) {
            return d.warning === "true" ? "link warning" : "link"
        })
                .attr("d", customSpline)


        //draw a node at the end of the link
        nodeSVG.append("svg:circle")
                .attr("stroke", "#3191c1")
                .attr("fill", "#fff")
                .attr("r", 5.5)
                //.on("click", click(node))
                .attr("transform", "translate(" + (txtW + 20) + ",0)");
        //}
    }
    //node.on("click", click(node));

    //}

});

d3.select("svg")
    .call(d3.behavior.zoom()
          .scaleExtent([0.5, 10])
          .on("zoom", zoom));
    //update(data);
}


function zoom() {
    var scale = d3.event.scale,
    translation = d3.event.translate,
    tbound = -h * scale,
    bbound = h * scale,
    lbound = (-w - m[1]) * scale,
    rbound = (w - m[3]) * scale;
// limit translation to thresholds
translation = [
    Math.max(Math.min(translation[0], rbound), lbound),
    Math.max(Math.min(translation[1], bbound), tbound)
];
d3.select(".drawarea")
    .attr("transform", "translate(" + translation + ")" +
          " scale(" + scale + ")");
}

// 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);
}

/*function click(node) 
  {
    alert(node.name);
    //document.getElementById('gid').innerHTML = "sucess";
    document.getElementById('gid').innerHTML = node.gid;
    document.getElementById('gname').innerHTML = node.name;
    document.getElementById('gmethod').innerHTML = node.method;
    document.getElementById('gmtype').innerHTML = node.methodtype;
    document.getElementById('gdate').innerHTML = node.date;
    document.getElementById('gcountry').innerHTML = node.country;
    document.getElementById('gloc').innerHTML = node.location;
    document.getElementById('gcname').innerHTML = node.cname;
    document.getElementById('gref').innerHTML = node.ref;
    document.getElementById('gpid1').innerHTML = node.gpid1;
    document.getElementById('gpid2').innerHTML = node.gpid2;
    //document.getElementById('try').value = d.name;     
}*/
4

0 回答 0