Newer
Older
weather-servlet / src / main / webapp / charts.js
var cCanvas, cCtx, ressie_angle = 0;
var CIRCLE_RADIUS = 0.75;
var REAR_ARROW_WIDTH = 0.18;
var FRONT_ARROW_WIDTH = 0.15;
var BEARING_ARROW_WIDTH = 0.08;
var BEARING_ARROW_LENGTH = 0.65;

function drawCompass(angle) {
  cCanvas = document.getElementById("compass");
  if (!cCanvas) {
    return;
  }
  cCtx = cCanvas.getContext("2d");
  if (!cCtx) {
    return;
  }
  cCtx.clearRect(0, 0, cCanvas.width, cCanvas.height);
  var minWidthHeight = Math.min(cCanvas.width, cCanvas.height);
  var FRONT_45 = minWidthHeight / 2 * CIRCLE_RADIUS * Math.sin(Math.PI / 4) * FRONT_ARROW_WIDTH;
  cCtx.save();
  cCtx.translate(cCanvas.width / 2, cCanvas.height / 2);
  cCtx.strokeStyle = "rgb(136, 136, 136)";
  cCtx.lineWidth = 0.75;
  for (var i = 0; i < 2; i++) {
    cCtx.beginPath();
    cCtx.arc(0, 0, minWidthHeight / 2 * CIRCLE_RADIUS, 0, Math.PI * 2, true);
    cCtx.closePath();
    if (i == 0) {
      cCtx.fillStyle = "rgba(255,255,255,0.5)";
      cCtx.fill();
    } else {
      cCtx.stroke();
    }
  }
  for (var i = 0; i < 2; i++) {
    cCtx.beginPath();
    cCtx.moveTo(0, -minWidthHeight / 2 * REAR_ARROW_WIDTH);
    cCtx.lineTo(minWidthHeight / 2 * CIRCLE_RADIUS * Math.sin(Math.PI / 4),
                -minWidthHeight / 2 * CIRCLE_RADIUS * Math.sin(Math.PI / 4));
    cCtx.lineTo(minWidthHeight / 2 * REAR_ARROW_WIDTH, 0);
    cCtx.lineTo(minWidthHeight / 2 * CIRCLE_RADIUS * Math.sin(Math.PI / 4),
                minWidthHeight / 2 * CIRCLE_RADIUS * Math.sin(Math.PI / 4));
    cCtx.lineTo(0, minWidthHeight / 2 * REAR_ARROW_WIDTH);
    cCtx.lineTo(-minWidthHeight / 2 * CIRCLE_RADIUS * Math.sin(Math.PI / 4),
                minWidthHeight / 2 * CIRCLE_RADIUS * Math.sin(Math.PI / 4));
    cCtx.lineTo(-minWidthHeight / 2 * REAR_ARROW_WIDTH, 0);
    cCtx.lineTo(-minWidthHeight / 2 * CIRCLE_RADIUS * Math.sin(Math.PI / 4),
                -minWidthHeight / 2 * CIRCLE_RADIUS * Math.sin(Math.PI / 4));
    cCtx.lineTo(0, -minWidthHeight / 2 * REAR_ARROW_WIDTH);
    cCtx.closePath();
    if (i == 0) {
      cCtx.fillStyle = "rgb(0, 0, 255)";
      cCtx.fill();
    } else {
      cCtx.stroke();
    }
  }
  for (var i = 0; i < 2; i++) {
    cCtx.save();
    for(var j=0; j<4; j++) {
      cCtx.beginPath();
      cCtx.moveTo(0, 0);
      cCtx.lineTo(FRONT_45, -FRONT_45);
      cCtx.lineTo(0, -minWidthHeight / 2);
      cCtx.lineTo(0, 0);
      cCtx.closePath();
      if (i == 0) {
        cCtx.fillStyle = "rgb(255,0,0)";
        cCtx.fill();
      } else {
        cCtx.stroke();
      }
      cCtx.beginPath();
      cCtx.moveTo(0, 0);
      cCtx.lineTo(-FRONT_45, -FRONT_45);
      cCtx.lineTo(0, -minWidthHeight / 2);
      cCtx.lineTo(0, 0);
      cCtx.closePath();
      if (i == 0) {
        cCtx.fillStyle = "rgb(255,255,255)";
        cCtx.fill();
      } else {
        cCtx.stroke();
      }
      cCtx.rotate(Math.PI / 2);
    }
    cCtx.restore();
  }
  for (var i = 0; i < 2; i++) {
    cCtx.save();
    cCtx.rotate(angle * Math.PI / 180.0);
    cCtx.beginPath();
    cCtx.moveTo(0, BEARING_ARROW_WIDTH * minWidthHeight / 2);
    cCtx.lineTo(BEARING_ARROW_WIDTH * minWidthHeight / 2, 0);
    cCtx.lineTo(0, -minWidthHeight * BEARING_ARROW_LENGTH / 2);
    cCtx.lineTo(-BEARING_ARROW_WIDTH * minWidthHeight / 2, 0);
    cCtx.lineTo(0, BEARING_ARROW_WIDTH * minWidthHeight / 2);
    cCtx.closePath();
    if (i == 0) {
      cCtx.fillStyle = "rgb(238,238,0)";
      cCtx.fill();
    } else {
      cCtx.lineWidth = 3;
      cCtx.strokeStyle = "rgb(0, 0, 0)";
      cCtx.stroke();
    }
    cCtx.restore();
  }
  cCtx.restore();
}

