Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

crf-heat-map

Package Overview
Dependencies
Maintainers
4
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

crf-heat-map - npm Package Compare versions

Comparing version 1.2.1 to 1.3.0

crfHeatMap.js

12

package.json
{
"name": "crf-heat-map",
"description": "Heat Map showing database form status at different levels",
"version": "1.2.1",
"version": "1.3.0",
"author": "Rho, Inc.",
"license": "MIT",
"homepage": "https://github.com/rhoinc/crf-heat-map#readme",
"main": "./build/crfHeatMap.js",
"main": "./crfHeatMap.js",
"module": "./src/wrapper.js",

@@ -20,8 +20,8 @@ "keywords": [

"scripts": {
"build": "npm audit fix && npm run bundle && npm run format && npm run build-md",
"build-md": "node ./scripts/configuration-markdown.js",
"build": "npm audit fix && npm run bundle && npm run format && npm run build-wiki",
"build-wiki": "node ./scripts/configuration-markdown.js",
"bundle": "rollup -c",
"format": "npm run format-src && npm run format-build",
"format": "npm run format-src && npm run format-bundle",
"format-src": "prettier --print-width=100 --tab-width=4 --single-quote --write \"src/**/!(*defineLayout|*defineStyles).js\"",
"format-build": "prettier --print-width=100 --tab-width=4 --single-quote --write build/crfHeatMap.js",
"format-bundle": "prettier --print-width=100 --tab-width=4 --single-quote --write ./crfHeatMap.js",
"test-page": "start chrome ./test-page/index.html && start firefox ./test-page/index.html && start iexplore file://%CD%/test-page/index.html",

@@ -28,0 +28,0 @@ "watch": "rollup -c -w"

@@ -6,67 +6,4 @@ The most straightforward way to customize the CRF Heat Map is by using a configuration object whose properties describe the behavior and appearance of the table. Since the CRF Heat Map is a Webcharts `table` object, many default Webcharts settings are set in the [webchartsSettings.js file](https://github.com/RhoInc/crf-heat-map/blob/master/src/configuration/webchartsSettings.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 crf-heat-map setting as of version 1.2.0.
The sections below describe each crf-heat-map setting as of version 1.3.0.
## settings.site_col
`string`
Specifies variable for use as site ID
**default:** `"sitename"`
## settings.id_col
`string`
Specifies variable for use as subject ID
**default:** `"subjectnameoridentifier"`
## settings.visit_col
`string`
Specifies variable for use as Visit ID
**default:** `"folderinstancename"`
## settings.visit_order_col
`string`
Specifies variable for determining order of Visit ID
**default:** `"folder_ordinal"`
## settings.form_col
`string`
Specifies variable for use as Form ID
**default:** `"ecrfpagename"`
## settings.id_freeze_col
`string`
Specifies variable for subject-level freeze status
**default:** `"subjfreezeflg"`
## settings.id_status_col
`string`
Specifies variable for subject status
**default:** `"status"`
## settings.nestings

@@ -82,9 +19,2 @@ `array`

### settings.nestings[].settings_col
`string`
Settings Column
**default:** none
### settings.nestings[].value_col

@@ -111,4 +41,11 @@ `string`

### settings.nestings[].role
`string`
Specify Optional Role
**default:** none
## settings.value_cols

@@ -171,4 +108,50 @@ `array`

### settings.filter_cols[].value_col
`string`
Variable Name
**default:** none
### settings.filter_cols[].label
`string`
Label
**default:** none
### settings.filter_cols[].multiple
`boolean`
Multi-select
**default:** none
### settings.filter_cols[].subject_export
`boolean`
Include variable in subject-level export
**default:** none
## settings.visit_order_col
`string`
Specifies variable for determining order of ID with Visit role
**default:** `"folder_ordinal"`
## settings.form_order_col
`string`
Specifies variable for determining order of ID with Form role
**default:** `"form_ordinal"`
## settings.display_cell_annotations

@@ -208,4 +191,13 @@ `boolean`

## settings.nesting_filters
`boolean`
Adds filters for each of the nesting variables
**default:** `true`
# Webcharts settings
The object below contains each Webcharts setting as of version 1.2.0.
The object below contains each Webcharts setting as of version 1.3.0.

@@ -212,0 +204,0 @@ ```

@@ -5,47 +5,5 @@ {

"overview": "The most straightforward way to customize the CRF Heat Map is by using a configuration object whose properties describe the behavior and appearance of the table. Since the CRF Heat Map is a Webcharts `table` object, many default Webcharts settings are set in the [webchartsSettings.js file](https://github.com/RhoInc/crf-heat-map/blob/master/src/configuration/webchartsSettings.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 CRF Heat Map to facilitate data mapping and other custom functionality. These custom settings are described in detail below and are set in the [rendererSettings.js file](https://github.com/RhoInc/crf-heat-map/blob/master/src/configuration/rendererSettings.js). All defaults can be overwritten by the passed configuration object.",
"version": "1.2.0",
"version": "1.3.0",
"type": "object",
"properties": {
"site_col" : {
"title": "Site Column",
"description": "Specifies variable for use as site ID",
"type": "string",
"default": "sitename"
},
"id_col" : {
"title": "Subject ID Column",
"description": "Specifies variable for use as subject ID",
"type": "string",
"default": "subjectnameoridentifier"
},
"visit_col" : {
"title": "Visit Column",
"description": "Specifies variable for use as Visit ID",
"type": "string",
"default": "folderinstancename"
},
"visit_order_col" : {
"title": "Visit Order Column",
"description": "Specifies variable for determining order of Visit ID",
"type": "string",
"default": "folder_ordinal"
},
"form_col" : {
"title": "Form Column",
"description": "Specifies variable for use as Form ID",
"type": "string",
"default": "ecrfpagename"
},
"id_freeze_col" : {
"title": "Subject Freeze Column",
"description": "Specifies variable for subject-level freeze status",
"type": "string",
"default": "subjfreezeflg"
},
"id_status_col" : {
"title": "Subject Status Column",
"description": "Specifies variable for subject status",
"type": "string",
"default": "status"
},
"nestings": {

@@ -58,6 +16,2 @@ "title": "Data Nesting",

"properties":{
"settings_col":{
"title":"Settings Column",
"type":"string"
},
"value_col":{

@@ -74,2 +28,6 @@ "title":"Value Column",

"type":"boolean"
},
"role":{
"title":"Specify Optional Role",
"type":"string"
}

@@ -80,24 +38,24 @@ }

{
"settings_col": "site_col",
"value_col" : null,
"value_col" : "sitename",
"label": "Site",
"default_nesting": true
"default_nesting": true,
"role": "site_col"
},
{
"settings_col": "id_col",
"value_col" : null,
"value_col" : "subjectnameoridentifier",
"label": "Subject ID",
"default_nesting": true
"default_nesting": true,
"role": "id_col"
},
{
"settings_col": "visit_col",
"value_col" : null,
"value_col" : "folderinstancename",
"label": "Folder",
"default_nesting": false
"default_nesting": false,
"role": "visit_col"
},
{
"settings_col": "form_col",
"value_col" : null,
"value_col" : "ecrfpagename",
"label": "Form",
"default_nesting": false
"default_nesting": false,
"role": "form_col"
}

@@ -151,12 +109,60 @@ ]

"items": {
"title": "Variable Name",
"description": "the name of the filter variable",
"type": "string"
"type": "object",
"properties":{
"value_col":{
"title":"Variable Name",
"type":"string"
},
"label":{
"title":"Label",
"type":"string"
},
"multiple":{
"title":"Multi-select",
"type": "boolean"
},
"subject_export":{
"title":"Include variable in subject-level export",
"type":"boolean"
}
}
},
"default": [
"subset1",
"subset2",
"subset3"
{
"value_col": "subset1",
"label": "Subset 1"
},
{
"value_col": "subset2",
"label": "Subset 2"
},
{
"value_col": "subset3",
"label": "Subset 3"
},
{
"value_col": "subjfreezeflg",
"label": "Subject Freeze Status",
"subject_export" : true
},
{
"value_col": "status",
"label": "Subject Status",
"multiple": true,
"subject_export" : true
}
]
},
"visit_order_col" : {
"title": "Visit Order Column",
"description": "Specifies variable for determining order of ID with Visit role",
"type": "string",
"default": "folder_ordinal"
},
"form_order_col" : {
"title": "Form Order Column",
"description": "Specifies variable for determining order of ID with Form role",
"type": "string",
"default": "form_ordinal"
},
"display_cell_annotations": {

@@ -185,4 +191,10 @@ "title": "Display Cell Annotations",

"default": 10000
},
"nesting_filters": {
"title": "Enable Nesting Variables Filters",
"description": "Adds filters for each of the nesting variables",
"type": "boolean",
"default": true
}
}
}
export default function rendererSettings() {
return {
site_col: 'sitename',
id_col: 'subjectnameoridentifier',
visit_col: 'folderinstancename',
visit_order_col: 'folder_ordinal',
form_col: 'ecrfpagename',
id_freeze_col: 'subjfreezeflg',
id_status_col: 'status',
nestings: [
{
settings_col: 'site_col',
value_col: null, // set in syncSettings()
value_col: 'sitename',
label: 'Site',
default_nesting: true
default_nesting: true,
role: 'site_col'
},
{
settings_col: 'id_col',
value_col: null, // set in syncSettings()
value_col: 'subjectnameoridentifier',
label: 'Subject ID',
default_nesting: true
default_nesting: true,
role: 'id_col'
},
{
settings_col: 'visit_col',
value_col: null, // set in syncSettings(0
value_col: 'folderinstancename',
label: 'Folder',
default_nesting: false
default_nesting: false,
role: 'visit_col'
},
{
settings_col: 'form_col',
value_col: null, // set in syncSettings()
value_col: 'ecrfpagename',
label: 'Form',
default_nesting: false
default_nesting: false,
role: 'form_col'
}

@@ -89,8 +82,35 @@ ],

],
filter_cols: ['subset1', 'subset2', 'subset3'],
filter_cols: [
{
value_col: 'subset1',
label: 'Subset 1'
},
{
value_col: 'subset2',
label: 'Subset 2'
},
{
value_col: 'subset3',
label: 'Subset 3'
},
{
value_col: 'subjfreezeflg',
label: 'Subject Freeze Status',
subject_export: true
},
{
value_col: 'status',
label: 'Subject Status',
multiple: true,
subject_export: true
}
],
visit_order_col: 'folder_ordinal',
form_order_col: 'form_ordinal',
display_cell_annotations: true,
expand_all: false,
sliders: false,
max_rows_warn: 10000
max_rows_warn: 10000,
nesting_filters: true
};
}

@@ -5,16 +5,8 @@ import controlInputs from './controlInputs';

const defaultControls = controlInputs();
const labels = {};
labels[settings.site_col] = 'Site';
labels[settings.id_freeze_col] = 'Subject Freeze Status';
labels[settings.id_status_col] = 'Subject Status';
settings.filter_cols.forEach((filter_col, i) => {
const filter = {
type: 'subsetter',
value_col: filter_col,
label: labels[filter_col]
? labels[filter_col]
: /^subset\d$/.test(filter_col)
? filter_col.replace(/^s/, 'S').replace(/(\d)/, ' $1')
: filter_col.label || filter_col.value_col || filter_col,
multiple: filter_col == settings.id_status_col ? true : false
value_col: filter_col.value_col,
label: filter_col.label ? filter_col.label : filter_col.value_col,
multiple: filter_col.multiple ? filter_col.multiple : false
};

@@ -21,0 +13,0 @@ defaultControls.splice(i, 0, filter);

export default function syncSettings(settings) {
//Sync nestings with data variable settings.
const settingsKeys = Object.keys(settings);
const settingsCols = settingsKeys.filter(settingsKey => /_col$/.test(settingsKey));
settings.nestings.forEach(nesting => {
nesting.value_col =
nesting.value_col ||
settings[settingsCols.find(settingsCol => settingsCol === nesting.settings_col)];
});
// sort value_cols so that crfs come before query cols regardless of order in rendererSettings

@@ -16,2 +7,7 @@ settings.value_cols.sort(function(a, b) {

// Assign nest variables with specfic roles to specific settings
settings.nestings.map(function(d) {
if (typeof d.role != 'undefined') settings[d.role] = d.value_col;
});
//Define initial nesting variables.

@@ -26,9 +22,23 @@ settings.id_cols = settings.nestings

// Define nesting filters
var nest_settings = [];
if (settings.nesting_filters === true) {
settings.nestings.forEach(setting =>
nest_settings.push({
value_col: setting.value_col,
label: setting.label
})
);
}
//Define filter variables.
settings.filter_cols = Array.isArray(settings.filter_cols)
? [settings.site_col, settings.id_freeze_col, settings.id_status_col].concat(
settings.filter_cols
)
: [settings.site_col, settings.id_freeze_col, settings.id_status_col];
? nest_settings.concat(settings.filter_cols)
: nest_settings;
//Define cols to include in subject level export
settings.subject_export_cols = settings.filter_cols.filter(
filter => filter.subject_export == true
);
// add labels specified in rendererSettings as headers

@@ -35,0 +45,0 @@ settings.headers = settings.value_cols.map(d => d.label);

@@ -10,3 +10,5 @@ import createNestControls from './defineLayout/createNestControls';

.append('div')
.attr('id', 'crf-heat-map'),
.datum(this)
.classed('crf-heat-map', true)
.attr('id', `crf-heat-map${document.querySelectorAll('.crf-heat-map').length}`)
};

@@ -16,6 +18,8 @@

if (isIE) {
this.containers.main.append("p").style({'color':'red','font-size':'20px','padding':'20px'}).text("Internet Explorer use is not recommended with the CRF Heat Map. You are likely to experience slower loading times.")
this.containers.main
.append('p')
.classed('chm-ie-sucks', true)
.text('Internet Explorer use is not recommended with the CRF Heat Map. You are likely to experience slower loading times.')
}
/**-------------------------------------------------------------------------------------------\

@@ -22,0 +26,0 @@ Left column

import redraw from '../onLayout/customizeFilters/redraw';
import customizeNestOptions from './createNestControls/customizeNestOptions';
import customizeNestSelects from './createNestControls/customizeNestSelects';

@@ -14,3 +16,3 @@ export default function createNestControls() {

.text('');
var idNote = this.containers.nestControls.append('span').attr('class', 'span-description');
// var idNote = this.containers.nestControls.append('span').attr('class', 'span-description');
var idSelects = this.containers.nestControls

@@ -47,2 +49,5 @@ .selectAll('select')

//ensure natural nest control options and behavior
customizeNestOptions.call(this, config.id_cols);
idSelects.on('change', function() {

@@ -74,5 +79,11 @@ //indicate loading

// Enforce Select Logic
customizeNestSelects.call(context, idSelects);
//Update nesting variables.
context.table.config.id_cols = uniqueLevels;
//Maintain nest options logic
customizeNestOptions.call(context, uniqueLevels);
//Summarize filtered data and redraw table.

@@ -79,0 +90,0 @@ redraw.call(context.table);

@@ -34,3 +34,3 @@ export const firstColumnWidth = 16;

'}',
'body #crf-heat-map {' +
'body .crf-heat-map {' +
' font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;' +

@@ -40,8 +40,8 @@ ' font-size: 16px;' +

'}',
'#crf-heat-map {' +
'.crf-heat-map {' +
'}',
'#crf-heat-map div {' +
'.crf-heat-map div {' +
' box-sizing: content-box;' +
'}',
'#crf-heat-map select {' +
'.crf-heat-map select {' +
' font-size: 12px;' +

@@ -52,2 +52,7 @@ '}',

'}',
'.chm-ie-sucks {' +
' color: red;',
' font-size: 20px;',
' padding: 20px;',
'}',
'.chm-column {' +

@@ -122,8 +127,7 @@ ' display: inline-block;' +

'#chm-controls .control-group > * {' +
' display: inline-block !important;' +
' margin: 0;' +
' display: block;' +
' width: auto;' +
'}',
'#chm-controls .wc-control-label {' +
' width: 58%;' +
' text-align: right;' +
' text-align: center;' +
'}',

@@ -133,10 +137,42 @@ '#chm-controls .span-description {' +

'#chm-controls select.changer {' +
' width: 40%;' +
' float: right;' +
' overflow-y: auto;' +
' margin: 0 auto;' +
'}',
'#chm-controls input.changer {' +
' margin-left: 2% !important;' +
'.chm-control-grouping {' +
' display: inline-block;' +
'}',
'.chm-control-grouping .control-group .wc-control-label {' +
' text-align: center;' +
'}',
'.chm-control-grouping--label {' +
' text-align: center;' +
' width: 100%;' +
' font-size: 20px;' +
'}',
'.chm-other-controls {' +
' border-bottom: 1px solid lightgray;' +
' padding-bottom: 7px;' +
'}',
'.chm-nesting-filters {' +
' display: flex;' +
' flex-wrap: wrap ;' +
' margin-top: 10px;' +
' justify-content: space-evenly;' +
'}',
'.chm-nesting-filter {' +
' width : 100px !important;' +
' display : block !important;' +
'}',
//checkboxes
'.chm-checkbox {' +
' display: inline-flex !important;' +
' justify-content: center;' +
'}',
'.chm-checkbox .wc-control-label {' +
' margin-right: 5px;' +
'}',
'.chm-checkbox .changer {' +
' margin-top: 5px !important;' +
'}',
/***--------------------------------------------------------------------------------------\

@@ -171,3 +207,10 @@ Right column

` padding-left: ${paddingLeft}px;` +
' min-width : 100px;' +
'}',
'.chm-nest-control.chm-hide {' +
' float: left;' +
' display: none;' +
' clear: left;' +
` padding-left: ${paddingLeft}px;` +
'}',
'#chm-nest-control--1 {' +

@@ -367,3 +410,3 @@ ' margin-left: 0;' +

'}',
'.wc-table table tbody tr.grayParent td:not(:first-child) {' +
'.wc-table table tbody tr.grayParent td:not(:first-child) {' +
' background: #CCCCCC;' +

@@ -375,4 +418,8 @@ ' color: black;' +

'.chm-cell--id {' + ' background: white;' + '}',
'.chm-cell--id {' + ' background: white;' +
' text-overflow: ellipsis;' +
' white-space: nowrap;' +
' overflow: hidden;' +
' max-width: 0px;' +
'}' ,
'.chm-table-row--expandable .chm-cell--id {' +

@@ -379,0 +426,0 @@ ' color: blue;' +

@@ -9,6 +9,7 @@ export default function checkRequiredVariables() {

this.settings.synced.value_cols.map(d => d.col),
this.settings.synced.filter_cols
this.settings.synced.filter_cols.map(filter => filter.value_col)
])
)
.values();
const missingVariables = requiredVariables.filter(

@@ -18,3 +19,3 @@ variable => this.data.variables.indexOf(variable.split(' (')[0]) < 0

if (missingVariables.length)
alert(
console.log(
`The data are missing ${

@@ -21,0 +22,0 @@ missingVariables.length === 1 ? 'this variable' : 'these variables'

@@ -7,2 +7,3 @@ import customizeRows from './onDraw/customizeRows';

import toggleCellAnnotations from './onDraw/toggleCellAnnotations';
import addIdHover from './onDraw/addIdHover';
import dataExport from './onDraw/dataExport';

@@ -44,2 +45,3 @@ import flagParentRows from './onDraw/flagParentRows';

toggleCellAnnotations.call(this);
addIdHover.call(this);
dataExport.call(this);

@@ -46,0 +48,0 @@ flagParentRows.call(this);

@@ -9,5 +9,4 @@ export default function addInfoBubbles() {

.data(chart.initial_config.value_cols)
.append('span')
.html(' &#9432')
.attr('title', d => d.description);
.attr('title', d => d.description)
.style('cursor', 'help');
}
import customizeRows from '../customizeRows';
import customizeCells from '../customizeCells';
import toggleCellAnnotations from '../toggleCellAnnotations';
import addIdHover from '../addIdHover';
import flagParentRows from '../flagParentRows';

@@ -105,3 +106,6 @@

toggleCellAnnotations.call(chart);
// maintain display cell annotations setting since we are not drawing
addIdHover.call(chart);
}
}

@@ -43,5 +43,5 @@ export default function customizeCells(chart, cells) {

? d.text
: String(Math.floor(d.text * 100)) + '%'
: d3.format('%')(d.text)
: d.text
);
}

@@ -52,3 +52,3 @@ export default function csv() {

['N/A', ''].indexOf(d[col]) < 0
? Math.floor(d[col] * 100)
? d[col] * 100
: d[col];

@@ -55,0 +55,0 @@

@@ -22,19 +22,30 @@ export default function deriveData() {

if (subject_id_col) {
//Add headers.
this.export.headers.push('Site', 'Subject Status', 'Subject Freeze Status');
//Add headers and columns
if (this.config.site_col) {
this.export.headers.push('Site');
this.export.cols.push('site');
}
//Add columns.
this.export.cols.push('site', 'status', 'freeze');
if (this.config.subject_export_cols) {
this.config.subject_export_cols.forEach(function(d) {
table.export.headers.push(d.label);
table.export.cols.push(d.value_col);
});
}
// build look up for subject
var subjects = d3.set(table.data.initial.map(d => d[this.config.id_col])).values();
var subjectMap = subjects.reduce((acc, cur) => {
var subjectDatum = this.data.initial.find(d => d[this.config.id_col] === cur);
acc[cur] = {
site: subjectDatum[this.config.site_col],
status: subjectDatum[this.config.id_status_col],
freeze: subjectDatum[this.config.id_freeze_col]
};
return acc;
}, {});
if (this.config.site_col || this.config.subject_export_cols) {
var subjects = d3.set(table.data.initial.map(d => d[this.config.id_col])).values();
var subjectMap = subjects.reduce((acc, cur) => {
var subjectDatum = this.data.initial.find(d => d[this.config.id_col] === cur);
acc[cur] = {};
if (this.config.site_col) acc[cur]['site'] = subjectDatum[this.config.site_col];
if (this.config.subject_export_cols) {
this.config.subject_export_cols.forEach(function(d) {
acc[cur][d.value_col] = subjectDatum[d.value_col];
});
}
return acc;
}, {});
}
}

@@ -58,3 +69,3 @@

// Now "join" subject level information to export data
if (subject_id_col) {
if ((this.config.site_col || this.config.subject_export_cols) && this.config.id_col) {
const subjectID = d[`Nest ${subject_id_col_index + 1}: ${this.config.id_col}`];

@@ -61,0 +72,0 @@ Object.assign(d, subjectMap[subjectID]);

@@ -10,12 +10,3 @@ export default function xlsx() {

};
const arrayOfArrays = this.export.data.map(d =>
this.export.cols.map(
col =>
value_cols.indexOf(col) > -1 &&
context.typeDict[col] == 'crfs' &&
['N/A', ''].indexOf(d[col]) < 0
? Math.floor(d[col] * 100) / 100
: d[col]
)
); // convert data from array of objects to array of arrays.
const arrayOfArrays = this.export.data.map(d => this.export.cols.map(col => d[col])); // convert data from array of objects to array of arrays.
const workbook = {

@@ -22,0 +13,0 @@ SheetNames: [sheetName, 'Current Filters'],

import summarizeData from './onInit/summarizeData';
import removeFilters from './onInit/removeFilters';
import removeSubjectExportCols from './onInit/removeSubjectExportCols';

@@ -7,2 +9,8 @@ export default function onInit() {

//remove subject-level export columns that have multiple values within a subject
removeSubjectExportCols.call(this);
//remove single-level or dataless filters
removeFilters.call(this);
//Summarize raw data.

@@ -9,0 +17,0 @@ summarizeData.call(this);

import calculateStatistics from './summarizeData/calculateStatistics';
import sortRows from './summarizeData/sortRows';

@@ -37,4 +38,2 @@ export default function summarizeData() {

}
// console.log(d)
});

@@ -45,41 +44,5 @@

// if there is a visit order column specificed in settings and it's present in the data use it to sort the folder rows
if (
this.initial_config.visit_order_col &&
Object.keys(this.data.initial[0]).includes(this.initial_config.visit_order_col)
) {
//Collapse array of arrays to array of objects.
this.data.summarized = d3.merge(this.data.summaries).sort(function(a, b) {
const visitIndex = context.config.id_cols.indexOf(context.initial_config.visit_col);
if (visitIndex > -1) {
var aIds = a.id.split(' |');
var bIds = b.id.split(' |');
var i;
for (i = 0; i < context.config.id_cols.length; i++) {
if (aIds[i] === bIds[i]) {
continue;
} else {
// because the visit_order variable is numeric we want to treat it differently
if (i === visitIndex) {
return typeof aIds[i] == 'undefined'
? -1
: parseFloat(a.folder_ordinal) < parseFloat(b.folder_ordinal)
? -1
: 1;
} else {
return typeof aIds[i] === 'undefined' ? -1 : aIds[i] < bIds[i] ? -1 : 1;
}
}
}
} else {
return a.id < b.id ? -1 : 1;
}
});
} else {
// otherwise sort alphabetically
this.data.summarized = d3.merge(this.data.summaries).sort((a, b) => (a.id < b.id ? -1 : 1));
}
// sort rows
sortRows.call(this);
// this.data.raw = this.data.summarized;
//end performance test

@@ -86,0 +49,0 @@ var t1 = performance.now();

@@ -44,11 +44,20 @@ export default function calculateStatistics(onInit = true) {

context.initial_config.value_cols.forEach(value_col => {
const count = d3.sum(d, di => di[value_col.col]);
var count;
if (typeof value_col.denominator === 'undefined') {
count = d3.sum(d, di => di[value_col.col]);
} else {
// ensure numerator is subsetted in the event that an error is made
// and an ID has a value of 1 and a denominator value of 0.
var subset = d.filter(row => row[value_col.denominator] === '1');
count = d3.sum(subset, di => di[value_col.col]);
}
summary[value_col.col] =
crfsNoDenominator.map(m => m.col).indexOf(value_col.col) > -1
? summary.nForms
? count / summary.nForms
? Math.floor(count / summary.nForms * 100) / 100
: 'N/A'
: crfsDenominator.map(m => m.col).indexOf(value_col.col) > -1
? summary['n' + value_col.denominator]
? count / summary['n' + value_col.denominator]
? Math.floor(count / summary['n' + value_col.denominator] * 100) /
100
: 'N/A'

@@ -61,3 +70,4 @@ : queries.map(m => m.col).indexOf(value_col.col) > -1

summary.parents = d[0].parents;
summary.folder_ordinal = d[0].folder_ordinal;
summary.visit_order = d[0][context.initial_config.visit_order_col];
summary.form_order = d[0][context.initial_config.form_order_col];
return summary;

@@ -76,3 +86,4 @@ })

d.parents = d.values.parents;
d.folder_ordinal = d.values.folder_ordinal;
d.visit_order = d.values.visit_order;
d.form_order = d.values.form_order;

@@ -79,0 +90,0 @@ delete d.values;

import customizeFilters from './onLayout/customizeFilters';
import tweakMultiSelects from './onLayout/tweakMultiSelects';
import customizeCheckboxes from './onLayout/customizeCheckboxes';
import moveExportButtons from './onLayout/moveExportButtons';
//import moveExportButtons from './onLayout/moveExportButtons';
import addColumnControls from './onLayout/addColumnControls';
import formatControls from './onLayout/formatControls';

@@ -13,2 +14,3 @@ export default function onLayout() {

addColumnControls.call(this);
formatControls.call(this);
}
import update from './update';
import filterData from '../filterData';
export default function onInput(filter) {
export default function addEventListeners(filter) {
const context = this;

@@ -9,3 +9,3 @@

filter.inputBoxes = filter.div.selectAll('.range-value').on('change', function(d) {
const loadingdiv = d3.select('#chm-loading');
const loadingdiv = context.parent.containers.main.select('#chm-loading');

@@ -12,0 +12,0 @@ loadingdiv.classed('chm-hidden', false);

import update from './update';
import filterData from '../filterData';
export default function onInput(filter) {
export default function addEventListeners(filter) {
const context = this;

@@ -9,3 +9,3 @@

filter.sliders = filter.div.selectAll('.range-slider').on('change', function(d) {
const loadingdiv = d3.select('#chm-loading');
const loadingdiv = context.parent.containers.main.select('#chm-loading');

@@ -12,0 +12,0 @@ loadingdiv.classed('chm-hidden', false);

@@ -29,3 +29,3 @@ import toggleCellAnnotations from './../onDraw/toggleCellAnnotations';

} else {
var loadingdiv = d3.select('#chm-loading'); // fix this later due to confirm box
var loadingdiv = context.parent.containers.main.select('#chm-loading'); // fix this later due to confirm box

@@ -74,3 +74,3 @@ loadingdiv.classed('chm-hidden', false);

var loadingdiv = d3.select('#chm-loading');
var loadingdiv = context.parent.containers.main.select('#chm-loading');

@@ -77,0 +77,0 @@ loadingdiv.classed('chm-hidden', false);

@@ -25,3 +25,3 @@ import redraw from './customizeFilters/redraw';

//Update filter object.
//Update filter val
context.filters.find(filter => filter.col === di.value_col).val = this

@@ -35,2 +35,8 @@ .multiple

//Update filter index
context.filters.find(filter => filter.col === di.value_col).index = this
.multiple
? null
: dropdown.selectAll('option:checked').property('index');
//Filter data.

@@ -41,3 +47,3 @@ context.data.initial_filtered = context.data.initial;

filter =>
filter.val !== 'All' &&
!(filter.all === true && filter.index === 0) &&
!(

@@ -44,0 +50,0 @@ Array.isArray(filter.val) &&

@@ -122,1 +122,54 @@ if (typeof Object.assign != 'function') {

}
if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function(valueToFind, fromIndex) {
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
// 1. Let O be ? ToObject(this value).
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If len is 0, return false.
if (len === 0) {
return false;
}
// 4. Let n be ? ToInteger(fromIndex).
// (If fromIndex is undefined, this step produces the value 0.)
var n = fromIndex | 0;
// 5. If n = 0, then
// a. Let k be n.
// 6. Else n < 0,
// a. Let k be len + n.
// b. If k < 0, let k be 0.
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
function sameValueZero(x, y) {
return (
x === y ||
(typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y))
);
}
// 7. Repeat, while k < len
while (k < len) {
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
// b. If SameValueZero(valueToFind, elementK) is true, return true.
if (sameValueZero(o[k], valueToFind)) {
return true;
}
// c. Increase k by 1.
k++;
}
// 8. Return false
return false;
}
});
}

@@ -16,2 +16,3 @@ //utility functions

import onDraw from './onDraw';
import onDestroy from './onDestroy';

@@ -63,3 +64,8 @@ import init from './init';

crfHeatMap.table.on('draw', onDraw);
crfHeatMap.table.on('destroy', onDestroy);
crfHeatMap.destroy = () => {
crfHeatMap.table.destroy();
};
//stylesheet

@@ -66,0 +72,0 @@ defineStyles.call(crfHeatMap);

d3.csv(
'https://raw.githubusercontent.com/RhoInc/data-library/master/data/clinical-trials/data-cleaning/dmc_datapage.csv',
function(d) {
'https://raw.githubusercontent.com/RhoInc/data-library/master/data/clinical-trials/data-cleaning/forms.csv',
function(d,i) {
return d;
},
function(error, data) {
if (error)
console.log(error);
function(data) {
var instance = crfHeatMap(
'#container'
'#container', // element
{
} // settings
);
instance.init(data);
instance.init(data);
destroyToggle //test destruction
.on('click', function() {
instance.destroy()
});
}

@@ -34,1 +37,8 @@ );

});
//Add button that toggles DESTRUCTION
const destroyToggle = d3.select('#title')
.append('button')
.attr('id', 'destroy-toggle')
.style('float', 'right')
.text('Destroy');

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc