D3.js设置初始缩放级别

时间:2013-04-23 20:15:56

标签: javascript d3.js zoom

我设置了几个图表来放大容器,效果很好。但是,在初始加载时,缩放级别太接近了。有没有设置初始缩放级别的方法,以避免必须先缩小?我熟悉.scale()方法,但没有任何运气实现它。这是要走的路还是我缺少的东西?

这是我迄今为止关于缩放的内容:

var margin = {top: 20, right: 120, bottom: 20, left: 120},
    width = 50000 - margin.right - margin.left,
    height = 120000 - margin.top - margin.bottom;

var x = d3.scale.linear()
    .domain([0, width])
    .range([0, width]);

var y = d3.scale.linear()
    .domain([0, height])
    .range([height, 0]);

var tree = d3.layout.tree()
    .size([height, width])
    .separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });

var diagonal = d3.svg.diagonal()
    .projection(function(d) { return [d.x, d.y]; });

function zoom(d) {        
  svg.attr("transform",
      "translate(" + d3.event.translate + ")"+ " scale(" + d3.event.scale + ")");
}

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    .attr("pointer-events", "all")
    .call(d3.behavior.zoom()
        .x(x)
        .y(y)
        .scaleExtent([0,8])
        .on("zoom", zoom))
        .append('g');

svg.append('rect')
    .attr('width', width*5)
    .attr('height', height)
    .attr('border-radius', '20')
    .attr('fill', 'sienna');

6 个答案:

答案 0 :(得分:29)

我终于通过将初始变换和缩放行为设置为相同的值来实现此功能。

var zoom = d3.behavior.zoom().translate([100,50]).scale(.5);

vis = svg.append("svg:svg")
     .attr("width", width)
     .attr("height", height)
     .call(zoom.on("zoom",zooming))
           .append("svg:g")
           .attr("transform","translate(100,50)scale(.5,.5)");  

答案 1 :(得分:25)

  

D3v4回答

如果您在这里寻找相同但使用D3 v4,

var zoom = d3.zoom().on("zoom", zooming);

vis = svg.append("svg:svg")
     .attr("width", width)
     .attr("height", height)
     .call(zoom) // here
     .call(zoom.transform, d3.zoomIdentity.translate(100, 50).scale(0.5))
     .append("svg:g")
     .attr("transform","translate(100,50) scale(.5,.5)");

答案 2 :(得分:15)

如果有人仍然遇到问题,请将此答案添加为已接受答案的附录:

让这个很容易理解的是here

话虽如此,我设置了三个变量:

scale,zoomWidth和zoomHeight

scale是您想要缩放的初始比例,然后是

zoomWidth和zoomHeight定义如下:

zoomWidth = (width-scale*width)/2
zoomHeight = (height-scale*height)/2

其中宽度和高度是" vis"的宽度和高度。 svg元素

然后将上述翻译修改为:

.attr("transform", "translate("+zoomWidth+","+zoomHeight+") scale("+scale+")")

以及缩放功能:

d3.behavior.zoom().translate([zoomWidth,zoomHeight]).scale(scale)

这样做有效地确保在加载可视化文件时对元素进行缩放和居中。

如果这有助于您,请告诉我!欢呼声。

答案 3 :(得分:6)

适用于d3.js v4

这类似于davcs86's answer,但它重用了初始变换并实现了缩放功能。

// Initial transform to apply
var transform = d3.zoomIdentity.translate(200, 0).scale(1);
var zoom = d3.zoom().on("zoom", handleZoom);

var svg = d3.select("body")
  .append('svg')
  .attr('width', 800)
  .attr('height', 300)
  .style("background", "red")
  .call(zoom)                       // Adds zoom functionality
  .call(zoom.transform, transform); // Calls/inits handleZoom

var zoomable = svg
  .append("g")
  .attr("class", "zoomable")
  .attr("transform", transform);    // Applies initial transform

var circles = zoomable.append('circle')
  .attr("id", "circles")
  .attr("cx", 100)
  .attr("cy", 100)
  .attr('r', 20);

function handleZoom(){
  if (zoomable) {
    zoomable.attr("transform", d3.event.transform);
  }
};

查看实际操作:jsbin link

