From a83ba45f7721ee18ddab2f354211bf84319a09c1 Mon Sep 17 00:00:00 2001 From: jwildfire Date: Thu, 19 Sep 2019 12:16:17 -0300 Subject: [PATCH 01/14] update version and rebuild --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index ec89354..b480c8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "hep-explorer", - "version": "1.1.0", + "version": "1.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f7a5acc..f6f8867 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "hep-explorer", "description": "Interactive Graphic for Exploring Hepatic Data in Clinical Trials", - "version": "1.1.0", + "version": "1.1.1", "author": "Rho, Inc.", "license": "MIT", "homepage": "https://github.com/SafetyGraphics/hep-explorer#readme", From ed5889ac023545ed153eed1c78f05121587d0185 Mon Sep 17 00:00:00 2001 From: jwildfire Date: Thu, 19 Sep 2019 12:39:56 -0300 Subject: [PATCH 02/14] adds example with custom measures. #303 --- test-page/example4/index.html | 23 ++++++++++ test-page/example4/index.js | 84 +++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 test-page/example4/index.html create mode 100644 test-page/example4/index.js diff --git a/test-page/example4/index.html b/test-page/example4/index.html new file mode 100644 index 0000000..d823ffc --- /dev/null +++ b/test-page/example4/index.html @@ -0,0 +1,23 @@ + + + Hepatic Safety Explorer - Example 2 + + + + + + + + + + + + +
Hepatic Safety Explorer
+
Example 4 - Example with custom measures
+
This is a demo page for the interactive Hepatic Explorer created by the ASA-DIA Interactive Safety Graphics working group. Code, details and documentation are available on github.
+
+ + + + diff --git a/test-page/example4/index.js b/test-page/example4/index.js new file mode 100644 index 0000000..2973f9c --- /dev/null +++ b/test-page/example4/index.js @@ -0,0 +1,84 @@ +const settings = { + max_width: 600, + value_col: 'LBORRES', + measure_col: 'TESTNAM', + visit_col:"VISIT", + // visitn_col: 'VISITNUM', + studyday_col: 'STUDYDAY', + normal_col_low: 'LBORRESLO', + normal_col_high: 'LBORRESHI', + id_col: 'SUBJID', + group_cols: ['TRTA','SEX'], + filters: [ + { + value_col: 'TRTA', + label: 'Treatment' + }, + { + value_col: 'SEX', + label: 'Sex' + }, + { + value_col: 'SUBJID', + label: 'ID' + } + ], + measure_values:{ + 'ALT':'ALT (SGPT)', + 'AST':'AST (SGOT)', + 'TB':'Total Bilirubin', + 'ALP':"Alkaline Phosphatase", + 'GGT':"GGT", + "LDH":"LDH" + }, + cuts:{ + ALT: { + relative_baseline: 3.8, + relative_uln: 3, + absolute: 1.0 +}, +AST: { + relative_baseline: 3.8, + relative_uln: 3, + absolute: 1.0 +}, +TB: { + relative_baseline: 4.8, + relative_uln: 2, + absolute: 40 +}, +ALP: { + relative_baseline: 3.8, + relative_uln: 1, + absolute: 1.0 +}, + GGT: { + relative_baseline: 3.8, + relative_uln: 3, + absolute: 20 + }, + LDH: { + relative_baseline: 3.8, + relative_uln: 3, + absolute: 200 + } + }, + x_options:['ALT', 'AST', 'ALP','GGT',"LDH"], + y_options:['TB', 'GGT', "LDH"], + baseline:{ + value_col:"STUDYDAY", + values:[1] + }, + analysisFlag:{ + value_col:"EPOCH", + values:["Analysis"] + } +}; +const chart = hepexplorer('#container', settings); +d3.csv('../example2/allQuads.csv', function(data) { + data.forEach(function(d){ + d.EPOCH = +d.STUDYDAY > 1 ? "Analysis" : "Baseline"; + d.AgeGroup = +d.AGE < 60 ? "<60":"60+"; + }) + chart.init(data); +}); From b1f56b93b5642f7020c7078fb72d4b10c24a23b1 Mon Sep 17 00:00:00 2001 From: jwildfire Date: Thu, 19 Sep 2019 13:54:08 -0300 Subject: [PATCH 03/14] Calculate default cuts. fix #304 --- hepexplorer.js | 23 ++++++++++- src/callbacks/onInit/checkMeasureDetails.js | 14 +++++++ src/configuration/settings.js | 6 ++- test-page/example4/index.js | 44 ++++++++++----------- 4 files changed, 61 insertions(+), 26 deletions(-) diff --git a/hepexplorer.js b/hepexplorer.js index a89e363..8871150 100644 --- a/hepexplorer.js +++ b/hepexplorer.js @@ -285,7 +285,11 @@ }, xMeasure: null, //set in syncSettings yMeasure: null, //set in syncSettings - display: null //set in syncSettings + display: null, //set in syncSettings + defaults: { + relative_baseline: 3.8, + relative_uln: 3 + } }, imputation_methods: { ALT: 'data-driven', @@ -847,6 +851,23 @@ } }); }); + + //check that all measure_values have associated cut measure_values + console.log(config.cuts); + Object.keys(config.measure_values).forEach(function(m) { + console.log(m); + // does a cut point for the custom value exist? if not create it. + if (!config.cuts.hasOwnProperty(m)) { + config.cuts[m] = {}; + } + + // does the cut have non-null baseline and ULN cuts associated, if not use the default values + config.cuts[m].relative_baseline = + config.cuts[m].relative_baseline || config.cuts.defaults.relative_baseline; + config.cuts[m].relative_uln = + config.cuts[m].relative_uln || config.cuts.defaults.relative_uln; + }); + console.log(config.cuts); } function iterateOverData() { diff --git a/src/callbacks/onInit/checkMeasureDetails.js b/src/callbacks/onInit/checkMeasureDetails.js index b13a17b..79677e8 100644 --- a/src/callbacks/onInit/checkMeasureDetails.js +++ b/src/callbacks/onInit/checkMeasureDetails.js @@ -37,4 +37,18 @@ export default function checkMeasureDetails() { } }); }); + + //check that all measure_values have associated cut measure_values + Object.keys(config.measure_values).forEach(function(m) { + // does a cut point for the custom value exist? if not create it. + if (!config.cuts.hasOwnProperty(m)) { + config.cuts[m] = {}; + } + + // does the cut have non-null baseline and ULN cuts associated, if not use the default values + config.cuts[m].relative_baseline = + config.cuts[m].relative_baseline || config.cuts.defaults.relative_baseline; + config.cuts[m].relative_uln = + config.cuts[m].relative_uln || config.cuts.defaults.relative_uln; + }); } diff --git a/src/configuration/settings.js b/src/configuration/settings.js index d5c092b..a1bcb75 100644 --- a/src/configuration/settings.js +++ b/src/configuration/settings.js @@ -60,7 +60,11 @@ export default function settings() { }, xMeasure: null, //set in syncSettings yMeasure: null, //set in syncSettings - display: null //set in syncSettings + display: null, //set in syncSettings + defaults: { + relative_baseline: 3.8, + relative_uln: 3 + } }, imputation_methods: { ALT: 'data-driven', diff --git a/test-page/example4/index.js b/test-page/example4/index.js index 2973f9c..8533a66 100644 --- a/test-page/example4/index.js +++ b/test-page/example4/index.js @@ -31,38 +31,34 @@ const settings = { 'GGT':"GGT", "LDH":"LDH" }, + /* cuts:{ ALT: { - relative_baseline: 3.8, - relative_uln: 3, - absolute: 1.0 -}, -AST: { - relative_baseline: 3.8, - relative_uln: 3, - absolute: 1.0 -}, -TB: { - relative_baseline: 4.8, - relative_uln: 2, - absolute: 40 -}, -ALP: { - relative_baseline: 3.8, - relative_uln: 1, - absolute: 1.0 -}, - GGT: { relative_baseline: 3.8, - relative_uln: 3, - absolute: 20 + relative_uln: 3 + }, + AST: { + relative_baseline: 3.8, + relative_uln: 3 + }, + TB: { + relative_baseline: 4.8, + relative_uln: 2 + }, + ALP: { + relative_baseline: 3.8, + relative_uln: 1 }, + GGT: { + relative_baseline: 3.8, + relative_uln: 3 + }, LDH: { relative_baseline: 3.8, - relative_uln: 3, - absolute: 200 + relative_uln: 3 } }, + */ x_options:['ALT', 'AST', 'ALP','GGT',"LDH"], y_options:['TB', 'GGT', "LDH"], baseline:{ From a81ebed1a02572b0edeffb946eff70ff2ddcbd1c Mon Sep 17 00:00:00 2001 From: jwildfire Date: Thu, 19 Sep 2019 13:57:55 -0300 Subject: [PATCH 04/14] add comment in example --- test-page/example4/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test-page/example4/index.js b/test-page/example4/index.js index 8533a66..33ba392 100644 --- a/test-page/example4/index.js +++ b/test-page/example4/index.js @@ -32,6 +32,7 @@ const settings = { "LDH":"LDH" }, /* + **Code below is required when measure_values is customized prior to v1.1.1** cuts:{ ALT: { relative_baseline: 3.8, From 34da44eac8e098c717c9cac1c547b8303294819d Mon Sep 17 00:00:00 2001 From: jwildfire Date: Fri, 20 Sep 2019 09:40:07 -0300 Subject: [PATCH 05/14] tweak settings flow. fix #308 --- hepexplorer.js | 117 ++++++++++++++++-------------- src/configuration/settings.js | 3 - src/configuration/syncSettings.js | 18 ++++- 3 files changed, 76 insertions(+), 62 deletions(-) diff --git a/hepexplorer.js b/hepexplorer.js index 8871150..4553e2b 100644 --- a/hepexplorer.js +++ b/hepexplorer.js @@ -283,9 +283,6 @@ relative_baseline: 3.8, relative_uln: 1 }, - xMeasure: null, //set in syncSettings - yMeasure: null, //set in syncSettings - display: null, //set in syncSettings defaults: { relative_baseline: 3.8, relative_uln: 3 @@ -388,18 +385,21 @@ } //Replicate settings in multiple places in the settings object - function syncSettings(settings) { - settings.marks[0].per[0] = settings.id_col; + function syncSettings(settings$$1) { + var defaults = settings(); + settings$$1.marks[0].per[0] = settings$$1.id_col; //set grouping config - if (typeof settings.group_cols == 'string') { - settings.group_cols = [{ value_col: settings.group_cols, label: settings.group_cols }]; + if (typeof settings$$1.group_cols == 'string') { + settings$$1.group_cols = [ + { value_col: settings$$1.group_cols, label: settings$$1.group_cols } + ]; } - if (!(settings.group_cols instanceof Array && settings.group_cols.length)) { - settings.group_cols = [{ value_col: 'NONE', label: 'None' }]; + if (!(settings$$1.group_cols instanceof Array && settings$$1.group_cols.length)) { + settings$$1.group_cols = [{ value_col: 'NONE', label: 'None' }]; } else { - settings.group_cols = settings.group_cols.map(function(group) { + settings$$1.group_cols = settings$$1.group_cols.map(function(group) { return { value_col: group.value_col || group, label: group.label || group.value_col || group @@ -407,33 +407,34 @@ }); var hasNone = - settings.group_cols + settings$$1.group_cols .map(function(m) { return m.value_col; }) .indexOf('NONE') > -1; if (!hasNone) { - settings.group_cols.unshift({ value_col: 'NONE', label: 'None' }); + settings$$1.group_cols.unshift({ value_col: 'NONE', label: 'None' }); } } - if (settings.group_cols.length > 1) { - settings.color_by = settings.group_cols[1].value_col - ? settings.group_cols[1].value_col - : settings.group_cols[1]; + if (settings$$1.group_cols.length > 1) { + settings$$1.color_by = settings$$1.group_cols[1].value_col + ? settings$$1.group_cols[1].value_col + : settings$$1.group_cols[1]; } else { - settings.color_by = 'NONE'; + settings$$1.color_by = 'NONE'; } //make sure filters is an Array - if (!(settings.filters instanceof Array)) { - settings.filters = typeof settings.filters == 'string' ? [settings.filters] : []; + if (!(settings$$1.filters instanceof Array)) { + settings$$1.filters = + typeof settings$$1.filters == 'string' ? [settings$$1.filters] : []; } //Define default details. - var defaultDetails = [{ value_col: settings.id_col, label: 'Subject Identifier' }]; - if (settings.filters) { - settings.filters.forEach(function(filter) { + var defaultDetails = [{ value_col: settings$$1.id_col, label: 'Subject Identifier' }]; + if (settings$$1.filters) { + settings$$1.filters.forEach(function(filter) { var obj = { value_col: filter.value_col ? filter.value_col : filter, label: filter.label @@ -453,8 +454,8 @@ }); } - if (settings.group_cols) { - settings.group_cols + if (settings$$1.group_cols) { + settings$$1.group_cols .filter(function(f) { return f.value_col != 'NONE'; }) @@ -478,17 +479,18 @@ } //parse details to array if needed - if (!(settings.details instanceof Array)) { - settings.details = typeof settings.details == 'string' ? [settings.details] : []; + if (!(settings$$1.details instanceof Array)) { + settings$$1.details = + typeof settings$$1.details == 'string' ? [settings$$1.details] : []; } //If [settings.details] is not specified: - if (!settings.details) settings.details = defaultDetails; + if (!settings$$1.details) settings$$1.details = defaultDetails; else { //If [settings.details] is specified: //Allow user to specify an array of columns or an array of objects with a column property //and optionally a column label. - settings.details.forEach(function(detail) { + settings$$1.details.forEach(function(detail) { if ( defaultDetails .map(function(d) { @@ -505,45 +507,53 @@ : detail }); }); - settings.details = defaultDetails; + settings$$1.details = defaultDetails; } // If settings.analysisFlag is null - if (!settings.analysisFlag) settings.analysisFlag = { value_col: null, values: [] }; - if (!settings.analysisFlag.value_col) settings.analysisFlag.value_col = null; - if (!(settings.analysisFlag.values instanceof Array)) { - settings.analysisFlag.values = - typeof settings.analysisFlag.values == 'string' - ? [settings.analysisFlag.values] + if (!settings$$1.analysisFlag) settings$$1.analysisFlag = { value_col: null, values: [] }; + if (!settings$$1.analysisFlag.value_col) settings$$1.analysisFlag.value_col = null; + if (!(settings$$1.analysisFlag.values instanceof Array)) { + settings$$1.analysisFlag.values = + typeof settings$$1.analysisFlag.values == 'string' + ? [settings$$1.analysisFlag.values] : []; } //if it is null, set settings.baseline.value_col to settings.studyday_col. - if (!settings.baseline) settings.baseline = { value_col: null, values: [] }; - if (!settings.baseline.value_col) settings.baseline.value_col = settings.studyday_col; - if (!(settings.baseline.values instanceof Array)) { - settings.baseline.values = - typeof settings.baseline.values == 'string' ? [settings.baseline.values] : []; + if (!settings$$1.baseline) settings$$1.baseline = { value_col: null, values: [] }; + if (!settings$$1.baseline.value_col) + settings$$1.baseline.value_col = settings$$1.studyday_col; + if (!(settings$$1.baseline.values instanceof Array)) { + settings$$1.baseline.values = + typeof settings$$1.baseline.values == 'string' ? [settings$$1.baseline.values] : []; } //parse x_ and y_options to array if needed - if (!(settings.x_options instanceof Array)) { - settings.x_options = typeof settings.x_options == 'string' ? [settings.x_options] : []; + if (!(settings$$1.x_options instanceof Array)) { + settings$$1.x_options = + typeof settings$$1.x_options == 'string' ? [settings$$1.x_options] : []; } - if (!(settings.y_options instanceof Array)) { - settings.y_options = typeof settings.y_options == 'string' ? [settings.y_options] : []; + if (!(settings$$1.y_options instanceof Array)) { + settings$$1.y_options = + typeof settings$$1.y_options == 'string' ? [settings$$1.y_options] : []; } - // track initial Cutpoint (lets us detect when cutpoint should change) - settings.cuts.x = settings.x.column; - settings.cuts.y = settings.y.column; - settings.cuts.display = settings.display; - //Attach measure columns to axis settings. - settings.x.column = settings.x_options[0]; - settings.y.column = settings.y_options[0]; + settings$$1.x.column = settings$$1.x_options[0]; + settings$$1.y.column = settings$$1.y_options[0]; + + // track initial Cutpoint (lets us detect when cutpoint should change) + settings$$1.cuts.x = settings$$1.x.column; + settings$$1.cuts.y = settings$$1.y.column; + settings$$1.cuts.display = settings$$1.display; + settings$$1.cuts.defaults = settings$$1.cuts.defaults || defaults.cuts.defaults; + settings$$1.cuts.defaults.relative_uln = + settings$$1.cuts.defaults.relative_uln || defaults.cuts.defaults.relative_uln; + settings$$1.cuts.defaults.relative_baseline = + settings$$1.cuts.defaults.relative_baseline || defaults.cuts.defaults.relative_baseline; - return settings; + return settings$$1; } function controlInputs() { @@ -853,9 +863,7 @@ }); //check that all measure_values have associated cut measure_values - console.log(config.cuts); Object.keys(config.measure_values).forEach(function(m) { - console.log(m); // does a cut point for the custom value exist? if not create it. if (!config.cuts.hasOwnProperty(m)) { config.cuts[m] = {}; @@ -867,7 +875,6 @@ config.cuts[m].relative_uln = config.cuts[m].relative_uln || config.cuts.defaults.relative_uln; }); - console.log(config.cuts); } function iterateOverData() { diff --git a/src/configuration/settings.js b/src/configuration/settings.js index a1bcb75..f7be191 100644 --- a/src/configuration/settings.js +++ b/src/configuration/settings.js @@ -58,9 +58,6 @@ export default function settings() { relative_baseline: 3.8, relative_uln: 1 }, - xMeasure: null, //set in syncSettings - yMeasure: null, //set in syncSettings - display: null, //set in syncSettings defaults: { relative_baseline: 3.8, relative_uln: 3 diff --git a/src/configuration/syncSettings.js b/src/configuration/syncSettings.js index ec77f55..d61c1fd 100644 --- a/src/configuration/syncSettings.js +++ b/src/configuration/syncSettings.js @@ -1,5 +1,8 @@ +import getDefaults from './settings'; + //Replicate settings in multiple places in the settings object export default function syncSettings(settings) { + const defaults = getDefaults(); settings.marks[0].per[0] = settings.id_col; //set grouping config @@ -118,14 +121,21 @@ export default function syncSettings(settings) { settings.y_options = typeof settings.y_options == 'string' ? [settings.y_options] : []; } - // track initial Cutpoint (lets us detect when cutpoint should change) + //Attach measure columns to axis settings. + settings.x.column = settings.x_options[0]; + settings.y.column = settings.y_options[0]; + + // track initial Cutpoint (lets us detect when cutpoint should change) settings.cuts.x = settings.x.column; settings.cuts.y = settings.y.column; settings.cuts.display = settings.display; - //Attach measure columns to axis settings. - settings.x.column = settings.x_options[0]; - settings.y.column = settings.y_options[0]; + // Confirm detaults are set + settings.cuts.defaults = settings.cuts.defaults || defaults.cuts.defaults; + settings.cuts.defaults.relative_uln = + settings.cuts.defaults.relative_uln || defaults.cuts.defaults.relative_uln; + settings.cuts.defaults.relative_baseline = + settings.cuts.defaults.relative_baseline || defaults.cuts.defaults.relative_baseline; return settings; } From cf6ef2ba93a474223d7d62254446e14cf153e68c Mon Sep 17 00:00:00 2001 From: jwildfire Date: Fri, 20 Sep 2019 09:59:58 -0300 Subject: [PATCH 06/14] merge default and user settings for cuts. fix #305 --- hepexplorer.js | 16 +++++++++++++--- src/callbacks/onInit/checkMeasureDetails.js | 4 ++-- src/configuration/syncSettings.js | 10 +++++++++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/hepexplorer.js b/hepexplorer.js index 4553e2b..aebe15e 100644 --- a/hepexplorer.js +++ b/hepexplorer.js @@ -543,16 +543,26 @@ settings$$1.x.column = settings$$1.x_options[0]; settings$$1.y.column = settings$$1.y_options[0]; - // track initial Cutpoint (lets us detect when cutpoint should change) + // track initial Cutpoint (lets us detect when cutpoint should change) settings$$1.cuts.x = settings$$1.x.column; settings$$1.cuts.y = settings$$1.y.column; settings$$1.cuts.display = settings$$1.display; + + // Confirm detaults are set settings$$1.cuts.defaults = settings$$1.cuts.defaults || defaults.cuts.defaults; settings$$1.cuts.defaults.relative_uln = settings$$1.cuts.defaults.relative_uln || defaults.cuts.defaults.relative_uln; settings$$1.cuts.defaults.relative_baseline = settings$$1.cuts.defaults.relative_baseline || defaults.cuts.defaults.relative_baseline; + // keep default cuts if user hasn't provided an alternative + var cutMeasures = Object.keys(settings$$1.cuts); + Object.keys(defaults.cuts).forEach(function(m) { + if (cutMeasures.indexOf(m) == -1) { + settings$$1.cuts[m] = defaults.cuts[m]; + } + }); + return settings$$1; } @@ -862,9 +872,9 @@ }); }); - //check that all measure_values have associated cut measure_values + //check that all measure_values have associated cuts Object.keys(config.measure_values).forEach(function(m) { - // does a cut point for the custom value exist? if not create it. + // does a cut point for the measure exist? If not, use the default config or create a placeholder. if (!config.cuts.hasOwnProperty(m)) { config.cuts[m] = {}; } diff --git a/src/callbacks/onInit/checkMeasureDetails.js b/src/callbacks/onInit/checkMeasureDetails.js index 79677e8..762950a 100644 --- a/src/callbacks/onInit/checkMeasureDetails.js +++ b/src/callbacks/onInit/checkMeasureDetails.js @@ -38,9 +38,9 @@ export default function checkMeasureDetails() { }); }); - //check that all measure_values have associated cut measure_values + //check that all measure_values have associated cuts Object.keys(config.measure_values).forEach(function(m) { - // does a cut point for the custom value exist? if not create it. + // does a cut point for the measure exist? If not, create a placeholder. if (!config.cuts.hasOwnProperty(m)) { config.cuts[m] = {}; } diff --git a/src/configuration/syncSettings.js b/src/configuration/syncSettings.js index d61c1fd..d3b5b16 100644 --- a/src/configuration/syncSettings.js +++ b/src/configuration/syncSettings.js @@ -124,7 +124,7 @@ export default function syncSettings(settings) { //Attach measure columns to axis settings. settings.x.column = settings.x_options[0]; settings.y.column = settings.y_options[0]; - + // track initial Cutpoint (lets us detect when cutpoint should change) settings.cuts.x = settings.x.column; settings.cuts.y = settings.y.column; @@ -137,5 +137,13 @@ export default function syncSettings(settings) { settings.cuts.defaults.relative_baseline = settings.cuts.defaults.relative_baseline || defaults.cuts.defaults.relative_baseline; + // keep default cuts if user hasn't provided an alternative + const cutMeasures = Object.keys(settings.cuts); + Object.keys(defaults.cuts).forEach(function(m) { + if (cutMeasures.indexOf(m) == -1) { + settings.cuts[m] = defaults.cuts[m]; + } + }); + return settings; } From af9c0e9d97f52514ad39c5e90b30e0ae082eb98f Mon Sep 17 00:00:00 2001 From: jwildfire Date: Fri, 20 Sep 2019 10:20:50 -0300 Subject: [PATCH 07/14] add 'all' option for axes and point size. fix #311 --- hepexplorer.js | 23 +++++++++++------------ src/configuration/controlInputs.js | 2 +- src/configuration/settings.js | 13 +++---------- src/configuration/syncSettings.js | 6 ++++++ test-page/example4/index.js | 4 ++-- 5 files changed, 23 insertions(+), 25 deletions(-) diff --git a/hepexplorer.js b/hepexplorer.js index aebe15e..4c551b0 100644 --- a/hepexplorer.js +++ b/hepexplorer.js @@ -262,19 +262,12 @@ TB: 'Total Bilirubin', ALP: 'Alkaline phosphatase (ALP)' }, - x_options: ['ALT', 'AST', 'ALP'], + addMeasures: false, + x_options: 'all', y_options: ['TB'], point_size: 'Uniform', - point_size_options: ['ALT', 'AST', 'ALP', 'TB', 'rRatio'], + point_size_options: 'all', cuts: { - ALT: { - relative_baseline: 3.8, - relative_uln: 3 - }, - AST: { - relative_baseline: 3.8, - relative_uln: 3 - }, TB: { relative_baseline: 4.8, relative_uln: 2 @@ -528,6 +521,12 @@ typeof settings$$1.baseline.values == 'string' ? [settings$$1.baseline.values] : []; } + //check for 'all' in x_, y_ and point_size_options + var allMeasures = Object.keys(settings$$1.measure_values); + if (settings$$1.x_options == 'all') settings$$1.x_options = allMeasures; + if (settings$$1.y_options == 'all') settings$$1.y_options = allMeasures; + if (settings$$1.point_size_options == 'all') settings$$1.point_size_options = allMeasures; + //parse x_ and y_options to array if needed if (!(settings$$1.x_options instanceof Array)) { settings$$1.x_options = @@ -647,7 +646,7 @@ description: 'Parameter to set point radius', options: ['point_size'], start: null, // set in syncControlInputs() - values: ['Uniform'], + values: ['Uniform', 'rRatio'], require: true }, { @@ -874,7 +873,7 @@ //check that all measure_values have associated cuts Object.keys(config.measure_values).forEach(function(m) { - // does a cut point for the measure exist? If not, use the default config or create a placeholder. + // does a cut point for the measure exist? If not, create a placeholder. if (!config.cuts.hasOwnProperty(m)) { config.cuts[m] = {}; } diff --git a/src/configuration/controlInputs.js b/src/configuration/controlInputs.js index d56fd0d..0d59b8a 100644 --- a/src/configuration/controlInputs.js +++ b/src/configuration/controlInputs.js @@ -79,7 +79,7 @@ export default function controlInputs() { description: 'Parameter to set point radius', options: ['point_size'], start: null, // set in syncControlInputs() - values: ['Uniform'], + values: ['Uniform', 'rRatio'], require: true }, { diff --git a/src/configuration/settings.js b/src/configuration/settings.js index f7be191..43b9637 100644 --- a/src/configuration/settings.js +++ b/src/configuration/settings.js @@ -37,19 +37,12 @@ export default function settings() { TB: 'Total Bilirubin', ALP: 'Alkaline phosphatase (ALP)' }, - x_options: ['ALT', 'AST', 'ALP'], + addMeasures: false, + x_options: 'all', y_options: ['TB'], point_size: 'Uniform', - point_size_options: ['ALT', 'AST', 'ALP', 'TB', 'rRatio'], + point_size_options: 'all', cuts: { - ALT: { - relative_baseline: 3.8, - relative_uln: 3 - }, - AST: { - relative_baseline: 3.8, - relative_uln: 3 - }, TB: { relative_baseline: 4.8, relative_uln: 2 diff --git a/src/configuration/syncSettings.js b/src/configuration/syncSettings.js index d3b5b16..bdf7293 100644 --- a/src/configuration/syncSettings.js +++ b/src/configuration/syncSettings.js @@ -112,6 +112,12 @@ export default function syncSettings(settings) { typeof settings.baseline.values == 'string' ? [settings.baseline.values] : []; } + //check for 'all' in x_, y_ and point_size_options + const allMeasures = Object.keys(settings.measure_values); + if (settings.x_options == 'all') settings.x_options = allMeasures; + if (settings.y_options == 'all') settings.y_options = allMeasures; + if (settings.point_size_options == 'all') settings.point_size_options = allMeasures; + //parse x_ and y_options to array if needed if (!(settings.x_options instanceof Array)) { settings.x_options = typeof settings.x_options == 'string' ? [settings.x_options] : []; diff --git a/test-page/example4/index.js b/test-page/example4/index.js index 33ba392..0a975aa 100644 --- a/test-page/example4/index.js +++ b/test-page/example4/index.js @@ -60,8 +60,8 @@ const settings = { } }, */ - x_options:['ALT', 'AST', 'ALP','GGT',"LDH"], - y_options:['TB', 'GGT', "LDH"], + // x_options:['ALT', 'AST', 'ALP','GGT',"LDH"], + y_options:['TB'], baseline:{ value_col:"STUDYDAY", values:[1] From a060f0265f954a8a86660fb9b3113ddc348ccd07 Mon Sep 17 00:00:00 2001 From: jwildfire Date: Fri, 20 Sep 2019 11:32:38 -0300 Subject: [PATCH 08/14] starting to add logic for all values. controls are broken though --- hepexplorer.js | 37 ++++++++++++++++----- src/callbacks/onInit/checkMeasureDetails.js | 21 +++++++++++- src/configuration/settings.js | 2 +- test-page/example4/index.js | 1 + 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/hepexplorer.js b/hepexplorer.js index 4c551b0..b9578e8 100644 --- a/hepexplorer.js +++ b/hepexplorer.js @@ -262,7 +262,7 @@ TB: 'Total Bilirubin', ALP: 'Alkaline phosphatase (ALP)' }, - addMeasures: false, + add_measures: false, x_options: 'all', y_options: ['TB'], point_size: 'Uniform', @@ -565,7 +565,7 @@ return settings$$1; } - function controlInputs() { + function controlInputs$1() { return [ { type: 'number', @@ -820,12 +820,13 @@ var configuration = { settings: settings, syncSettings: syncSettings, - controlInputs: controlInputs, + controlInputs: controlInputs$1, syncControlInputs: syncControlInputs }; function checkMeasureDetails() { var config = this.config; + var defaults = this.initial_settings; var measures = d3 .set( this.raw_data.map(function(d) { @@ -854,10 +855,21 @@ '.' ); + //automatically add Measures if requested + if (config.add_measures) { + measures.forEach(function(m, i) { + if (specifiedMeasures.indexOf(m) == -1) { + config.measure_values['m' + i] = m; + } + }); + } + console.log(config.measure_values); + //check that x_options, y_options and size_options all have value keys/values in measure_values - var valid_options = d3.merge([Object.keys(config.measure_values), ['rRatio']]); + var valid_options = Object.keys(config.measure_values); var all_options = ['x_options', 'y_options', 'point_size_options']; all_options.forEach(function(options) { + // remove invalid options config[options].forEach(function(option) { if (valid_options.indexOf(option) == -1) { delete config[options][option]; @@ -869,8 +881,17 @@ ); } }); + + // add options for controls requesting 'all' measures + if (defaults.point_size_options == 'all') + config[option] = d3.merge([['Uniform', 'rRatio'], valid_options]); }); + //update controls to use the current options + controlInputs.find(function(ci) { + return ci.label === 'Point Size'; + }).values = []; + //check that all measure_values have associated cuts Object.keys(config.measure_values).forEach(function(m) { // does a cut point for the measure exist? If not, create a placeholder. @@ -4071,7 +4092,7 @@ aspect: 2 }; - var controlInputs$1 = [ + var controlInputs$2 = [ { type: 'subsetter', label: 'Select Labs', @@ -4493,20 +4514,20 @@ var spaghettiElement = this.element + ' .participantDetails .spaghettiPlot .chart'; //Add y axis type options - controlInputs$1.find(function(f) { + controlInputs$2.find(function(f) { return f.label == 'Y-axis Display Type'; }).values = config.display_options.map(function(m) { return m.label; }); //sync parameter filter - controlInputs$1.find(function(f) { + controlInputs$2.find(function(f) { return f.label == 'Select Labs'; }).value_col = config.measure_col; var spaghettiControls = webcharts.createControls(spaghettiElement, { location: 'top', - inputs: controlInputs$1 + inputs: controlInputs$2 }); //draw that chart diff --git a/src/callbacks/onInit/checkMeasureDetails.js b/src/callbacks/onInit/checkMeasureDetails.js index 762950a..d800881 100644 --- a/src/callbacks/onInit/checkMeasureDetails.js +++ b/src/callbacks/onInit/checkMeasureDetails.js @@ -1,6 +1,7 @@ export default function checkMeasureDetails() { var chart = this; var config = this.config; + var defaults = this.initial_settings; const measures = d3 .set(this.raw_data.map(d => d[config.measure_col])) .values() @@ -21,10 +22,21 @@ export default function checkMeasureDetails() { }: ${missingMeasures.join(', ')}.` ); + //automatically add Measures if requested + if (config.add_measures) { + measures.forEach(function(m, i) { + if (specifiedMeasures.indexOf(m) == -1) { + config.measure_values['m' + i] = m; + } + }); + } + console.log(config.measure_values); + //check that x_options, y_options and size_options all have value keys/values in measure_values - const valid_options = d3.merge([Object.keys(config.measure_values), ['rRatio']]); + const valid_options = Object.keys(config.measure_values); const all_options = ['x_options', 'y_options', 'point_size_options']; all_options.forEach(function(options) { + // remove invalid options config[options].forEach(function(option) { if (valid_options.indexOf(option) == -1) { delete config[options][option]; @@ -36,8 +48,15 @@ export default function checkMeasureDetails() { ); } }); + + // add options for controls requesting 'all' measures + if (defaults[option] == 'all') + config[option] = valid_options; }); + //update controls to use the current options + controlInputs.find(ci => ci.label === 'Point Size').values = []; + //check that all measure_values have associated cuts Object.keys(config.measure_values).forEach(function(m) { // does a cut point for the measure exist? If not, create a placeholder. diff --git a/src/configuration/settings.js b/src/configuration/settings.js index 43b9637..e759872 100644 --- a/src/configuration/settings.js +++ b/src/configuration/settings.js @@ -37,7 +37,7 @@ export default function settings() { TB: 'Total Bilirubin', ALP: 'Alkaline phosphatase (ALP)' }, - addMeasures: false, + add_measures: false, x_options: 'all', y_options: ['TB'], point_size: 'Uniform', diff --git a/test-page/example4/index.js b/test-page/example4/index.js index 0a975aa..73949eb 100644 --- a/test-page/example4/index.js +++ b/test-page/example4/index.js @@ -31,6 +31,7 @@ const settings = { 'GGT':"GGT", "LDH":"LDH" }, + add_measures:true, /* **Code below is required when measure_values is customized prior to v1.1.1** cuts:{ From 7b33f083015d61b56733038d7627b2372de606df Mon Sep 17 00:00:00 2001 From: jwildfire Date: Mon, 23 Sep 2019 07:52:51 -0300 Subject: [PATCH 09/14] creates addMeasures setting --- hepexplorer.js | 54 ++++++++++++--------- src/callbacks/onInit/checkMeasureDetails.js | 27 ++++++----- src/configuration/syncControlInputs.js | 4 +- src/configuration/syncSettings.js | 5 +- test-page/example4/index.js | 5 +- 5 files changed, 57 insertions(+), 38 deletions(-) diff --git a/hepexplorer.js b/hepexplorer.js index b9578e8..e00faca 100644 --- a/hepexplorer.js +++ b/hepexplorer.js @@ -521,10 +521,13 @@ typeof settings$$1.baseline.values == 'string' ? [settings$$1.baseline.values] : []; } - //check for 'all' in x_, y_ and point_size_options + //check for 'all' in x_, y_ and point_size_options, but keep track if all options are used for later var allMeasures = Object.keys(settings$$1.measure_values); + settings$$1.x_options_all = settings$$1.x_options == 'all'; if (settings$$1.x_options == 'all') settings$$1.x_options = allMeasures; + settings$$1.y_options_all = settings$$1.y_options == 'all'; if (settings$$1.y_options == 'all') settings$$1.y_options = allMeasures; + settings$$1.point_size_options_all = settings$$1.point_size_options == 'all'; if (settings$$1.point_size_options == 'all') settings$$1.point_size_options = allMeasures; //parse x_ and y_options to array if needed @@ -565,7 +568,7 @@ return settings$$1; } - function controlInputs$1() { + function controlInputs() { return [ { type: 'number', @@ -710,7 +713,7 @@ return controlInput.option === 'x.column'; }); - xAxisMeasureControl.description = settings.x_options.join(', '); + //xAxisMeasureControl.description = settings.x_options.join(', '); xAxisMeasureControl.start = settings.x_options[0]; xAxisMeasureControl.values = settings.x_options; } @@ -739,7 +742,7 @@ var yAxisMeasureControl = controlInputs.find(function(controlInput) { return controlInput.option === 'y.column'; }); - yAxisMeasureControl.description = settings.y_options.join(', '); + // yAxisMeasureControl.description = settings.y_options.join(', '); yAxisMeasureControl.start = settings.y_options[0]; yAxisMeasureControl.values = settings.y_options; } @@ -820,13 +823,13 @@ var configuration = { settings: settings, syncSettings: syncSettings, - controlInputs: controlInputs$1, + controlInputs: controlInputs, syncControlInputs: syncControlInputs }; function checkMeasureDetails() { + var chart = this; var config = this.config; - var defaults = this.initial_settings; var measures = d3 .set( this.raw_data.map(function(d) { @@ -863,35 +866,42 @@ } }); } - console.log(config.measure_values); //check that x_options, y_options and size_options all have value keys/values in measure_values var valid_options = Object.keys(config.measure_values); - var all_options = ['x_options', 'y_options', 'point_size_options']; - all_options.forEach(function(options) { + var all_settings = ['x_options', 'y_options', 'point_size_options']; + all_settings.forEach(function(setting) { // remove invalid options - config[options].forEach(function(option) { + config[setting].forEach(function(option) { if (valid_options.indexOf(option) == -1) { delete config[options][option]; console.warn( option + " wasn't found in the measure_values index and has been removed from config." + - options + + setting + '. This may cause problems with the chart.' ); } }); // add options for controls requesting 'all' measures - if (defaults.point_size_options == 'all') - config[option] = d3.merge([['Uniform', 'rRatio'], valid_options]); + if (config[setting + '_all']) { + var point_size_options = d3.merge([['Uniform', 'rRatio'], valid_options]); + config[setting] = + setting == 'point_size_options' ? point_size_options : valid_options; + var controlLabel = + setting == 'x_options' + ? 'X-axis Measure' + : setting == 'y_options' + ? 'Y-axis Measure' + : 'Point Size'; + var input = chart.controls.config.inputs.find(function(ci) { + return ci.label == controlLabel; + }); + input.values = config[setting]; + } }); - //update controls to use the current options - controlInputs.find(function(ci) { - return ci.label === 'Point Size'; - }).values = []; - //check that all measure_values have associated cuts Object.keys(config.measure_values).forEach(function(m) { // does a cut point for the measure exist? If not, create a placeholder. @@ -4092,7 +4102,7 @@ aspect: 2 }; - var controlInputs$2 = [ + var controlInputs$1 = [ { type: 'subsetter', label: 'Select Labs', @@ -4514,20 +4524,20 @@ var spaghettiElement = this.element + ' .participantDetails .spaghettiPlot .chart'; //Add y axis type options - controlInputs$2.find(function(f) { + controlInputs$1.find(function(f) { return f.label == 'Y-axis Display Type'; }).values = config.display_options.map(function(m) { return m.label; }); //sync parameter filter - controlInputs$2.find(function(f) { + controlInputs$1.find(function(f) { return f.label == 'Select Labs'; }).value_col = config.measure_col; var spaghettiControls = webcharts.createControls(spaghettiElement, { location: 'top', - inputs: controlInputs$2 + inputs: controlInputs$1 }); //draw that chart diff --git a/src/callbacks/onInit/checkMeasureDetails.js b/src/callbacks/onInit/checkMeasureDetails.js index d800881..6b3e6b9 100644 --- a/src/callbacks/onInit/checkMeasureDetails.js +++ b/src/callbacks/onInit/checkMeasureDetails.js @@ -1,7 +1,6 @@ export default function checkMeasureDetails() { var chart = this; var config = this.config; - var defaults = this.initial_settings; const measures = d3 .set(this.raw_data.map(d => d[config.measure_col])) .values() @@ -30,33 +29,39 @@ export default function checkMeasureDetails() { } }); } - console.log(config.measure_values); //check that x_options, y_options and size_options all have value keys/values in measure_values const valid_options = Object.keys(config.measure_values); - const all_options = ['x_options', 'y_options', 'point_size_options']; - all_options.forEach(function(options) { + const all_settings = ['x_options', 'y_options', 'point_size_options']; + all_settings.forEach(function(setting) { // remove invalid options - config[options].forEach(function(option) { + config[setting].forEach(function(option) { if (valid_options.indexOf(option) == -1) { delete config[options][option]; console.warn( option + " wasn't found in the measure_values index and has been removed from config." + - options + + setting + '. This may cause problems with the chart.' ); } }); // add options for controls requesting 'all' measures - if (defaults[option] == 'all') - config[option] = valid_options; + if (config[setting + '_all']) { + const point_size_options = d3.merge([['Uniform', 'rRatio'], valid_options]); + config[setting] = setting == 'point_size_options' ? point_size_options : valid_options; + const controlLabel = + setting == 'x_options' + ? 'X-axis Measure' + : setting == 'y_options' + ? 'Y-axis Measure' + : 'Point Size'; + var input = chart.controls.config.inputs.find(ci => ci.label == controlLabel); + input.values = config[setting]; + } }); - //update controls to use the current options - controlInputs.find(ci => ci.label === 'Point Size').values = []; - //check that all measure_values have associated cuts Object.keys(config.measure_values).forEach(function(m) { // does a cut point for the measure exist? If not, create a placeholder. diff --git a/src/configuration/syncControlInputs.js b/src/configuration/syncControlInputs.js index b67d49c..8faae1f 100644 --- a/src/configuration/syncControlInputs.js +++ b/src/configuration/syncControlInputs.js @@ -33,7 +33,7 @@ export default function syncControlInputs(controlInputs, settings) { controlInput => controlInput.option === 'x.column' ); - xAxisMeasureControl.description = settings.x_options.join(', '); + //xAxisMeasureControl.description = settings.x_options.join(', '); xAxisMeasureControl.start = settings.x_options[0]; xAxisMeasureControl.values = settings.x_options; } @@ -60,7 +60,7 @@ export default function syncControlInputs(controlInputs, settings) { const yAxisMeasureControl = controlInputs.find( controlInput => controlInput.option === 'y.column' ); - yAxisMeasureControl.description = settings.y_options.join(', '); + // yAxisMeasureControl.description = settings.y_options.join(', '); yAxisMeasureControl.start = settings.y_options[0]; yAxisMeasureControl.values = settings.y_options; } diff --git a/src/configuration/syncSettings.js b/src/configuration/syncSettings.js index bdf7293..876621b 100644 --- a/src/configuration/syncSettings.js +++ b/src/configuration/syncSettings.js @@ -112,10 +112,13 @@ export default function syncSettings(settings) { typeof settings.baseline.values == 'string' ? [settings.baseline.values] : []; } - //check for 'all' in x_, y_ and point_size_options + //check for 'all' in x_, y_ and point_size_options, but keep track if all options are used for later const allMeasures = Object.keys(settings.measure_values); + settings.x_options_all = settings.x_options == 'all'; if (settings.x_options == 'all') settings.x_options = allMeasures; + settings.y_options_all = settings.y_options == 'all'; if (settings.y_options == 'all') settings.y_options = allMeasures; + settings.point_size_options_all = settings.point_size_options == 'all'; if (settings.point_size_options == 'all') settings.point_size_options = allMeasures; //parse x_ and y_options to array if needed diff --git a/test-page/example4/index.js b/test-page/example4/index.js index 73949eb..e77e6c6 100644 --- a/test-page/example4/index.js +++ b/test-page/example4/index.js @@ -61,8 +61,9 @@ const settings = { } }, */ - // x_options:['ALT', 'AST', 'ALP','GGT',"LDH"], - y_options:['TB'], + //x_options:['ALT', 'AST', 'ALP','GGT',"LDH"], +// x_options:"all", + // y_options:"all", baseline:{ value_col:"STUDYDAY", values:[1] From d9d4a31d1b1919f286013ce8c2439aa4eeda28cc Mon Sep 17 00:00:00 2001 From: jwildfire Date: Thu, 26 Sep 2019 09:47:29 -0300 Subject: [PATCH 10/14] Relabel measures in controls. fix #310 --- hepexplorer.js | 55 ++++++++++++++----- src/callbacks/onInit/checkMeasureDetails.js | 30 ++++++---- src/callbacks/onLayout.js | 2 + .../onLayout/relabelMeasureControls.js | 15 +++++ 4 files changed, 75 insertions(+), 27 deletions(-) create mode 100644 src/callbacks/onLayout/relabelMeasureControls.js diff --git a/hepexplorer.js b/hepexplorer.js index e00faca..619afc9 100644 --- a/hepexplorer.js +++ b/hepexplorer.js @@ -884,21 +884,26 @@ } }); - // add options for controls requesting 'all' measures - if (config[setting + '_all']) { - var point_size_options = d3.merge([['Uniform', 'rRatio'], valid_options]); - config[setting] = - setting == 'point_size_options' ? point_size_options : valid_options; - var controlLabel = - setting == 'x_options' - ? 'X-axis Measure' - : setting == 'y_options' - ? 'Y-axis Measure' - : 'Point Size'; - var input = chart.controls.config.inputs.find(function(ci) { - return ci.label == controlLabel; - }); - input.values = config[setting]; + // update the control input settings + var controlLabel = + setting == 'x_options' + ? 'X-axis Measure' + : setting == 'y_options' + ? 'Y-axis Measure' + : 'Point Size'; + var input = chart.controls.config.inputs.find(function(ci) { + return ci.label == controlLabel; + }); + + if (input) { + //only update this if the input settings exist - axis inputs with only one value are deleted + // add options for controls requesting 'all' measures + if (config[setting + '_all']) { + var point_size_options = d3.merge([['Uniform', 'rRatio'], valid_options]); + config[setting] = + setting == 'point_size_options' ? point_size_options : valid_options; + input.values = config[setting]; + } } }); @@ -2037,6 +2042,25 @@ .style('border-radius', '0.2em'); } + function relabelMeasureControls() { + var chart = this; + var config = this.config; + var controlLabels = ['X-axis Measure', 'Y-axis Measure', 'Point Size']; + var controlWraps = chart.controls.wrap.selectAll('div').filter(function(controlInput) { + return controlLabels.indexOf(controlInput.label) > -1; + }); + var controls = controlWraps.select('select'); + var options = controls.selectAll('option'); + var allKeys = Object.keys(config.measure_values); + options + .text(function(d) { + return allKeys.indexOf(d) > -1 ? config.measure_values[d] : d; + }) + .property('value', function(d) { + return d; + }); + } + function stopAnimation() { var chart = this; chart.svg @@ -2362,6 +2386,7 @@ initControlLabels.call(this); initEmptyChartWarning.call(this); initStudyDayControl.call(this); + relabelMeasureControls.call(this); } function updateAxisSettings() { diff --git a/src/callbacks/onInit/checkMeasureDetails.js b/src/callbacks/onInit/checkMeasureDetails.js index 6b3e6b9..2e93fd8 100644 --- a/src/callbacks/onInit/checkMeasureDetails.js +++ b/src/callbacks/onInit/checkMeasureDetails.js @@ -47,18 +47,24 @@ export default function checkMeasureDetails() { } }); - // add options for controls requesting 'all' measures - if (config[setting + '_all']) { - const point_size_options = d3.merge([['Uniform', 'rRatio'], valid_options]); - config[setting] = setting == 'point_size_options' ? point_size_options : valid_options; - const controlLabel = - setting == 'x_options' - ? 'X-axis Measure' - : setting == 'y_options' - ? 'Y-axis Measure' - : 'Point Size'; - var input = chart.controls.config.inputs.find(ci => ci.label == controlLabel); - input.values = config[setting]; + // update the control input settings + const controlLabel = + setting == 'x_options' + ? 'X-axis Measure' + : setting == 'y_options' + ? 'Y-axis Measure' + : 'Point Size'; + var input = chart.controls.config.inputs.find(ci => ci.label == controlLabel); + + if (input) { + //only update this if the input settings exist - axis inputs with only one value are deleted + // add options for controls requesting 'all' measures + if (config[setting + '_all']) { + const point_size_options = d3.merge([['Uniform', 'rRatio'], valid_options]); + config[setting] = + setting == 'point_size_options' ? point_size_options : valid_options; + input.values = config[setting]; + } } }); diff --git a/src/callbacks/onLayout.js b/src/callbacks/onLayout.js index 679ab70..456a078 100644 --- a/src/callbacks/onLayout.js +++ b/src/callbacks/onLayout.js @@ -14,6 +14,7 @@ import { initControlLabels } from './onLayout/initControlLabels'; import { addFootnote } from './onLayout/addFootnote'; import { addDownloadButton } from './onLayout/addDownloadButton'; import { initEmptyChartWarning } from './onLayout/initEmptyChartWarning'; +import { relabelMeasureControls } from './onLayout/relabelMeasureControls'; import customizePlotStyleToggle from './onLayout/customizePlotStyleToggle'; import initStudyDayControl from './onLayout/initStudyDayControl'; @@ -41,4 +42,5 @@ export default function onLayout() { initControlLabels.call(this); initEmptyChartWarning.call(this); initStudyDayControl.call(this); + relabelMeasureControls.call(this); } diff --git a/src/callbacks/onLayout/relabelMeasureControls.js b/src/callbacks/onLayout/relabelMeasureControls.js new file mode 100644 index 0000000..2470aa6 --- /dev/null +++ b/src/callbacks/onLayout/relabelMeasureControls.js @@ -0,0 +1,15 @@ +export function relabelMeasureControls() { + var chart = this; + var config = this.config; + const all_settings = ['x_options', 'y_options', 'point_size_options']; + const controlLabels = ['X-axis Measure', 'Y-axis Measure', 'Point Size']; + const controlWraps = chart.controls.wrap + .selectAll('div') + .filter(controlInput => controlLabels.indexOf(controlInput.label) > -1); + const controls = controlWraps.select('select'); + const options = controls.selectAll('option'); + var allKeys = Object.keys(config.measure_values); + options + .text(d => (allKeys.indexOf(d) > -1 ? config.measure_values[d] : d)) + .property('value', d => d); +} From 72a9f80d294bc4304237df3884e219acced541a7 Mon Sep 17 00:00:00 2001 From: jwildfire Date: Thu, 26 Sep 2019 10:29:40 -0300 Subject: [PATCH 11/14] standardizes default settings for measures. fix #315 --- hepexplorer.js | 28 +++++++++++++++++++------- src/configuration/settings.js | 4 +++- src/configuration/syncControlInputs.js | 6 +++--- src/configuration/syncSettings.js | 18 ++++++++++++++--- test-page/example4/index.js | 6 +++--- 5 files changed, 45 insertions(+), 17 deletions(-) diff --git a/hepexplorer.js b/hepexplorer.js index 619afc9..3d1ac44 100644 --- a/hepexplorer.js +++ b/hepexplorer.js @@ -264,9 +264,11 @@ }, add_measures: false, x_options: 'all', + x_default: 'ALT', y_options: ['TB'], - point_size: 'Uniform', + y_default: 'TB', point_size_options: 'all', + point_size_default: 'Uniform', cuts: { TB: { relative_baseline: 4.8, @@ -541,9 +543,21 @@ typeof settings$$1.y_options == 'string' ? [settings$$1.y_options] : []; } - //Attach measure columns to axis settings. - settings$$1.x.column = settings$$1.x_options[0]; - settings$$1.y.column = settings$$1.y_options[0]; + //set starting values for axis and point size settings. + settings$$1.point_size = + settings$$1.point_size_options.indexOf(settings$$1.point_size_default) > -1 + ? settings$$1.point_size_default + : settings$$1.point_size_default == 'rRatio' + ? 'rRatio' + : 'Uniform'; + settings$$1.x.column = + settings$$1.x_options.indexOf(settings$$1.x_default) > -1 + ? settings$$1.x_default + : settings$$1.x_options[0]; + settings$$1.y.column = + settings$$1.y_options.indexOf(settings$$1.y_default) > -1 + ? settings$$1.y_default + : settings$$1.y_options[0]; // track initial Cutpoint (lets us detect when cutpoint should change) settings$$1.cuts.x = settings$$1.x.column; @@ -714,7 +728,7 @@ }); //xAxisMeasureControl.description = settings.x_options.join(', '); - xAxisMeasureControl.start = settings.x_options[0]; + xAxisMeasureControl.start = settings.x.column; xAxisMeasureControl.values = settings.x_options; } @@ -743,7 +757,7 @@ return controlInput.option === 'y.column'; }); // yAxisMeasureControl.description = settings.y_options.join(', '); - yAxisMeasureControl.start = settings.y_options[0]; + yAxisMeasureControl.start = settings.y.column; yAxisMeasureControl.values = settings.y_options; } @@ -777,7 +791,7 @@ return ci.label === 'Point Size'; }); - pointSizeControl.start = settings.point_size || 'Uniform'; + pointSizeControl.start = settings.point_size; settings.point_size_options.forEach(function(d) { pointSizeControl.values.push(d); diff --git a/src/configuration/settings.js b/src/configuration/settings.js index e759872..74b7c43 100644 --- a/src/configuration/settings.js +++ b/src/configuration/settings.js @@ -39,9 +39,11 @@ export default function settings() { }, add_measures: false, x_options: 'all', + x_default: 'ALT', y_options: ['TB'], - point_size: 'Uniform', + y_default: 'TB', point_size_options: 'all', + point_size_default: 'Uniform', cuts: { TB: { relative_baseline: 4.8, diff --git a/src/configuration/syncControlInputs.js b/src/configuration/syncControlInputs.js index 8faae1f..03c6537 100644 --- a/src/configuration/syncControlInputs.js +++ b/src/configuration/syncControlInputs.js @@ -34,7 +34,7 @@ export default function syncControlInputs(controlInputs, settings) { ); //xAxisMeasureControl.description = settings.x_options.join(', '); - xAxisMeasureControl.start = settings.x_options[0]; + xAxisMeasureControl.start = settings.x.column; xAxisMeasureControl.values = settings.x_options; } @@ -61,7 +61,7 @@ export default function syncControlInputs(controlInputs, settings) { controlInput => controlInput.option === 'y.column' ); // yAxisMeasureControl.description = settings.y_options.join(', '); - yAxisMeasureControl.start = settings.y_options[0]; + yAxisMeasureControl.start = settings.y.column; yAxisMeasureControl.values = settings.y_options; } @@ -93,7 +93,7 @@ export default function syncControlInputs(controlInputs, settings) { const pointSizeControl = controlInputs.find(ci => ci.label === 'Point Size'); - pointSizeControl.start = settings.point_size || 'Uniform'; + pointSizeControl.start = settings.point_size; settings.point_size_options.forEach(function(d) { pointSizeControl.values.push(d); diff --git a/src/configuration/syncSettings.js b/src/configuration/syncSettings.js index 876621b..6b0ceea 100644 --- a/src/configuration/syncSettings.js +++ b/src/configuration/syncSettings.js @@ -130,9 +130,21 @@ export default function syncSettings(settings) { settings.y_options = typeof settings.y_options == 'string' ? [settings.y_options] : []; } - //Attach measure columns to axis settings. - settings.x.column = settings.x_options[0]; - settings.y.column = settings.y_options[0]; + //set starting values for axis and point size settings. + settings.point_size = + settings.point_size_options.indexOf(settings.point_size_default) > -1 + ? settings.point_size_default + : settings.point_size_default == 'rRatio' + ? 'rRatio' + : 'Uniform'; + settings.x.column = + settings.x_options.indexOf(settings.x_default) > -1 + ? settings.x_default + : settings.x_options[0]; + settings.y.column = + settings.y_options.indexOf(settings.y_default) > -1 + ? settings.y_default + : settings.y_options[0]; // track initial Cutpoint (lets us detect when cutpoint should change) settings.cuts.x = settings.x.column; diff --git a/test-page/example4/index.js b/test-page/example4/index.js index e77e6c6..257e99e 100644 --- a/test-page/example4/index.js +++ b/test-page/example4/index.js @@ -32,6 +32,9 @@ const settings = { "LDH":"LDH" }, add_measures:true, + x_default:"ALT", + // y_default:"ALT", + y_options:'all', /* **Code below is required when measure_values is customized prior to v1.1.1** cuts:{ @@ -61,9 +64,6 @@ const settings = { } }, */ - //x_options:['ALT', 'AST', 'ALP','GGT',"LDH"], -// x_options:"all", - // y_options:"all", baseline:{ value_col:"STUDYDAY", values:[1] From 9c9f4935c9f66def376e7bdaa5c0aeb75bb351ec Mon Sep 17 00:00:00 2001 From: jwildfire Date: Thu, 26 Sep 2019 10:33:17 -0300 Subject: [PATCH 12/14] update version --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index b480c8d..2061752 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "hep-explorer", - "version": "1.1.1", + "version": "1.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f6f8867..c8e12a6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "hep-explorer", "description": "Interactive Graphic for Exploring Hepatic Data in Clinical Trials", - "version": "1.1.1", + "version": "1.2.0", "author": "Rho, Inc.", "license": "MIT", "homepage": "https://github.com/SafetyGraphics/hep-explorer#readme", From a5506719a9d657ef4c1a30bccacb570c03bbc3fa Mon Sep 17 00:00:00 2001 From: jwildfire Date: Thu, 26 Sep 2019 12:40:52 -0300 Subject: [PATCH 13/14] Keep default measures unless overwritten --- hepexplorer.js | 10 ++++++++-- src/callbacks/onInit/checkMeasureDetails.js | 1 - src/configuration/syncSettings.js | 8 +++++++- test-page/example4/index.js | 3 --- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/hepexplorer.js b/hepexplorer.js index 3d1ac44..7421a10 100644 --- a/hepexplorer.js +++ b/hepexplorer.js @@ -523,6 +523,12 @@ typeof settings$$1.baseline.values == 'string' ? [settings$$1.baseline.values] : []; } + //merge in default measure_values if user hasn't specified changes + Object.keys(defaults.measure_values).forEach(function(val) { + if (!settings$$1.measure_values.hasOwnProperty(val)) + settings$$1.measure_values[val] = defaults.measure_values[val]; + }); + //check for 'all' in x_, y_ and point_size_options, but keep track if all options are used for later var allMeasures = Object.keys(settings$$1.measure_values); settings$$1.x_options_all = settings$$1.x_options == 'all'; @@ -564,7 +570,7 @@ settings$$1.cuts.y = settings$$1.y.column; settings$$1.cuts.display = settings$$1.display; - // Confirm detaults are set + // Confirm detault cuts are set settings$$1.cuts.defaults = settings$$1.cuts.defaults || defaults.cuts.defaults; settings$$1.cuts.defaults.relative_uln = settings$$1.cuts.defaults.relative_uln || defaults.cuts.defaults.relative_uln; @@ -920,7 +926,7 @@ } } }); - + console.log(config.measure_values); //check that all measure_values have associated cuts Object.keys(config.measure_values).forEach(function(m) { // does a cut point for the measure exist? If not, create a placeholder. diff --git a/src/callbacks/onInit/checkMeasureDetails.js b/src/callbacks/onInit/checkMeasureDetails.js index 2e93fd8..ae4048e 100644 --- a/src/callbacks/onInit/checkMeasureDetails.js +++ b/src/callbacks/onInit/checkMeasureDetails.js @@ -67,7 +67,6 @@ export default function checkMeasureDetails() { } } }); - //check that all measure_values have associated cuts Object.keys(config.measure_values).forEach(function(m) { // does a cut point for the measure exist? If not, create a placeholder. diff --git a/src/configuration/syncSettings.js b/src/configuration/syncSettings.js index 6b0ceea..df69390 100644 --- a/src/configuration/syncSettings.js +++ b/src/configuration/syncSettings.js @@ -112,6 +112,12 @@ export default function syncSettings(settings) { typeof settings.baseline.values == 'string' ? [settings.baseline.values] : []; } + //merge in default measure_values if user hasn't specified changes + Object.keys(defaults.measure_values).forEach(function(val) { + if (!settings.measure_values.hasOwnProperty(val)) + settings.measure_values[val] = defaults.measure_values[val]; + }); + //check for 'all' in x_, y_ and point_size_options, but keep track if all options are used for later const allMeasures = Object.keys(settings.measure_values); settings.x_options_all = settings.x_options == 'all'; @@ -151,7 +157,7 @@ export default function syncSettings(settings) { settings.cuts.y = settings.y.column; settings.cuts.display = settings.display; - // Confirm detaults are set + // Confirm detault cuts are set settings.cuts.defaults = settings.cuts.defaults || defaults.cuts.defaults; settings.cuts.defaults.relative_uln = settings.cuts.defaults.relative_uln || defaults.cuts.defaults.relative_uln; diff --git a/test-page/example4/index.js b/test-page/example4/index.js index 257e99e..e232a7a 100644 --- a/test-page/example4/index.js +++ b/test-page/example4/index.js @@ -32,9 +32,6 @@ const settings = { "LDH":"LDH" }, add_measures:true, - x_default:"ALT", - // y_default:"ALT", - y_options:'all', /* **Code below is required when measure_values is customized prior to v1.1.1** cuts:{ From 9f4355f2d64b2486cbf295c2a8723f23bc0c89ee Mon Sep 17 00:00:00 2001 From: Spencer Date: Fri, 27 Sep 2019 11:08:06 -0400 Subject: [PATCH 14/14] update example 0 --- test-page/example0/index.html | 2 +- test-page/example0/index.js | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/test-page/example0/index.html b/test-page/example0/index.html index d6c0245..ab2e52d 100644 --- a/test-page/example0/index.html +++ b/test-page/example0/index.html @@ -16,7 +16,7 @@
Hepatic Safety Explorer
Example 0 - Simulated Data
-
This is a demo page for the interactive Hepatic Explorer created by the ASA-DIA Interactive Safety Graphics working group. Code, details and documentation are available on github.
+
This is a demo page for the interactive Hepatic Explorer created by the ASA-DIA Interactive Safety Graphics working group. Code, details and documentation are available on github.
diff --git a/test-page/example0/index.js b/test-page/example0/index.js index 1e491d1..98d7ea5 100644 --- a/test-page/example0/index.js +++ b/test-page/example0/index.js @@ -10,12 +10,5 @@ d3.csv( } // settings ); instance.init(data); - console.log(instance) - - //quick test of participantSelected event - instance.chart.wrap.on("participantsSelected",function(){ - console.log("Participant Selected Event:") - console.log(d3.event.data) - }) } );