1

I am trying to plot the data with d3. My data looks like this:

dataset = [
["HBO", 23, "tv show"],
["HBO", 45, "movie"],
["Hulu", 40, "tv show"],
["Hulu", 56, "movie"]
]

I am using scaleLinear() for numerical data (d[1]) and scaleBand() for categorical data. Here is my code:

const dataset = [
  ["HBO", 23, "tv show"],
  ["HBO", 45, "movie"],
  ["Hulu", 40, "tv show"],
  ["Hulu", 56, "movie"]
];

const width = 600, height = 400;
const padding = 20, marginTop = 50;

// Min and max for y axis for Revenue values
const maxRevenue = d3.max(dataset, (d) => d[1]);
const minRevenue = d3.min(dataset, (d) => d[1]);

const yScale = d3
  .scaleLinear()
  .domain([minRevenue, maxRevenue])
  .range([height - padding, marginTop]);

const xScale = d3
  .scaleBand()
  .domain([dataset, (d) => d[2]])
  .range([0, 100]);

const rScale = d3
  .scaleBand()
  .domain([dataset, (d) => d[2]])
  .range([3, 3]);

// positioning the whole chart
const xAxis = d3.axisBottom(xScale);
const yAxis = d3.axisLeft(yScale);

const svg = d3
  .select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height)
  .attr("class", "chart")
  .attr("id", "chart");

svg
  .selectAll("circle")
  .data(dataset)
  .enter()
  .append("circle")
  .attr("cx", (d) => xScale(d[2]))
  .attr("cy", (d) => yScale(d[1]))
  .attr("r", (d) => rScale(d[2]))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

The expected output is the screenshot below. My code doesn't display the circles... enter image description here

Ruben Helsloot
  • 12,582
  • 6
  • 26
  • 49
Chique_Code
  • 1,422
  • 3
  • 23
  • 49

1 Answers1

2

For some reason, you used [dataset, (d) => d[2]], but that doesn't do anything. Well, it creates an array of a dataset and a function, but that's not what you wanted.

To actually create the array that you want (["tv show", "movie", "tv show", "movie"]), you need to call dataset.map((d) => d[2]) yourself:

const dataset = [
  ["HBO", 23, "tv show"],
  ["HBO", 45, "movie"],
  ["Hulu", 40, "tv show"],
  ["Hulu", 56, "movie"]
];

const width = 600, height = 400;
const padding = 20, marginTop = 50;

// Min and max for y axis for Revenue values
const maxRevenue = d3.max(dataset, (d) => d[1]);
const minRevenue = d3.min(dataset, (d) => d[1]);

const yScale = d3
  .scaleLinear()
  .domain([minRevenue, maxRevenue])
  .range([height - padding, marginTop]);

const xScale = d3
  .scaleBand()
  // You need to actually call `Array.prototype.map` yourself
  .domain(dataset.map((d) => d[2]))
  .range([0, 100]);

const rScale = d3
  .scaleBand()
  .domain(dataset.map((d) => d[2]))
  .range([3, 3]);

// positioning the whole chart
const xAxis = d3.axisBottom(xScale);
const yAxis = d3.axisLeft(yScale);

const svg = d3
  .select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height)
  .attr("class", "chart")
  .attr("id", "chart");

svg
  .selectAll("circle")
  .data(dataset)
  .enter()
  .append("circle")
  .attr("cx", (d) => xScale(d[2]))
  .attr("cy", (d) => yScale(d[1]))
  .attr("r", (d) => rScale(d[2]))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Ruben Helsloot
  • 12,582
  • 6
  • 26
  • 49