From a1a2993a17547d1119d9910428cb9c7ddd71972d Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 30 Jan 2024 10:22:22 +0200 Subject: [PATCH 1/3] Update grouping structure for indices --- capabilities.json | 2 +- src/Classes/viewModelClass.ts | 35 ++++++++++--------- src/Functions/index.ts | 6 ++-- .../assuranceIconToDraw.ts | 2 +- .../checkFlagDirection.ts | 0 .../variationIconsToDraw.ts | 2 +- src/defaultSettings.ts | 4 +-- 7 files changed, 27 insertions(+), 24 deletions(-) rename src/{Functions => Outlier Flagging}/assuranceIconToDraw.ts (93%) rename src/{Functions => Outlier Flagging}/checkFlagDirection.ts (100%) rename src/{Functions => Outlier Flagging}/variationIconsToDraw.ts (98%) diff --git a/capabilities.json b/capabilities.json index 21bf7e6..2d24ab3 100644 --- a/capabilities.json +++ b/capabilities.json @@ -210,7 +210,7 @@ "displayName": "Show Variation Icons", "type" : { "bool" : true } }, - "flag_variation_last": { + "flag_last_point": { "displayName": "Flag Only Last Point", "type" : { "bool" : true } }, diff --git a/src/Classes/viewModelClass.ts b/src/Classes/viewModelClass.ts index b3cda23..c1e1a5a 100644 --- a/src/Classes/viewModelClass.ts +++ b/src/Classes/viewModelClass.ts @@ -68,6 +68,7 @@ export default class viewModelClass { tickLabels: { x: number; label: string; }[]; plotProperties: plotPropertiesClass; splitIndexes: number[]; + groupStartEndIndexes: number[][]; firstRun: boolean; constructor() { @@ -88,6 +89,19 @@ export default class viewModelClass { this.splitIndexes = JSON.parse(split_indexes); this.inputData = extractInputData(options.dataViews[0].categorical, this.inputSettings.settings); + const allIndexes: number[] = this.splitIndexes + .concat([-1]) + .concat(this.inputData.groupingIndexes) + .concat([this.inputData.limitInputArgs.keys.length - 1]) + .filter((d, idx, arr) => arr.indexOf(d) === idx) + .sort((a,b) => a - b); + + this.groupStartEndIndexes = new Array(); + for (let i: number = 0; i < allIndexes.length - 1; i++) { + this.groupStartEndIndexes.push([allIndexes[i] + 1, allIndexes[i + 1] + 1]) + } + console.log(this.groupStartEndIndexes) + this.calculateLimits(); this.scaleAndTruncateLimits(); this.flagOutliers(); @@ -113,24 +127,13 @@ export default class viewModelClass { const limitFunction: (args: controlLimitsArgs) => controlLimitsObject = limitFunctions[this.inputSettings.settings.spc.chart_type]; - if (this.splitIndexes.length > 0 || this.inputData.groupingIndexes.length > 0) { - const indexes: number[] = this.splitIndexes - .concat(this.inputData.groupingIndexes) - .concat([this.inputData.limitInputArgs.keys.length - 1]) - .filter((d, idx, arr) => arr.indexOf(d) === idx) - .sort((a,b) => a - b); - const groupedData: dataObject[] = indexes.map((d, idx) => { + if (this.groupStartEndIndexes.length > 1) { + const groupedData: dataObject[] = this.groupStartEndIndexes.map((indexes) => { // Force a deep copy const data: dataObject = JSON.parse(JSON.stringify(this.inputData)); - if(idx === 0) { - data.limitInputArgs.denominators = data.limitInputArgs.denominators.slice(0, d + 1) - data.limitInputArgs.numerators = data.limitInputArgs.numerators.slice(0, d + 1) - data.limitInputArgs.keys = data.limitInputArgs.keys.slice(0, d + 1) - } else { - data.limitInputArgs.denominators = data.limitInputArgs.denominators.slice(indexes[idx - 1] + 1, d + 1) - data.limitInputArgs.numerators = data.limitInputArgs.numerators.slice(indexes[idx - 1] + 1, d + 1) - data.limitInputArgs.keys = data.limitInputArgs.keys.slice(indexes[idx - 1] + 1, d + 1) - } + data.limitInputArgs.denominators = data.limitInputArgs.denominators.slice(indexes[0], indexes[1]) + data.limitInputArgs.numerators = data.limitInputArgs.numerators.slice(indexes[0], indexes[1]) + data.limitInputArgs.keys = data.limitInputArgs.keys.slice(indexes[0], indexes[1]) return data; }) diff --git a/src/Functions/index.ts b/src/Functions/index.ts index 53853b6..c5a37c2 100644 --- a/src/Functions/index.ts +++ b/src/Functions/index.ts @@ -1,9 +1,9 @@ -export { default as assuranceIconToDraw } from "./assuranceIconToDraw" +export { default as assuranceIconToDraw } from "../Outlier Flagging/assuranceIconToDraw" export { default as between } from "./between" export { default as broadcastBinary, pow, add, subtract, divide, multiply } from "./broadcastBinary" export { default as broadcastUnary, sqrt, abs, exp, lgamma, square } from "./broadcastUnary" export { default as buildTooltip } from "./buildTooltip" -export { default as checkFlagDirection } from "./checkFlagDirection" +export { default as checkFlagDirection } from "../Outlier Flagging/checkFlagDirection" export { c4, c5, a3, b3, b4 } from "./Constants" export { default as diff } from "./diff" export { default as extractConditionalFormatting } from "./extractConditionalFormatting" @@ -15,7 +15,7 @@ export { default as getAesthetic } from "./getAesthetic" export { default as rep } from "./rep" export { default as repIfScalar } from "./repIfScalar" export { default as truncate, type truncateInputs } from "./truncate" -export { default as variationIconsToDraw } from "./variationIconsToDraw" +export { default as variationIconsToDraw } from "../Outlier Flagging/variationIconsToDraw" export { mean, median, sum, max, min } from "d3-array" export { default as validateDataView } from "./validateDataView" export { default as validateInputData } from "./validateInputData" diff --git a/src/Functions/assuranceIconToDraw.ts b/src/Outlier Flagging/assuranceIconToDraw.ts similarity index 93% rename from src/Functions/assuranceIconToDraw.ts rename to src/Outlier Flagging/assuranceIconToDraw.ts index 1bdc67b..e0d1e55 100644 --- a/src/Functions/assuranceIconToDraw.ts +++ b/src/Outlier Flagging/assuranceIconToDraw.ts @@ -1,4 +1,4 @@ -import type { viewModelClass } from "../Classes/"; +import type { viewModelClass } from "../Classes"; export default function assuranceIconToDraw(viewModel: viewModelClass): string { const imp_direction: string = viewModel.inputSettings.settings.outliers.improvement_direction; diff --git a/src/Functions/checkFlagDirection.ts b/src/Outlier Flagging/checkFlagDirection.ts similarity index 100% rename from src/Functions/checkFlagDirection.ts rename to src/Outlier Flagging/checkFlagDirection.ts diff --git a/src/Functions/variationIconsToDraw.ts b/src/Outlier Flagging/variationIconsToDraw.ts similarity index 98% rename from src/Functions/variationIconsToDraw.ts rename to src/Outlier Flagging/variationIconsToDraw.ts index bb5699c..48e7eff 100644 --- a/src/Functions/variationIconsToDraw.ts +++ b/src/Outlier Flagging/variationIconsToDraw.ts @@ -14,7 +14,7 @@ export default function variationIconsToDraw(viewModel: viewModelClass): string[ "" : "" } const suffix: string = suffix_map[imp_direction]; - const flag_last: boolean = viewModel.inputSettings.settings.nhs_icons.flag_variation_last; + const flag_last: boolean = viewModel.inputSettings.settings.nhs_icons.flag_last_point; let allFlags: string[]; if (flag_last) { const N: number = currLimits.astpoint.length - 1; diff --git a/src/defaultSettings.ts b/src/defaultSettings.ts index 94fde42..50349ed 100644 --- a/src/defaultSettings.ts +++ b/src/defaultSettings.ts @@ -44,7 +44,7 @@ const defaultSettings = { }, nhs_icons: { show_variation_icons: false, - flag_variation_last: true, + flag_last_point: true, variation_icons_locations: "Top Right", variation_icons_scaling: 1, show_assurance_icons: false, @@ -143,7 +143,7 @@ export const settingsPaneGroupings = { "Two-In-Three": ["process_flag_type", "improvement_direction", "flag_series", "two_in_three", "twointhree_colour_improvement", "twointhree_colour_deterioration", "twointhree_colour_neutral_low", "twointhree_colour_neutral_high"] }, nhs_icons: { - "Variation": ["show_variation_icons", "flag_variation_last", "variation_icons_locations", "variation_icons_scaling"], + "Variation": ["show_variation_icons", "flag_last_point", "variation_icons_locations", "variation_icons_scaling"], "Assurance": ["show_assurance_icons", "assurance_icons_locations", "assurance_icons_scaling"] }, lines: { From bafd8aeb100ffe39914617ea61f4a3380b157e15 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 30 Jan 2024 10:41:55 +0200 Subject: [PATCH 2/3] Flag outliers within each rebaseline group --- src/Classes/viewModelClass.ts | 52 ++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/src/Classes/viewModelClass.ts b/src/Classes/viewModelClass.ts index c1e1a5a..c2305b6 100644 --- a/src/Classes/viewModelClass.ts +++ b/src/Classes/viewModelClass.ts @@ -281,33 +281,47 @@ export default class viewModelClass { flagOutliers() { const process_flag_type: string = this.inputSettings.settings.outliers.process_flag_type; const improvement_direction: string = this.inputSettings.settings.outliers.improvement_direction; + const flag_series: boolean = this.inputSettings.settings.outliers.flag_series; + const trend_n: number = this.inputSettings.settings.outliers.trend_n; + const shift_n: number = this.inputSettings.settings.outliers.shift_n; this.outliers = { astpoint: rep("none", this.inputData.limitInputArgs.keys.length), two_in_three: rep("none", this.inputData.limitInputArgs.keys.length), trend: rep("none", this.inputData.limitInputArgs.keys.length), shift: rep("none", this.inputData.limitInputArgs.keys.length) } - if (this.inputSettings.settings.spc.chart_type !== "run") { - if (this.inputSettings.settings.outliers.astronomical) { - this.outliers.astpoint = checkFlagDirection( - astronomical(this.controlLimits.values, this.controlLimits.ll99, this.controlLimits.ul99), - { process_flag_type, improvement_direction }); + for (let i: number = 0; i < this.groupStartEndIndexes.length; i++) { + const start: number = this.groupStartEndIndexes[i][0]; + const end: number = this.groupStartEndIndexes[i][1]; + const group_values: number[] = this.controlLimits.values.slice(start, end); + const group_targets: number[] = this.controlLimits.targets.slice(start, end); + const group_ll99: number[] = this.controlLimits?.ll99?.slice(start, end); + const group_ll95: number[] = this.controlLimits?.ll95?.slice(start, end); + const group_ul95: number[] = this.controlLimits?.ul95?.slice(start, end); + const group_ul99: number[] = this.controlLimits?.ul99?.slice(start, end); + + if (this.inputSettings.settings.spc.chart_type !== "run") { + if (this.inputSettings.settings.outliers.astronomical) { + astronomical(group_values, group_ll99, group_ul99) + .forEach((flag, idx) => this.outliers.astpoint[start + idx] = flag) + } + if (this.inputSettings.settings.outliers.two_in_three) { + twoInThree(group_values, group_ll95, group_ul95, flag_series) + .forEach((flag, idx) => this.outliers.two_in_three[start + idx] = flag) + } } - if (this.inputSettings.settings.outliers.two_in_three) { - this.outliers.two_in_three = checkFlagDirection( - twoInThree(this.controlLimits.values, this.controlLimits.ll95, this.controlLimits.ul95, this.inputSettings.settings.outliers.flag_series), - { process_flag_type, improvement_direction }); + if (this.inputSettings.settings.outliers.trend) { + trend(group_values, trend_n, flag_series) + .forEach((flag, idx) => this.outliers.trend[start + idx] = flag) + } + if (this.inputSettings.settings.outliers.shift) { + shift(group_values, group_targets, shift_n, flag_series) + .forEach((flag, idx) => this.outliers.shift[start + idx] = flag) } } - if (this.inputSettings.settings.outliers.trend) { - this.outliers.trend = checkFlagDirection( - trend(this.controlLimits.values, this.inputSettings.settings.outliers.trend_n, this.inputSettings.settings.outliers.flag_series), - { process_flag_type, improvement_direction }); - } - if (this.inputSettings.settings.outliers.shift) { - this.outliers.shift = checkFlagDirection( - shift(this.controlLimits.values, this.controlLimits.targets, this.inputSettings.settings.outliers.shift_n, this.inputSettings.settings.outliers.flag_series), - { process_flag_type, improvement_direction }); - } + Object.keys(this.outliers).forEach(key => { + this.outliers[key] = checkFlagDirection(this.outliers[key], + { process_flag_type, improvement_direction }); + }) } } From f55ec84bad965d9a34266f66423153760c5c7696 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 30 Jan 2024 11:02:45 +0200 Subject: [PATCH 3/3] Tidy naming and order --- capabilities.json | 8 ++++---- src/Classes/viewModelClass.ts | 1 - src/defaultSettings.ts | 6 +----- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/capabilities.json b/capabilities.json index 2d24ab3..b6b966c 100644 --- a/capabilities.json +++ b/capabilities.json @@ -114,7 +114,7 @@ "type" : { "bool" : true } }, "astronomical": { - "displayName": "Astronomical Points", + "displayName": "Highlight Astronomical Points", "type" : { "bool" : true } }, "ast_colour_improvement":{ @@ -134,7 +134,7 @@ "type": { "fill": { "solid": { "color": true } } } }, "shift": { - "displayName": "Shifts", + "displayName": "Highlight Shifts", "type" : { "bool" : true } }, "shift_n": { @@ -158,7 +158,7 @@ "type": { "fill": { "solid": { "color": true } } } }, "trend": { - "displayName": "Trends", + "displayName": "Highlight Trends", "type" : { "bool" : true } }, "trend_n": { @@ -182,7 +182,7 @@ "type": { "fill": { "solid": { "color": true } } } }, "two_in_three": { - "displayName": "Two-in-Three", + "displayName": "Highlight Two-in-Three", "type" : { "bool" : true } }, "twointhree_colour_improvement":{ diff --git a/src/Classes/viewModelClass.ts b/src/Classes/viewModelClass.ts index c2305b6..61b7f15 100644 --- a/src/Classes/viewModelClass.ts +++ b/src/Classes/viewModelClass.ts @@ -100,7 +100,6 @@ export default class viewModelClass { for (let i: number = 0; i < allIndexes.length - 1; i++) { this.groupStartEndIndexes.push([allIndexes[i] + 1, allIndexes[i + 1] + 1]) } - console.log(this.groupStartEndIndexes) this.calculateLimits(); this.scaleAndTruncateLimits(); diff --git a/src/defaultSettings.ts b/src/defaultSettings.ts index 50349ed..b365eec 100644 --- a/src/defaultSettings.ts +++ b/src/defaultSettings.ts @@ -43,8 +43,8 @@ const defaultSettings = { twointhree_colour_neutral_high: "#490092" }, nhs_icons: { - show_variation_icons: false, flag_last_point: true, + show_variation_icons: false, variation_icons_locations: "Top Right", variation_icons_scaling: 1, show_assurance_icons: false, @@ -142,10 +142,6 @@ export const settingsPaneGroupings = { "Trends": ["process_flag_type", "improvement_direction", "flag_series", "trend", "trend_n", "trend_colour_improvement", "trend_colour_deterioration", "trend_colour_neutral_low", "trend_colour_neutral_high"], "Two-In-Three": ["process_flag_type", "improvement_direction", "flag_series", "two_in_three", "twointhree_colour_improvement", "twointhree_colour_deterioration", "twointhree_colour_neutral_low", "twointhree_colour_neutral_high"] }, - nhs_icons: { - "Variation": ["show_variation_icons", "flag_last_point", "variation_icons_locations", "variation_icons_scaling"], - "Assurance": ["show_assurance_icons", "assurance_icons_locations", "assurance_icons_scaling"] - }, lines: { "Main": ["show_main", "width_main", "type_main", "colour_main"], "Target": ["show_target", "width_target", "type_target", "colour_target", "ttip_show_target", "ttip_label_target"],