D3.js force graph zoom [дубликат]

Вы всегда можете использовать indexOf несколько раз:

String.prototype.replaceAll = function(substring, replacement) {
    var result = '';
    var lastIndex = 0;

    while(true) {
        var index = this.indexOf(substring, lastIndex);
        if(index === -1) break;
        result += this.substring(lastIndex, index) + replacement;
        lastIndex = index + substring.length;
    }

    return result + this.substring(lastIndex);
};

Это не переходит в бесконечный цикл, когда замена содержит совпадение.

21
задан davcs86 20 April 2017 в 17:01
поделиться

5 ответов

Я, наконец, получил это для работы, установив как начальное преобразование, так и поведение масштабирования на одно и то же значение.

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)");  
25
ответ дан Musakkhir Sayyed 18 August 2018 в 17:39
поделиться

D3v4 answer

Если вы ищете то же самое, но с 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)");
16
ответ дан davcs86 18 August 2018 в 17:39
поделиться

Добавление этого ответа в качестве дополнения к принятому ответу в случае, если у кого-то все еще есть проблемы:

То, что сделало это очень легким для понимания, выглядело здесь

При этом я установил три переменные: шкала

, масштаб ZoomWidth и zoomHeight

- это начальная шкала, на которую вы хотите масштабировать, а затем

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)

. Это эффективно гарантирует, что ваш элемент будет масштабироваться и центрироваться при загрузке вашей визуализации.

Дайте мне знать, если это вам поможет! Приветствия.

13
ответ дан deweyredman 18 August 2018 в 17:39
поделиться
  • 1
    У меня есть уровни увеличения, загруженные из JSON, я пытаюсь воссоздать уровень масштабирования при загрузке svg. Не могли бы вы разместить свое полное решение? :) – Vedran Maricevic. 29 January 2016 в 10:47
  • 2
    Было бы так приятно, если бы эта ссылка все еще работала ... Благодарим за Архив Wayback – Dan 24 September 2016 в 02:56
  • 3
    обновляя свой первоначальный ответ, чтобы ссылаться на заархивированную ссылку. благодаря! – deweyredman 4 January 2017 в 19:56
  • 4
    в моем случае zoomWidth и zoomHeight, где "offsetLeft" и "offsetTop" – Jodo 19 August 2017 в 08:03

Применяется к d3.js v4

Это похоже на ответ davcs86 , но он повторно использует начальное преобразование и реализует функцию масштабирования.

// 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

2
ответ дан hexnod 18 August 2018 в 17:39
поделиться

Я использовал d3 с реакцией и очень разочаровался в том, что начальный зум не работает.

Я попробовал решения здесь, и ни одна из них не работала, вместо этого использовалась начальный масштабный коэффициент и позиции, а затем обновлялась функция масштабирования на основе этих масштабных коэффициентов и позиций

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 не работал в моем случае. Поэтому мне пришлось делать

const getEvent = () => require('d3-selection').event;
0
ответ дан Prasanna 18 August 2018 в 17:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: