2
\$\begingroup\$

I would like to get feedback on the code. It is working and can be seen here.

I welcome any kind of feedback, since I am just starting to use JavaScript. Epecially in the case of performance, there might be better ways to code.

$(document).ready(function () {
    var latlng, altitude, time, distance;
    var graphDataAlt = []; var graphDataTime = [];
    var showTime = false;
    var margin, svg, ruler, map, marker;

    $.ajax({
        url: "LoadStreams.php",
        dataType: "json",
        type: "post",
        success: function (data) {
            drawGraph(data);
        }
    });
    //Below the main loop program for all the graph functions
    function drawGraph(data) {
        //TODO: Test on datatypes and set data
        latlng = data[0].data;
        time = data[1].data;
        distance = data[2].data;
        altitude = data[3].data;
        var parseDate = d3.time.format("%H:%M:%S").parse;
        for (var i = 0; i < distance.length; i++) {
            var obj = {}; var obj1 = {};
            obj.hor = distance[i] / 1000;
            obj1.hor = parseTime(time[i]);
            obj1.hor = parseDate(obj1.hor);
            obj.vert = altitude[i];
            obj1.vert = altitude[i];
            graphDataAlt.push(obj);
            graphDataTime.push(obj1);
        }
        //******************* GOOGLE MAPS *********************
        //set Path and bounds
        var path = [];
        var bounds = new google.maps.LatLngBounds();
        for (i = 0; i < latlng.length; i++) {
            var lat = latlng[i][0];
            var lng = latlng[i][1];
            path.push(new google.maps.LatLng(lat, lng));
            bounds.extend(new google.maps.LatLng(lat, lng));
        }
        //define Map
        var mapOptions = {
            zoom: 11,
            center: new google.maps.LatLng(0, 0),
            mapTypeId: google.maps.MapTypeId.TERRAIN
        };
        var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
        //define Polyline
        var route = new google.maps.Polyline({
            path: path,
            geodesic: false,
            strokeColor: '#FF0000',
            strokeOpacity: 1.0,
            strokeWeight: 2
        });
        //Set Bounds
        map.fitBounds(bounds);
        //Show route on the map
        route.setMap(map);
        //Define the marker
        var image = {
            url: 'cycling.png'
        };
        var marker = new google.maps.Marker({
            icon: image
        });
        //********************** SVG ***************************************
        showGraph(graphDataAlt);
        //TODO define the eventhandlers for moving the ruler and markers
        // Toggle de data voor de graph
        $("#test").on("click", function () {
            showTime = !showTime;
            if (showTime) { $("#test").text("Distance"); updateGraph(graphDataTime, showTime); }
            else { $("#test").text("Time"); updateGraph(graphDataAlt, showTime); }
        });
        var svg = d3.select("#graph1");
        var ruler = d3.select(".ruler");
        svg.select("#grid")
                .on("mouseout", function () { ruler.style("display", "none"); marker.setMap(null); })
                .on("mousemove", mousemove)
                ;
        function mousemove() {
            x = d3.mouse(this)[0];
            ruler.style("display", null); marker.setMap(map);
            ruler.attr("transform", "translate(" + x + ", 0)");
            var latlng = path[Math.floor((x / width) * path.length)];
            marker.setPosition(latlng);
        }

    }; //drawGraph

    var margin = { top: 30, right: 20, bottom: 30, left: 50 },
                 width = 1200 - margin.left - margin.right,
                 height = 200 - margin.top - margin.bottom;

    function updateGraph(data, showTime) {
        if (!showTime) {
            var x = d3.scale.linear()
                .range([0, width])
                .domain([0, d3.max(data, function (d) { return d.hor; })]);
        }
        else {
            var x = d3.time.scale()
                .range([0, width])
                .domain(d3.extent(data, function (d) { return d.hor; }));
        }
        var max = d3.max(data, function (d) { return d.vert; });
        var min = d3.min(data, function (d) { return d.vert; });
        if (max < 50) { max = 200; }
        if (min < -5) { min = -50; }
        var y = d3.scale.linear()
                .rangeRound([height, 0])
                .domain([min, max]);

        function make_x_axis() {
            return d3.svg.axis()
                 .scale(x)
                 .orient("bottom")
                 .ticks(10)
        }

        var svg = d3.select("#graph1");

        svg.select("g.grid")
                .call(make_x_axis()
                     .tickSize(-height, 0, 0)
                     .tickFormat("")
                );
        //Update Area
        var area = d3.svg.area()
                 .x(function (d) { return x(d.hor); })
                 .y0(height)
                 .y1(function (d) { return y(d.vert); });

        svg.select("path.area")
                 .datum([data])
                 .attr("d", area(data));

        var valueline = d3.svg.line()
                .x(function (d) { return x(d.hor); })
                .y(function (d) { return y(d.vert); });

        svg.select("path.line")
                .data([data])
                .attr("d", valueline(data));


        //Update x axis
        if (showTime) {
            var xAxis = d3.svg.axis().scale(x)
                 .orient("bottom").ticks(11)
                 .tickFormat(d3.time.format("%H:%M:%S"));
        }
        else {
            var xAxis = d3.svg.axis().scale(x)
                 .orient("bottom").ticks(10);
        }

        var parseDate = d3.time.format("%X").parse;
        svg.select(".x.axis")
                 .data([data])
                 .call(xAxis)
                 .selectAll("text").text(function (d, i) { if (showTime) { return parseDate(d.hor) } else { return d = d + '.0 km' } });
    }

    function showGraph(data) {
        var x = d3.scale.linear()
                .range([0, width])
                .domain([0, d3.max(data, function (d) { return d.hor; })]);
        var max = d3.max(data, function (d) { return d.vert; });
        var min = d3.min(data, function (d) { return d.vert; });
        if (max < 50) { max = 200; }
        if (min < -5) { min = -50; }
        var y = d3.scale.linear()
                .rangeRound([height, 0])
                .domain([min, max]);
        // Define Axis
        var xAxis = d3.svg.axis().scale(x)
                 .orient("bottom").ticks(10);

        var yAxis = d3.svg.axis().scale(y)
                 .orient("left").ticks(4);

        var valueline = d3.svg.line()
                .x(function (d) { return x(d.hor); })
                .y(function (d) { return y(d.vert); });
        // Define Area
        var area = d3.svg.area()
             .x(function (d) { return x(d.hor); })
             .y0(height)
             .y1(function (d) { return y(d.vert); });

        var svg = d3.select("#graph1")
                 .append("svg")
                     .attr("width", width + margin.left + margin.right)
                     .attr("height", height + margin.top + margin.bottom)
                 .append("g")
                     .attr("transform",
                           "translate(" + margin.left + "," + margin.top + ")");

        function make_x_axis() {
            return d3.svg.axis()
                 .scale(x)
                 .orient("bottom")
                 .ticks(10)
        }

        function make_y_axis() {
            return d3.svg.axis()
                     .scale(y)
                     .orient("left")
                     .ticks(4)
        }
        // Add Area
        svg.append("g")
                .append("path")
                .datum(data)
                .attr("class", "area")
                .attr("d", area(data));
        // Add the line
        svg.append("g")
               .attr("class", "path")
               .append("path")
               .attr("class", "line")
               .attr("d", valueline(data));
        //Add Grid
        svg.append("g")
                .attr("class", "grid")
                .attr("transform", "translate(0," + height + ")")
                .call(make_x_axis()
                     .tickSize(-height, 0, 0)
                     .tickFormat("")
                );
        svg.append("g")
                .attr("class", "grid")
                .call(make_y_axis()
                         .tickSize(-width, 0, 0)
                         .tickFormat("")
                 );
        // Add the X Axis
        svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis)
                .selectAll("text").text(function (d, i) { return d = d + '.0 km'; }); //units toevoegen

        // Add the Y Axis
        svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .selectAll("text").text(function (d, i) { return d = d + ' m'; }); // units toevoegen 

        //Add Ruler
        var ruler = svg.append("g")
                .attr("class", "ruler")
                .style("display", "none");

        ruler.append("line")
                .style("stroke", "black")
                .style("stroke-width", "1")
                .style("pointer-events", "none")
                .attr("x0", 0)
                .attr("y0", 0)
                .attr("x1", 0)
                .attr("y1", height);

        //Add the event Rect
        svg.append("g")
                .attr("id", "grid")
                .append("rect")
                .attr("class", "event-rect")
                .attr("x", 0)
                .attr("y", 0)
                .attr("height", height)
                .attr("width", width)
                .attr("style", "fill: transparent");

    }

    function parseTime(secs) {
        var t = new Date(1970, 0, 1);
        t.setSeconds(secs);
        var s = t.toTimeString().substr(0, 8);
        return s;
    };
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I'm sorry this is so short, but I only have time to give it a quick once-over right now.

The first thing I noticed was the flickering of the cycling icon as I scroll through the bottom. Compared to the rest of the application, which looks great, this was awful.

This is happening because you are assigning the Marker to the Map on mousemove, which doesn't make much sense. If you move this initialisation to a mouseover handler instead, the flicker will be gone:

svg.select("#grid").on("mouseover", function() {
    ruler.style("display", null);
    marker.setMap(map);
}).on("mousemove", function() {
    var x = d3.mouse(this)[0];
    ruler.attr("transform", "translate(" + x + ", 0)");
    marker.setPosition(path[Math.floor((x / width) * path.length)]);
}).on("mouseout",  function() {
    ruler.style("display", none");
    marker.setMap(null);
});

You'll note that I got rid of latlng (didn't seem to add much value to me) and that I declared x as a local variable.

\$\endgroup\$
1
  • \$\begingroup\$ Thx for the quick response, Schism. This is a very good improvement. The flicker was indeed one of the things i wanted to solve. I updated the script on azure. Thx again \$\endgroup\$
    – gedysan
    Commented Aug 19, 2014 at 18:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.