ФRuŠKać

Chart

constructor
Chart()

Option name Type Description
container HTMLDomElement
function Chart(container) {
    var self = this;
    self.visible = false;
    self.container = container;
}

Chart

prototype
Chart.prototype

Chart.prototype = {

setVisible

method
Chart.prototype.setVisible()

Option name Type Description
value boolean

Set chart container visibility

setVisible: function (value) {

    var self = this;

    self.visible = value;

    var className = 'on';

    if (self.visible) {
        util.addClass(self.container, className);
    } else {
        util.removeClass(self.container, className);
        map.placeMarker();
    }

    var center = gmap.getCenter();
    google.maps.event.trigger(gmap, "resize");
    gmap.setCenter(center);

},

show

method
Chart.prototype.show()

Option name Type Description
points Array

Show chart

show: function (points, isFixedLayout) {

    var self = this;

    self.setVisible(true);

    if (isFixedLayout) {
        util.remove(document.getElementById('chart_button_close'));
    }

    var elevator = new google.maps.ElevationService;

    // Load the Visualization API and the corechart package.
    google.charts.load('current', {
        packages: ['corechart'],
        language: fruskac.config.lang
    });

    // Set a callback to run when the Google Visualization API is loaded.
    google.charts.setOnLoadCallback(function () {
        getPathElevation(points, elevator, function (rows) {

            // Create the data table.
            var data = new google.visualization.DataTable();
            data.addColumn('number', i18n.translate(I18N_DISTANCE));
            data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
            data.addColumn('number', i18n.translate(I18N_ELEVATION));
            data.addRows(rows);

            // Set chart options
            var options = {
                lineWidth: 2,
                areaOpacity: 0.4,
                series: {
                    0: {
                        color: '#d2003b',
                        visibleInLegend: false
                    }
                },
                focusTarget: 'category',
                axisTitlesPosition: 'none',
                hAxis: {
                    baselineColor: 'transparent',
                    gridlines: {
                        color: 'transparent'
                    },
                    ticks: [0, Math.round(rows[rows.length - 1][0] * 10) / 10]
                },
                vAxis: {
                    baselineColor: 'transparent',
                    minValue: 0,
                    gridlines: {
                        color: 'transparent'
                    }
                },
                legend: {
                    position: 'none'
                },
                tooltip: {
                    isHtml: true
                }
            };

            // Instantiate and draw our chart, passing in some options.
            var chart = new google.visualization.AreaChart(document.getElementById('chart'));
            chart.draw(data, options);

            var timeout;

            google.visualization.events.addListener(chart, 'onmouseover', function (coords) {

                if (timeout) {
                    clearTimeout(timeout);
                }

                map.placeMarker(points.getAt(Math.round(coords.row * points.length / chartResolution)), 'tracker');
            });

            google.visualization.events.addListener(chart, 'onmouseout', function () {
                timeout = setTimeout(function () {
                    map.placeMarker(null);
                }, 300);
            });

            window.addEventListener('resize', function () {
                chart.draw(data, options);
            });

        });
    });

}
    };

getPathElevation

function
getPathElevation()

Option name Type Description
points Array.<Object>
elevator google.maps.ElevationService
callback Function
function getPathElevation(points, elevator, callback) {

    var ratio = Math.round(points.length / chartResolution),
        gpath = [],
        distance = 0;

    points.forEach(function (point, index) {

        if (index % ratio === 0) {
            gpath.push(point);
        }

        distance += index ? getDistance(points.getAt(index), points.getAt(index - 1)) : 0;

    });


    // Create a PathElevationRequest object using this array.
    elevator.getElevationAlongPath({
        'path': gpath,
        'samples': chartResolution
    }, function (elevations) {
        var rows = [],
            r = distance / (elevations.length - 1);

        elevations.forEach(function (e, index) {
            var d = r * index;
            rows.push([d, getTooltipContent(d, e.elevation), e.elevation]);
        });

        callback(rows);
    });
}

getDistance

function
getDistance()

Option name Type Description
p1 google.maps.LatLng
p2 google.maps.LatLng

calculates distance between two points in km's

function getDistance(p1, p2) {
    //return (google.maps.geometry.spherical.computeDistanceBetween(p1, p2) / 1000).toFixed(2);
    var R = 6378137; // Earth’s mean radius in meter
    var dLat = rad(p2.lat() - p1.lat());
    var dLong = rad(p2.lng() - p1.lng());
    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
        Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) *
        Math.sin(dLong / 2) * Math.sin(dLong / 2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = R * c;
    return d / 1000; // "d" returns the distance in meter
}

rad

function
rad()

Option name Type Description
x number
function rad(x) {
    return x * Math.PI / 180;
}

getTooltipContent

function
getTooltipContent()

Option name Type Description
distance
elevation number

Get HTML content for tooltip

function getTooltipContent(distance, elevation) {
    return i18n.translate(I18N_ELEVATION) + ': ' + '<strong>' + Math.round(elevation) + ' m' + '</strong>' +
        '<br>'
        + i18n.translate(I18N_DISTANCE) + ': ' + '<strong>' + Math.round(distance * 10) / 10 + ' km' + '</strong>';
}

window.closeChart = function () {
    chart.setVisible(false);
};

return Chart;

})();