javascriptdc.jscrossfilter

How do you create a pie chart of subitems using a crossfiltered powered dc.js chart?


Suppose I have a list of customers with their orders:

const customers = [
  { id: 1, orders: [{ products: ["apple", "banana"] }, { products: ["apple"] }] },
  { id: 2, orders: [{ products: ["strawberry"] }] },
  { id: 3, orders: [{ products: ["apple"] }, { products: ["strawberry"] }] },
  { id: 4, orders: [] }
]

I would like to see a pie chart that shows a slice for every single product available. When filtering, I would like to click on "apple" and filter by the customers who ordered apples at any point in time.

I'm currently able to render the pie chart but it shows every possible combination of products as a slice.

Meaning, my pie chart has a slice for apple, banana, strawberry, apple, strawberry, and none.

This isn't what I'm going for. I did this by creating the dimension:

const dimension = crossfilter.dimension((customer: Customer) => {

    const productList = customer.orders.flatMap(x => x.products)
    const products = new Set<string>(productList);
    const result = [...products ];
    if (result.length === 0) return "none";

    return result;
})

const group = dimension.group();

The filtering behavior works correctly but the pie charts slices are not sustainable in this way.

EDIT: I added a js fiddle that demonstrates the situation a little more clearly: https://jsfiddle.net/qcaod71z/1/


Solution

  • https://github.com/crossfilter/crossfilter/wiki/API-Reference#dimension

    You can now set the second argument specify that the return value is an array.

    const dimension = crossfilter.dimension((customer: Customer) => {
        const productList = customer.orders.flatMap(x => x.products)
        const products = new Set<string>(productList);
        const result = [...products ];
        if (result.length === 0) return "none";
    
        return result;
    }, true)