New to cross filter and working on a project that needs to maintain summed totals and peak values of those summed totals over a date range.
Tried to utilize the complex reduction from the dc.js examples.
I was able to get the max of a specific make and model over the date range but not the summed total peak (summed by day) for say the Region dimension or color dimension.
The project requires the following charts.
Below is a sample of the data (With the exclusion of the date being converted to a date object.)
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}
];
To put your question another way, you want to group by both color and day, and then find the max day for each color.
I'm going to assume you are also using dc.js since you mention it in your question. What we'll do is keep a running count of days for each color. Then, in the value accessor, we will find the max.
This is more efficient than calculating the maximum during group reduction.
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
);
Use it with a valueAccessor
like this:
chart.valueAccessor(({key, value}) => d3.max(Object.values(value)))
This retrieves all the counts from the day->count object and finds the max count.
I used this fiddle to test. I changed the value of
{Date: "11/27/2020", 'Inventory Region': 'NE', 'Make and Model': 'kia forte', 'Inventory Count': 4150,Color: 'white', 'Color Inventory': 2700},
because 11/26 was the max day for every color, and I wanted to exercise the code better.
To test, I mapped each value using the value accessor:
console.log(JSON.stringify(colorDayGroup.all().map(({key, value}) => ({key, value: d3.max(Object.values(value))})), null, 2))
Result:
[
{
"key": "blue",
"value": 2300
},
{
"key": "brown",
"value": 4620
},
{
"key": "charcoal",
"value": 3665
},
{
"key": "red",
"value": 6525
},
{
"key": "silver",
"value": 5950
},
{
"key": "white",
"value": 2700
}
]