У меня есть немного неприятная проблема.Позиционирование элементов SVG через .getBoundingClientRect() в переменной ширине div
Я пытаюсь расположить кучу элементов окружности SVG в соответствии с существующим набором текстовых элементов SVG, которые имеют сходные свойства.
Элементы окружности создаются в отдельном процессе, чем текстовые элементы, поэтому позиционирование новых элементов осуществляется с использованием тех же самых преобразований и т. Д., Поскольку старый не является жизнеспособным вариантом.
Я пытаюсь использовать .getBoundingClientRect(), чтобы получить позиции, поскольку текстовые элементы преобразуются в позицию (так что .getBBox() не является опцией), а не позиционируется по атрибутам x и y.
С .getBoundingClientRect(), я могу получить правильный размер/расположение новых элементов, но так как ширина SVG-содержащего div является переменной, всегда есть немного странное смещение, которое я не могу учитывать.
Я создал упрощенный пример моей проблемы here. Измените размер и обновите страницу, чтобы увидеть проблему в действии.
Код, который я использую для размещения элементов окружности, реплицируется ниже.
var circs = theSvg.selectAll("circle")
.data(theCircles)
.enter()
.append("circle")
.attr("r", 15)
.attr("fill", "#f00")
.style("opacity", 0.3)
.attr("transform", function(d){
var sizeDif = 800/(d3.select(".svgTestHolder")[0][0].getBoundingClientRect()["width"]);
var theNum = parseInt(d.split("&")[1]);
var thePosition = theSvg.selectAll("text").filter(function(e){
return e == theNum;})[0];
var theCoords = thePosition[0].getBoundingClientRect();
var leftOffset = d3.select(".svgTestHolder")[0][0].getBoundingClientRect()["left"];
var leftOffset2 = d3.select(".svgTest")[0][0].getBoundingClientRect()["left"];
var bottomOffset = d3.select(".svgTestHolder")[0][0].getBoundingClientRect()["top"];
var bottomOffset2 = d3.select(".svgTest")[0][0].getBoundingClientRect()["top"];
return
"translate(" + ((theCoords["left"] - leftOffset - leftOffset2)
* sizeDif) + "," + ((theCoords["top"] - bottomOffset - bottomOffset2)
* sizeDif) + ")";
})
EDIT:
Это очень задерживается обновление только отметить, что в то время как я не смог ответить на мой вопрос, как уже говорилось, я был в состоянии сделать работоспособную решение, основанное на предложении Павла Лебо к экстракту преобразуется из целевого элемента.
В моем случае мне пришлось использовать ряд последовательных преобразований, а не комбинацию преобразования и изменения положения x/y (из-за некоторых реалий проекта, не представленных в связанном примере). Но я рад, что нашел ответ!
Я понимаю, что теоретически getBBox() решит мою проблему, но поскольку я использовал преобразование на элементах, которые мне нужны, getBBox() не является решением. Вот почему я пытался позиционировать путем смещения в соответствии с getBoundingClientRect() и добавлением/вычитанием смещения родительских элементов по мере необходимости (см. [Обновленный скрипт] (https://jsfiddle.net/rrpfmm6d/3/)).Я искал альтернативы getBBox() для преобразованных элементов, включая применение матрицы преобразования SVG к текстовым элементам x и y (согласно [этому парню] (http://stackoverflow.com/a/18561829/3899852) решение). – Jess
Вы говорите, что не можете использовать одни и те же преобразования, но почему вы не можете просто скопировать их из текстовых элементов? Например: https://jsfiddle.net/rrpfmm6d/5/ –
Я немного поиграл с извлечением трансформирования, но не сделал этого так, как вы сказали, потому что я стараюсь избегать установки позиций cx и cy на круги (в фактической части), я уже трансформирую круги в соответствии с другим набором параметров, и поэтому стараюсь, чтобы cx и cy были равны 0. Я дам вашему предложению вращение, а также рассмотрю применение нескольких преобразований и отчетов. Благодаря! – Jess