Вы всегда можете использовать 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);
};
Это не переходит в бесконечный цикл, когда замена содержит совпадение.
Я, наконец, получил это для работы, установив как начальное преобразование, так и поведение масштабирования на одно и то же значение.
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)");
D3v4 answer
blockquote>Если вы ищете то же самое, но с 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)");
Добавление этого ответа в качестве дополнения к принятому ответу в случае, если у кого-то все еще есть проблемы:
То, что сделало это очень легким для понимания, выглядело здесь
При этом я установил три переменные: шкала
, масштаб 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)
. Это эффективно гарантирует, что ваш элемент будет масштабироваться и центрироваться при загрузке вашей визуализации.
Дайте мне знать, если это вам поможет! Приветствия.
Применяется к 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
Я использовал 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;