Coder1000
Coder1000

Reputation: 4461

Why are not all my text labels showing in my Scatterplot?

QUESTION:

Why are not all my text labels showing in my Scatterplot ?

It should iterate over each element in my data, but it seems to stop after a few ?

What have I done wrong ?

Thanks in advance for your answers.


CODE:

<html>
    <head>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
        <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
        <link rel="stylesheet" href="main.css">
    </head>
    <body>
        <div class="container-fluid">
            <h1 class="text-center title">Doping and Performance for Cyclists</h1>
            <div class="text-center">
                <div id="results"></div>
            </div>

        </div>
    </body>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script
  src="https://code.jquery.com/jquery-3.1.1.min.js"
  integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
  crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>

    <script type="text/javascript">   
        d3.json("https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/cyclist-data.json", function(error, json) {
          if (error) {
              return console.warn(error);
          }
          visualizeThe(json);
        });

        function visualizeThe(data) {

            const  margin = {
                top: 10,
                right: 6,
                bottom: 20,
                left: 70
            }

            const w = 900 - margin.left - margin.right;
            const h = 500 - margin.top - margin.bottom;
            const barWidth = Math.ceil(w / data.length);
            const parse = d3.timeParse("%m:%s");
            const format = d3.timeFormat("%m:%s");

            const  minTime = d3.min(data, (d) => (d["Seconds"]));
            const  maxTime = d3.max(data, (d) => (d["Seconds"]));

            const xScale = d3.scaleTime()
                .domain([maxTime, minTime])    
                .range([0, w]);   

            const yScale = d3.scaleLinear()
                .domain([d3.max(data, (d) => d["Place"]), 0])
                .range([h, 0]);

            const xAxis = d3.axisBottom(xScale);

            const yAxis = d3.axisLeft(yScale)

            const svg = d3.select("#results")
                .append("svg")
                .attr("width",  w + margin.left + margin.right)
                .attr("height", h + margin.top + margin.bottom);

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


            svg.append("g")
               .attr("transform", "translate(40," + (h+margin.top) + ")")
               .call(xAxis);

            svg.append("g")
               .attr("transform", "translate(40," + margin.top + ")")
               .call(yAxis);

            svg.selectAll("circle")
                .data(data)
                .enter()
                .append("circle")
                .attr("class", "dot")
                .attr("r", 4)
                .attr("cx", (d) => 40+xScale(d["Seconds"]))
                .attr("cy", (d) => yScale(d["Place"]))
                .attr("fill", (d) =>  (d["Doping"] == "" ? "black" : "red"))
                .on("mouseover", function(d) {      
                div.transition()        
                    .duration(200)      
                    .style("opacity", .9);      
                div .html(d["Doping"] == "" ? "No Doping Allegations" : d["Doping"] )   
                    .style("left", (d3.event.pageX - 7) + "px")     
                    .style("top", (d3.event.pageY - 30) + "px");    
                })                  
                .on("mouseout", function(d) {       
                div.transition()        
                    .duration(500)      
                    .style("opacity", 0);   
                });

            svg.selectAll("text")
                .data(data)
                .enter()
                .append("text")
                .text((d) => d["Name"])
                .attr("x", (d) =>  40+xScale(d["Seconds"]))
                .attr("y", (d) => yScale(d["Place"]))
                .attr("transform", "translate(8,4)")
                .style("font-size", 10);
        }

    </script>

</html>

Upvotes: 1

Views: 45

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102174

In this statement...

svg.selectAll("text")
    .data(data)
    .enter()
    .append("text")

... you start your enter selection for the texts.

However, when you get to that statement, you already have text elements in that SVG. The result is that some of the data points are bound to those texts, and your enter selection is shorter than what it should be.

Solution: select something that doesn't exist:

svg.selectAll("foo")
    .data(data)
    .enter()
    .append("text")

Here is your updated CodePen: https://codepen.io/anon/pen/JNbYjj?editors=1000

Upvotes: 1

Related Questions