// Raw observations per group (Box-Muller Gaussian; Math.random is seeded by
// the sample template).
function sample(mean, sd, n) {
var points = []
for (var k = 0; k < n; k++) {
var u1 = Math.random(),
u2 = Math.random()
var g = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2)
points.push(Math.round((mean + g * sd) * 10) / 10)
}
return points
}
var options = {
series: [
{
name: 'Response time',
data: [
{ x: 'Control', points: sample(340, 55, 180) },
{ x: 'Variant A', points: sample(305, 40, 180) },
{ x: 'Variant B', points: sample(285, 62, 180) },
],
},
],
chart: {
type: 'raincloud',
height: 440,
},
title: {
text: 'Response times by cohort',
},
subtitle: {
text: 'Half-density cloud + raw observations; box lane turned off',
},
plotOptions: {
bar: {
distributed: true,
},
violin: {
// Hide the five-number box: its lane reflows to the cloud, so the rain
// sits directly against the density baseline (no dead strip).
box: {
show: false,
},
},
},
legend: {
show: false,
},
yaxis: {
title: {
text: 'Response time (ms)',
},
},
}
var chart = new ApexCharts(document.querySelector('#chart'), options)
chart.render()