'Using hashmaps with d3
I have a set of data that is coming from an API with information about banking transactions. I want to loop through the array and add all transactions within the same month to get a total for the month to display in a bar graph using d3. I tried using a hashmap (see below) to get the outcome that I wanted but I cannot get d3 to draw the values onto the graph. Does d3 only work using arrays? Or is there a better method to doing this?
MODEL DATA (An array that can have n numbers of transactions per user)
[{
id: 25,
amount: 45.21,
accountNumber: '1200548129',
location: 'Account transfer',
type: 'transfer',
dateOfTransaction: '2022-04-06'
}]
HASHMAP RESULT (can be n number of hashes based on month selected within the year and year date.)
{Apr: 3825.09, Mar: 186104.94}
ACTUAL D3 ATTEMPT (The axes are displaying correctly but the bars will not render)
const Dates: {
1: string;
2: string;
3: string;
4: string;
5: string;
6: string;
7: string;
8: string;
9: string;
10: string;
11: string;
12: string;
} = {
1: "Jan",
2: "Feb",
3: "Mar",
4: "Apr",
5: "May",
6: "Jun",
7: "Jul",
8: "Aug",
9: "Sep",
10: "Oct",
11: "Nov",
12: "Dec",
};
transactions
.filter((t) => {
return t.dateOfTransaction.substring(0, 4) === year;
})
.map((t) => {
const i: number = +t.dateOfTransaction.substring(6, 7);
const items: { date: string; amount: number } = {
date: Dates[
i as keyof {
1: string;
2: string;
3: string;
4: string;
5: string;
6: string;
7: string;
8: string;
9: string;
10: string;
11: string;
12: string;
}
],
amount: t.amount,
};
if (DateAmount[items.date]) {
const newAmount: number = DateAmount[items.date] + items.amount;
DateAmount[items.date] = parseFloat(newAmount.toFixed(2));
} else {
DateAmount[items.date] = parseFloat(items.amount.toFixed(2));
}
return true;
});
const svg = select(svgRef.current)
.style("background-color", "white")
.style("overflow", "visible")
.attr("width", CHART_WIDTH)
.attr("height", CHART_HEIGHT);
const x = scaleBand()
.domain(Object.keys(DateAmount))
.rangeRound([0, CHART_WIDTH])
.padding(0.6);
const y = scaleLinear()
.domain([0, max(Object.values(DateAmount))] as Iterable<NumberValue>)
.range([CHART_HEIGHT, 0]);
svg
.append("g")
.style("color", "black")
.style("transform", "translate(0,100%)")
.style("overflow", "visibile")
.call(axisBottom(x));
svg
.append("g")
.style("color", "black")
.style("transform", "translate(100%,0)")
.style("overflow", "visibile")
.call(axisLeft(y));
svg
.selectAll(".bar")
.data(Object.create(DateAmount))
.join("rect")
.style("fill", "red")
.attr("width", x.bandwidth())
.attr("height", (data) => CHART_HEIGHT - y(data as NumberValue))
.attr("x", (data) => x(data as string) as string | number)
.attr("y", (data) => y(data as NumberValue));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