function svgPathMap(svg_path, move_fun, line_fun, curve_fun, close_fun) {
  var i = 0;
  while (i < svg_path.length) {
    if (svg_path[i] == "M") {
      var move_xy = svg_path[i+1].split(",");
      move_fun(move_xy[0], move_xy[1]);
      i = i + 2;
    } else if (svg_path[i] == "L") {
      var line_xy = svg_path[i+1].split(",");
      line_fun(line_xy[0], line_xy[1]);
      i = i + 2;
    } else if (svg_path[i] == "C") {
      var xy1 = svg_path[i+1].split(","), xy2 = svg_path[i+2].split(","), xy3 = svg_path[i+3].split(",");
      curve_fun(xy1[0], xy1[1], xy2[0], xy2[1], xy3[0], xy3[1]);
      i = i + 4;
    } else if (svg_path[i] == "z") {
      close_fun();
      i++;
    }
  }
}

function drawRessie() {
  cCanvas = document.getElementById("compass");
  if (!cCanvas) {
    return;
  }
  cCtx = cCanvas.getContext("2d");
  if (!cCtx) {
    return;
  }
  cCtx.clearRect(0, 0, cCanvas.width, cCanvas.height);
  var SVG_PATH=("M 242.14286,620.93361 C 242.14286,620.93361 307.14286,540.93361 318.57143,526.6479 "+
                "C 330,512.36218 309.28571,498.07647 309.28571,498.07647 C 309.28571,498.07647 291.19688,481.65613 287.85714,477.36218 "+
                "C 282.85715,470.93361 290.78801,462.50108 298.57143,463.79075 C 310.72728,465.80491 334.28571,463.79075 347.85714,456.6479 "+
                "C 361.42857,449.50504 360.71429,440.21933 370,435.21933 C 379.28571,430.21933 390,425.93361 407.14286,423.07647 "+
                "C 424.05247,420.2582 430.71429,413.07647 437.14286,409.50504 C 443.57143,405.93361 450,398.07647 451.42857,405.21933 "+
                "C 452.85714,412.36218 480,520.93361 480,520.93361 C 480,520.93361 447.14286,551.6479 440,555.93361 "+
                "C 432.85714,560.21933 427.85714,567.36218 423.57143,567.36218 C 419.28571,567.36218 409.28571,574.50504 409.28571,574.50504 "+
                "L 408.57143,594.50504 C 408.57143,594.50504 407.85714,615.21933 405,615.93361 "+
                "C 402.14286,616.6479 392.14286,625.93361 375,613.79075 C 357.85714,601.6479 337.14286,593.07647 327.14286,595.93361 "+
                "C 317.14286,598.79075 298.57143,603.07647 298.57143,603.07647 C 298.57143,603.07647 265,641.6479 259.28571,641.6479 "+
                "C 253.57143,641.6479 243.57143,643.07647 240.71429,635.93361 C 237.85714,628.79076 242.14286,621.6479 242.14286,620.93361 z").split(" ");
  var max_x = 0, max_y = 0, min_x = 2000, min_y = 2000;
  var minWidthHeight = Math.min(cCanvas.width, cCanvas.height);
  function bound(x, y) {
    max_x = Math.max(max_x, x);
    max_y = Math.max(max_y, y);
    min_x = Math.min(min_x, x);
    min_y = Math.min(min_y, y);
  }
  svgPathMap(SVG_PATH, bound, bound, function(cx1, cy1, cx2, cy2, x, y) {bound(x, y);}, function() {});
  cCtx.save();
  if (ressie_angle < 360) {
    ressie_angle = ressie_angle + 1;
  } else {
    ressie_angle = 0;
  } 
  cCtx.translate(minWidthHeight / 2, minWidthHeight / 2);
  cCtx.rotate(Math.PI / 180 * ressie_angle);
  var scale = minWidthHeight / Math.max(max_x - min_x, max_y - min_y) / Math.sqrt(2);
  cCtx.scale(scale, scale);
  cCtx.translate(-(min_x + max_x) / 2, -(min_y + max_y) / 2);
  cCtx.beginPath();
  cCtx.strokeStyle = "rgb(136, 136, 136)";
  cCtx.fillStyle = "rgb(34, 170, 238)";
  svgPathMap(SVG_PATH, function(x, y) {cCtx.moveTo(x, y);},
                       function(x, y) {cCtx.lineTo(x, y);},
                       function(x1, y1, x2, y2, x, y) {cCtx.bezierCurveTo(x1, y1, x2, y2, x, y);},
                       function() {cCtx.closePath(); cCtx.fill();});
  svgPathMap(SVG_PATH, function(x, y) {cCtx.moveTo(x, y);},
                       function(x, y) {cCtx.lineTo(x, y);},
                       function(x1, y1, x2, y2, x, y) {cCtx.bezierCurveTo(x1, y1, x2, y2, x, y);},
                       function() {cCtx.closePath(); cCtx.stroke();});
  cCtx.restore();
}