我正在处理d3.js组织结构图,以下是来自Codepen https://codepen.io/pablojgarea/pen/PPYLLa的示例
如何将曲线更改为直线。我从下面尝试了许多可能性,因此链接没有帮助。
D3 js - is it possible to draw straight lines between tree nodes?
function getParameterByName(name){ name = name.replace(/ [[] /,“ \ [”)。replace(/ []] /,“ \]”); var regex = new RegExp(“ [\?&]” +名称+“ =([^&#] *)”), 结果= regex.exec(location.search); 返回结果=== null? “”:decodeURIComponent(结果1。replace(/ + / g,“”)); }
function generarImagen() {
var html = d3.select("svg")
.attr("title", "test")
.attr("version", 1.1)
.attr("xmlns", "http://www.w3.org/2000/svg")
.node().parentNode.innerHTML;
$(".preview").html("<img src=data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(html))) + ">");
}
function collapse(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
}
}
/* $(".node .texto .cuadro-nodo-texto i.fa.fa-info-circle").unbind("click").on("click", function(e){
var cuadroEnlaces=$(this).closest("g").parent().find(".cuadro-nodo-enlaces");
if(cuadroEnlaces.is(':visible')){
cuadroEnlaces.hide()
}else{
cuadroEnlaces.show()
}
//e.preventDefault();
e.stopPropagation();
//console.log("enlace");
});*/
}
function getDepth(obj) {
var depth = 0;
if (obj.children) {
obj.children.forEach(function(d) {
var tmpDepth = getDepth(d)
if (tmpDepth > depth) {
depth = tmpDepth
}
})
}
return 1 + depth
}
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.2, // ems
x = text.attr("x"),
y = text.attr("y"),
dy = text.attr("dy") ? text.attr("dy") : 0;
tspan = text.text(null).append("tspan").attr("x", x).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
var centradox = x + (width - tspan.node().getComputedTextLength()) / 2;
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", x).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
var _queryTreeSort = function(options) {
var cfi, e, i, id, o, pid, rfi, ri, thisid, _i, _j, _len, _len1, _ref, _ref1;
id = options.id || "id";
pid = options.parentid || "parentid";
ri = [];
rfi = {};
cfi = {};
o = [];
_ref = options.q;
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
e = _ref[i];
rfi[e[id]] = i;
if (cfi[e[pid]] == null) {
cfi[e[pid]] = [];
}
cfi[e[pid]].push(options.q[i][id]);
}
_ref1 = options.q;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
e = _ref1[_j];
if (rfi[e[pid]] == null) {
ri.push(e[id]);
}
}
while (ri.length) {
thisid = ri.splice(0, 1);
o.push(options.q[rfi[thisid]]);
if (cfi[thisid] != null) {
ri = cfi[thisid].concat(ri);
}
}
return o;
};
var _makeTree = function(options) {
var children, e, id, o, pid, temp, _i, _len, _ref;
id = options.id || "id";
pid = options.parentid || "parentid";
children = options.children || "children";
temp = {};
o = [];
_ref = options.q;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
e = _ref[_i];
e[children] = [];
temp[e[id]] = e;
if (temp[e[pid]] != null) {
temp[e[pid]][children].push(e);
} else {
o.push(e);
}
}
return o;
};
var _renderTree = function(tree) {
var e, html, _i, _len;
html = "<ul class='sections'>";
for (_i = 0, _len = tree.length; _i < _len; _i++) {
e = tree[_i];
html += "<li class='department'><a href=''><span>" + e.name + "</span></a>";
if (e.children != null) {
html += _renderTree(e.children);
}
html += "</li>";
}
html += "</ul>";
return html;
};
$(document).ready(function() {
var id_padre = getParameterByName('organigrama_id_padre');
if (id_padre == '') {
id_padre = 1;
}
var indiceNodo = 0;
resultado = _queryTreeSort({
q: orgJSON
});
// $('#arbol_resultado').html(JSON.stringify(sqlquery, true, 2));
var treeBD;
treeBD = _makeTree({
q: resultado
});
var html_arbol = _renderTree(treeBD);
// $('#arbol_ordenado').html(JSON.stringify(treeBD, true, 2));
var margin = {
top: 20,
right: 30,
bottom: 20,
left: 30
},
width = $(".org-chart.cf").width() - margin.right - margin.left,
height = 1200 - margin.top - margin.bottom;
var i = 0,
duration = 750,
root;
var tree = d3.layout.tree()
.size([width, height])
.separation(function separation(a, b) {
return (a.parent == b.parent ? 1 : 2) * a.depth;
});
var diagonal = d3.svg.diagonal()
.projection(function(d) {
return [d.x, d.y];
});
var svg = d3.select(".org-chart").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
//.attr("viewbox", "0 0 500 500")
.call(zm = d3.behavior.zoom().scaleExtent([0.5, 3]).on("zoom", redraw))
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.style("text-rendering", "optimizeLegibility")
.style("shape-rendering", "default");
var slider = d3.select(".sliderZoom").append("p").append("input")
.datum({})
.attr("type", "range")
.attr("value", 1)
.attr("min", zm.scaleExtent()[0])
.attr("max", zm.scaleExtent()[1])
.attr("step", (zm.scaleExtent()[1] - zm.scaleExtent()[0]) / 100)
.on("input", slided);
function slided(d) {
zm.scale(d3.select(this).property("value"))
.event(svg);
}
zm.translate([margin.left, margin.top]);
var flare = treeBD[0];
root = flare;
root.x0 = width / 2;
root.y0 = 0;
var num_nodo = 0;
/*
function getIndiceHijo(nodo){
var padre=
}*/
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
var profundidadArbol = getDepth(root);
//var hijosPares = (source._children != null) ? 1 - (source._children.length % 2) : 0;
//var numeroHijos = 0;
var profundidadActual = source.depth;
// Normalize for fixed-depth.
var indice = 0;
var niveles = [];
for (n = 0; n < profundidadArbol; n++) {
niveles[n] = 0;
}
nodes.forEach(function(d, i) {
//var index = d3.select(this).indexOf(d3.select(this.parentNode).datum());
//var hijosPares=(d._children != null) ? (1-d._children.length) % 2 : 0;
//console.log("update");
/* indice=i-numeroHijos;
if (d.depth > profundidadActual) {
numeroHijos=(d._children != null) ? d._children.length : 0;
}*/
niveles[d.depth] = niveles[d.depth] + 1;
indice = niveles[d.depth];
//console.log(d.name+":"+d.depth+":"+i+":"+indice);
if (d.depth > 1) {
d.y = d.depth * 200;
if (d.parent.children.length > 2) {
d.y += (indice % 2) * 75;
}
} else if (d.depth == 1) { //primer nivel, menos separación
d.y = d.depth * 100;
if (d.parent.children.length > 2) {
d.y += (indice % 2) * 75;
}
} else {
d.y = 0;
}
});
// Update the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function(d, i) {
return d.id || (d.id = ++i);
});
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter();
var grupoNodo = nodeEnter.append("g")
.attr("class", "node")
.attr("id", function(d) {
return d.id
})
.attr("transform", function(d, i) {
return "translate(" + source.x0 + "," + source.y0 + ")";
})
.on("mouseover", mouseover)
.on("mouseout", mouseout)
//.call(drag);
;
var grupoTexto = grupoNodo.append("g")
.attr("class", "texto");
grupoTexto.append("circle")
.attr("r", 1e-6)
.on("click", click)
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "lightgrey";
});
/* var cuadroTexto = grupoTexto.append('foreignObject');
cuadroTexto.attr('dx', function(d) { return 2*d.name.length} )
.attr('y', function(d) { return d.children || d._children ? 0 : 100; })
.on("click", click)
.html(function(d,i) {
var cuadroNodoEnlaces = '<div class="cuadro-nodo-enlaces"><div class="enlaces-nodo">'
+'<a title="Ver en directorio" href="/directorio?id='+d.id+'"><i class="fa fa-list-alt"></i></a>'
+'<a title="Ver Organigrama" href="<?php echo $_SERVER['REQUEST_URI']; ?>&organigrama_id_padre='+d.id+'"><i class="fa fa-sitemap"></i></a>'
+'</div></div>';
var cuadroNodo = '<div class="cuadro-nodo-texto">'
+cuadroNodoEnlaces
+'<div class="texto-nodo">'
+d.name
+'</div></div>';
return cuadroNodo;
});*/
//si tiene hijos
grupoTexto.append('rect')
.on("click", click)
.attr("x", "-75px")
.attr("y", "20")
.attr("rx", 4)
.attr("ry", 4)
.attr("width", 150)
.attr("height", 50)
.attr("fill", "#fff")
.attr("class", "rectangulo-hijos")
.style("stroke", "#777")
//.attr("transform", "rotate(-2)")
.style("stroke-width", function(d) {
var hijos = 0;
if (d._children != null) {
hijos = d._children.length;
}
return (hijos <= 0) ? "0px" : "0.2px";
});
grupoTexto.append('rect')
.on("click", click)
.attr("x", "-75px")
.attr("y", "20")
.attr("rx", 4)
.attr("ry", 4)
.attr("width", 150)
.attr("height", 50)
.attr("fill", "#fff")
.attr("class", "rectangulo-hijos2")
.style("stroke", "#777")
//.attr("transform", "rotate(2)")
.style("stroke-width", function(d) {
var hijos = 0;
if (d._children != null) {
hijos = d._children.length;
}
return (hijos <= 0) ? "0px" : "0.2px";
});
//Dibujamos el cuadro con la barra de enlaces y con el texto de cada departamento
grupoTexto.append('rect')
.attr("class", "barra-enlaces")
.attr("x", "-75px")
.attr("y", "0")
.attr("width", 150)
.attr("height", 20)
.attr("fill", "#247497")
.attr("stroke", "#ccc")
.attr("stroke-width", "0.2px");
grupoTexto.append('a')
.attr("x", "-50px")
.attr("y", "10")
.attr("xlink:href", function(d) {
return '/directorio?id=' + d.id;
})
.attr("xlink:title", "Ver directorio")
.attr("fill", "white")
.attr("height", 20)
.attr("width", 150)
.attr("font-size", 12)
.append('text')
.attr("font-family", "FontAwesome")
.attr("x", "40px")
.attr("y", "15")
.text('\uf095');
grupoTexto.append('a')
.attr("x", "25px")
.attr("y", "10")
.attr("xlink:href", function(d) {
return window.location.href + "&organigrama_id_padre=" + d.id;
})
.attr("xlink:title", "Ver organigrama")
.attr("fill", "white")
.attr("height", 20)
.attr("width", 150)
.attr("font-size", 12)
.append('text')
.attr("font-family", "FontAwesome")
.attr("x", "55px")
.attr("y", "15")
.text('\uf0e8');
grupoTexto.append('rect')
.on("click", click)
.attr("x", "-75px")
.attr("y", "20")
.attr("rx", 4)
.attr("ry", 4)
.attr("width", 150)
.attr("height", 50)
.attr("fill", "white")
.classed("rectangulo-texto", true)
.attr("stroke", "#777")
.attr("stroke-width", "0.2px");
grupoTexto.append('text')
.on("click", click)
.text(function(d, i) {
return d.name;
})
.attr("x", "0")
.attr("text-anchor", "middle")
.attr("y", "33")
.attr("font-size", 11)
.attr("fill", "#555")
.call(wrap, 140);
var grupoEnlaces = grupoNodo.append("g").attr("class", "nodo-enlaces");
/* grupoEnlaces.append('foreignObject')
.attr('dx', function(d) { return 2*d.name.length} )
.attr('y', function(d) { return d.children || d._children ? 0 : 100; })
.html(function(d,i) {
var cuadroNodo = '<div class="cuadro-nodo-enlaces"><div class="enlaces-nodo">'
+'<a href="/directorio?id='+d.id+'"><i class="fa fa-list-alt"></i></a>'
+'<a href="<?php echo $_SERVER['REQUEST_URI']; ?>&organigrama_id_padre='+d.id+'"><i class="fa fa-sitemap"></i></a>'
+'</div></div>';
return cuadroNodo;
});*/
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
nodeUpdate.select("circle")
.attr("r", 4.5)
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "lightgrey";
});
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.x + "," + source.y + ")";
})
.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;
});
actualizarEventos();
//d3.selectAll(".node").call(drag);
/*var delay=2000; //1 seconds
setTimeout(function(){
generarImagen();
}, delay); */
} //fin update
// 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;
}
/* var nodo = d3.select(this.parentNode.parentNode);
activo = nodo.attr("activo");
if (activo == 1){
//nodo.moveToBack();
nodo.attr("activo",0);
nodo.attr("class","noactivo");
//d3.select(this.parentNode).select("rect").style("fill","#0079c2");
}else{
//nodo.moveToFront();
nodo.attr("activo",1);
nodo.attr("class","activo");
//d3.select(this.parentNode).select("rect").style("fill","#229be4");
}
*/
update(d);
}
d3.selection.prototype.moveToFront = function() {
return this.each(function() {
//this.parentNode.appendChild(this);
// this.parentNode.replaceChild(this, this)
});
};
d3.selection.prototype.moveToBack = function() {
return this.each(function() {
var firstChild = this.parentNode.firstChild;
if (firstChild) {
// this.remove();
//this.parentNode.insertBefore(this, firstChild);
}
});
};
function redraw(d) {
$(".sliderZoom input").val(d3.event.scale);
/* $( ".texto-nodo" ).each(function() {
var width = $( this ).outerWidth();
var maximo = parseInt($(this).css("max-width"));
var minimo = parseInt($(this).css("min-width"));
if(minimo > width) width=minimo;
var marginLeft = width / 2;
if(maximo < (width + marginLeft)){
width=maximo;
}else{
width = width + marginLeft;
}
marginLeft = width / 2;
// set css
//$(this).css('margin-left', -marginLeft).css("width", width);
var position = $(this).offset().top;
if (position < 180){
$(this).parent().css("opacity",0);
}else{
$(this).parent().css("opacity",1)
}
});
*/
/* var delay=2000; //1 seconds
setTimeout(function(){
generarImagen();
}, delay); */
var escala = 1;
var d3scale = d3.event.scale;
escala = (d3scale > 1) ? (1.1 / d3scale) : 0.8;
if (d3scale == 1) escala = 1;
d3.selectAll(".texto").attr("transform", "scale(" + escala + ")");
//console.log("here", d3.event.translate, d3.event.scale);
svg.attr("transform",
"translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
}
// Initialize the display to show a few nodes.
// root.children.forEach(toggleAll);
root.children.forEach(collapse);
update(root);
d3.select(self.frameElement).style("height", "600px").style("width", width);
/* $(".cuadro-nodo-enlaces a").on("click", function(e){
window.location = $(this).attr('href');
//e.preventDefault();
e.stopPropagation();
console.log("enlace");
});*/
/* $(".node .texto .cuadro-nodo-texto i.fa-info-circle").on("click", function(e){
var cuadroEnlaces=$(this).closest("g").parent().find(".cuadro-nodo-enlaces");
if(cuadroEnlaces.is(':visible')){
cuadroEnlaces.hide()
}else{
cuadroEnlaces.show()
}
e.stopPropagation();
console.log("enlace2");
});*/
//d3.selectAll(".node").call(drag);
});