{"size": 1756, "ext": "js", "max_stars_repo_path": "src/eatTheRich.js", "max_stars_repo_name": "RodrigoRoaRodriguez/MEM-treemaps", "max_stars_repo_stars_event_min_datetime": "2018-09-05T08:32:48.000Z", "max_stars_repo_stars_event_max_datetime": "2018-09-05T08:32:48.000Z", "max_issues_repo_path": "src/eatTheRich.js", "max_issues_repo_name": "RodrigoRoaRodriguez/MEM-treemaps", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "src/eatTheRich.js", "max_forks_repo_name": "RodrigoRoaRodriguez/MEM-treemaps", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": 1, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 37.3617021277, "max_line_length": 80, "alphanum_fraction": 0.624715262}
import slice from './slice';

export default function eatTheRich({ children, value }, x0, y0, x1, y1, ratio) {
  let x = x1; // Start from the right
  let remainingValue = value;
  const height = y1 - y0;

  for (let end = children.length, start = 1; end >= 1; end -= start) {
    if (children[end - 1].value <= 0) { end--; continue; } // Skip empty nodes.
    const width = x - x0;

    const alpha = width / height / remainingValue / ratio;
    start = 1;
    let sumValue = 0;
    let minValue = children[end - start].value;
    let maxValue = minValue;
    let valueByArea = children[end - start].value ** 2 * alpha;
    let worst = Math.max(maxValue / valueByArea, valueByArea / minValue);
    // Keep adding nodes while the aspect ratio maintains or improves.
    for (; end - start >= 0; ++start) {
      const nodeValue = children[end - start].value;
      minValue = nodeValue > minValue ? minValue : nodeValue;
      maxValue = nodeValue < maxValue ? maxValue : nodeValue;
      sumValue += nodeValue;
      valueByArea = sumValue ** 2 * alpha;
      const newWorst = Math.max(maxValue / valueByArea, valueByArea / minValue);
      if (newWorst > worst) { // It added too many and ratio got worse
        sumValue -= nodeValue; // Roll back last one.
        break;
      }
      worst = newWorst;
    }
    start--;
    // Carve out a column from the remaining area
    const nextX = remainingValue ? x - width * sumValue / remainingValue : x0;
    // Pass it to slice as a fake node and let it subdivide it.
    const fakeNode = {
      value: sumValue,
      children: children.slice(end - start, end),
    };
    slice(fakeNode, nextX, y0, x, y1);
    // Update values for next iteration.
    remainingValue -= sumValue;
    x = nextX;
  }
}
