2017-06-23 1 views
0

Je suis en train de faire un barchart tirant des données de https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/GDP-data.jsond3.select (ce) n'est pas la sélection de la rect

Ce projet fait partie des projets de d3 FCC. J'essaie de créer une info-bulle div sur chaque barre lorsque vous la survolez.

Cependant, je n'arrive pas à obtenir l'attribut 'x'. Quand je passe la souris un bar, il dit ceci dans la console:

TypeError: r.getAttribute is not a function 
    at _t.yl [as attr] (d3.v4.min.js:4) 
    at SVGRectElement.svg.selectAll.data.enter.append.attr.attr.attr.attr.attr.on.d (barchart.js:70) 
    at SVGRectElement.<anonymous> (d3.v4.min.js:2) 

Voici le bout de code pour les rects:

svg.selectAll('rect') 
     .data(data) 
     .enter() 
     .append('rect') 
     .attr('x', (d, i) => { 
     return xScale(new Date(d[0])); 
     }) 
     .attr('y', d => { 
     return yScale(d[1]) - padding; 
     }) 
     .attr('width', Math.round(w/data.length)) 
     .attr('height', d => { 
     return h - yScale(d[1]); 
     }) 
     .attr('fill', d => { 
     return `rgb(50, 50, ${Math.floor(colorScale(d[1]))})`; 
     }) 
     .on('mouseover', d => { 
     console.log(d3.select(this).attr('x')); 
     }); 

Reste du code de référence:

$('document').ready(function() { 

    const url = 'https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/GDP-data.json'; 

    $.getJSON(url, function(json) { 
    const data = json.data; 

    const margin = { 
     top: 30, 
     right: 10, 
     bottom: 30, 
     left: 75 
    }; 

    const w = 1000; 
    const h = 500; 
    const padding = 20; 



    const minDate = new Date(data[0][0]); 
    const maxDate = new Date(data[274][0]); 

    const xScale = d3.scaleTime() 
        .domain([minDate, maxDate]) 
        .range([margin.left, w - margin.right]); 

    const yScale = d3.scaleLinear() 
        .domain([0, d3.max(data, d => { return d[1] })]) 
        .range([h - margin.bottom, margin.top]); 

    const colorScale = d3.scaleLinear() 
         .domain([0, d3.max(data, d => { return d[1] })]) 
         .range([0, 255]); 

    const xAxis = d3.axisBottom(xScale) 
        .ticks(d3.timeYear.every(5)); 

    const yAxis = d3.axisLeft(yScale); 

    var div = d3.select('body') 
       .append('div') 
       .attr('class', 'tooltip') 
       .style('opacity', 0); 


    const svg = d3.select('body') 
      .append('svg') 
      .attr('width', w) 
      .attr('height', h); 

    svg.selectAll('rect') 
     .data(data) 
     .enter() 
     .append('rect') 
     .attr('x', (d, i) => { 
     return xScale(new Date(d[0])); 
     }) 
     .attr('y', d => { 
     return yScale(d[1]) - padding; 
     }) 
     .attr('width', Math.round(w/data.length)) 
     .attr('height', d => { 
     return h - yScale(d[1]); 
     }) 
     .attr('fill', d => { 
     return `rgb(50, 50, ${Math.floor(colorScale(d[1]))})`; 
     }) 
     .on('mouseover', d => { 
     console.log(d3.select(this).attr('x')); 
     }); 

    svg.append('g') 
     .attr('class', 'axis') 
     .attr('transform', `translate(0, ${h - padding})`) 
     .call(xAxis); 

    svg.append('g') 
     .attr('class', 'axis') 
     .attr('transform', `translate(${margin.left}, 0)`) 
     .call(yAxis); 

    svg.append("text") 
     .attr("transform", "rotate(-90)") 
     .attr('x', - margin.top) 
     .attr("y", margin.left + padding) 
     .style("text-anchor", "end") 
     .text("Gross Domestic Product, USA"); 
    }); 
}); 

Répondre

2

Vous ne pouvez pas utilisez une fonction fléchée si vous voulez que this soit défini par d3, comme indiqué here:

Une fonction de flèche ne crée pas ce propre contexte, donc this a sa signification d'origine à partir du contexte englobant.

Ce qui suit fonctionnera comme prévu:

.on('mouseover', function(d) { 
    console.log(d3.select(this).attr('x')); 
});