Skip to content

Commit

Permalink
fix RhoInc#84; fix RhoInc#85; fix RhoInc#86
Browse files Browse the repository at this point in the history
  • Loading branch information
samussiah committed Mar 22, 2021
1 parent f7ac1ab commit 1e1d04e
Show file tree
Hide file tree
Showing 14 changed files with 412 additions and 639 deletions.
932 changes: 315 additions & 617 deletions safetyShiftPlot.js

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions src/callbacks/onInit.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,22 @@ export default function onInit() {
// 4. Update control inputs.
updateControlInputs.call(this);

//Set initial measure.
this.config.measure = this.config.measure || this.measures[0];

//Set baseline and comparison visits.
this.config.x_params.visits = this.config.x_params.visits || [this.visits[0]];
this.config.y_params.visits = this.config.y_params.visits || this.visits.slice(1);

//Filter raw data on initial measure and derive baseline/comparison data.
this.measureData = this.initial_data.filter(
d => d[this.config.measure_col] === this.config.measure
d => d.ssp_measure === this.config.measure
);
this.filteredData = this.measureData; // filtered data placeholder
this.raw_data = preprocessData.call(this, this.measureData); // preprocessed measure data
if (Array.isArray(this.config.filters) && this.config.filters.length)
this.config.filters.forEach(filter => {
if (filter.start)
this.filteredData = this.filteredData
.filter(d => d[filter.value_col] === filter.start);
});
this.raw_data = preprocessData.call(this, this.filteredData); // preprocessed measure data

//Define initial domains.
this.config.x.domain = extent(this.raw_data.map(d => d.shiftx));
Expand Down
3 changes: 3 additions & 0 deletions src/callbacks/onInit/addVariables.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
export default function addVariables() {
this.initial_data.forEach(d => {
d[this.config.measure_col] = d[this.config.measure_col].trim();
d.ssp_measure = d.hasOwnProperty(this.config.unit_col)
? `${d[this.config.measure_col]} (${d[this.config.unit_col]})`
: d[this.config.measure_col];
});
}
31 changes: 27 additions & 4 deletions src/callbacks/onInit/getMeasures.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
import { set } from 'd3';
import { dataOps } from 'webcharts';

export default function getMeasures() {
this.measures = set(this.initial_data.map(d => d[this.config.measure_col]))
.values()
.sort();
// Define set of measure values as they appear in the data.
this.measures = this.initial_data[0].hasOwnProperty(this.config.measure_order_col)
? [...new Set(this.initial_data.map(d => +d[this.config.measure_order_col])).values()]
.sort((a, b) => a - b)
.map(
value =>
this.initial_data.find(d => +d[this.config.measure_order_col] === value)[
this.config.measure_col
]
)
: [...new Set(this.initial_data.map(d => d[this.config.measure_col])).values()].sort(
dataOps.naturalSorter
);

// Define set of measure values with units (in ADaM units are already attached; in SDTM units are captured in a separate variable).
this.ssp_measures = this.initial_data[0].hasOwnProperty(this.config.measure_order_col)
? [...new Set(this.initial_data.map(d => +d[this.config.measure_order_col])).values()]
.sort((a, b) => a - b)
.map(
value =>
this.initial_data.find(d => +d[this.config.measure_order_col] === value)
.ssp_measure
) // sort measures by measure order
: [...new Set(this.initial_data.map(d => d.ssp_measure)).values()].sort(
dataOps.naturalSorter
); // sort measures alphabetically
}
23 changes: 22 additions & 1 deletion src/callbacks/onInit/updateControlInputs.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
export default function updateControlInputs() {
this.controls.config.inputs.find(input => input.option === 'measure').values = this.measures;
const measureInput = this.controls.config.inputs
.find(input => input.option === 'measure');
measureInput.values = this.ssp_measures;
console.log(this.config.start_value);

if (
this.config.start_value &&
this.ssp_measures.indexOf(this.config.start_value) < 0 &&
this.measures.indexOf(this.config.start_value) < 0
) {
measureInput.start = this.ssp_measures[0];
console.warn(
`${this.config.start_value} is an invalid measure. Defaulting to ${measureInput.start}.`
);
} else if (this.config.start_value && this.ssp_measures.indexOf(this.config.start_value) < 0) {
measureInput.start = this.ssp_measures[this.measures.indexOf(this.config.start_value)];
console.warn(
`${this.config.start_value} is missing the units value. Defaulting to ${measureInput.start}.`
);
} else measureInput.start = this.config.start_value || this.ssp_measures[0];
this.config.measure = measureInput.start;

this.controls.config.inputs.find(
input => input.option === 'x_params_visits'
).values = this.visits;
Expand Down
9 changes: 7 additions & 2 deletions src/callbacks/onLayout/addFilters.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default function addFilters(chart) {
chart.config.filters.forEach(filter => {
//Capture distinct [filter.value_col] values.
filter.values = set(chart.initial_data.map(d => d[filter.value_col])).values();
filter.value = 'All';
filter.value = filter.start || 'All';

//Attach filter to the DOM.
const controlGroup = chart.controls.wrap
Expand All @@ -21,9 +21,14 @@ export default function addFilters(chart) {
//Attach distinct [filter.value_col] values as select options.
changer
.selectAll('option')
.data(['All'].concat(filter.values))
.data(
filter.all
? ['All'].concat(filter.values)
: filter.values
)
.enter()
.append('option')
.property('selected', d => d === filter.value)
.text(d => d);

//Define dropdown event listener.
Expand Down
2 changes: 1 addition & 1 deletion src/callbacks/onLayout/customizeMeasureControl.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function custmoizeMeasureControl() {

//Redefine raw and preprocessed measure data, x-domain, and y-domain.
this.measureData = this.initial_data.filter(
d => d[this.config.measure_col] === this.config.measure
d => d.ssp_measure === this.config.measure
);
this.raw_data = preprocessData.call(this, this.measureData);
this.config.x.domain = extent(this.raw_data.map(d => d.shiftx));
Expand Down
2 changes: 1 addition & 1 deletion src/callbacks/onResize/listVisits.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { set } from 'd3';
export default function listVisits() {
var possibleVisits = set(
this.initial_data
.filter(f => f[this.config.measure_col] === this.config.measure)
.filter(f => f.ssp_measure === this.config.measure)
.map(d => d[this.config.visit_col])
).values();
possibleVisits.sort((a, b) => this.visits.indexOf(a) - this.visits.indexOf(b));
Expand Down
4 changes: 2 additions & 2 deletions src/configuration/controlInputs.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ export default function controlInputs() {
{
type: 'dropdown',
values: [],
label: 'Baseline visit(s)',
label: 'Timepoint 1',
option: 'x_params_visits',
require: true,
multiple: true
},
{
type: 'dropdown',
values: [],
label: 'Comparison visit(s)',
label: 'Timepoint 2',
option: 'y_params_visits',
require: true,
multiple: true
Expand Down
2 changes: 2 additions & 0 deletions src/configuration/rendererSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ export default function rendererSettings() {
visit_col: 'VISIT',
visit_order_col: 'VISITNUM',
measure_col: 'TEST',
measure_order_col: 'TESTN',
value_col: 'STRESN',
unit_col: 'STRESU',
start_value: null,
x_params: { visits: null, stat: 'mean' },
y_params: { visits: null, stat: 'mean' },
Expand Down
6 changes: 6 additions & 0 deletions src/configuration/syncControlInputs.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ export default function syncControlInputs(controlInputs, settings) {
};
filterObject.label = filter.label || filterObject.value_col;
filterObject.type = 'subsetter';
filterObject.all = filterObject.all !== undefined
? filterObject.all
: true;
filterObject.start = filterObject.start !== undefined
? filterObject.start
: null;

if (filter instanceof Object) Object.assign(filterObject, filter);

Expand Down
1 change: 0 additions & 1 deletion src/configuration/syncSettings.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export default function syncSettings(settings) {
settings.measure = settings.start_value;
return settings;
}
3 changes: 1 addition & 2 deletions src/util/preprocessData.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function preprocessData(rawData) {
return d[config.visit_col];
})
.key(function(d) {
return d[config.measure_col];
return d.ssp_measure;
})
.rollup(function(r) {
var value = r[0][config.value_col];
Expand All @@ -24,7 +24,6 @@ export default function preprocessData(rawData) {
}

function setVal(e, params) {
console.log(params);
var visits = e.values.filter(function(f) {
return params.visits.indexOf(f.key) !== -1;
});
Expand Down
20 changes: 17 additions & 3 deletions test-page/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
d3.csv(
'https://raw.githubusercontent.com/RhoInc/data-library/master/data/clinical-trials/renderer-specific/adbds.csv',
function(d) {
function(d,i) {
return d;
},
function(data) {
const ssp = safetyShiftPlot(
const measures = [...new Set(data.map(d => d.TEST)).values()]
.sort(webCharts.dataOps.naturalSorter)
.sort(() => .5 - Math.random());
data.forEach(d => {
d.TESTN = measures.findIndex(measure => measure === d.TEST);
});

const instance = safetyShiftPlot(
'#container', // element
{
filters: [
{value_col: 'SITEID', label: 'Site ID'},
{value_col: 'SEX', label: 'Sex'},
{value_col: 'RACE', label: 'Race'},
{value_col: 'ARM', label: 'Treatment Group'},
{value_col: 'USUBJID', label: 'Participant ID'},
],
} // settings
);
ssp.init(data);
instance.init(data);
}
);

0 comments on commit 1e1d04e

Please sign in to comment.