1

I've got an HTML5 canvas 'join the dots' type thing going - 2 lines with dots at their angle points - this is fine but I want to plot the X coordinates programatically with external JSON data (pulled from a 'local' server so won't need to be JSONP) - I hope I explain this clearly ...

I'm not trying to convert the JSON data into new DOM elements, but instead I need to apply the data to the actual script which maps the canvas coordinates. Ideally I want to use jQuery for this and my guess is that I will need to parse a JSON object via .getJSON(), but this is where I need some help.

Both X and Y coordinates are currently initiated with hard-coded variables in the canvas script but I want the JSON data to parse into the X variable programatically (the Y co-ords can stay hard coded and work fine for both lines).

Here's a fiddle of what I have so far: http://jsfiddle.net/ByT58/6/

Here's the markup/script for reference - and big thanks in advance for any help!:

HTML:

<div class="canvas-wrap">
        <canvas id="myCanvas" width="200" height="115"></canvas>
    </div>

Here's how the external JSON would look:

{
    "red": {
        "r01x": 20,
        "r02x": 149,
        "r03x": 50
    },
    "blue": {
        "b01x": 80,
        "b02x": 179,
        "b03x": 20
    }
}

JS:

var ctx = document.getElementsByTagName('canvas')[0].getContext('2d');

// set attributes for all circles
var radius = 7;

// set attributes for all lines
ctx.lineWidth = 5;
ctx.lineJoin = 'round';

// set X co-ords for Red
var r01x = 20;
var r02x = 149;
var r03x = 50;

// set X co-ords for Blue
var b01x = 80;
var b02x = 179;
var b03x = 20;

// Set default Y coordinates for both Red and Blue
var y01 = 20;
var y02 = 50;
var y03 = 100;

// RED dots
ctx.beginPath();
ctx.fillStyle = "#E51919";
ctx.arc(r01x, y01, radius, 0, Math.PI * 2, true);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.fillStyle = "#E51919";
ctx.arc(r02x, y02, radius, 0, Math.PI * 2, true);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.fillStyle = "#E51919";
ctx.arc(r03x, y03, radius, 0, Math.PI * 2, true);
ctx.fill();
ctx.closePath();

// RED line
ctx.beginPath();
ctx.moveTo(r01x, y01);
ctx.lineTo(r02x, y02);
ctx.lineTo(r03x, y03);     
ctx.strokeStyle = "#E51919";
ctx.stroke();
ctx.closePath();

// BLUE dots
ctx.beginPath();
ctx.fillStyle = "#133175";
ctx.arc(b01x, y01, radius, 0, Math.PI * 2, true);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.fillStyle = "#133175";
ctx.arc(b02x, y02, radius, 0, Math.PI * 2, true);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.fillStyle = "#133175";
ctx.arc(b03x, y03, radius, 0, Math.PI * 2, true);
ctx.fill();
ctx.closePath();

// BLUE line
ctx.beginPath();
ctx.moveTo(b01x, y01);
ctx.lineTo(b02x, y02);
ctx.lineTo(b03x, y03);     
ctx.strokeStyle = "#133175";
ctx.stroke();
ctx.closePath();
redplanet
  • 158
  • 4
  • 17
  • Do you notice that you repeat the code? Doesn't that hint you that you should use an array and a loop? – Joseph Jun 08 '13 at 16:08
  • Yes, and the logic would be 1: plot the json key/value into a multidimensional array, 2: use `.each()` to parse the array and insert the array key/value into the canvas script variables. Trouble is that my chops aren't up to that - I could possibly do this for elements inserted into the DOM but don't know how to parse them into the canvas script. I'm guessing so came here for advice. – redplanet Jun 08 '13 at 16:37

1 Answers1

1

If you were to put your JSON data into the form:

{
    red:  { color: "#E51919", x: [20,149,50] },
    blue: { color: "#133175", x: [80,179,20] }
}

Your draw function would look something like (jsFiddle here):

function draw(data) {
    var ctx = document.getElementsByTagName('canvas')[0].getContext('2d');

    // set attributes for all circles
    var radius = 7;

    // set attributes for all lines
    ctx.lineWidth = 5;
    ctx.lineJoin = 'round';

    var y = [20,50,100];
    for(var key in data) {
        var x = data[key].x;
        ctx.fillStyle = data[key].color;
        for(var i = 0; i < x.length; ++i) {
            ctx.beginPath();
            ctx.arc(x[i], y[i], radius, 0, Math.PI * 2, true);
            ctx.fill();
            ctx.closePath();
        }

        ctx.beginPath();
        ctx.moveTo(x[0], y[0]);
        ctx.lineTo(x[1], y[1]);
        ctx.lineTo(x[2], y[2]);
        ctx.strokeStyle = data[key].color;
        ctx.stroke();
        ctx.closePath();
    }
}

draw({
    red:  { color: "#E51919", x: [20,149,50] },
    blue: { color: "#133175", x: [80,179,20] }
});

Using JQuery to retrieve the JSON data from the server use jQuery.getJSON() or jQuery.ajax()

for example (no error handling...):

$.getJSON('path/data.json', function(data, textStatus, jqXHR) {
    console.log(textStatus);
    draw(data);
})
.fail(function( jqXHR, textStatus, errorThrown) { console.log(textStatus + " :: " + errorThrown ); });
dc5
  • 12,341
  • 2
  • 35
  • 47
  • Fantastic, thanks very much! Works perfectly on my localhost with the json data included in the script file. However, when I comment out the inline json and use `$getJSON` it doesn't work, and I'm not getting any console error. I've updated the fiddle to reflect what I'm doing locally, is there anything obviously wrong there? [jsfiddle.net/ByT58/11/](http://jsfiddle.net/ByT58/11/) – redplanet Jun 08 '13 at 18:08
  • I am calling jquery cdn in the localhost file so that's not the problem. – redplanet Jun 08 '13 at 18:20
  • Can advise here please? I'm not trying to be lazy but I can't see where this is going wrong. In the console I'm getting `http://localhost:9000/html5/canvas/data-3.json` and a 200 OK message, I've got console logs before and after the json call so I believe everything is loading fine. Any suggestions please? – redplanet Jun 08 '13 at 19:48
  • Hard to say - You might try accessing data-3.json directly in the browser. The only thing I can suggest is to set a breakpoint in your handler and walk through the code to get a better idea of what might be happening. BTW: also updated the sample above with an error handler to show you how to get more detail on a failure. – dc5 Jun 08 '13 at 21:52
  • Thanks, actually tried both of what you mentioned, can see the file fine in browser and syntax error with 2x .fail functions, bummer. Also happens that jsonlint is calling a syntax error on the json data, the same data that works fine when referenced inline. I'm gonna hit a few books but also check out from this for now - uk hours. Thanks so far I'll hit this again later. – redplanet Jun 08 '13 at 23:16