3đź‘Ť
âś…
You’re passing an array of arrays as data but the D3 code expects an array of objects with specific keys.
I tried to convert the data format into an array of objects.
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>
👤dostogircse171
1đź‘Ť
The Python pandas
dataframe returns NaN
for empty results (short for “Not a Number”). You can change it by using the fillna
method on your dataframe:
df = df.fillna('')
This should solve the problem downstream for display issues, but you’ll have to dig a bit deeper to find why it is being passed for height.
👤FlipperPA
- [Django]-How to filter ManyToMany field in Django queryset?
- [Django]-Django import-export exclude not working
- [Django]-How to pass a parameter to a view with HTMX and Django?
Source:stackexchange.com