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" +...