D3.js BTS Project Lesson #6

Craig Oda
CodeCakes
Published in
4 min readNov 13, 2018

finish project by creating y axis

Previous Lessons

Learning Resources

Create Weight and Height Scales

  1. create get heightScale()
  2. assign constants for heightMin and heightMax
  3. create constant for heightScale
  4. .domain is [heightMin -1, …]
  5. set range. Use this.height for height of chart area
  6. return heightScale

repeat process for weightScale()

// JavaScript Getter
get heightScale() {
const heightMin = d3.min(this.data, d => d.height);
const heightMax = d3.max(this.data, d => d.height);
const heightScale = d3.scaleLinear()
.domain([heightMin - 1, heightMax])
.range([this.height, 0]);
return heightScale;
}
// JavaScript Getter
get weightScale() {
const weightMin = d3.min(this.data, d => d.weight);
const weightMax = d3.max(this.data, d => d.weight);
const weightScale = d3.scaleLinear()
.domain([weightMin - 2, weightMax])
.range([this.height, 0]);
return weightScale;
}

Create Weight and Height Axis

Create two different getters, one for heightAxis() and one for weightAxis().

// JavaScript Getter
get heightAxis() {
return d3.axisLeft(this.heightScale);
}
// JavaScript Getter
get weightAxis() {
return d3.axisLeft(this.weightScale);
}

Display Axis in changeStats()

  1. create constant yAxisContainer and assign it to a group by appending a group .append('g') to this.svg
  2. chain attribute ('id', 'yAxis') to the group
  3. use if statement to check if selection is weight or height
  4. if height, use .call(this.heightAxis)
changeStats(selection) {

const yAxisContainer = this.svg.append('g')
.attr('id', 'yAxis');
if (selection == 'height') {
yAxisContainer
.call(this.heightAxis);

add else if to check for weight.

if (selection == 'height') {
yAxisContainer
.call(this.heightAxis);
} else if (selection == 'weight') {
yAxisContainer
.call(this.weightAxis);
}

remove old axis

close to the top of the method changeStats(selection), remove the existing y axis.

d3.select('#yAxis').remove();

Add datapoints

chain y attribute to this.datapoint

hint:

.attr('y', d => this.heightScale(d.height));

Adjust cy up by subtracting half of the imageSize

compare lowest values to verify the plot is accurate.

verify weight.

Create Getter for y axis labels

  1. get yAxisLabel() {...
  2. const yLabelHeight
  3. const yLabelOffset (negative value to move to the left)
  4. append text
  5. add attribute for id yAxisLabel
  6. close to the top of the getter, select the id for yAxisLabel and remove it
  7. Change text of y axis label in changeStats()
  8. create a similar .text for height.
// JavaScript Getter
get yAxisLabel() {
d3.select('#yAxisLabel').remove();
const yLabelHeight = this.height * 0.75;
const yLabelOffset = -60;
const yAxisLabel = this.svg.append('text')
.attr('x', yLabelOffset)
.attr('y', yLabelHeight)
.attr('transform', `rotate(-90, ${yLabelOffset}, ${yLabelHeight})`)
.attr('id', 'yAxisLabel');
return yAxisLabel;
}

in changeStats()

this.yAxisLabel.text('BTS Member Weight (lbs)');

You’re now close to finishing the project.

Add transitions.

this.datapoints                               
.attr('y', '0')
.transition()
.attr('y', d => this.heightScale(d.height) - this.imageSize/2)
.duration(800);

Questions

  1. In the section above, where is this.datapoints defined?

2. In the method generateDatapoints() what does each line do? In line 27, where do you get this.data? In line 31, what is this.getImageFile(d)?

3. What is the advantage of putting the methods in a class?

4. What does the constructor do?

5. What does this refer to?

6. In drawChart, how do you use the class? Go to the file and explain.

7. In drawChart.js can we use a fat arrow function to handle the event for the statsButton press?

Congratulations

You’ve finished the D3 BTS Project

--

--

Craig Oda
CodeCakes

open source advocate, writer, Flutter developer, father, husband, fly fisherman, surfer