Skip to content

Commit

Permalink
Merge pull request #313 from AUS-DOH-Safety-and-Quality/grouped-handling
Browse files Browse the repository at this point in the history
Initial implementation of scorecard/summary table functionality
  • Loading branch information
andrjohns authored Aug 6, 2024
2 parents 43aa5c6 + 0e8d378 commit 672c4db
Show file tree
Hide file tree
Showing 20 changed files with 824 additions and 309 deletions.
102 changes: 100 additions & 2 deletions capabilities.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
{ "displayName": "Outcome/Numerator", "name": "numerators", "kind": "Measure" },
{ "displayName": "Denominator", "name": "denominators", "kind": "Measure" },
{ "displayName": "ID Key (Date)", "name": "key", "kind": "Grouping" },
{ "displayName": "Indicator", "name": "indicator", "kind": "Grouping" },
{ "displayName": "Grouping (Summary Table)", "name": "indicator", "kind": "Grouping" },
{ "displayName": "Rebaseline Groupings", "name": "groupings", "kind": "Measure" },
{ "displayName": "SD (for xbar)", "name": "xbar_sds", "kind": "Measure" },
{ "displayName": "Tooltips", "name": "tooltips", "kind": "Measure" }
Expand Down Expand Up @@ -117,7 +117,7 @@
}
},
"outliers" : {
"displayName": "Outlier Highlighting",
"displayName": "Outlier Detection",
"properties": {
"process_flag_type": {
"displayName": "Type of Change to Flag",
Expand Down Expand Up @@ -759,6 +759,104 @@
"show_table": {
"displayName": "Show Summary Table",
"type" : { "bool" : true }
},
"table_header_font": {
"displayName": "Header Font",
"type": { "formatting": { "fontFamily": true } }
},
"table_header_size": {
"displayName": "Header Font Size",
"type": { "formatting": { "fontSize": true } }
},
"table_header_colour":{
"displayName": "Header Font Colour",
"type": { "fill": { "solid": { "color": true } } }
},
"table_header_bg_colour":{
"displayName": "Header Background Colour",
"type": { "fill": { "solid": { "color": true } } }
},
"table_header_font_weight": {
"displayName": "Header Font Weight",
"type": {
"enumeration" : [
{ "displayName" : "Normal", "value" : "normal" },
{ "displayName" : "Bold", "value" : "bold" }
]
}
},
"table_header_text_transform": {
"displayName": "Header Text Transform",
"type": {
"enumeration" : [
{ "displayName" : "Uppercase", "value" : "uppercase" },
{ "displayName" : "Lowercase", "value" : "lowercase" },
{ "displayName" : "Capitalise", "value" : "capitalize" },
{ "displayName" : "None", "value" : "none" }
]
}
},
"table_header_text_align": {
"displayName": "Text Alignment",
"type": { "formatting": { "alignment": true } }
},
"table_body_font": {
"displayName": "Body Font",
"type": { "formatting": { "fontFamily": true } }
},
"table_body_size": {
"displayName": "Body Font Size",
"type": { "formatting": { "fontSize": true } }
},
"table_body_colour":{
"displayName": "Body Font Colour",
"type": { "fill": { "solid": { "color": true } } }
},
"table_body_bg_colour":{
"displayName": "Body Background Colour",
"type": { "fill": { "solid": { "color": true } } }
},
"table_body_font_weight": {
"displayName": "Font Weight",
"type": {
"enumeration" : [
{ "displayName" : "Normal", "value" : "normal" },
{ "displayName" : "Bold", "value" : "bold" }
]
}
},
"table_body_text_transform": {
"displayName": "Text Transform",
"type": {
"enumeration" : [
{ "displayName" : "Uppercase", "value" : "uppercase" },
{ "displayName" : "Lowercase", "value" : "lowercase" },
{ "displayName" : "Capitalise", "value" : "capitalize" },
{ "displayName" : "None", "value" : "none" }
]
}
},
"table_body_text_align": {
"displayName": "Text Alignment",
"type": { "formatting": { "alignment": true } }
},
"table_opacity": {
"displayName": "Opacity",
"type": { "numeric": true }
},
"table_opacity_unselected": {
"displayName": "Opacity if Unselected",
"type": { "numeric": true }
},
"table_text_overflow": {
"displayName": "Text Overflow Handling",
"type": {
"enumeration" : [
{ "displayName" : "Ellipsis", "value" : "ellipsis" },
{ "displayName" : "Truncate", "value" : "clip" },
{ "displayName" : "None", "value" : "none" }
]
}
}
}
},
Expand Down
10 changes: 6 additions & 4 deletions src/Classes/derivedSettingsClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default class derivedSettingsClass {
multiplier: number
percentLabels: boolean
chart_type_props: {
name: string,
needs_denominator: boolean,
denominator_optional: boolean,
numerator_non_negative: boolean,
Expand All @@ -31,11 +32,11 @@ export default class derivedSettingsClass {
value_name: string
}

update(inputSettings: defaultSettingsType) {
const chartType: string = inputSettings.spc.chart_type;
update(inputSettingsSpc: defaultSettingsType["spc"]) {
const chartType: string = inputSettingsSpc.chart_type;
const pChartType: boolean = ["p", "pp"].includes(chartType);
const percentSettingString: string = inputSettings.spc.perc_labels;
let multiplier: number = inputSettings.spc.multiplier;
const percentSettingString: string = inputSettingsSpc.perc_labels;
let multiplier: number = inputSettingsSpc.multiplier;
let percentLabels: boolean;

if (percentSettingString === "Yes") {
Expand All @@ -53,6 +54,7 @@ export default class derivedSettingsClass {
}

this.chart_type_props = {
name: chartType,
needs_denominator: ["p", "pp", "u", "up", "xbar", "s"].includes(chartType),
denominator_optional: ["i", "i_m", "i_mm", "run", "mr"].includes(chartType),
numerator_non_negative: ["p", "pp", "u", "up", "s", "c", "g", "t"].includes(chartType),
Expand Down
14 changes: 4 additions & 10 deletions src/Classes/plotPropertiesClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,22 @@ export type axisProperties = {
};

export default class plotPropertiesClass {
width: number;
height: number;
displayPlot: boolean;
xAxis: axisProperties;
yAxis: axisProperties;
xScale: d3.ScaleLinear<number, number, never>;
yScale: d3.ScaleLinear<number, number, never>;

// Separate function so that the axis can be re-calculated on changes to padding
initialiseScale(): void {
initialiseScale(svgWidth: number, svgHeight: number): void {
this.xScale = d3.scaleLinear()
.domain([this.xAxis.lower, this.xAxis.upper])
.range([this.xAxis.start_padding,
this.width - this.xAxis.end_padding]);
svgWidth - this.xAxis.end_padding]);

this.yScale = d3.scaleLinear()
.domain([this.yAxis.lower, this.yAxis.upper])
.range([this.height - this.yAxis.start_padding,
.range([svgHeight - this.yAxis.start_padding,
this.yAxis.end_padding]);
}

Expand All @@ -53,10 +51,6 @@ export default class plotPropertiesClass {
derivedSettings: derivedSettingsClass,
colorPalette: colourPaletteType): void {

// Get the width and height of plotting space
this.width = options.viewport.width;
this.height = options.viewport.height;

this.displayPlot = plotPoints
? plotPoints.length > 1
: null;
Expand Down Expand Up @@ -154,6 +148,6 @@ export default class plotPropertiesClass {
label_colour: colorPalette.isHighContrast ? colorPalette.foregroundColour : inputSettings.y_axis.ylimit_label_colour
};

this.initialiseScale();
this.initialiseScale(options.viewport.width, options.viewport.height);
}
}
43 changes: 41 additions & 2 deletions src/Classes/settingsClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ type DataViewPropertyValue = powerbi.default.DataViewPropertyValue
type VisualObjectInstanceEnumerationObject = powerbi.default.VisualObjectInstanceEnumerationObject;
type VisualObjectInstance = powerbi.default.VisualObjectInstance;
type VisualObjectInstanceContainer = powerbi.default.VisualObjectInstanceContainer;
import { extractConditionalFormatting } from "../Functions";
import { extractConditionalFormatting, isNullOrUndefined } from "../Functions";
import { default as defaultSettings, type settingsValueTypes, settingsPaneGroupings, settingsPaneToggles } from "../defaultSettings";
import derivedSettingsClass from "./derivedSettingsClass";
import { type ConditionalReturnT, type SettingsValidationT } from "../Functions/extractConditionalFormatting";
Expand All @@ -19,6 +19,10 @@ export type defaultSettingsKey = keyof defaultSettingsType;
export type defaultSettingsNestedKey = NestedKeysOf<defaultSettingsType[defaultSettingsKey]>;
export type settingsScalarTypes = number | string | boolean;

export type optionalSettingsTypes = Partial<{
[K in keyof typeof defaultSettings]: Partial<defaultSettingsType[K]>;
}>;

export type paneGroupingsNestedKey = "all" | NestedKeysOf<typeof settingsPaneGroupings[keyof typeof settingsPaneGroupings]>;
export type paneTogglesNestedKey = "all" | NestedKeysOf<typeof settingsPaneToggles[keyof typeof settingsPaneToggles]>;

Expand All @@ -33,6 +37,8 @@ export default class settingsClass {
settings: defaultSettingsType;
derivedSettings: derivedSettingsClass;
validationStatus: SettingsValidationT;
settingsGrouped: defaultSettingsType[];
derivedSettingsGrouped: derivedSettingsClass[];

/**
* Function to read the values from the settings pane and update the
Expand All @@ -46,6 +52,22 @@ export default class settingsClass {
// Get the names of all classes in settingsObject which have values to be updated
const allSettingGroups: string[] = Object.keys(this.settings);

const is_grouped: boolean = inputView.categorical.values?.source?.roles?.indicator;
let group_idxs: number[] = new Array<number>();
this.settingsGrouped = new Array<defaultSettingsType>();
if (is_grouped) {
group_idxs = inputView.categorical.values.grouped().map(d => {
this.settingsGrouped.push(Object.fromEntries(Object.keys(defaultSettings).map((settingGroupName) => {
return [settingGroupName, Object.fromEntries(Object.keys(defaultSettings[settingGroupName]).map((settingName) => {
return [settingName, defaultSettings[settingGroupName][settingName]];
}))];
})) as settingsValueTypes);

return d.values[0].values.findIndex(d_in => !isNullOrUndefined(d_in));
});
}


allSettingGroups.forEach((settingGroup: defaultSettingsKey) => {
const condFormatting: ConditionalReturnT<defaultSettingsType[defaultSettingsKey]>
= extractConditionalFormatting(inputView?.categorical, settingGroup, this.settings);
Expand Down Expand Up @@ -73,10 +95,27 @@ export default class settingsClass {
= condFormatting?.values
? condFormatting?.values[0][settingName]
: defaultSettings[settingGroup][settingName]["default"]

if (is_grouped) {
group_idxs.forEach((idx, idx_idx) => {
this.settingsGrouped[idx_idx][settingGroup][settingName]
= condFormatting?.values
? condFormatting?.values[idx][settingName]
: defaultSettings[settingGroup][settingName]["default"]
})
}
})
})

this.derivedSettings.update(this.settings)
this.derivedSettings.update(this.settings.spc)
this.derivedSettingsGrouped = new Array<derivedSettingsClass>();
if (is_grouped) {
this.settingsGrouped.forEach((d) => {
const newDerived = new derivedSettingsClass();
newDerived.update(d.spc);
this.derivedSettingsGrouped.push(newDerived);
})
}
}

/**
Expand Down
Loading

0 comments on commit 672c4db

Please sign in to comment.