D3.mouse (this) return Uncaught TypeError: Cannot read the 'sourceEvent' property from null

I have a character diagram + string + character that is converted when users click the y axis to switch between linear and sqrt. http://bl.ocks.org/jebeck/9457536 . it works fine with one SVG, but when there is more than one svg on one web page, it can work only with one of svg (s); on the rest svg (s), the lines and characters move to the same point, because the x values ​​are not a number. debugging shows d3.mouse (invisibleRect.node ()) get Uncaught TypeError: Unable to read the 'sourceEvent' property from null. I suspiciously this is due to the priority of the last element when there is more than one svg element on the same page, but just struggling for a good solution. thank.

d3.csv("data13.csv", function(error, data) {
  if (error) throw error;
  if (data.length == 0) {
    svg.append("text").text("data is empty");
    throw "No Input";
  }

  var attributeName = d3.keys(data[0])[0];
  var metricList = d3.keys(data[0]).slice(1);
  var target = metricList[metricList.length - 1];
  data.forEach(function(d) {
var maxData = d3.max(data,function(d){ return d3.max(metricList.map(function(name){return +d[name];}));});
  var minData = d3.min(data,function(d){ return d3.min(metricList.map(function(name){return +d[name];}));});

  x0.domain(metricList);
  x1.domain(data.map(function(d) { return d[attributeName];})).rangeRoundBands([0, x0.rangeBand()]);
  y.domain([Math.min(0,minData)*space_to_top, Math.max(0, maxData)*space_to_top]);

 svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);

  svg.append("g")
  .attr("class", "y axis")
  .call(yAxis);

  var drawBars = svg.selectAll(".bars")
  .data(metricList)
.enter().append("g")
  .attr("class", "bargroup")
  .attr("transform", function(name) { return "translate(" + x0(name) + ",0)"; });

  drawBars.selectAll("rect")
  .data(function(metricName) { return data.map(function(d){ return {name: d[attributeName],
                                                                    value: +d[metricName],
                                                                    title: metricName};});})
  .enter().append("rect")
  .attr("width", x1.rangeBand())
  .attr("x", function(d) { return x1(d.name); })
  .attr("y", function(d) { return y(Math.max(0, d.value)); })
  .attr("height", function(d) { return Math.abs(y(d.value) - y(0)); })
  .style("fill", function(d) { return color(d.name); })
  .on("mouseover", function(d) {
        d3.select(this).style("fill", "red");
    })
  .on("mouseout", function(d) {
        d3.select(this).style("fill",color(d.name));
  })
  .append("title")
  .text(function(d) { return attributeName+": " + d.name
                             + "\nCategory: " + d.title
                             + "\nValue: " + d.value; });

data.forEach(function(d,i){
var lineFunction = d3.svg.line()
                   .x(function(k) { return x0(k)+x1(d[attributeName])+x1.rangeBand()/2; })
                   .y(function(k) { return y(+d[target]); });

svg.append("path")
   .attr("class","targetLine"+i)
   .attr("d", lineFunction(metricList))
   .style("stroke","#959595")
   .style("stroke-width", 1);

// create symbols along the line
svg.append("g")
  .selectAll("path")
  .data(metricList)
  .enter()
  .append("path")
  .attr("class","symbol"+i)
  .attr("transform", function(k) { return "translate(" + (x0(k)+x1(d[attributeName])+x1.rangeBand()/2) + ","
                                                       + y(+d[target]) + ")"; })
  .attr("d", d3.svg.symbol()
               .type(symbol(d[attributeName]))
               .size(64))
  .style("fill", color(d[attributeName]))
  .style("stroke","000000")
  .on("mouseover", function(k){
    d3.select(this).attr("d",d3.svg.symbol().type(symbol(d[attributeName])).size(180));
  })
  .on("mouseout", function(k){
    d3.select(this).attr("d",d3.svg.symbol().type(symbol(d[attributeName])).size(64));
  })
  .append("title")
  .text( target +" for "+d[attributeName]+": "+d[target]);
  });
// toggle between linear and sqrt y axis

  var sqrtScale = d3.scale.sqrt().clamp(true).range([height, 0]);
        sqrtScale.domain([Math.min(0,minData)*space_to_top, Math.max(0, maxData)*space_to_top]);
  var sqrtAxis = d3.svg.axis().scale(sqrtScale).orient('left');
var log = false;
    var transitionDuration = 500;
var lineFunction_sqrt = d3.svg.line()
                   .x(function(k) { return x0(k)+x1(data[i][attributeName])+x1.rangeBand()/2; })
                   .y(function(k) { return sqrtScale(+data[i][target]); });

    var lineFunction_linear = d3.svg.line()
                   .x(function(k) { return x0(k)+x1(data[i][attributeName])+x1.rangeBand()/2; })
                   .y(function(k) { return y(+data[i][target]); });

        invisibleRect = svg.append('rect')
            .attr({
                'x': -margin.left,
                'y': 0,
                'height': height,
                'width': margin.left,
                'fill': '#FFFFFF',
                'opacity': 0.0,
                'id': 'invisibleRect'
            });

        invisibleRect.on('click', function() {
            try {
                hoverHelp.remove();
            }
            catch (ReferenceError) {
                console.log("There no hoverHelp right now.");
            }
            if (!log) {
                svg.select('.y.axis')
                    .transition()
                    .duration(transitionDuration)
                    .call(sqrtAxis);
                drawBars.selectAll("rect")
                    .transition()
                    .duration(transitionDuration)
                    .attr("y", function(d) { return sqrtScale(Math.max(0, d.value)); })
                    .attr("height", function(d) { return Math.abs(sqrtScale(d.value) - sqrtScale(0));});
                for (i=0;i<data.length;i++){

                    svg.select(".targetLine"+i)
                   .transition()
                   .duration(transitionDuration)
                   .attr("d", lineFunction_sqrt(metricList,i));
               };
                for (i=0;i<data.length;i++){

                    svg.selectAll(".symbol"+i)
                       .transition()
                       .duration(transitionDuration)
                       .attr("transform", function(k) {
                        return "translate(" + (x0(k)+x1(data[i][attributeName])+x1.rangeBand()/2) + ","
                                                       + sqrtScale(+data[i][target]) + ")"; });
               };
                log = true;
            }
            else {
                svg.select('.y.axis')
                    .transition()
                    .duration(transitionDuration)
                    .call(yAxis);
                drawBars.selectAll("rect")
                    .transition()
                    .duration(transitionDuration)
                    .attr("y", function(d) { return y(Math.max(0, d.value)); })
                    .attr("height", function(d) { return Math.abs(y(d.value) - y(0));});
                for (i=0;i<data.length;i++){

                    svg.select(".targetLine"+i)
                   .transition()
                   .duration(transitionDuration)
                   .attr("d", lineFunction_linear(metricList,i));
               };
               for (i=0;i<data.length;i++){

                    svg.selectAll(".symbol"+i)
                       .transition()
                       .duration(transitionDuration)
                       .attr("transform", function(k) {
                        return "translate(" + (x0(k)+x1(data[i][attributeName])+x1.rangeBand()/2) + ","
                                                       + y(+data[i][target]) + ")"; });
               };
                log = false;
            }
        });

        invisibleRect.on('mouseover', function() {
          debugger;
            var coords = d3.mouse(invisibleRect.node());
            var hoverHelp = svg.append('g').attr('id', 'hoverHelp');

            var x = coords[0];
            var y = coords[1];

            var triangleSize = 25;
            var rectWidth = 200;
            var rectHeight = 50;

            hoverHelp.append('polygon')
                .attr({
                    'fill': '#3F0040',
                    'opacity': 0.5,
                    'points': x + ',' + y + ' ' + (x + triangleSize) + ',' + (y - triangleSize) + ' ' + (x + triangleSize + rectWidth) + ',' + (y - triangleSize) + ' ' + (x + triangleSize + rectWidth) + ',' + (y - triangleSize + rectHeight) + ' ' + (x + triangleSize) + ',' + (y - triangleSize + rectHeight) + ' ' + (x + triangleSize) + ',' + (y + triangleSize),
                    'stroke-width': 3,
                    'stroke': '#FD00FF',
                    'stroke-linecap': 'round'
                 });

            hoverHelp.append('text')
                .attr({
                    'x': x + triangleSize + rectWidth/2,
                    'y': y - triangleSize + rectHeight/2,
                    'text-anchor': 'middle',
                    'dominant-baseline': 'central',
                    'fill': '#FFFFFF',
                    'text-weight': 'bold'
                })
                .text('Click to toggle axis.');
        });
        invisibleRect.on('mouseout', function() {
            try {
                hoverHelp.remove();
            }
            catch (ReferenceError) {
                console.log("There no hoverHelp right now.");
            }
        });
+4
source share

Source: https://habr.com/ru/post/1658251/


All Articles