ArrToo / Strava elevation graph fix

// ==UserScript==
// @name         Strava elevation graph fix
// @namespace    http://arrtoo.co.uk/
// @version      0.1
// @description  Fixes Strava's elevation graph to fill the graph area
// @author       ArrToo
// @license MIT
// @match        https://www.strava.com/*
// @grant        none
// @require      https://code.jquery.com/jquery-3.2.1.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// ==/UserScript==
/* global $, waitForKeyElements */

// Use the size of the hidden graph of just extremities, but it has odd horizon
// (Cosmetic improvement would be to actually move horizontal grid lines to more rounded positions)
waitForKeyElements('g[id^="area"]', fixElev);
function fixElev (jNode) {
    'use strict';
    if(jNode.parent().children().length != 1) { // Main graph and hidden shading lap graph are similarly named - just do calcs on one of them
        jNode.each(function(){
            var line = $(this).children('path#line'); // The hidden graph of extremities - but often with odd horizon
            var area = $(this).children('path#area'); // The main graph - but often too tall
            var y = line.get(0).getBBox().height; // Size of extremities graph
            var ay = area.get(0).getBBox().height; // Size of main graph
            var ly = ay - y;
            var h = $(this).parent().get(0).getBBox().height; // Size of graph area

            // Full size
            var ys = h / y; // Scale our graph according to extremities graph
            var clp = $(document).find('rect' + /#\w+/.exec($(this).attr('clip-path'))); // Find this graph's clip path
            clp.attr('height',h-ly-clp.attr('y')); // Drop the extra bottom on main graph
            $(this).attr('transform','translate(0 ' + (-(h-ly)*(ys-1)+ly) + ') scale(1 ' + ys + ')'); // Scale and reposition main graph

            // Also fix shading version to show laps
            var other = $(this).parent().children().children('g[id^=area]').parent(); // Locate copy of graphs used for shading laps
            clp = $(document).find('rect' + /#\w+/.exec(other.attr('clip-path'))); // Find this graph's clip path
            clp.attr('height',h-ly-clp.attr('y')); // Drop the extra bottom
            other.attr('transform','translate(0 ' + (-(h-ly)*(ys-1)+ly) + ') scale(1 ' + ys + ')'); // Scale and reposition

            // Fix axis
            var yaxis = $(this).parent().parent().children('g#yaxis');
            if(yaxis.length != 0) { // Graphs are in place, so now this section for y-axis should be filled too
                var ticks = yaxis.children('g.tick'); // Tick marks up the y-axis
                var texts = ticks.children('text'); // Text in the ticks
                var pos = [], lbl = [];
                var i;
                for(i = 0; i < ticks.length; i++) { // Collect tick y positions and texts (value + units)
                    pos[i] = /,\s*([\d.]+)/.exec(ticks.get(i).getAttribute('transform')); // ",218.75","218.75"
                    lbl[i] = /([\d.]+)\s*(\w+)/.exec(texts.get(i).innerHTML); // "200 ft","200","ft"
                }
                var pp = (lbl[1][1]-lbl[0][1])/(pos[0][1]-pos[1][1]); // Per pixel scale for current y-axis
                var extent = y * pp; // Actual extent of the extremities of the elevation graph
                var realpp = extent / h; // Per pixel scale for new y-axis
                var y0 = lbl[0][1] - (h-pos[0][1])*pp; // Starting point on current y-axis (same as starting point for unclipped main graph)
                var max = ay*pp + y0; // Max elevation on new y-axis
                var min = max - extent; // Min elevation on new y-axis (not the same as old y-axis!)
                for(i = 0; i < ticks.length; i++) {
                    texts.get(i).innerHTML = Math.round(((h-pos[i][1])*realpp + min)) + lbl[i][2]; // New y-axis values at old line points
                }
            }
        });
    }
}