首页 > 解决方案 > d3拖动功能返回错误

问题描述

我正在为此苦苦挣扎,它的一段代码与我之前使用过多次的代码几乎相同,我真的找不到问题所在。我正在附加一些我希望能够单击并拖动的文本。但是,当我开始拖动时,出现以下错误:

annotations.js:106 Uncaught TypeError: Cannot read property 'x' of null

这是我正在使用的代码

let radius;
        let yOffset = 0;
        let xOffset = 0;

        let textLabel = parent.append('text')
            .on('mouseover', pointer)
            .attr('class', 'highlighted-label')
            .attr('x',d => xScale(d.x))
            .attr('y',d => yScale(d.y))
            .attr("dy",0)
            .text((d) => {
                radius = sizeScale(d.value)
                return d.label + ' '+ formatDecimal(d.value)
            })
            .call(d3.drag()
                .on('start', dragstarted)
                .on('drag', dragged)
                .on('end', dragended))
            // .call(wrap,lineWidth,(d => xScale(d.x)),"highlighted-label")
            // .call(offset)

这些是功能:

function pointer() {
            this.style.cursor = 'pointer';
        }

        function dragstarted() {
            d3.select(this).raise().classed('active', true);
        }

        function dragged() {
            d3.select(this).attr('transform', `translate(${d3.event.x}, ${d3.event.y})`);
        }

        function dragended() {
            d3.select(this).classed('active', false);
        }

感激地收到任何帮助

标签: javascriptd3.js

解决方案


我发现首先添加 ag 元素然后调用该元素上的拖动几乎可以完美地工作。只要你直接针对dragstart函数中的元素。它还允许您换行文本。但它确实使文本在第一次拖动时跳转。如果我再次单击并拖动文本,它的行为就完美了。代码没有看起来像这样:

textLabel.append('g')
        .append('text')
            .attr('class', 'highlighted-label')
            .attr('x',d => xScale(d.targetX))
            .attr('y',d => yScale(d.targetY))
            .attr('dy',0)
            .text((d) => {
                if (intersect) {
                    radius = sizeScale(d.radius);
                }
                else {radius = d.radius};
                return d.title + ' '+ d.note
            })


            .call(wrap,lineWidth,(d => xScale(d.targetX)),"highlighted-label")
            //.call(offset)

       textLabel.call(d3.drag()
            .on('start', dragstarted)
            .on('drag', dragged)
            .on('end', dragended));

function wrap(text, width,x, media) {
            text.each(function() {
                var text = d3.select(this),
                words = text.text().split(/\s+/).reverse(),
                word,
                line = [],
                lineNumber = 0,
                lineHeight = 1.0,
                y = text.attr("y"),
                dy = parseFloat(text.attr("dy")),
                tspan = text.text(null).append("tspan").attr("class", media).attr("x", x).attr("y", y).attr("dy", dy + "em");
                while (word = words.pop()) {
                    line.push(word);
                    tspan.text(line.join(" "));
                    if (tspan.node().getComputedTextLength() > width) {
                        tspan.text(line.join(" "));
                        line = [word];
                        tspan = text.append("tspan").attr("class", media).attr("x", x).attr("y", y).attr("dy",++lineNumber * lineHeight + dy + "em").text(word);
                    }
                }
            });
        }
        function pointer(d) {
            this.style.cursor = 'pointer';
        }

        function dragstarted(d) {
            d3.select(this).raise().classed('active', true);
        }

        function dragged(d) {

            d3.select(this).selectAll('tspan').attr("x", d.x = d3.event.x).attr("y", d.y = d3.event.y);
            d3.select(this).selectAll('text').attr("x", d.x = d3.event.x).attr("y", d.y = d3.event.y);
        }

        function dragended(d) {
            d3.select(this).classed('active', false);
        }

推荐阅读