clinical-timelines
Advanced tools
Comparing version 1.4.0 to 1.4.1
{ | ||
"name": "clinical-timelines", | ||
"description": "A general purpose graphical timeline library", | ||
"version": "1.4.0", | ||
"version": "1.4.1", | ||
"author": "Rho, Inc.", | ||
@@ -28,4 +28,8 @@ "license": "MIT", | ||
"format-build": "prettier --print-width=100 --tab-width=4 --single-quote --write build/clinicalTimelines.js", | ||
"test": "npm run test-call && npm run test-init && npm run test-interactivity", | ||
"test-call": "mocha --timeout 5000 --require babel-register --recursive ./test/call.js", | ||
"test-init": "mocha --timeout 5000 --require babel-register --recursive ./test/init.js", | ||
"test-interactivity": "mocha --timeout 5000 --require babel-register --recursive ./test/interactivity/viewChange.js", | ||
"test-page": "start chrome ./build/test-page/index.html && start firefox ./build/test-page/index.html && start iexplore file://%CD%/build/test-page/index.html", | ||
"test": "mocha --timeout 5000 --require babel-register --recursive ./test/**/*.js", | ||
"unit-test": "mocha --timeout 5000 --require babel-register --recursive ./test/call.js", | ||
"watch": "rollup -c -w" | ||
@@ -32,0 +36,0 @@ }, |
@@ -15,3 +15,3 @@ # Clinical Timelines | ||
[Click here](https://rhoinc.github.io/viz-library/examples/0022-clinical-timelines/example.html) to see a demo with clinical trial data as the input. | ||
[Click here](https://rhoinc.github.io/clinical-timelines/build/test-page/) to see a demo with clinical trial data as the input. | ||
@@ -48,2 +48,1 @@ ## Usage | ||
* [Release Notes](https://github.com/RhoInc/clinical-timelines/releases) | ||
* [Examples](https://rhoinc.github.io/viz-library/) |
@@ -6,3 +6,3 @@ The most straightforward way to customize the Clinical Timelines is by using a configuration object whose properties describe the behavior and appearance of the chart. Since the Clinical Timelines is a Webcharts `chart` object, many default Webcharts settings are set in the [settings.js file](https://github.com/RhoInc/clinical-timelines/blob/master/src/defaults/settings.js) as [described below](#webcharts-settings). Refer to the [Webcharts documentation](https://github.com/RhoInc/Webcharts/wiki/Chart-Configuration) for more details on these settings. | ||
# Renderer-specific settings | ||
The sections below describe each clinical-timelines setting as of version 1.3.0. | ||
The sections below describe each clinical-timelines setting as of version 1.4.0. | ||
@@ -290,2 +290,11 @@ ## settings.id_col | ||
## settings.transpose_data | ||
`boolean` | ||
by default data are exported as one record per event; this option transposes the data so each even type has two columns: start and end | ||
**default:** `false` | ||
## settings.details | ||
@@ -362,3 +371,3 @@ `array` | ||
# Webcharts settings | ||
The object below contains each Webcharts setting as of version 1.3.0. | ||
The object below contains each Webcharts setting as of version 1.4.0. | ||
@@ -365,0 +374,0 @@ ``` |
@@ -1,295 +0,290 @@ | ||
{"title": "settings" | ||
,"description": "JSON schema for the configuration of the clinical-timelines" | ||
,"overview": "The most straightforward way to customize the Clinical Timelines is by using a configuration object whose properties describe the behavior and appearance of the chart. Since the Clinical Timelines is a Webcharts `chart` object, many default Webcharts settings are set in the [settings.js file](https://github.com/RhoInc/clinical-timelines/blob/master/src/defaults/settings.js) as [described below](#webcharts-settings). Refer to the [Webcharts documentation](https://github.com/RhoInc/Webcharts/wiki/Chart-Configuration) for more details on these settings.\nIn addition to the standard Webcharts settings several custom settings not available in the base Webcharts library have been added to the Clinical Timelines to facilitate data mapping and other custom functionality. These custom settings are described in detail below. All defaults can be overwritten by users." | ||
,"version": "1.3.0" | ||
,"type": "object" | ||
,"properties": | ||
{"id_col": | ||
{"title": "ID" | ||
,"description": "unique identifier variable name" | ||
,"default": "USUBJID" | ||
,"type": "string" | ||
} | ||
,"id_unit": | ||
{"title": "ID Unit" | ||
,"description": "unique identifier unit" | ||
,"default": "participant" | ||
,"type": "string" | ||
} | ||
,"id_characteristics": | ||
{"title": "ID Characteristics" | ||
,"description": "an array of identifier characteristic variables and associated metadata" | ||
,"type": "array" | ||
,"items": | ||
{"type": "object" | ||
,"properties": | ||
{"value_col": | ||
{"title": "Variable name" | ||
,"type": "string" | ||
{ | ||
"title": "settings", | ||
"description": "JSON schema for the configuration of the clinical-timelines", | ||
"overview": "The most straightforward way to customize the Clinical Timelines is by using a configuration object whose properties describe the behavior and appearance of the chart. Since the Clinical Timelines is a Webcharts `chart` object, many default Webcharts settings are set in the [settings.js file](https://github.com/RhoInc/clinical-timelines/blob/master/src/defaults/settings.js) as [described below](#webcharts-settings). Refer to the [Webcharts documentation](https://github.com/RhoInc/Webcharts/wiki/Chart-Configuration) for more details on these settings.\nIn addition to the standard Webcharts settings several custom settings not available in the base Webcharts library have been added to the Clinical Timelines to facilitate data mapping and other custom functionality. These custom settings are described in detail below. All defaults can be overwritten by users.", | ||
"version": "1.4.0", | ||
"type": "object", | ||
"properties": { | ||
"id_col": { | ||
"title": "ID", | ||
"description": "unique identifier variable name", | ||
"default": "USUBJID", | ||
"type": "string" | ||
}, | ||
"id_unit": { | ||
"title": "ID Unit", | ||
"description": "unique identifier unit", | ||
"default": "participant", | ||
"type": "string" | ||
}, | ||
"id_characteristics": { | ||
"title": "ID Characteristics", | ||
"description": "an array of identifier characteristic variables and associated metadata", | ||
"type": "array", | ||
"items": { | ||
"type": "object", | ||
"properties": { | ||
"value_col": { | ||
"title": "Variable name", | ||
"type": "string" | ||
}, | ||
"label": { | ||
"title": "Variable label", | ||
"type": "string" | ||
} | ||
,"label": | ||
{"title": "Variable label" | ||
,"type": "string" | ||
} | ||
} | ||
} | ||
} | ||
,"event_col": | ||
{"title": "Event Type" | ||
,"description": "event type variable name" | ||
,"default": "DOMAIN" | ||
,"type": "string" | ||
} | ||
,"event_types": | ||
{"title": "Initial Event Types" | ||
,"description": "an array of event types displayed initially" | ||
,"type": "array" | ||
,"items": | ||
{"type": "string"} | ||
} | ||
,"event_highlighted": | ||
{"title": "Highlighted Event" | ||
,"description": "initial highlighted event type" | ||
,"default": null | ||
,"type": "string" | ||
} | ||
,"event_highlight_color": | ||
{"title": "Highlighted Event Color" | ||
,"description": "fill color of highlighted events" | ||
,"default": null | ||
,"type": "string" | ||
} | ||
,"filters": | ||
{"title": "Filters" | ||
,"description": "an array of filter variables and associated metadata" | ||
,"type": "array" | ||
,"items": | ||
{"type": "object" | ||
,"properties": | ||
{"value_col": | ||
{"title": "Variable name" | ||
,"type": "string" | ||
}, | ||
"event_col": { | ||
"title": "Event Type", | ||
"description": "event type variable name", | ||
"default": "DOMAIN", | ||
"type": "string" | ||
}, | ||
"event_types": { | ||
"title": "Initial Event Types", | ||
"description": "an array of event types displayed initially", | ||
"type": "array", | ||
"items": { | ||
"type": "string" | ||
} | ||
}, | ||
"event_highlighted": { | ||
"title": "Highlighted Event", | ||
"description": "initial highlighted event type", | ||
"default": null, | ||
"type": "string" | ||
}, | ||
"event_highlight_color": { | ||
"title": "Highlighted Event Color", | ||
"description": "fill color of highlighted events", | ||
"default": null, | ||
"type": "string" | ||
}, | ||
"filters": { | ||
"title": "Filters", | ||
"description": "an array of filter variables and associated metadata", | ||
"type": "array", | ||
"items": { | ||
"type": "object", | ||
"properties": { | ||
"value_col": { | ||
"title": "Variable name", | ||
"type": "string" | ||
}, | ||
"label": { | ||
"title": "Variable label", | ||
"type": "string" | ||
} | ||
,"label": | ||
{"title": "Variable label" | ||
,"type": "string" | ||
} | ||
} | ||
} | ||
} | ||
,"groupings": | ||
{"title": "ID Grouping" | ||
,"description": "an array of categorical ID characteristic variables with which to group IDs" | ||
,"type": "array" | ||
,"items": | ||
{"type": "object" | ||
,"properties": | ||
{"value_col": | ||
{"title": "Variable name" | ||
,"type": "string" | ||
}, | ||
"groupings": { | ||
"title": "ID Grouping", | ||
"description": "an array of categorical ID characteristic variables with which to group IDs", | ||
"type": "array", | ||
"items": { | ||
"type": "object", | ||
"properties": { | ||
"value_col": { | ||
"title": "Variable name", | ||
"type": "string" | ||
}, | ||
"label": { | ||
"title": "Variable label", | ||
"type": "string" | ||
} | ||
,"label": | ||
{"title": "Variable label" | ||
,"type": "string" | ||
} | ||
} | ||
} | ||
} | ||
,"grouping_initial": | ||
{"title": "Initial ID Grouping" | ||
,"description": "initial ID grouping variable" | ||
,"default": null | ||
,"type": "string" | ||
} | ||
,"grouping_direction": | ||
{"title": "Grouping Annotation Placement" | ||
,"description": "grouping annotation placement" | ||
,"default": "horizontal" | ||
,"type": "string" | ||
,"enum": | ||
["horizontal" | ||
,"vertical" | ||
}, | ||
"grouping_initial": { | ||
"title": "Initial ID Grouping", | ||
"description": "initial ID grouping variable", | ||
"default": null, | ||
"type": "string" | ||
}, | ||
"grouping_direction": { | ||
"title": "Grouping Annotation Placement", | ||
"description": "grouping annotation placement", | ||
"default": "horizontal", | ||
"type": "string", | ||
"enum": [ | ||
"horizontal", | ||
"vertical" | ||
] | ||
} | ||
,"time_scale": | ||
{"title": "Time Scale" | ||
,"description": "the time scale on which to plot events" | ||
,"type": "string" | ||
,"default": "date" | ||
,"enum": | ||
["date" | ||
,"day"] | ||
} | ||
,"stdt_col": | ||
{"title": "Start Date" | ||
,"description": "start date variable name" | ||
,"default": "STDT" | ||
,"type": "string" | ||
} | ||
,"endt_col": | ||
{"title": "End Date" | ||
,"description": "end date variable name" | ||
,"default": "ENDT" | ||
,"type": "string" | ||
} | ||
,"date_range": | ||
{"title": "Date Range" | ||
,"description": "start and stop dates with which to define the x-axis domain and which match settings.date_format" | ||
,"type": "array" | ||
,"minItems": 2 | ||
,"maxItems": 2 | ||
,"items": | ||
{"type": "string"} | ||
} | ||
,"date_format": | ||
{"title": "Input Date Format" | ||
,"description": "date format of start and stop date variables" | ||
,"default": "%Y-%m-%d" | ||
,"type": "string" | ||
} | ||
,"date_display_format": | ||
{"title": "Displayed Date Format" | ||
,"description": "date format of x-axis" | ||
,"default": "%Y-%m-%d" | ||
,"type": "string" | ||
} | ||
,"stdy_col": | ||
{"title": "Start Day" | ||
,"description": "start day variable name" | ||
,"default": "STDY" | ||
,"type": "string" | ||
} | ||
,"endy_col": | ||
{"title": "End Day" | ||
,"description": "end day variable name" | ||
,"default": "ENDY" | ||
,"type": "string" | ||
} | ||
,"day_range": | ||
{"title": "Day Range" | ||
,"description": "start and stop days with which to define the x-axis domain" | ||
,"type": "array" | ||
,"minItems": 2 | ||
,"maxItems": 2 | ||
,"items": | ||
{"type": "number"} | ||
} | ||
,"seq_col": | ||
{"title": "Sequence Number" | ||
,"description": "event type sequence variable name" | ||
,"default": "SEQ" | ||
,"type": "string" | ||
} | ||
,"tooltip_col": | ||
{"title": "Event Details" | ||
,"description": "hovering over a mark displays a tooltip with the details of the event" | ||
,"default": "TOOLTIP" | ||
,"type": "string" | ||
} | ||
,"ongo_col": | ||
{"title": "Ongoing?" | ||
,"description": "ongoing event indicator variable name" | ||
,"default": "ONGO" | ||
,"type": "string" | ||
} | ||
,"ongo_val": | ||
{"title": "Ongoing Value" | ||
,"description": "ongoing event indicator value" | ||
,"default": "Y" | ||
,"type": "string" | ||
} | ||
,"reference_lines": | ||
{"title": "Reference Timepoints" | ||
,"description": "an array of reference timepoints and associated descriptions" | ||
,"type": "array" | ||
,"items": | ||
{"type": "object" | ||
,"properties": | ||
{"timepoint": | ||
{"title": "Timepoint" | ||
,"type": "string" | ||
}, | ||
"time_scale": { | ||
"title": "Time Scale", | ||
"description": "the time scale on which to plot events", | ||
"type": "string", | ||
"default": "date", | ||
"enum": [ | ||
"date", | ||
"day" | ||
] | ||
}, | ||
"stdt_col": { | ||
"title": "Start Date", | ||
"description": "start date variable name", | ||
"default": "STDT", | ||
"type": "string" | ||
}, | ||
"endt_col": { | ||
"title": "End Date", | ||
"description": "end date variable name", | ||
"default": "ENDT", | ||
"type": "string" | ||
}, | ||
"date_range": { | ||
"title": "Date Range", | ||
"description": "start and stop dates with which to define the x-axis domain and which match settings.date_format", | ||
"type": "array", | ||
"minItems": 2, | ||
"maxItems": 2, | ||
"items": { | ||
"type": "string" | ||
} | ||
}, | ||
"date_format": { | ||
"title": "Input Date Format", | ||
"description": "date format of start and stop date variables", | ||
"default": "%Y-%m-%d", | ||
"type": "string" | ||
}, | ||
"date_display_format": { | ||
"title": "Displayed Date Format", | ||
"description": "date format of x-axis", | ||
"default": "%Y-%m-%d", | ||
"type": "string" | ||
}, | ||
"stdy_col": { | ||
"title": "Start Day", | ||
"description": "start day variable name", | ||
"default": "STDY", | ||
"type": "string" | ||
}, | ||
"endy_col": { | ||
"title": "End Day", | ||
"description": "end day variable name", | ||
"default": "ENDY", | ||
"type": "string" | ||
}, | ||
"day_range": { | ||
"title": "Day Range", | ||
"description": "start and stop days with which to define the x-axis domain", | ||
"type": "array", | ||
"minItems": 2, | ||
"maxItems": 2, | ||
"items": { | ||
"type": "number" | ||
} | ||
}, | ||
"seq_col": { | ||
"title": "Sequence Number", | ||
"description": "event type sequence variable name", | ||
"default": "SEQ", | ||
"type": "string" | ||
}, | ||
"tooltip_col": { | ||
"title": "Event Details", | ||
"description": "hovering over a mark displays a tooltip with the details of the event", | ||
"default": "TOOLTIP", | ||
"type": "string" | ||
}, | ||
"ongo_col": { | ||
"title": "Ongoing?", | ||
"description": "ongoing event indicator variable name", | ||
"default": "ONGO", | ||
"type": "string" | ||
}, | ||
"ongo_val": { | ||
"title": "Ongoing Value", | ||
"description": "ongoing event indicator value", | ||
"default": "Y", | ||
"type": "string" | ||
}, | ||
"reference_lines": { | ||
"title": "Reference Timepoints", | ||
"description": "an array of reference timepoints and associated descriptions", | ||
"type": "array", | ||
"items": { | ||
"type": "object", | ||
"properties": { | ||
"timepoint": { | ||
"title": "Timepoint", | ||
"type": "string" | ||
}, | ||
"label": { | ||
"title": "Reference timepoint description", | ||
"type": "string" | ||
} | ||
,"label": | ||
{"title": "Reference timepoint description" | ||
,"type": "string" | ||
} | ||
} | ||
}, | ||
"transpose_data": { | ||
"title": "Transpose Data Export?", | ||
"description": "by default data are exported as one record per event; this option transposes the data so each even type has two columns: start and end", | ||
"type": "boolean", | ||
"default": false | ||
}, | ||
"details": { | ||
"title": "Details Listing", | ||
"description": "an array of detail listing variables and associated metadata", | ||
"type": "array", | ||
"items": { | ||
"type": "object", | ||
"properties": { | ||
"value_col": { | ||
"title": "Variable name", | ||
"type": "string" | ||
}, | ||
"label": { | ||
"title": "Variable label", | ||
"type": "string" | ||
} | ||
} | ||
} | ||
} | ||
,"details": | ||
{"title": "Details Listing" | ||
,"description": "an array of detail listing variables and associated metadata" | ||
,"type": "array" | ||
,"items": | ||
{"type": "object" | ||
,"properties": | ||
{"value_col": | ||
{"title": "Variable name" | ||
,"type": "string" | ||
}, | ||
"details_config": { | ||
"title": "Details Listing Settings", | ||
"description": "a webcharts table settings object", | ||
"type": "object", | ||
"properties": { | ||
"cols": { | ||
"title": "List of variables", | ||
"type": "array", | ||
"items": { | ||
"type": "string" | ||
} | ||
,"label": | ||
{"title": "Variable label" | ||
,"type": "string" | ||
}, | ||
"headers": { | ||
"title": "List of headers", | ||
"type": "string", | ||
"items": { | ||
"type": "string" | ||
} | ||
}, | ||
"searchable": { | ||
"title": "Searchable?", | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"sortable": { | ||
"title": "sortable?", | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"pagination": { | ||
"title": "Paginated?", | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"exportable": { | ||
"title": "Exportable?", | ||
"type": "boolean", | ||
"default": true | ||
} | ||
} | ||
} | ||
,"details_config": | ||
{"title": "Details Listing Settings" | ||
,"description": "a webcharts table settings object" | ||
,"type": "object" | ||
,"properties": | ||
{"cols": | ||
{"title": "List of variables" | ||
,"type": "array" | ||
,"items": | ||
{"type": "string"} | ||
} | ||
,"headers": | ||
{"title": "List of headers" | ||
,"type": "string" | ||
,"items": | ||
{"type": "string"} | ||
} | ||
,"searchable": | ||
{"title": "Searchable?" | ||
,"type": "boolean" | ||
,"default": true | ||
} | ||
,"sortable": | ||
{"title": "sortable?" | ||
,"type": "boolean" | ||
,"default": true | ||
} | ||
,"pagination": | ||
{"title": "Paginated?" | ||
,"type": "boolean" | ||
,"default": true | ||
} | ||
,"exportable": | ||
{"title": "Exportable?" | ||
,"type": "boolean" | ||
,"default": true | ||
} | ||
} | ||
} | ||
} | ||
} |
@@ -0,0 +0,0 @@ import settings from './settings'; |
@@ -22,4 +22,11 @@ import { format, time } from 'd3'; | ||
settings.x_displayFormat = time.format(settings.date_display_format); | ||
settings.time_function = dt => | ||
settings.x_parseFormat.parse(dt) ? settings.x_parseFormat.parse(dt) : new Date(dt); | ||
settings.time_function = dt => { | ||
let parsed; | ||
try { | ||
parsed = settings.x_parseFormat.parse(dt); | ||
} catch (error) { | ||
parsed = new Date(dt); | ||
} | ||
return parsed; | ||
}; | ||
} else if (settings.time_scale === 'day') { | ||
@@ -26,0 +33,0 @@ settings.st_col = settings.stdy_col; |
@@ -0,0 +0,0 @@ import onInit from './onInit'; |
@@ -15,4 +15,4 @@ import { select } from 'd3'; | ||
//Define ID data. | ||
const longIDdata = this.long_data.filter(di => di[this.config.id_col] === this.selected_id), | ||
wideIDdata = this.wide_data.filter(di => di[this.config.id_col] === this.selected_id); | ||
const longIDdata = this.long_data.filter(di => di[this.config.id_col] === this.selected_id); | ||
const wideIDdata = this.wide_data.filter(di => di[this.config.id_col] === this.selected_id); | ||
@@ -48,3 +48,3 @@ //Draw ID characteristics. | ||
null, | ||
clinicalTimelines.test | ||
this.clinicalTimelines.test | ||
); | ||
@@ -65,4 +65,4 @@ | ||
), | ||
clinicalTimelines.test | ||
this.clinicalTimelines.test | ||
); | ||
} |
@@ -7,10 +7,10 @@ import syncTimeScaleSettings from '../../../../defaults/syncSettings/syncTimeScaleSettings'; | ||
else { | ||
const anyDates = this.initial_data.some( | ||
d => d.hasOwnProperty(this.config.stdt_col) && d[this.config.stdt_col] !== '' | ||
), | ||
anyDays = this.initial_data.some( | ||
d => d.hasOwnProperty(this.config.stdy_col) && d[this.config.stdy_col] !== '' | ||
); | ||
this.anyDates = this.initial_data.some( | ||
d => d.hasOwnProperty(this.config.stdt_col) && d[this.config.stdt_col] !== '' | ||
); | ||
this.anyDays = this.initial_data.some( | ||
d => d.hasOwnProperty(this.config.stdy_col) && d[this.config.stdy_col] !== '' | ||
); | ||
if (!anyDates && !anyDays) { | ||
if (!this.anyDates && !this.anyDays) { | ||
const errorText = `The data either contain neither ${this.config.stdt_col} nor ${ | ||
@@ -26,3 +26,3 @@ this.config.stdy_col | ||
throw new Error(errorText); | ||
} else if (!anyDates && this.config.time_scale === 'date') { | ||
} else if (!this.anyDates && this.config.time_scale === 'date') { | ||
console.warn( | ||
@@ -37,3 +37,3 @@ `The data either do not contain a variable named ${this.config.stdt_col} or ${ | ||
syncTimeScaleSettings(this.IDtimeline.config); | ||
} else if (!anyDays && this.config.time_scale === 'day') { | ||
} else if (!this.anyDays && this.config.time_scale === 'day') { | ||
console.warn( | ||
@@ -50,5 +50,5 @@ `The data either do not contain a variable named ${this.config.stdy_col} or ${ | ||
return anyDates && anyDays; | ||
return this.anyDates && this.anyDays; | ||
} | ||
}); | ||
} |
@@ -20,6 +20,6 @@ import { time } from 'd3'; | ||
if (has_stdy) { | ||
if (!/^ *\d+ *$/.test(d[this.config.stdy_col])) d[this.config.stdy_col] = ''; | ||
if (!/^ *-?\d+ *$/.test(d[this.config.stdy_col])) d[this.config.stdy_col] = ''; | ||
} | ||
if (has_endy) { | ||
if (!/^ *\d+ *$/.test(d[this.config.endy_col])) | ||
if (!/^ *-?\d+ *$/.test(d[this.config.endy_col])) | ||
d[this.config.endy_col] = d[this.config.stdy_col]; | ||
@@ -26,0 +26,0 @@ } |
@@ -6,35 +6,41 @@ import '../../../util/number-isinteger'; | ||
//Date range | ||
this.full_date_range = [ | ||
min(this.initial_data, d => | ||
time.format(this.config.date_format).parse(d[this.config.stdt_col]) | ||
), | ||
max(this.initial_data, d => | ||
time.format(this.config.date_format).parse(d[this.config.endt_col]) | ||
) | ||
]; | ||
this.date_range = | ||
this.config.date_range instanceof Array && | ||
this.config.date_range.length === 2 && | ||
this.config.date_range[0].toString() !== this.config.date_range[1].toString() && | ||
this.config.date_range.every( | ||
date => date instanceof Date || time.format(this.config.date_format).parse(date) | ||
) | ||
? this.config.date_range.map( | ||
date => | ||
date instanceof Date ? date : time.format(this.config.date_format).parse(date) | ||
) | ||
: this.full_date_range; | ||
if (this.anyDates) { | ||
this.full_date_range = [ | ||
min(this.initial_data, d => | ||
time.format(this.config.date_format).parse(d[this.config.stdt_col]) | ||
), | ||
max(this.initial_data, d => | ||
time.format(this.config.date_format).parse(d[this.config.endt_col]) | ||
) | ||
]; | ||
this.date_range = | ||
this.config.date_range instanceof Array && | ||
this.config.date_range.length === 2 && | ||
this.config.date_range[0].toString() !== this.config.date_range[1].toString() && | ||
this.config.date_range.every( | ||
date => date instanceof Date || time.format(this.config.date_format).parse(date) | ||
) | ||
? this.config.date_range.map( | ||
date => | ||
date instanceof Date | ||
? date | ||
: time.format(this.config.date_format).parse(date) | ||
) | ||
: this.full_date_range; | ||
} | ||
//Day range | ||
this.full_day_range = [ | ||
min(this.initial_data, d => +d[this.config.stdy_col]), | ||
max(this.initial_data, d => +d[this.config.endy_col]) | ||
]; | ||
this.day_range = | ||
this.config.day_range instanceof Array && | ||
this.config.day_range.length === 2 && | ||
this.config.day_range[0].toString() !== this.config.day_range[1].toString() && | ||
this.config.day_range.every(day => Number.isInteger(+day)) | ||
? this.config.day_range.map(day => +day) | ||
: this.full_day_range; | ||
if (this.anyDays) { | ||
this.full_day_range = [ | ||
min(this.initial_data, d => +d[this.config.stdy_col]), | ||
max(this.initial_data, d => +d[this.config.endy_col]) | ||
]; | ||
this.day_range = | ||
this.config.day_range instanceof Array && | ||
this.config.day_range.length === 2 && | ||
this.config.day_range[0].toString() !== this.config.day_range[1].toString() && | ||
this.config.day_range.every(day => Number.isInteger(+day)) | ||
? this.config.day_range.map(day => +day) | ||
: this.full_day_range; | ||
} | ||
} |
import IDdetails from './onLayout/IDdetails'; | ||
import controlGroupLayout from './onLayout/controlGroupLayout'; | ||
import augmentOtherControls from './onLayout/augmentOtherControls'; | ||
import addTimeRangeControls from './onlayout/addTimeRangeControls'; | ||
import addTimeRangeControls from './onLayout/addTimeRangeControls'; | ||
import augmentFilters from './onLayout/augmentFilters'; | ||
@@ -6,0 +6,0 @@ import topXaxis from './onLayout/topXaxis'; |
@@ -9,2 +9,3 @@ import { min, max, time, set } from 'd3'; | ||
.values() | ||
.sort() | ||
.map((d, i) => { | ||
@@ -11,0 +12,0 @@ const groupingObject = { |
@@ -7,3 +7,2 @@ import { nest, min, time, set } from 'd3'; | ||
\-------------------------------------------------------------------------------------------**/ | ||
if (this.config.y.sort === 'earliest') { | ||
@@ -14,11 +13,9 @@ if (this.config.y.grouping) { | ||
.key(d => d[this.config.y.grouping] + '|' + d[this.config.id_col]) | ||
.rollup(d => min(d, di => this.config.time_function(di[this.config.st_col]))) | ||
.rollup(d => min(d, di => this.config.time_function(di.wc_value))) | ||
.entries(this.longDataInsideTimeRange) | ||
.sort((a, b) => { | ||
const aGrouping = a.key.split('|')[0], | ||
bGrouping = b.key.split('|')[0], | ||
earliestEventSort = | ||
a.values > b.values | ||
? -2 | ||
: a.values < b.values ? 2 : a.key > b.key ? -1 : 1; | ||
const aGrouping = a.key.split('|')[0]; | ||
const bGrouping = b.key.split('|')[0]; | ||
const earliestEventSort = | ||
a.values > b.values ? -2 : a.values < b.values ? 2 : a.key > b.key ? -1 : 1; | ||
@@ -25,0 +22,0 @@ return aGrouping > bGrouping |
@@ -10,3 +10,4 @@ import { select } from 'd3'; | ||
.select('text') | ||
.attr('dy', context.y.rangeBand() / 3); | ||
.attr('dx', 4) | ||
.attr('dy', context.y.rangeBand() / 4); | ||
@@ -13,0 +14,0 @@ //Insert a rectangle with which to visually group each ID's events. |
@@ -0,0 +0,0 @@ /*------------------------------------------------------------------------------------------------\ |
@@ -0,0 +0,0 @@ /*------------------------------------------------------------------------------------------------\ |
136
test/init.js
@@ -1,133 +0,5 @@ | ||
import jsdom from 'jsdom'; | ||
import clinicalTimelines from '../src/index'; | ||
import expect from 'expect'; | ||
import { select } from 'd3'; | ||
import init from './testFunctions/init'; | ||
import settingsObjects from './settingsObjects/index'; | ||
describe('clinical-timelines initialization', () => { | ||
const | ||
{ JSDOM } = jsdom, | ||
settings = { | ||
groupings: [ | ||
'ARM', | ||
'SITEID' | ||
], | ||
details_config: { | ||
exportable: false | ||
} | ||
}, | ||
data = require('./data/ADTIMELINES.json'); | ||
let dom, | ||
container, | ||
CT; | ||
before(() => { | ||
dom = new JSDOM('<!DOCTYPE html><body><div></div></body>'); | ||
container = dom.window.document.querySelector('div'); | ||
CT = clinicalTimelines(container, settings, dom); | ||
CT.init(data); | ||
}); | ||
beforeEach(() => { | ||
}); | ||
afterEach(() => { | ||
}); | ||
describe('User passes data to clinicalTimelines.', () => { | ||
it('attaches the data to the clinicalTimelines object', () => { | ||
expect(CT.hasOwnProperty('data') && CT.data.raw === data).toBeTruthy(); | ||
}); | ||
/***--------------------------------------------------------------------------------------\ | ||
Details | ||
\--------------------------------------------------------------------------------------***/ | ||
it('updates the population details', () => { | ||
const | ||
nodeList = dom.window.document | ||
.querySelectorAll('#ct-population-details .ct-stats'), | ||
nodes = Array.from(nodeList); | ||
expect(nodes.filter(node => node.firstChild.nodeValue).length).toEqual(3); | ||
}); | ||
it('updates the ID details', () => { | ||
const | ||
nodeList = dom.window.document | ||
.querySelectorAll('#ct-ID-details .ct-characteristic'), | ||
nodes = Array.from(nodeList); | ||
expect(nodes.filter(node => node.firstChild.nodeValue).length).toEqual(CT.settings.synced.id_characteristics.length); | ||
}); | ||
/***--------------------------------------------------------------------------------------\ | ||
Controls | ||
\--------------------------------------------------------------------------------------***/ | ||
it('adds an ID view dropdown', () => { | ||
const | ||
nodeList = dom.window.document | ||
.querySelectorAll('#ct-controls .ct-ID'); | ||
expect(nodeList.length).toEqual(1); | ||
}); | ||
it('adds an event highlighting dropdown', () => { | ||
const | ||
nodeList = dom.window.document | ||
.querySelectorAll('#ct-controls #control-event_highlighted'); | ||
expect(nodeList.length).toEqual(1); | ||
}); | ||
it('adds an x-axis scale dropdown', () => { | ||
const | ||
nodeList = dom.window.document | ||
.querySelectorAll('#ct-controls #control-time_scale'); | ||
expect(nodeList.length).toEqual(1); | ||
}); | ||
it('adds x-axis time range controls', () => { | ||
const | ||
nodeList = dom.window.document | ||
.querySelectorAll('#ct-controls .ct-time-range'); | ||
expect(nodeList.length).toEqual(2); | ||
}); | ||
it('adds a y-axis sort dropdown', () => { | ||
const | ||
nodeList = dom.window.document | ||
.querySelectorAll('#ct-controls #control-y-sort'); | ||
expect(nodeList.length).toEqual(1); | ||
}); | ||
it('adds a y-axis grouping dropdown', () => { | ||
const | ||
nodeList = dom.window.document | ||
.querySelectorAll('#ct-controls #control-y-grouping'); | ||
expect(nodeList.length).toEqual(1); | ||
}); | ||
/***--------------------------------------------------------------------------------------\ | ||
Filters | ||
\--------------------------------------------------------------------------------------***/ | ||
it('adds ongoing, event type, and user-specified filters', () => { | ||
const | ||
nodeList = dom.window.document | ||
.querySelectorAll('#ct-controls .ct-filter'); | ||
expect(nodeList.length).toEqual(CT.settings.synced.filters.length); | ||
}); | ||
/***--------------------------------------------------------------------------------------\ | ||
Timelines | ||
\--------------------------------------------------------------------------------------***/ | ||
it('draws the legend and the chart', () => { | ||
const | ||
node = dom.window.document | ||
.querySelector('#ct-timelines .wc-chart'), | ||
legend = node.querySelector('.legend'), | ||
SVG = node.querySelector('.wc-svg'); | ||
expect(legend && SVG).toBeTruthy(); | ||
}); | ||
}); | ||
}); | ||
for (const settingsObject of settingsObjects) | ||
init(settingsObject); |
import jsdom from 'jsdom'; | ||
import clinicalTimelines from '../../src/index'; | ||
import IDchange from '../../src/timelines/callbacks/onLayout/augmentFilters/IDchange'; | ||
import expect from 'expect'; | ||
@@ -13,3 +14,12 @@ import { select } from 'd3'; | ||
container, | ||
CT; | ||
CT, | ||
IDselect, | ||
IDoptions, | ||
allOption, | ||
timelinesSVG, | ||
IDtimeline, | ||
listing, | ||
IDs, | ||
index, | ||
ID; | ||
@@ -21,16 +31,32 @@ before(() => { | ||
CT.init(data); | ||
IDselect = dom.window.document.querySelector('#ct-controls .ct-ID .changer'); | ||
IDoptions = [...IDselect.querySelectorAll('option')]; | ||
allOption = IDoptions.find(d => d.value === 'All'); | ||
//Select the timelines SVG, the ID timeline container, and the listing container nodes. | ||
timelinesSVG = dom.window.document.querySelector('div#ct-timelines .wc-chart .wc-svg'); | ||
IDtimeline = dom.window.document.querySelector('div#ct-ID-timeline'); | ||
listing = dom.window.document.querySelector('div#ct-listing'); | ||
}); | ||
beforeEach(() => { | ||
const | ||
IDs = [...dom.window.document.querySelectorAll('#ct-controls .ct-ID option')] | ||
.filter(d => d.value !== 'All'), | ||
index = Math.round(Math.random()*IDs.length), | ||
ID = IDs.find((d,i) => i === index); | ||
console.log(dom.window.document.querySelectorAll('#ct-controls .ct-ID option:selected')); | ||
ID.selected = true; | ||
console.log(dom.window.document.querySelectorAll('#ct-controls .ct-ID option:selected')); | ||
//Randomly select an ID from the dropdown. | ||
IDs = IDoptions.filter(d => d.value !== 'All'); | ||
index = Math.round(Math.random()*IDs.length); | ||
ID = IDs.find((d,i) => i === index); | ||
//Set the selected index of the dropdown, | ||
//the selected boolean of the option to true, | ||
//and call IDchange(), passing the dropdown as an argument. | ||
IDselect.selectedIndex = index + 1; | ||
ID.selected = true; | ||
IDchange.call(CT.timelines, IDselect); | ||
}); | ||
afterEach(() => { | ||
//Reset the ID dropdown. | ||
ID.selected = false; | ||
allOption.selected = true; | ||
IDselect.selectedIndex = 0; | ||
IDchange.call(CT.timelines, IDselect); | ||
}); | ||
@@ -40,11 +66,15 @@ | ||
it('hides the timelines', () => { | ||
const | ||
timelines = dom.window.document | ||
.querySelector('#ct-timelines .wc-chart .wc-svg'); | ||
console.log(timelines.classList); | ||
//expect(CT.hasOwnProperty('data') && CT.data.raw === data).toBeTruthy(); | ||
//it('hides the timelines', () => { | ||
// expect(timelinesSVG.classList.contains('ct-hidden')).toEqual(true); | ||
//}); | ||
it('unhides the ID timeline', () => { | ||
expect(IDtimeline.classList.contains('ct-hidden')).toEqual(false); | ||
}); | ||
it('unhides the listing', () => { | ||
expect(listing.classList.contains('ct-hidden')).toEqual(false); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
135
0
910801
8826
47