Add Axes to a Visualization Dataset Question

Add Axes to a Visualization Dataset Question
0

#1

Tell us what’s happening:

What is passing when I call:

.attr("cx", (d) => xScale(d[0]))

in

    svg.selectAll("circle")
       .data(dataset)
       .enter()
       .append("circle")
       .attr("cx", (d) => xScale(d[0]))

xScale uses dataset to find the max as shown in:

const xScale = d3.scale.linear()
        .domain([0, d3.max(dataset, (d) => d[0])])

So what does the d pass?

Your code so far


<body>
  <script>
    const dataset = [
                  [ 34,     78 ],
                  [ 109,   280 ],
                  [ 310,   120 ],
                  [ 79,   411 ],
                  [ 420,   220 ],
                  [ 233,   145 ],
                  [ 333,   96 ],
                  [ 222,    333 ],
                  [ 78,    320 ],
                  [ 21,   123 ]
                ];
    
    const w = 500;
    const h = 500;
    const padding = 60;
    
    const xScale = d3.scaleLinear()
                     .domain([0, d3.max(dataset, (d) => d[0])])
                     .range([padding, w - padding]);
    
    const yScale = d3.scaleLinear()
                     .domain([0, d3.max(dataset, (d) => d[1])])
                     .range([h - padding, padding]);
    
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    
    svg.selectAll("circle")
       .data(dataset)
       .enter()
       .append("circle")
       .attr("cx", (d) => xScale(d[0]))
       .attr("cy",(d) => yScale(d[1]))
       .attr("r", (d) => 5);
    
    svg.selectAll("text")
       .data(dataset)
       .enter()
       .append("text")
       .text((d) =>  (d[0] + "," + d[1]))
       .attr("x", (d) => xScale(d[0] + 10))
       .attr("y", (d) => yScale(d[1]))
    
    const xAxis = d3.axisBottom(xScale);
    // Add your code below this line
    const yAxis = d3.axisLeft(yScale);
    // Add your code above this line
    
    svg.append("g")
       .attr("transform", "translate(0," + (h - padding) + ")")
       .call(xAxis);
    
    // Add your code below this line
    svg.append("g")
       .attr("transform", "translate("+(w - padding) + ", 0")
       .call(yAxis);
    
    
    // Add your code above this line
  
  </script>
</body>

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0.

Link to the challenge:
https://learn.freecodecamp.org/data-visualization/data-visualization-with-d3/add-axes-to-a-visualization


#2

Good day @jacoblhughes,

Good question.

Well,

The more things build upon each other, the more it gets complex leaving us with little room to understand it clearly.

     svg.selectAll("circle")
       .data(dataset)
       .enter()
       .append("circle")
       .attr("cx", (d) => xScale(d[0]))

Looking up, you can see that the svg which is nothing other than the scalable vector graphics is targetting the circle shape.

svg.selectAll("circle")

Do we all agree that it’s the circle which is being targetted?

Yes.

After targetting the circle, we get the positions for all circles which is contained in the dataset:

.data(dataset)

Once we have selected the shape, selected the dataset, we need to join them.
The enter() function serves as an initial join of data(in the dataset) to element(circle shape)

In other terms, we have initially joined the circle to the dataset.

To the selected shape, with its joined dataset which have been joined, we append the “circle” element.

Why do we append to the selected element?

It’s a question that I haven’t figured out but will let you know once it is.

Past that, the appended the circles will be a number of circles:

How will they be a number of circles?

Because we are not displaying one circle but many circles based on the dimensions found in the dataset.

the first circle will be based on these values: [ 34, 78]
the second circle will be based on these values: [ 109, 280 ]
And so on…

coming down to your core question:

What is passing when I call:
.attr("cx", (d) => xScale(d[0]))

Well,

Let’s break it down

.attr("cx", (d) => xScale(d[0]))

We know by now that the attr function is made of two parameters:

The first parameter is the “axis” of where the element will be positioned.

The traditional one is X OR Y

But

The circle axis is CX OR CY

I don’t know why it has an added c in front but I assume that it is just meaning “Circle X” or "Circle Y"

Looking on this:

.attr(“cx”, (d) => xScale(d[0]))

The first attribute will be CX and the second attribute is what?

(d) => xScale(d[0])

That is a callback function having one parameter d which contains the current array based on the current loop

When starting for the first time, d will have these values => [ 34, 78 ]

The real question is: How do I extract the value for CX and CY?

Well,

Just like an array, d[0] is 34 & d[1] is 78

Don’t forget that the cx will be done for all the arrays in the dataset

What does it mean?

The d[0] and d[1] will be replaced in each iteration.

So far the logic is fine but the exercise wants us to make use of the padding exploited in the xScale and yScale functions for the display

That is why we pass the d[0] to the xScale function within our callback function.

.attr("cx", (d) => xScale(d[0])) will return the correct position for cx.