Had a follow-up question Original Question which was to group by both color and day, and then find the max day for each color. Gordon did a great job explaining how to keep a running sum for each color per day and find the max. Now I am trying to show the total sum of all colors and their respective peaks in a bar chart.
In short I am looking for a single data point that sums the peak values into a total value and displays Total. I am confused what I should use for the dimension as I want a custom X dim value named TOTAL instead of a list of all of the colors. For the original example a single bar with a value of 25,760 would be displayed for the sum of the peak Color Inventory.
var carData = [
{Date: "11/26/2020", 'Inventory Region': 'SW', 'Make and Model': 'buick enclave' , 'Inventory Count': 12710, Color: 'charcoal' ,'Color Inventory': 3665},
{Date: "11/26/2020", 'Inventory Region': 'SW', 'Make and Model': 'chevrolet 1500' , 'Inventory Count': 8510, Color: 'brown', 'Color Inventory': 2520},
{Date: "11/26/2020", 'Inventory Region': 'NE', 'Make and Model': 'chevrolet camaro', 'Inventory Count': 5250, Color: 'silver', 'Color Inventory': 750},
{Date: "11/26/2020", 'Inventory Region': 'NW', 'Make and Model': 'chevrolet malibu', 'Inventory Count': 4300, Color: 'brown','Color Inventory': 2100},
{Date: "11/26/2020", 'Inventory Region': 'NW', 'Make and Model': 'dodge coupe', 'Inventory Count': 15100, Color: 'silver', 'Color Inventory': 5200},
{Date: "11/26/2020", 'Inventory Region': 'NE', 'Make and Model': 'jeep compass', 'Inventory Count': 7300, Color: 'blue', 'Color Inventory': 2300},
{Date: "11/26/2020", 'Inventory Region': 'NE', 'Make and Model': 'kia forte', 'Inventory Count': 4250,Color: 'white', 'Color Inventory': 2200},
{Date: "11/26/2020", 'Inventory Region': 'SW', 'Make and Model': 'kia sorento', 'Inventory Count': 9450,Color: 'red', 'Color Inventory': 6525},
{Date: "11/27/2020", 'Inventory Region': 'SW', 'Make and Model': 'buick enclave' , 'Inventory Count': 11251, Color: 'charcoal' ,'Color Inventory': 2206},
{Date: "11/27/2020", 'Inventory Region': 'SW', 'Make and Model': 'chevrolet 1500' , 'Inventory Count': 8246, Color: 'brown', 'Color Inventory': 2256},
{Date: "11/27/2020", 'Inventory Region': 'NE', 'Make and Model': 'chevrolet camaro', 'Inventory Count': 5200, Color: 'silver', 'Color Inventory': 700},
{Date: "11/27/2020", 'Inventory Region': 'NW', 'Make and Model': 'chevrolet malibu', 'Inventory Count': 4250, Color: 'brown','Color Inventory': 2050},
{Date: "11/27/2020", 'Inventory Region': 'NW', 'Make and Model': 'dodge coupe', 'Inventory Count': 15000, Color: 'silver', 'Color Inventory': 5100},
{Date: "11/27/2020", 'Inventory Region': 'NE', 'Make and Model': 'jeep compass', 'Inventory Count': 7200, Color: 'blue', 'Color Inventory': 2200},
{Date: "11/27/2020", 'Inventory Region': 'NE', 'Make and Model': 'kia forte', 'Inventory Count': 4150,Color: 'white', 'Color Inventory': 2100},
{Date: "11/27/2020", 'Inventory Region': 'SW', 'Make and Model': 'kia sorento', 'Inventory Count': 8953,Color: 'red', 'Color Inventory': 6058}
];
Here is the group reduce function from the previous answer:
const cf = crossfilter(carData),
colorDimension = cf.dimension(({Color}) => Color),
colorDayGroup = colorDimension.group().reduce(
(p, v) => { // add
const day = d3.timeDay(v.Date).getTime(); // 2. round to day, convert to int
p[day] = (p[day] || 0) + v['Color Inventory']; // 3
return p;
},
(p, v) => { // remove
const day = d3.timeDay(v.Date).getTime(); // round to day, convert to int
p[day] = (p[day] || 0) - v['Color Inventory']; // 4
return p;
},
() => ({}) // 1. init
);
and the value accessor which calculates the max:
chart.valueAccessor(({key, value}) => d3.max(Object.values(value)))
If you want a single value to supply to the dc.js NumberDisplay widget, the best way to get it in there is to supply a fake groupAll object, that is, an object with the single method .value()
, which returns the value.
Here, we want it to take the sum of the max value from each bin:
function sum_peaks_groupAll(group) {
return {
value: () => d3.sum(group.all(), ({value}) => d3.max(Object.values(value)))
};
}
const sumPeaks = sum_peaks_groupAll(colorDayGroup);
For historic reasons, the number display widget requires passing the identity function as value accessor when using a groupAll object for its group:
number.group(sumPeaks)
.valueAccessor(d => d);
If you want a bar chart displaying this sum, then you want an ordinary fake group. It's the same calculation but a method named .all()
that returns an array with a single element which is a key/value pair:
function sum_peaks_group(group) {
return {
all: () => ([{
key: 'All',
value: d3.sum(group.all(), ({value}) => d3.max(Object.values(value)))
}])
};
}