2

I am completely new to d3. I have the following CSV:

HeaderAttempts  HeaderGoals FreekickAttempts    FreekickGoals   Team
5                     2             3                 2         Team A
2                     2             12                1         Team A
8                     2             13                5         Team B
4                     3             6                 2         Team B
7                     2             10                1         Team C
6                     5             13                7         Team C
8                     7             9                 3         Team C

I am trying to create a scatter plot where x axis will have attempts and y axis will have the goals. i have been able to create a scatter plot for the header attempts and goals by using the following code:

<script src="//d3js.org/d3.v3.min.js"></script>

<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;


var x = d3.scale.linear()
    .range([0, width]);

var y = d3.scale.linear()
    .range([height, 0]);


var color = d3.scale.category10();

var axisNames = { 
                    HeaderAttempts: 'HeaderAttempts', 
                   HeaderGoals: 'HeaderGoals', 
                    FreekickAttempts: 'FreekickAttempts', 
                    FreekickGoals: 'FreekickGoals' 
                };

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");


var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");


d3.csv("FootballData.csv", function(error, data) {
  data.forEach(function(d) {
    d.HeaderAttempts = +d.HeaderAttempts;
    d.HeaderGoals = +d.HeaderGoals;
    d.FreekickAttempts = +d.FreekickAttempts;
    d.FreekickGoals = +d.FreekickGoals;
  });

  x.domain(d3.extent(data, function(d) { return d.HeaderAttempts; })).nice();
  y.domain(d3.extent(data, function(d) { return d.HeaderGoals; })).nice();



  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
    .append("text")
      .attr("class", "label")
      .attr("x", width)
      .attr("y", -6)
      .style("text-anchor", "end")
      .text("attempts");

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("class", "label")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("goals")

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

 var circlesH = svg.selectAll(".dot")
      .data(data)
    .enter().append("circle")
      .attr("class", "dot")
      .attr("r", 3.5)
      .attr("cx", function(d) { return x(d.HeaderAttempts); })
      .attr("cy", function(d) { return y(d.HeaderGoals); })
      .style("fill", function(d) { return color(d.Team); })
      .on("mouseover", function(d) {
         tooltip.transition()
            .duration(200)
            .style("opacity", 1.0);
         tooltip.html(d.HeaderAttempts+" ,"+ d.HeaderGoals)
            .style("left", (d3.event.pageX + 5) + "px")
            .style("top", (d3.event.pageY - 18) + "px");
      })
      .on("mouseout", function(d) {
         tooltip.transition()
            .duration(500)
            .style("opacity", 0);
      });

var circlesF = svg.selectAll(".dot")
      .data(data)
    .enter().append("circle")
      .attr("class", "dot")
      .attr("r", 3.5)
      .attr("cx", function(d) { return x(d.FreekickAttempts); })
      .attr("cy", function(d) { return y(d.FreekickGoals); })
      .style("fill", function(d) { return color(d.Team); })
      .on("mouseover", function(d) {
         tooltip.transition()
            .duration(200)
            .style("opacity", 1.0);
         tooltip.html(d.FreekickAttempts+" ,"+ d.FreekickGoals)
            .style("left", (d3.event.pageX + 5) + "px")
            .style("top", (d3.event.pageY - 18) + "px");
      })
      .on("mouseout", function(d) {
         tooltip.transition()
            .duration(500)
            .style("opacity", 0);
      });     

  var legend = svg.selectAll(".legend")
      .data(color.domain())
      .enter().append("g")
      .attr("class", "legend")
      .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });


  legend.append("rect")
      .attr("x", width - 18)
      .attr("width", 18)
      .attr("height", 18)
      .style("fill", color);


  legend.append("text")
      .attr("x", width - 24)
      .attr("y", 9)
      .attr("dy", ".35em")
      .style("text-anchor", "end")
      .text(function(d) { return d; });



  d3.selectAll("[name=v]")
  .on("change", function() {
      var selected = this.value;
      display = this.checked ? "inline" : "none";


  svg.selectAll(".dot")
      .filter(function(d) {return selected == d.Team;})
      .attr("display", display);
      });


});
</script>

<div id="filter">
    <b>team Filter:</b>
        <br>
    <input name='v' value="Team A" type="checkbox" checked>Team A
    </input>
        <br>
    <input name="v" value="Team B" type="checkbox" checked >Team B
    </input>
        <br>
    <input name="v" value="Team C" type="checkbox" checked >Team C
    </input>
  </div>

I know this wasnt going to work but had to give it a shot. Now i have no idea how to proceed. This is actually a truncated data and i still have 4 more columns: PenaltyAttempts, PenaltyGoals, CornerAttempts, CornerGoals

2
  • can you paste your full code here... Commented Feb 15, 2016 at 7:40
  • I edited the existing question for the code. plz have a look. Commented Feb 15, 2016 at 8:42

1 Answer 1

1

Your approach of making separate graphs and overlapping in this is not really correct.

Better way is to make your dataset as per your requirement.

data.forEach(function(d) {
    d.HeaderAttempts = +d.HeaderAttempts;
    d.HeaderGoals = +d.HeaderGoals;
    d.FreekickAttempts = +d.FreekickAttempts;
    d.FreekickGoals = +d.FreekickGoals;
    var attempts = d.HeaderAttempts + d.FreekickAttempts;//calculate all attempts of a team
    var goals = d.HeaderGoals + d.FreekickGoals;//calculate all goals of a team
    //make your data set like this
    all.push({
      team: d.Team,
      attempts: attempts,
      goals: goals
    });
  });

Then use this all object to make your domains

  x.domain(d3.extent(all, function(d) { return d.attempts; })).nice();
  y.domain(d3.extent(all, function(d) { return d.goals; })).nice();

Even points can be made easily like this:

  svg.selectAll(".dot")
    .data(all)
    .enter().append("circle")
      .attr("class", "dot")
      .attr("r", 3.5)
      .attr("cx", function(d) {console.log(d,"s");return x(d.attempts); })
      .attr("cy", function(d) { return y(d.goals); })
      .style("fill", function(d) { return color(d.team); })

Working code here

Hope this helps!

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the effort Cyril :) I really appreciate that. But I wasn't looking for a sum of d.HeaderAttempts + d.FreekickAttempts; & d.HeaderGoals + d.FreekickGoals; I wanted to have a plot for (HeaderAttempts,HeaderGoals) and (FreekickAttempts,FreekickGoals) on the same graph. Like having a dual-axis for two different sets. I apologize for the misunderstanding.
OK i understand that you want to make separate graphs of these combination (HeaderAttempts,HeaderGoals) and (FreekickAttempts,FreekickGoals) can you put a screen shot of how the dual axis will look...or how your graph should look

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.