答案 4 :(得分:1)

D3JS 6 个回答

假设您希望初始位置和比例分别为 xyscale

const zoom = d3.zoom();

const svg = d3.select("#containerId")
    .append("svg")
    .attr("width", width)
    .attr("height", height)
    .call(zoom.transform, d3.zoomIdentity.translate(x, y).scale(scale)
    .call(zoom.on('zoom', (event) => {
        svg.attr('transform', event.transform);
     }))
    .append("g")
    .attr('transform', `translate(${x}, ${y})scale(${k})`);

.call(zoom.transform, d3.zoomIdentity.translate(x, y).scale(scale) 确保在触发缩放事件时,event.transform 变量会考虑平移和缩放。紧随其后的一行处理缩放,而最后一行用于在“启动”时仅应用一次平移和缩放。

答案 5 :(得分:0)

我正在使用d3做出反应,对初始变焦无法正常工作感到非常沮丧。

我在这里尝试过这些解决方案但没有一个工作,而是使用初始比例因子和位置,然后根据这些比例因子和位置更新缩放功能

#!/usr/bin/python
temps_min=21
temps_max=45
nb_time_slot=245

categorie=[[6,6,6,4,4,2,2,99],[6,6,6,4,4,2,2,99],[6,6,6,4,4,2,2,99],[3,3,3,2,2,2,99],[3,3,3,2,2,2,99],[4,4,4,4,2,2,99],[6,6,6,2,2,2,99],[6,6,6,2,2,2,99],[6,6,6,2,2,2,99],[6,6,6,2,2,2,99],[1,1,1,1,1,1,1,1,1,1,1,1,1]]
dernier_match_depart=[0]*10
case_courante_depart=0
tour_depart=[0]*10
echeancier =[None]*(nb_time_slot+10)
profondeur =0

#function
def choix(prof, case_courante, dernier_match, tour):
        global categorie,temps_min,temps_max,nb_time_slot,echeancier
        for i in range (0,10):
                print ("Profondeur:", prof)
                print(i)
                if (dernier_match[i] == 0):
                        for x in range (case_courante,case_courante + categorie[i][tour[i]]):
                                echeancier[x] = i
                        case_courante = case_courante + categorie[i][tour[i]]
                        dernier_match[i] = case_courante
                        tour[i] = tour[i] + 1
                        print echeancier
                        choix(prof+1, case_courante, dernier_match, tour)
                print ("case courante:", case_courante)
                print ("tour", tour)
                print ("dernier_match",dernier_match)
                if (categorie[i][tour[i]] != 99 and dernier_match[i]+temps_min < case_courante and dernier_match[i]+temps_max > case_courante and case_courante<nb_time_slot):
                        print ("if principal\n")
                        print ("slots dans ce tour",categorie[i][tour[i]])
                        for x in range (case_courante,case_courante + categorie[i][tour[i]]):
                                echeancier[x] = i
                        case_courante = case_courante + categorie[i][tour[i]]
                        dernier_match[i] = case_courante
                        tour[i] = tour[i] + 1
                        print echeancier
                        choix(prof+1, case_courante, dernier_match, tour)
                for a in range (0,9):
                        if (categorie[a][tour[a]] != 99):
                                break
                        else:
                                if (a == 9):
                                        print ("Solution trouvee\n")
                                        print (echeancier)
                                        exit()
#main
choix(0,case_courante_depart,dernier_match_depart, tour_depart)

缩放功能看起来像这样

const initialScale = 3;
const initialTranslate = [
  width * (1 - initialScale) / 2,
  height * (1 - initialScale) / 2,
];

const container = svg
  .append('g')
  .attr(
    'transform',
    `translate(${initialTranslate[0]}, ${initialTranslate[1]})scale(${initialScale})`
  );

如果你注意到svg.call( zoom().on('zoom', () => { const transformation = getEvent().transform; let {x, y, k} = transformation; x += initialTranslate[0]; y += initialTranslate[1]; k *= initialScale; container.attr('transform', `translate(${x}, ${y})scale(${k})`); }) ); 是一个函数,那是因为getEvent()中的导入事件在我的情况下不起作用。所以我必须做

d3-selection