2016-04-16 12 views
0

Ich verwende dagre-d3, das auf d3.js basiert. Nachdem mein Diagramm gerendert wurde, möchte ich es zoomen, um alle Inhalte anzupassen und es muss zentriert werden.dagre-d3 js Zoom Passend für alle Inhalte

Wie man sehen kann ich es in Ordnung Zentrum kann, aber ich kann nicht alle Inhalte zu passen scheint, als meine Höhe ist 400

Bitte beachten Sie, dass ich eine Lösung will, die für andere dagre Situation verwendbar sein sollten, nur zum Beispiel Skalierung auf 0.5 passt in diesem Fall kann aber das ist nicht was ich will.

JSFIDDLE:https://jsfiddle.net/bababalcksheep/xa9rofm5/8/

CODE:

'use strict'; 
// 
// setup Zoom from example http://bl.ocks.org/mgold/f61420a6f02adb618a70 
// 
var width = 960, 
    height = 400, 
    center = [width/2, height/2]; 
// 
var svg = d3.select('svg'), 
    inner = svg.select('g'); 
// 

var zoom = d3.behavior.zoom() 
    .translate([0, 0]) 
    .scale(1) 
    .size([900, 400]) 
    .scaleExtent([1, 8]) 
    .on('zoom', zoomed); 
// 
svg 
    .call(zoom) // delete this line to disable free zooming 
    .call(zoom.event); 

function zoomed() { 
    inner.attr('transform', 'translate(' + zoom.translate() + ')scale(' + zoom.scale() + ')'); 
} 

function interpolateZoom(translate, scale) { 
    var self = this; 
    return d3.transition().duration(350).tween('zoom', function() { 
    var iTranslate = d3.interpolate(zoom.translate(), translate), 
     iScale = d3.interpolate(zoom.scale(), scale); 
    return function (t) { 
     zoom 
     .scale(iScale(t)) 
     .translate(iTranslate(t)); 
     zoomed(); 
    }; 
    }); 
} 

function zoomClick() { 
    var clicked = d3.event.target, 
    direction = 1, 
    factor = 0.2, 
    target_zoom = 1, 
    center = [width/2, height/2], 
    extent = zoom.scaleExtent(), 
    translate = zoom.translate(), 
    translate0 = [], 
    l = [], 
    view = { 
     x: translate[0], 
     y: translate[1], 
     k: zoom.scale() 
    }; 

    d3.event.preventDefault(); 
    direction = (this.id === 'zoom_in') ? 1 : -1; 
    target_zoom = zoom.scale() * (1 + factor * direction); 

    if (target_zoom < extent[0] || target_zoom > extent[1]) { 
    return false; 
    } 

    translate0 = [(center[0] - view.x)/view.k, (center[1] - view.y)/view.k]; 
    view.k = target_zoom; 
    l = [translate0[0] * view.k + view.x, translate0[1] * view.k + view.y]; 

    view.x += center[0] - l[0]; 
    view.y += center[1] - l[1]; 

    interpolateZoom([view.x, view.y], view.k); 
} 

d3.selectAll('button').on('click', zoomClick); 
// 
// 
// 
// tcp-state-diagram EXAMPLE 
// 
// Create a new directed graph 
var g = new dagreD3.graphlib.Graph().setGraph({}); 

// States and transitions from RFC 793 
var states = ['CLOSED', 'LISTEN', 'SYN RCVD', 'SYN SENT', 
    'ESTAB', 'FINWAIT-1', 'CLOSE WAIT', 'FINWAIT-2', 
    'CLOSING', 'LAST-ACK', 'TIME WAIT' 
]; 

// Automatically label each of the nodes 
states.forEach(function (state) { 
    g.setNode(state, { 
    label: state 
    }); 
}); 

