Public
Edited
Feb 25, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
for (let i = 0; i < results.length; i++) {
let x = results[i];
for (let col of ['Step','ActualEnrolled','leafai_PredictedEligible','leafai_Unmatched','leafai_Matched','leafai_Skipped','human_Matched','human_Skipped']) {
x[col] = parseInt(x[col]);
}
x.leafai_Recall = x.leafai_Matched / x.ActualEnrolled;
x.human_Recall = x.human_Matched / x.ActualEnrolled;
}
}
Insert cell
Insert cell
Insert cell
Insert cell
{
const gridColor = 'rgb(240,240,240)';
const leafaiColor = '#0082b1';
const labelColor = 'rgb(170,170,170)';
const humanColor = 'orange'
const width = 500;
const height = 150;
const leafAiArea = (nct, disease, left, top, bottom) => {
return vl.markArea(
{interpolate: "linear", opacity: 0.1, line: { color: leafaiColor }, color: leafaiColor}
).encode(
vl.x().fieldQ('Step')
.axis(
{grid: true /*, gridDash: {value: [2,4]} */, gridColor: 'white', tickColor: 'white', tickCount: 7, labelFontSize: 14,
labelColor: labelColor, domainColor: 'white', titlePadding: 10, titleFontSize: 14, titleFontWeight: 500}
)
.title(bottom ? 'Line Number' : null),
vl.y().fieldQ('leafai_Matched')
/*.scale(
{domain: [0, 200]}
)*/
.axis(
left ?
{grid: true /*, gridDash: {value: [2,4]} */, gridColor: gridColor, tickColor: 'white', labels: true, labelFontSize: 14,
labelColor: labelColor, domainColor: 'white', titlePadding: 20, titleFontSize: 14, titleFontWeight: 500, orient: 'left'}
: null
)
.title(left ? "# Matched" : null)
).title(nct + ' (' + disease + ')')
.transform(vl.filter('datum.leafai_Skipped !== 1'));
};

const leafAiPoints = () => {
return vl.markPoint({ fill: 'white', color: leafaiColor, size: 60, opacity: 1 }).encode(
vl.x().fieldQ('Step'),
vl.y().fieldQ('leafai_Matched')/*.scale({domain: [0, 200]})*/.axis(false)
).transform(vl.filter('datum.leafai_Skipped !== 1'));
};

const humanPoints = () => {
return vl.markPoint({ fill: 'white', color: humanColor, size: 60, opacity: 1 }).encode(
vl.x().fieldQ('Step'),
vl.y().fieldQ('human_Matched')/*.scale({domain: [0, 200]})*/.axis(false).title('')
).transform(vl.filter('datum.human_Skipped !== 1'));
};

const humanArea = (left) => {
return vl.markArea(
{interpolate: "linear", opacity: 0.1, line: { color: humanColor }, color: humanColor}
).encode(
vl.x().fieldQ('Step'),
vl.y().fieldQ('human_Matched')
/*.scale(
{domain: [0, 200]}
)*/
.axis(
!left ?
{grid: true /*, gridDash: {value: [2,4]} */, gridColor: gridColor, tickColor: 'white', labels: true, labelFontSize: 14,
labelColor: labelColor, domainColor: 'white', titlePadding: 20, titleFontSize: 14, titleFontWeight: 500, orient: 'right'}
: null
)
.title(!left ? "% Recall" : null)
).transform(vl.filter('datum.human_Skipped !== 1'));
};

const layered = (nct, disease, left, top, bottom) => {
return vl.layer(leafAiArea(nct, disease, left, top, bottom), leafAiPoints(), humanArea(left), humanPoints())
.data(results)
.transform(vl.filter('datum.NCT == "' + nct + '"'))
.resolve({scale: {y: 'independent'}})
.width(width)
.height(height)
};

const charts = [
{nct: 'NCT02786537', disease: 'Hepatitis C'}, {nct: 'NCT03621761', disease: 'Multiple Sclerosis'},
{nct: 'NCT04852822', disease: 'Chronic Lymphocytic Leukemia'}, {nct: 'NCT03782376', disease: "Crohn's Disease"},
{nct: 'NCT04501952', disease: 'COVID-19'}, {nct: 'NCT03335371', disease: 'Type 1 Diabetes'},
{nct: 'NCT04217551', disease: 'Cardiac Arrest'}, {nct: 'NCT03029611', disease: 'Ovarian Cancer'}
]
.map((x,i) => layered(x.nct, x.disease, true, i === 0, i === 3 || i === 6));

return vl.vconcat(charts).render();
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more