{
const height = 750;
const width = 750;
const scatterWidth = width * 0.35;
const scatterHeight = height * 0.2;
const histwidth = 3.75 * scatterWidth;
const histHeight = (height - scatterHeight) / 3 - (6 * 4);
const severitywidth = width * 0.585;
const severityheight = height * 0.2;
const brush = vl.selectInterval().encodings('x').resolve('intersect');
const hist =
vl.markBar()
.encode(
vl.x().fieldQ('AGE').title('Age Groups')
.bin({maxbins: 100, minstep: 0.5})
.axis({format: 'd', titleAnchor: 'start'}),
vl.y().count().title(null)
);
const hist_layer = vl.layer(
hist.params(brush).encode(vl.color().value('lightgrey')),
hist.transform(vl.filter(brush)));
const scatter_distraction =
vl.markCircle()
.transform (
vl.groupby('AGE')
.aggregate(
vl.sum('DISTRACTION').as('DISTRACTED'),
vl.sum('NO_DISTRACTION').as('NOT_DISTRACTED')
)
)
.encode(
vl.x().fieldQ('DISTRACTED').scale({domain: [0, 11000]}).title('Distracted Driving'),
vl.y().fieldQ('NOT_DISTRACTED').title('Undistracted Driving'),
vl.color().if(brush, vl.value('green')).value('grey').scale({scheme: 'tableau10'}),
vl.opacity().if(brush, vl.value(0.8)).value(0.1),
vl.tooltip([
{field: 'AGE', type: 'ordinal', title: 'Age'},
{field: 'DISTRACTED', type: 'quantitative', title: 'Distracted'},
{field: 'NOT_DISTRACTED', type: 'quantitative', title: 'Not Distracted'}
])
);
const scatter_drunk =
vl.markCircle()
.transform (
vl.groupby('AGE')
.aggregate(
vl.sum('DRUNK').as('DRINKING'),
vl.sum('NOT_DRUNK').as('NO_DRINKING')
)
)
.encode(
vl.x().fieldQ('DRINKING').scale({domain: [0, 12000]}).title('Drunk'),
vl.y().fieldQ('NO_DRINKING').title('Not Drunk'),
vl.color().if(brush, vl.value('green')).value('grey').scale({scheme: 'tableau10'}),
vl.opacity().if(brush, vl.value(0.8)).value(0.1),
vl.tooltip([
{field: 'AGE', type: 'ordinal', title: 'Age'},
{field: 'DRINKING', type: 'quantitative', title: 'Drunk'},
{field: 'NO_DRINKING', type: 'quantitative', title: 'Not Drunk'}
])
);
const scatter_drugs =
vl.markCircle()
.transform (
vl.groupby('AGE')
.aggregate(
vl.sum('DRUGS').as('DRUGS_USED'),
vl.sum('NO_DRUGS').as('NO_DRUGS_USED')
)
)
.encode(
vl.x().fieldQ('DRUGS_USED').scale({domain: [0, 12000]}).title('Drugs Used'),
vl.y().fieldQ('NO_DRUGS_USED').title('No Drugs Used'),
vl.color().if(brush, vl.value('green')).value('grey').scale({scheme: 'tableau10'}),
vl.opacity().if(brush, vl.value(0.8)).value(0.1),
vl.tooltip([
{field: 'AGE', type: 'ordinal', title: 'Age'},
{field: 'DRUGS_USED', type: 'quantitative', title: 'Drugs Used'},
{field: 'NO_DRUGS_USED', type: 'quantitative', title: 'No Drugs Used'}
])
);
const bar_distraction =
vl.markBar()
.transform(
vl.filter("datum.DISTRACTION_TYPE !== 'no distraction'"),
vl.filter(brush)
)
.encode(
vl.x().count().scale({domain: [0, 25000]}).title(null),
vl.y().fieldN("DISTRACTION_TYPE").sort(vl.count("count()").order("descending")).title(null),
vl.color().fieldN("DISTRACTION_TYPE").legend(null),
vl.tooltip([
{field: 'DISTRACTION_TYPE', type: 'nominal', title: 'Type of Distraction'},
vl.x().count().title ('Number of crashes')
])
)
.title("Distraction Types");
const bar_drunk =
vl.markBar()
.transform(
vl.filter("datum.DRINKING_TYPE !== 'no drinking'"),
vl.filter(brush)
)
.encode(
vl.x().count().scale({domain: [0, 15000]}).title(null),
vl.y().fieldN("DRINKING_TYPE").sort(vl.count("count()").order("descending")).title(null),
vl.color().fieldN("DRINKING_TYPE").legend(null),
vl.tooltip([{field: 'DRINKING_TYPE', type: 'nominal', title: 'Level of Drunkenness'}, vl.x().count().title('Number of crashes')])
)
.title("Alcohol Related Crash Types");
const bar_drugs =
vl.markBar()
.transform(
vl.filter("datum.DRUG_USE !== 'no'"),
vl.filter(brush)
)
.encode(
vl.x().count().scale({domain: [0, 50000]}).title(null),
vl.y().fieldN("DRUG_USE").sort(vl.count("count()").order("descending")).title(null),
vl.color().fieldN("DRUG_USE").legend(null),
vl.tooltip([{field: 'DRUG_USE', type: 'nominal', title: 'Drugs Used?'}, vl.x().count().title('Number of Crashes')])
)
.title("Drugs Related Crash Types");
const bar_severity =
vl.markBar()
.transform(
vl.filter("datum.DCRASH_SEVERITY !== 'no distraction'"),
vl.filter(brush)
)
.encode(
vl.x().count().title(null).scale({domain: [0, 300000]}),
vl.y().fieldN("CRASH_SEVERITY").sort(vl.count("count()").order("descending")).title(null),
vl.color().fieldN("CRASH_SEVERITY").scale({scheme: 'tableau10'}),
vl.tooltip([{field: 'CRASH_SEVERITY', type: 'nominal', title: 'Level of Severity'}, vl.x().count().title("Number of Crashes")])
)
.title("Level of Crash Severity");
const line_severity =
vl.markLine()
.data(crash_data)
.transform(
vl.groupby(["CRASH_YEAR"])
)
.encode(
vl.x().fieldT("CRASH_YEAR").timeUnit('year').title(null),
vl.y().count().title(null),
vl.color().fieldN("CRASH_SEVERITY").scale({scheme: 'tableau10'}),
vl.tooltip([
{field: 'CRASH_SEVERITY', type: 'Nominal', title: 'Level of Severity'},
vl.x().count().title('Number of Crashes')
])
)
.title("Crash Severity Over Time")
return vl.vconcat(
vl.hconcat(
hist_layer.width(histwidth).height(histHeight)
),
vl.hconcat(
scatter_distraction.width(scatterWidth).height(scatterHeight),
scatter_drunk.width(scatterWidth).height(scatterHeight),
scatter_drugs.width(scatterWidth).height(scatterHeight),
).spacing({row: 30, column: 35}),
vl.hconcat(
bar_distraction.width(scatterWidth).height(scatterHeight),
bar_drunk.width(scatterWidth).height(scatterHeight),
bar_drugs.width(scatterWidth).height(scatterHeight)
),
vl.hconcat(
line_severity.width(severitywidth).height(severityheight),
bar_severity.width(severitywidth).height(severityheight)
)
).spacing(10).padding(10).data(crash_data).render();
}