/* CODE for rule!Generate_P */ load( local!categories: index(ri!data, ri!categoryField,{}), local!labels: index(ri!data, ri!labelField, {}), /* Loop over the list of series labels to find the datapoints / / for each series */ apply( rule!generateChartSeries ( data: ri!data, categoryField: ri!categoryField, labelField: ri!labelField, datapointField: ri!datapointField, /* Remove duplicates from the list of categories */ categories: union( local!categories, local!categories ), label: _, selectedField:ri!selectedField, datasubset:ri!datasubset, startIndex:ri!startIndex ), /* Remove duplicates from the list of series labels */ union(local!labels, cast(typeof(local!labels), {})) ) ) ------------------------------------------------------------------------------------------------------------------------------------------------------ /* CODE for rule!generateChartSeries */ a!chartSeries( label:ri!label, /* Loop over list of categories to find each datapoint that matches both / / the series label and the category. This will ensure that the datapoints / / are in the correct order to display in the chart. */ data: apply( rule!findDatapoints( data: ri!data, categoryField: ri!categoryField, labelField: ri!labelField, datapointField: ri!datapointField, category: _, label: ri!label ), ri!categories ), links: apply( a!dynamicLink(value: _, saveInto:ri!selectedField), /*index(ri!datasubset.data, ri!categoryField, {})*/ union(index(ri!datasubset.data, ri!categoryField, {}), cast(typeof(index(ri!datasubset.data, ri!categoryField, {})), {})) ) ) ------------------------------------------------------------------------------------------------------------------------------------------------------ /* CODE for rule!findDatapoints */ with( local!categories: index(ri!data, ri!categoryField, {}), local!labels: index(ri!data, ri!labelField, {}), /* Find all datapoints that match both the category and chart series label */ local!intersection: intersection( where(local!categories=cast(typeof(local!categories), ri!category), 0), where(local!labels=cast(typeof(local!labels), ri!label), 0) ), if( length(local!intersection)=0, /* If there is no datapoint for this category-label pair, return 0 so that / / all subsequent points are in the correct order with the categories */ 0, index(index(ri!data, ri!datapointField, {}), local!intersection, 0) ) )