У меня возникают проблемы при попытке обновить атрибуты элемента, используя d3 (v3.5) в TypeScript (v3.1).В JavaScript у меня есть код, подобный следующему.
function getAttr(d) {
// modifies the "this" element with the following attribute
d3.select(this).attr({
id: d.id, cx: d.cx, cy: d.cy, r: d.r
});
}
function drawCircles() {
// update elements
var svgCircles = d3.select('g#circles').selectAll('circle')
.data(circles)
.each(getAttr);
// create elements
svgCircles
.enter()
.append('circle')
.each(getAttr);
// delete elements
svgCircles.exit().remove();
}
Обратите внимание, что в JavaScript я передаю функцию в each
, и эта функция каким-то волшебным образом с d3.select(this)
ссылается на соответствующий элемент SVG / HTML.Этот подход использования this
не может быть выполнен в TypeScript, поскольку this
будет , а не будет ссылкой на соответствующий элемент SVG / HTML.
Есть несколько примеров в Интернете, которые близки к решению этой проблемы, но они не дотягивают.Это сообщение в блоге говорит о проблеме this
в контексте обработки события.Чтобы получить ссылку на элемент SVG / HTML, автор использует d3.event.currentTarget
(такое свойство недоступно и / или не определено в используемой мной версии d3).Этот SO post решил бы мою проблему, за исключением того, что обновление не включает each
.
Любые идеи о том, как изменить SVG / HTML-элементы, соответствующие элементам данных, с помощью each
?
В качестве обходного пути, без использования each
, поскольку я понимаю, что это создает много проблем, я следую этому шаблону обновления JavaScript , и он хорошо работает с TypeScript.Мне нравится, что это работает, но не так сильно, поскольку мне нужно построчно обновлять атрибуты.
drawCircles(): void {
// data join
const svgCircles = d3.select('g#circles')
.selectAll('circle')
.data(circles);
// create
svgCircles.enter().append('circle');
// create + update
svgCircles.attr('id', (datum) => datum.id);
svgCircles.attr('cx', (datum) => datum.cx);
svgCircles.attr('cy', (datum) => datum.cy);
svgCircles.attr('r', (datum) => datum.r);
// delete
svgCircles.exit().remove();
}