// Set up the edges 
g.setEdge('CLOSED', 'LISTEN', { 
    label: 'open' 
}); 
g.setEdge('LISTEN', 'SYN RCVD', { 
    label: 'rcv SYN' 
}); 
g.setEdge('LISTEN', 'SYN SENT', { 
    label: 'send' 
}); 
g.setEdge('LISTEN', 'CLOSED', { 
    label: 'close' 
}); 
g.setEdge('SYN RCVD', 'FINWAIT-1', { 
    label: 'close' 
}); 
g.setEdge('SYN RCVD', 'ESTAB', { 
    label: 'rcv ACK of SYN' 
}); 
g.setEdge('SYN SENT', 'SYN RCVD', { 
    label: 'rcv SYN' 
}); 
g.setEdge('SYN SENT', 'ESTAB', { 
    label: 'rcv SYN, ACK' 
}); 
g.setEdge('SYN SENT', 'CLOSED', { 
    label: 'close' 
}); 
g.setEdge('ESTAB', 'FINWAIT-1', { 
    label: 'close' 
}); 
g.setEdge('ESTAB', 'CLOSE WAIT', { 
    label: 'rcv FIN' 
}); 
g.setEdge('FINWAIT-1', 'FINWAIT-2', { 
    label: 'rcv ACK of FIN' 
}); 
g.setEdge('FINWAIT-1', 'CLOSING', { 
    label: 'rcv FIN' 
}); 
g.setEdge('CLOSE WAIT', 'LAST-ACK', { 
    label: 'close' 
}); 
g.setEdge('FINWAIT-2', 'TIME WAIT', { 
    label: 'rcv FIN' 
}); 
g.setEdge('CLOSING', 'TIME WAIT', { 
    label: 'rcv ACK of FIN' 
}); 
g.setEdge('LAST-ACK', 'CLOSED', { 
    label: 'rcv ACK of FIN' 
}); 
g.setEdge('TIME WAIT', 'CLOSED', { 
    label: 'timeout=2MSL' 
}); 

// Set some general styles 
g.nodes().forEach(function (v) { 
    var node = g.node(v); 
    node.rx = node.ry = 5; 
}); 

// Add some custom colors based on state 
g.node('CLOSED').style = 'fill: #f77'; 
g.node('ESTAB').style = 'fill: #7f7'; 

// Create the renderer 
var render = new dagreD3.render(); 

// Run the renderer. This is what draws the final graph. 
render(inner, g); 

// Center the graph 
var initialScale = 0.75; 
var _height = svg.attr('height') - g.graph().height; 
var _width = svg.attr('width') - g.graph().width; 
console.log(height/_height); 

zoom.translate([(svg.attr('width') - g.graph().width * initialScale)/2, 10]).scale(1).event(svg); 

//svg.transition().duration(750).call(zoom.translate([0, 0]).scale(1).event); 
//svg.transition().duration(500).attr('transform', 'scale(0.75) translate(0,0)'); 

Antwort

1

die entsprechende Standard-Skala das kleinere Verhältnis der SVG Höhe (oder Breite) den Zoom Behälter Höhe (oder Breite) sein würde, . Vereinfacht ein bisschen:

var padding = 20, 
    bBox = inner.node().getBBox(), 
    hRatio = height/(bBox.height + padding), 
    wRatio = width/(bBox.width + padding); 

zoom.translate([(width - bBox.width * initialScale)/2, padding/2]) 
    .scale(hRatio < wRatio ? hRatio : wRatio) 
    .event(svg); 

Aktualisiert fiddle.

+0

Es funktioniert für ein gegebenes Beispiel. Aber sehen Sie hier https://jsfiddle.net/bababalcksheep/xa9rofm5/11/ Ich kann nicht scheinen, es zu arbeiten. Irgendwelche Ideen? mein Svg kann entweder zu lange oder zu breite Knoten haben. einige – django

+0

, wie dies scheint zu funktionieren, aber ich kann nicht verstehen, Logik der Multiplikation * wRatio * initialScale https://jsfiddle.net/bababalcksheep/xa9rofm5/12/ jetzt svg mit Breite, Höhe 300 für Prüfung '' 'Javascript Zoom .translate ([(width - bBox.width * wRatio * initialScale)/2, Auffüllen/2]) .scale (hRatio django