2016-04-16 139 views
0

我使用的是基於d3.js的dagre-d3。 我的圖形呈現後,我希望它縮放以適應所有內容,它必須居中。dagre-d3 js放大適合所有內容

正如你看到的,我可以居中好吧,但我似乎無法滿足所有內容我的身高是400

請注意,我想這應該是可用於其他dagre情況的解決方案,例如剛縮放到0.5將適合在這種情況下可能是,但這不是我想要的。

的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)'); 

回答

1

適當的默認規模將是SVG高度的較小比率(或寬度)的變焦容器高度(或寬度) 。簡化一下:

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

更新fiddle

+0

它適用於給定的例子。但看到這裏https://jsfiddle.net/bababalcksheep/xa9rofm5/11/ 我似乎無法使它work.any想法? 我的svg可能有太長或太寬的節點。 – django

+0

一些如何這似乎工作,但我無法理解乘以* wRatio * initialScale https://jsfiddle.net/bababalcksheep/xa9rofm5/12/ 現在的寬度,高度300 SVG測試 '''的JavaScript 變焦的邏輯.translate([(width - bBox.width * wRatio * initialScale)/ 2,padding/2]) .scale(hRatio django