Basic line
author(s):
Torstein Hønsi
HTML
<script src="https://code.highcharts.com/highcharts.js"></script>
<figure id="figures" class="highcharts-figure">
</figure>
CSS
.highcharts-figure, .highcharts-data-table table {
min-width: 360px;
max-width: 800px;
margin: 1em auto;
}
.highcharts-data-table table {
font-family: Verdana, sans-serif;
border-collapse: collapse;
border: 1px solid #EBEBEB;
margin: 10px auto;
text-align: center;
width: 100%;
max-width: 500px;
}
.highcharts-data-table caption {
padding: 1em 0;
font-size: 1.2em;
color: #555;
}
.highcharts-data-table th {
font-weight: 600;
padding: 0.5em;
}
.highcharts-data-table td, .highcharts-data-table th, .highcharts-data-table caption {
padding: 0.5em;
}
.highcharts-data-table thead tr, .highcharts-data-table tr:nth-child(even) {
background: #f8f8f8;
}
.highcharts-data-table tr:hover {
background: #f1f7ff;
}
JavaScript
/// normal() returns a random number from the standard normal distribution.
/// Uses the Box-Muller transform.
const normal = () => Math.sqrt(-2.0 * Math.log(Math.random())) * Math.cos(2.0 * Math.PI * Math.random());
/// normal01(..) returns normally distributed random number, whose range is
/// truncated at `sigma` standard deviations and shifted to interval `[0, 1]`.
const normal01 = (sigma = 8) => {
while (true) {
let num = normal() / (sigma + 0.0) + 0.5; // translate to [0, 1]
if (0 <= num && num <= 1) return num; // ok if in range, else resample
}
}
/// skewnormal(..) returns a random number from the normal distribution that has
/// been streched and offset to range from `min` to `max`, skewed with `skew`,
/// and truncated to `sigma` standard deviations. See https://stackoverflow.com/a/74258559/213246
const skewnormal = (min, max, skew = 1, sigma = 8) => {
var num = normal01(sigma);
num = Math.pow(num, skew) // skew
num *= max - min // stretch to fill range
num += min // offset to min
return num;
}
/// lognormal() returns a random number from the log-normal distribution.
const lognormal = () => Math.exp(normal());
var containerIndex = 0;
function addFigure({title, n, min, max, increment, fn}) {
const round_to_increment = (x, increment) => {
return Math.ceil(x / increment) * increment;
};
let data = {};
let hc_data = [];
// Collect n samples
for (i = 0; i < n; i += 1) {
let rand_num = fn();
let key = round_to_increment(rand_num, increment);
data[key] = (data[key] || 0) + 1;
}
// Count number of samples at each increment
for (let j = min; j < max; j += increment) {
let i = round_to_increment(j, increment);
hc_data.push({
"x": i,
"y": data[i] || 0
});
}
// Sort
hc_data = hc_data.sort(function(a, b) {
if (a.x < b.x) return -1;
if (a.x > b.x) return 1;
return 0;
});
let div = document.createElement("div");
div.id = "container" +...