我正在try 使用D3(V7)在我的网页上显示一个基本的动画条形图.这是在Django项目中完成的,因此从我的views.py文件向我的图表提供了数据.但是,该图表仅部分显示在页面上.将显示x轴线和y轴线以及轴标签.以下是我的错误消息:

Error: <rect> attribute height: Expected length, "NaN".

以下是我的html模板的相关部分:

 <div id="chart-container"></div>

        <script src="https://d3js.org/d3.v7.min.js"></script>

        <script type="text/javascript">
          const data = JSON.parse('{{ assign_levels|safe }}');

          const margin = {top: 10, right: 30, bottom: 140, left: 60};
          const width = 400 - margin.left - margin.right;
          const height = 500 - margin.top - margin.bottom;

          const svg = d3.select("#chart-container")
              .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})`);

          const x = d3.scaleBand()
              .range([0, width])
              .domain(data.map(d => d.level_assign))
              .padding(0.3);
          
          const y = d3.scaleLinear()
              .range([height, 0])
              .domain([0, d3.max(data, d => d.count)]);

          svg.append("g")
              .call(d3.axisLeft(y));

          svg.selectAll(".bar")
              .data(data)
              .enter()
              .append("rect")
              .attr("class", "bar")
              .attr("x", d => x(d.level_assign))
              .attr("width", x.bandwidth())
              .attr("y", height)
              .attr("height", 0)
              .attr("fill", "#5F9EA0")
              .transition()
              .duration(1000)
              .delay((d, i) => i * 100)
              .attr("y", d => y(d.count))
              .attr("height", d => height - y(d.count));

          svg.append("g")
              .attr("transform", `translate(0, ${height})`)
              .call(d3.axisBottom(x))
              .selectAll("text")
              .attr("transform", "rotate(-45)")
              .style("text-anchor", "end")
              .attr("dx", "-.8em")
              .attr("dy", ".15em");

          svg.append("text")
              .attr("transform", "rotate(-90)")
              .attr("y", 0 - margin.left)
              .attr("x",0 - (height / 2))
              .attr("dy", "1em")
              .style("text-anchor", "middle")
              .text("Study Count");

          svg.append("text")
              .attr("x", (width + margin.left + margin.right) / 2)
              .attr("y", margin.top / 2)
              .attr("text-anchor", "middle")
              .style("font-size", "16px")
              .text("Level of Assignment");
      </script>

下面是我在图表中输入的代码:

[["Class", 36], ["School - cluster", 6], ["Individual", 20], ["N", 1], ["School - multi-site", 9], ["Not provided/ not available", 4], ["Region or district", 1]]

我不明白为什么错误消息告诉我它收到了高度的"NaN",因为我可以看到高度是以绝对值设置的,例如500.

推荐答案

您将一个数组数组作为数据传递,但D3代码需要一个具有特定键的对象array. 我try 将数据格式转换为对象array.

You need to update your code slightly to achieve this. Check the code below:

const rawData = JSON.parse('{{ assign_levels|safe }}');
const data = rawData.map(d => ({level_assign: d[0], count: d[1]}));

This will convert your data to this format instead of a list of arrays.

[
  {"level_assign": "Class", "count": 36},
  {"level_assign": "School - cluster", "count": 6},
  {"level_assign": "Individual", "count": 20},
  {"level_assign": "N", "count": 1},
  {"level_assign": "School - multi-site", "count": 9},
  {"level_assign": "Not provided/ not available", "count": 4},
  {"level_assign": "Region or district", "count": 1}
]

Here is an example with full code:

//script.js
const rawData = [
    ["Class", 36],
    ["School - cluster", 6],
    ["Individual", 20],
    ["N", 1],
    ["School - multi-site", 9],
    ["Not provided/ not available", 4],
    ["Region or district", 1],
];

const data = rawData.map((d) => ({
    level_assign: d[0],
    count: d[1]
}));

const margin = {
    top: 10,
    right: 30,
    bottom: 140,
    left: 60
};
const width = 400 - margin.left - margin.right;
const height = 500 - margin.top - margin.bottom;

const svg = d3
    .select("#chart-container")
    .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})`);

const x = d3
    .scaleBand()
    .range([0, width])
    .domain(data.map((d) => d.level_assign))
    .padding(0.3);

const y = d3
    .scaleLinear()
    .range([height, 0])
    .domain([0, d3.max(data, (d) => d.count)]);

svg.append("g").call(d3.axisLeft(y));

svg.selectAll(".bar")
    .data(data)
    .enter()
    .append("rect")
    .attr("class", "bar")
    .attr("x", (d) => x(d.level_assign))
    .attr("width", x.bandwidth())
    .attr("y", height)
    .attr("height", 0)
    .attr("fill", "#5F9EA0")
    .transition()
    .duration(1000)
    .delay((d, i) => i * 100)
    .attr("y", (d) => y(d.count))
    .attr("height", (d) => height - y(d.count));

svg.append("g")
    .attr("transform", `translate(0, ${height})`)
    .call(d3.axisBottom(x))
    .selectAll("text")
    .attr("transform", "rotate(-45)")
    .style("text-anchor", "end")
    .attr("dx", "-.8em")
    .attr("dy", ".15em");

svg.append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 0 - margin.left)
    .attr("x", 0 - (height / 2))
    .attr("dy", "1em")
    .style("text-anchor", "middle")
    .text("Study Count");

svg.append("text")
    .attr("x", (width + margin.left + margin.right) / 2)
    .attr("y", margin.top / 2)
    .attr("text-anchor", "middle")
    .style("font-size", "16px")
    .text("Level of Assignment");
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>D3 Bar Chart</title>
</head>
<body>
    <div id="chart-container"></div>

    <script src="https://d3js.org/d3.v7.min.js"></script>
    <script src="script.js"></script>
</body>
</html>

Javascript相关问答推荐

在分区内迭代分区

对象和数字减法会抵消浏览器js中的数字

zoom svg以适应圆

Chrome是否忽略WebAuthentication userVerification设置?""

如何禁用附加图标点击的v—自动完成事件

TypeError:无法分解';React2.useContext(...)';的属性';basename';,因为它为空

有条件重定向到移动子域

如何在Angular拖放组件中同步数组?

TinyMCE 6导致Data:Image对象通过提供的脚本过度上载

获取';无法解决导入和导入";slick-carousel/slick/slick-theme.css";';错误

一个实体一刀VS每个实体多刀S

AddEventListner,按键事件不工作

将多个文本框中的输出合并到一个文本框中

如何在AG-Grid文本字段中创建占位符

重新渲染过多(&Q).REACT限制渲染次数以防止无限循环.使用REACT下拉菜单时

脚本语法错误只是一个字符串,而不是一个对象?

如何用react组件替换dom元素?

如何导入我在Web Worker创建的函数?

如何在HTML中使用rxjs显示动态更新

TS node 找不到依赖的模块