0

For my company, i have to develop functions to draw a Race Profile, and add the race checkpoints. At the moment, I have this:

Chart

But, here, my CP was added to the profile automatically. The problem is, that I would like to let our users decide if they want the CP displayed on the profile or not. Moreover, i would like to remove these checkpoints if the user don't want them to be displayed. I tried using a checkbox, but it didn't work. If you have any idea, or any advice to give me, i'll accept it with great pleasure.

Best Regards, Damien.

So, there is my css:

body {font: 10px sans-serif;}

 .axis path, .axis line {fill: none;  stroke: #000;  shape-rendering: crispEdges;}

.axis text { font-family: Lato; font-size: 13px;}

.grid path, .grid line { fill: none; stroke: rgba(0, 0, 0, 0.25); shape-rendering: crispEdges;}

.area { fill: darkorange;}

.marker.client .marker-bg, .marker.client path {fill: rgba(255, 127, 0, 0.8); stroke: rgba(255, 127, 0, 0.8); stroke-width: 3;}

.marker.server .marker-bg, .marker.server path { fill: rgba(0, 153, 51, 0.8);stroke: rgba(0, 153, 51, 0.8);stroke-width: 3;}

.marker path { fill: none;}

.legend text, .marker text { fill: #fff;font-weight: bold;}

.marker text {text-anchor: middle;}

And, there is my JS:

function profile(data) {

    var margin = {
        top: 20
        , right: 20
        , bottom: 60
        , left: 50
    }
        , width = 960 - margin.left - margin.right
        , height = 500 - margin.top - margin.bottom
        , innerwidth = width - margin.left - margin.right
        , innerheight = height - margin.top - margin.bottom;

    var x = d3.scaleLinear().range([0, width]);

    var y = d3.scaleLinear().range([height, 0]);

    var xAxis = d3.axisBottom().scale(x);

    var yAxis = d3.axisLeft().scale(y);

    var area = d3.area().x(function (d) {
        return x(d.d);
    }).y0(height).y1(function (d) {
        return y(d.a);
    })

    var svg = d3.select("body").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 + ")");

    x.domain(d3.extent(data, function (d) {
        return d.d;
    }));

    y.domain([0, d3.max(data, function (d) {
        return d.a;
    })]);

    var x_grid = d3.axisBottom().scale(x).tickSize(-height).tickFormat("");

    var y_grid = d3.axisLeft().scale(y).tickSize(-width).tickFormat("");

    svg.append('svg:path')
        .datum(data)
        .attr("class", "area")
        .attr("d", area)

    svg.append("svg:g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis)
        .append("text")
        .attr("transform", "translate(0," + margin.top * 2 + ")")
        .attr("x", width - (margin.right + margin.left))
        .text("Distance (km)")

    svg.append("svg:g")
        .attr("class", "y axis")
        .call(yAxis)
        .append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 6).attr("dy", ".71em")
        .style("text-anchor", "end")
        .text("Altitude (m)")

    svg.append("g")
        .attr("class", "x grid")
        .attr("transform", "translate(0," + height + ")")
        .call(x_grid);

    svg.append("g")
        .attr("class", "y grid")
        .call(y_grid);
    d3.json('data.json', function (error, rawData) {
        if (error) {
            console.error(error);
            return;
        }

        var data = rawData.map(function (d) {
            return {
                altitude: d.a,
                distance: d.d
            };
        });

        d3.json('markers.json', function (error, markerData) {
            if (error) {
                console.error(error);
                return;
            }

            var markers = markerData.map(function (marker) {
                return {
                    id: marker.id,
                    name: marker.name,
                    type: marker.type,
                    description: marker.description,
                    icon: marker.icon,
                    distance: marker.distance
                };
            });

            if (document.getElementById("cbox1").checked = true) {
                markers.forEach(function (marker, i) {
                    setTimeout(function () {
                        setItem(marker, svg, innerheight, x);

                    }, 1000 + 500 * i);
                });
            }
            else { //        removeItem(marker, svg, innerheight, x);
                alert("oui");
            }
        });
    });
}
function setItem(marker, svg, innerheight, x) {
    var radius = 20,
        xPos = x(marker.distance) - radius - 3,
        yPosStart = innerheight - radius - 3,
        yPosEnd = (marker.type === 'CP' ? 80 : 160) + radius - 3;

    var markerG = svg.append('g')
        .attr('class', 'marker ' + marker.type.toLowerCase())
        .attr('transform', 'translate(' + xPos + ', ' + yPosStart + ')')
        .attr('opacity', 0);

    markerG.transition()
        .duration(1000)
        .attr('transform', 'translate(' + xPos + ', ' + yPosEnd + ')')
        .attr('opacity', 1);

    markerG.append('path')
        .attr('d', 'M' + radius + ',' + (innerheight - yPosStart) + 'L' + radius + ',' + (innerheight - yPosStart))
        .transition()
        .duration(1000)
        .attr('d', 'M' + radius + ',' + (innerheight - yPosEnd) + 'L' + radius + ',' + (radius * 2));

    markerG.append('circle')
        .attr('class', 'marker-bg')
        .attr('cx', radius)
        .attr('cy', radius)
        .attr('r', radius);

    markerG.append('text')
        .attr('x', radius)
        .attr('y', radius * 0.9)
        .text(marker.type);

    markerG.append('text')
        .attr('x', radius)
        .attr('y', radius * 1.5)
        .text(marker.description);
}

$.ajax({
    url: '/site/raceprofile/profile.json'
    , method: 'GET'
    , success: function (data) {
        console.log("data =", data);
        profile(data);
    }
    , error: function (data) {
        console.log("err" + data)
    }
})

I also use two .json file: data.json

[{"d": 1488,"a": 145}, {"d": 1489, "a": 132}, {"d": 1490, "a": 70}, {"d": 1491, "a": 115}, {"d": 1492, "a": 44}, {"d": 1493, "a": 117}, {"d": 1494, "a": 9}, {"d": 1495, "a": 64}, {"d": 1496, "a": 37}, {"d": 1497, "a": 145}, {"d": 1498, "a": 14}, {"d": 1499, "a": 86}, {"d": 1500, "a": 119}, {"d": 1501, "a": 200}, {"d": 1502, "a": 23}, {"d": 1503, "a": 85}, {"d": 1504, "a": 145}, {"d": 1505, "a": 49}, {"d": 1506, "a": 145}, {"d": 1507, "a": 58}]

markers.json

[
{
    "id": "1",
    "name": "Depart - Vielle-Aure",
    "type": "CP",
    "description": "Départ",
    "icon": "../item_icons/iconCust/map-marker-checkpoint.svg",
    "distance": "1488"
  },{
    "id": "2",
    "name": "CP1 - Col de Portet",
    "type": "CP",
    "description": "1er CP",
    "icon": "../item_icons/iconCust/map-marker-checkpoint.svg",
    "distance": "1496"
  },{
    "id": "1",
    "name": "CP2 - Artigues",
    "type": "CP",
    "description": "2ème CP",
    "icon": "../item_icons/iconCust/map-marker-checkpoint.svg",
    "distance": "1504"
  }
]
Matthew Wilcoxson
  • 3,432
  • 1
  • 43
  • 48
Damien Brz
  • 27
  • 1
  • 11
  • What does the profile.json file look like? – Matthew Wilcoxson Jan 09 '17 at 14:39
  • Hi Matthew, Sorry for not answering before, It was my school's week. So, my profile.json looks like data.json, a file with always 2 attributes, altitude and distance. And, I have another question, it's quite long, so I'll write it in another answer :) Damien. – Damien Brz Jan 16 '17 at 09:33
  • The other question is here: http://stackoverflow.com/questions/41674400/get-coords-on-any-chart-point – Damien Brz Jan 16 '17 at 11:30

1 Answers1

0

Looks like you need to correct this if statement on your checkbox check code to:

if (document.getElementById("cbox1").checked === true ) {

However, that will only check once on page load, to update everytime the checkbox is changed add a function that is called on change:

d3.select("#cbox1").on("change",update);

function update() {
    if(d3.select("#cbox1").property("checked")){
       // do something
    }
    else {
        // undo something
    }
}

You have two options on what to do in the function. You can hide and show the markers by making them change transparency or you can regenerate the graph to remove or create them.

Matthew Wilcoxson
  • 3,432
  • 1
  • 43
  • 48
  • Hi Matthew, Thank you for your answer. So, i changed the line, but the code still doesn't want work. It doesn't even recognize the changing value of my checkbox. I tried to create some ressources on [GitHub](https://gist.github.com/Onchman/9349e63e8460d32fbe7926243035827b): And, another one on [codepen](https://codepen.io/Onchman/pen/egmGZV), but, I don't know how to add my json files on it... – Damien Brz Jan 05 '17 at 10:28
  • I've added alot more about how to update with a checkbox. – Matthew Wilcoxson Jan 06 '17 at 11:31