Create charts in workshop based on two objects

36 Views Asked by At

Is it possible to create bar charts in workshop based on two different object sets? For example I have two objects set Object A and Object B, I want to create a 3-D bar chart with X-axis( a date column) coming from Object A and Y-axis showing count categories i.e. coming from Object B. Edit - Object A is linked with Object B with 1-N link.

I didn't find anything in workshop itself and I was trying to do it with function based charts but not sure how to do it.

1

There are 1 best solutions below

1
ZettaP On

Going for Functions backed Charts should work. The crux of the work is to figure out which computation you need in the function to obtain what you want from the raw objects.

Assuming a cardinality of the categories for Object A and Object B being low enough (<<10k, let's assume 100), you would likely (below is only pseudocode, untested):

  1. perform an aggregation on Object A
const datesGrouped = await objects.groupBy(e => e.date.byDays()).count();
// Note: the count doesn't matter here, all you want is a short list of all the dates of Object A
  1. Iterate over each group of A and perform a computation for B
// Define the result map
const resultMap = new FunctionsMap<string, TwoDimensionalAggregation<Double>>();

// Alternative: For each string of the buckets array provided as input
const promises = buckets.map(currBucket => this.getObjectBBreakdown(currBucket));

// Use Promise.all to parallelize async execution of helper function
const allResolvedPromises = await Promise.all(promises);

// Populate resultMap with bucket and calculated value
for (let i = 0; i < buckets.length; i++) {
    resultMap.set(buckets[i], allResolvedPromises[i]);
}

And you would have another function, which for a particular object A can get you the breakdown of Object Bs

    @Function()
    private async getObjectBBreakdown(bucket: string): Promise<TwoDimensionalAggregation<Double>> {
        // Get the object A which maps to this bucket
        const startObjectAs = await Objects.search().objectAs().filter(o => o.date.exactMatch(bucket));
        // Pivot to the Object Bs
        const objectBGroups = startObjectAs.searchAroundObjectBs();

        // Compute the aggregation for this object set
        return await objectBGroups.groupBy(e => e.category.exactValue()).count()
    }

See docs

  1. then do something with both results directly in memory of the function to build your ThreeDimensionalAggregation. I don't have an example at hand for ThreeDimensional, but showing you a TwoDimensional:
        // Create a TwoDimensionalAggregation from the resultMap
        const aggregation: TwoDimensionalAggregation<string> = {
            buckets: Array.from(resultMap.entries()).map(([key, value]) => ({ key, value })),
        };

Note: If you want a "3D Chart" as in "With volumes" you might want to look at Vega plot available in Quiver. The pre-requisite will likely be the same in terms of function computation, but this would offer you additional charts options if the default ones in Workshop don't match you expectations.