D3 尺度的分类数据

categorical data with D3 scale

我正在尝试用 d3 绘制数据。我的数据如下所示:

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

我对数值数据使用 scaleLinear(),对分类数据使用 (d[1])scaleBand()。 这是我的代码:

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>

预期的输出是下面的屏幕截图。我的代码不显示圆圈...

出于某种原因,您使用了 [dataset, (d) => d[2]],但这没有任何作用。嗯,它创建了一个数据集数组和一个函数,但这不是你想要的。

要实际创建您想要的数组 (["tv show", "movie", "tv show", "movie"]),您需要自己调用 dataset.map((d) => d[2])

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>