Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active October 26, 2020 02:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nitaku/5f60d143735bdfc7d14c to your computer and use it in GitHub Desktop.
Save nitaku/5f60d143735bdfc7d14c to your computer and use it in GitHub Desktop.
Weather wheel

A recreation of this nice infographic in D3.js, with some modifications. A year of weather measurements is displayed in a single overview, highlighting seasonal processes. Data is obtained by querying Weather Underground's historical API.

A polar floating bar chart is used for minimum and maximum temperatures, while a HCL-interpolated color scale is used for means. Area encoding is instead used for precipitation (outer ring).

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define('d3-path', ['exports'], factory) :
factory((global.d3_path = {}));
}(this, function (exports) { 'use strict';
var pi = Math.PI;
var tau = 2 * pi;
var epsilon = 1e-6;
var tauEpsilon = tau - epsilon;
function Path() {
this._x0 = this._y0 = // start of current subpath
this._x1 = this._y1 = null; // end of current subpath
this._ = [];
}
function path() {
return new Path;
}
Path.prototype = path.prototype = {
moveTo: function(x, y) {
this._.push("M", this._x0 = this._x1 = +x, ",", this._y0 = this._y1 = +y);
},
closePath: function() {
if (this._x1 !== null) {
this._x1 = this._x0, this._y1 = this._y0;
this._.push("Z");
}
},
lineTo: function(x, y) {
this._.push("L", this._x1 = +x, ",", this._y1 = +y);
},
quadraticCurveTo: function(x1, y1, x, y) {
this._.push("Q", +x1, ",", +y1, ",", this._x1 = +x, ",", this._y1 = +y);
},
bezierCurveTo: function(x1, y1, x2, y2, x, y) {
this._.push("C", +x1, ",", +y1, ",", +x2, ",", +y2, ",", this._x1 = +x, ",", this._y1 = +y);
},
arcTo: function(x1, y1, x2, y2, r) {
x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
var x0 = this._x1,
y0 = this._y1,
x21 = x2 - x1,
y21 = y2 - y1,
x01 = x0 - x1,
y01 = y0 - y1,
l01_2 = x01 * x01 + y01 * y01;
// Is the radius negative? Error.
if (r < 0) throw new Error("negative radius: " + r);
// Is this path empty? Move to (x1,y1).
if (this._x1 === null) {
this._.push(
"M", this._x1 = x1, ",", this._y1 = y1
);
}
// Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
else if (!(l01_2 > epsilon));
// Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
// Equivalently, is (x1,y1) coincident with (x2,y2)?
// Or, is the radius zero? Line to (x1,y1).
else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {
this._.push(
"L", this._x1 = x1, ",", this._y1 = y1
);
}
// Otherwise, draw an arc!
else {
var x20 = x2 - x0,
y20 = y2 - y0,
l21_2 = x21 * x21 + y21 * y21,
l20_2 = x20 * x20 + y20 * y20,
l21 = Math.sqrt(l21_2),
l01 = Math.sqrt(l01_2),
l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
t01 = l / l01,
t21 = l / l21;
// If the start tangent is not coincident with (x0,y0), line to.
if (Math.abs(t01 - 1) > epsilon) {
this._.push(
"L", x1 + t01 * x01, ",", y1 + t01 * y01
);
}
this._.push(
"A", r, ",", r, ",0,0,", +(y01 * x20 > x01 * y20), ",", this._x1 = x1 + t21 * x21, ",", this._y1 = y1 + t21 * y21
);
}
},
arc: function(x, y, r, a0, a1, ccw) {
x = +x, y = +y, r = +r;
var dx = r * Math.cos(a0),
dy = r * Math.sin(a0),
x0 = x + dx,
y0 = y + dy,
cw = 1 ^ ccw,
da = ccw ? a0 - a1 : a1 - a0;
// Is the radius negative? Error.
if (r < 0) throw new Error("negative radius: " + r);
// Is this path empty? Move to (x0,y0).
if (this._x1 === null) {
this._.push(
"M", x0, ",", y0
);
}
// Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {
this._.push(
"L", x0, ",", y0
);
}
// Is this arc empty? We’re done.
if (!r) return;
// Is this a complete circle? Draw two arcs to complete the circle.
if (da > tauEpsilon) {
this._.push(
"A", r, ",", r, ",0,1,", cw, ",", x - dx, ",", y - dy,
"A", r, ",", r, ",0,1,", cw, ",", this._x1 = x0, ",", this._y1 = y0
);
}
// Otherwise, draw an arc!
else {
if (da < 0) da = da % tau + tau;
this._.push(
"A", r, ",", r, ",0,", +(da >= pi), ",", cw, ",", this._x1 = x + r * Math.cos(a1), ",", this._y1 = y + r * Math.sin(a1)
);
}
},
rect: function(x, y, w, h) {
this._.push("M", this._x0 = this._x1 = +x, ",", this._y0 = this._y1 = +y, "h", +w, "v", +h, "h", -w, "Z");
},
toString: function() {
return this._.join("");
}
};
var version = "0.1.2";
exports.version = version;
exports.path = path;
}));
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-path')) :
typeof define === 'function' && define.amd ? define('d3-shape', ['exports', 'd3-path'], factory) :
factory((global.d3_shape = {}),global.d3_path);
}(this, function (exports,d3Path) { 'use strict';
function constant(x) {
return function constant() {
return x;
};
};
var pi = Math.PI;
var halfPi = pi / 2;
var tau = 2 * pi;
function arcInnerRadius(d) {
return d.innerRadius;
}
function arcOuterRadius(d) {
return d.outerRadius;
}
function arcStartAngle(d) {
return d.startAngle;
}
function arcEndAngle(d) {
return d.endAngle;
}
function arcPadAngle(d) {
return d && d.padAngle; // Note: optional!
}
function asin(x) {
return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);
}
function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
var x10 = x1 - x0, y10 = y1 - y0,
x32 = x3 - x2, y32 = y3 - y2,
t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);
return [x0 + t * x10, y0 + t * y10];
}
// Compute perpendicular offset line of length rc.
// http://mathworld.wolfram.com/Circle-LineIntersection.html
function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
var x01 = x0 - x1,
y01 = y0 - y1,
lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01),
ox = lo * y01,
oy = -lo * x01,
x11 = x0 + ox,
y11 = y0 + oy,
x10 = x1 + ox,
y10 = y1 + oy,
x00 = (x11 + x10) / 2,
y00 = (y11 + y10) / 2,
dx = x10 - x11,
dy = y10 - y11,
d2 = dx * dx + dy * dy,
r = r1 - rc,
D = x11 * y10 - x10 * y11,
d = (dy < 0 ? -1 : 1) * Math.sqrt(Math.max(0, r * r * d2 - D * D)),
cx0 = (D * dy - dx * d) / d2,
cy0 = (-D * dx - dy * d) / d2,
cx1 = (D * dy + dx * d) / d2,
cy1 = (-D * dx + dy * d) / d2,
dx0 = cx0 - x00,
dy0 = cy0 - y00,
dx1 = cx1 - x00,
dy1 = cy1 - y00;
// Pick the closer of the two intersection points.
// TODO Is there a faster way to determine which intersection to use?
if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
return {
cx: cx0,
cy: cy0,
x01: -ox,
y01: -oy,
x11: cx0 * (r1 / r - 1),
y11: cy0 * (r1 / r - 1)
};
}
function arc() {
var innerRadius = arcInnerRadius,
outerRadius = arcOuterRadius,
cornerRadius = constant(0),
padRadius = null,
startAngle = arcStartAngle,
endAngle = arcEndAngle,
padAngle = arcPadAngle,
context = null,
output = null;
function arc() {
var buffer,
r,
r0 = +innerRadius.apply(this, arguments),
r1 = +outerRadius.apply(this, arguments),
a0 = startAngle.apply(this, arguments) - halfPi,
a1 = endAngle.apply(this, arguments) - halfPi,
da = Math.abs(a1 - a0),
cw = a1 > a0;
if (!context) context = buffer = d3Path.path();
// Ensure that the outer radius is always larger than the inner radius.
if (r1 < r0) r = r1, r1 = r0, r0 = r;
// Is it a point?
if (!(r1 > 0)) context.moveTo(0, 0);
// Or is it a circle or annulus?
else if (da >= tau) {
context.moveTo(r1 * Math.cos(a0), r1 * Math.sin(a0));
context.arc(0, 0, r1, a0, a1, !cw);
if (r0 > 0) {
context.moveTo(r0 * Math.cos(a1), r0 * Math.sin(a1));
context.arc(0, 0, r0, a1, a0, cw);
}
}
// Or is it a circular or annular sector?
else {
var a01 = a0,
a11 = a1,
a00 = a0,
a10 = a1,
da0 = da,
da1 = da,
ap = padAngle.apply(this, arguments) / 2,
rp = (ap > 0) && (padRadius ? +padRadius.apply(this, arguments) : Math.sqrt(r0 * r0 + r1 * r1)),
rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
rc0 = rc,
rc1 = rc;
// Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
if (rp > 0) {
var p0 = asin(rp / r0 * Math.sin(ap)),
p1 = asin(rp / r1 * Math.sin(ap));
if ((da0 -= p0 * 2) > 0) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
else da0 = 0, a00 = a10 = (a0 + a1) / 2;
if ((da1 -= p1 * 2) > 0) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
else da1 = 0, a01 = a11 = (a0 + a1) / 2;
}
var x01 = r1 * Math.cos(a01),
y01 = r1 * Math.sin(a01),
x10 = r0 * Math.cos(a10),
y10 = r0 * Math.sin(a10);
// Apply rounded corners?
if (rc > 0) {
var x11 = r1 * Math.cos(a11),
y11 = r1 * Math.sin(a11),
x00 = r0 * Math.cos(a00),
y00 = r0 * Math.sin(a00);
// Restrict the corner radius according to the sector angle.
if (da < pi) {
var oc = da0 > 0 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],
ax = x01 - oc[0],
ay = y01 - oc[1],
bx = x11 - oc[0],
by = y11 - oc[1],
kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2),
lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
rc0 = Math.min(rc, (r0 - lc) / (kc - 1));
rc1 = Math.min(rc, (r1 - lc) / (kc + 1));
}
}
// Is the sector collapsed to a line?
if (!(da1 > 0)) context.moveTo(x01, y01);
// Does the sector’s outer ring have rounded corners?
else if (rc1 > 0) {
var t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw),
t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
// Have the corners merged?
if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw);
// Otherwise, draw the two corners and the ring.
else {
context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw);
context.arc(0, 0, r1, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
context.arc(t1.cx, t1.cy, rc1, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw);
}
}
// Or is the outer ring just a circular arc?
else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
// Is there no inner ring, and it’s a circular sector?
// Or perhaps it’s an annular sector collapsed due to padding?
if (!(r0 > 0) || !(da0 > 0)) context.lineTo(x10, y10);
// Does the sector’s inner ring (or point) have rounded corners?
else if (rc0 > 0) {
var t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw),
t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
// Have the corners merged?
if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw);
// Otherwise, draw the two corners and the ring.
else {
context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw);
context.arc(0, 0, r0, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);
context.arc(t1.cx, t1.cy, rc0, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw);
}
}
// Or is the inner ring just a circular arc?
else context.arc(0, 0, r0, a10, a00, cw);
}
context.closePath();
if (buffer) return context = null, buffer + "" || null;
}
arc.centroid = function() {
var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;
return [Math.cos(a) * r, Math.sin(a) * r];
};
arc.innerRadius = function(_) {
return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant(+_), arc) : innerRadius;
};
arc.outerRadius = function(_) {
return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant(+_), arc) : outerRadius;
};
arc.cornerRadius = function(_) {
return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant(+_), arc) : cornerRadius;
};
arc.padRadius = function(_) {
return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant(+_), arc) : padRadius;
};
arc.startAngle = function(_) {
return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), arc) : startAngle;
};
arc.endAngle = function(_) {
return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), arc) : endAngle;
};
arc.padAngle = function(_) {
return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), arc) : padAngle;
};
arc.context = function(_) {
return arguments.length ? ((context = output = _ == null ? null : _), arc) : context;
};
return arc;
};
var slice = Array.prototype.slice;
function bind(curve, args) {
if (args.length < 2) return curve;
args = slice.call(args);
args[0] = null;
return function(context) {
args[0] = context;
return curve.apply(null, args);
};
};
function Linear(context) {
this._context = context;
}
Linear.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; // proceed
default: this._context.lineTo(x, y); break;
}
}
};
function curveLinear(context) {
return new Linear(context);
};
function x(p) {
return p[0];
};
function y(p) {
return p[1];
};
function area() {
var x0 = x,
x1 = null,
y0 = constant(0),
y1 = y,
defined = constant(true),
context = null,
curve = curveLinear,
output = null;
function area(data) {
var i,
j,
k,
n = data.length,
d,
defined0 = false,
buffer,
x0z = new Array(n),
y0z = new Array(n);
if (!context) output = curve(buffer = d3Path.path());
for (i = 0; i <= n; ++i) {
if (!(i < n && defined(d = data[i], i, data)) === defined0) {
if (defined0 = !defined0) {
j = i;
output.areaStart();
output.lineStart();
} else {
output.lineEnd();
output.lineStart();
for (k = i - 1; k >= j; --k) {
output.point(x0z[k], y0z[k]);
}
output.lineEnd();
output.areaEnd();
}
}
if (defined0) {
x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
}
}
if (buffer) return output = null, buffer + "" || null;
}
area.x = function(_) {
return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), x1 = null, area) : x0;
};
area.x0 = function(_) {
return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), area) : x0;
};
area.x1 = function(_) {
return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant(+_), area) : x1;
};
area.y = function(_) {
return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), y1 = null, area) : y0;
};
area.y0 = function(_) {
return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), area) : y0;
};
area.y1 = function(_) {
return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant(+_), area) : y1;
};
area.defined = function(_) {
return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), area) : defined;
};
area.curve = function(_) {
return arguments.length ? (curve = bind(_, arguments), context != null && (output = curve(context)), area) : curve;
};
area.context = function(_) {
return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
};
return area;
};
function noop() {};
function point(that, x, y) {
that._context.bezierCurveTo(
(2 * that._x0 + that._x1) / 3,
(2 * that._y0 + that._y1) / 3,
(that._x0 + 2 * that._x1) / 3,
(that._y0 + 2 * that._y1) / 3,
(that._x0 + 4 * that._x1 + x) / 6,
(that._y0 + 4 * that._y1 + y) / 6
);
};
function Basis(context) {
this._context = context;
}
Basis.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 =
this._y0 = this._y1 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 3: point(this, this._x1, this._y1); // proceed
case 2: this._context.lineTo(this._x1, this._y1); break;
}
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; break;
case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed
default: point(this, x, y); break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
}
};
function basis(context) {
return new Basis(context);
};
function BasisClosed(context) {
this._context = context;
}
BasisClosed.prototype = {
areaStart: noop,
areaEnd: noop,
lineStart: function() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 1: {
this._context.moveTo(this._x2, this._y2);
this._context.closePath();
break;
}
case 2: {
this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
this._context.closePath();
break;
}
case 3: {
this.point(this._x2, this._y2);
this.point(this._x3, this._y3);
this.point(this._x4, this._y4);
break;
}
}
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;
default: point(this, x, y); break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
}
};
function basisClosed(context) {
return new BasisClosed(context);
};
function BasisOpen(context) {
this._context = context;
}
BasisOpen.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 =
this._y0 = this._y1 = NaN;
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; break;
case 1: this._point = 2; break;
case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;
case 3: this._point = 4; // proceed
default: point(this, x, y); break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
}
};
function basisOpen(context) {
return new BasisOpen(context);
};
function Bundle(context, beta) {
this._basis = basis(context);
this._beta = beta;
}
Bundle.prototype = {
lineStart: function() {
this._x = [];
this._y = [];
this._basis.lineStart();
},
lineEnd: function() {
var x = this._x,
y = this._y,
j = x.length - 1;
if (j > 0) {
var x0 = x[0],
y0 = y[0],
dx = x[j] - x0,
dy = y[j] - y0,
i = -1,
t;
while (++i <= j) {
t = i / j;
this._basis.point(
this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
);
}
}
this._x = this._y = null;
this._basis.lineEnd();
},
point: function(x, y) {
this._x.push(+x);
this._y.push(+y);
}
};
function bundle(context, beta) {
return beta == null ? new Bundle(context, 0.85)
: (beta = +beta) === 1 ? basis(context)
: new Bundle(context, beta);
};
function point$1(that, x, y) {
that._context.bezierCurveTo(
that._x1 + that._k * (that._x2 - that._x0),
that._y1 + that._k * (that._y2 - that._y0),
that._x2 + that._k * (that._x1 - x),
that._y2 + that._k * (that._y1 - y),
that._x2,
that._y2
);
};
function Cardinal(context, k) {
this._context = context;
this._k = k;
}
Cardinal.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 = this._x2 =
this._y0 = this._y1 = this._y2 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 2: this._context.lineTo(this._x2, this._y2); break;
case 3: point$1(this, this._x1, this._y1); break;
}
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
case 2: this._point = 3; // proceed
default: point$1(this, x, y); break;
}
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
function cardinal(context, tension) {
return new Cardinal(context, (tension == null ? 1 : 1 - tension) / 6);
};
function CardinalClosed(context, k) {
this._context = context;
this._k = k;
}
CardinalClosed.prototype = {
areaStart: noop,
areaEnd: noop,
lineStart: function() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 1: {
this._context.moveTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 2: {
this._context.lineTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 3: {
this.point(this._x3, this._y3);
this.point(this._x4, this._y4);
this.point(this._x5, this._y5);
break;
}
}
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
default: point$1(this, x, y); break;
}
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
function cardinalClosed(context, tension) {
return new CardinalClosed(context, (tension == null ? 1 : 1 - tension) / 6);
};
function CardinalOpen(context, k) {
this._context = context;
this._k = k;
}
CardinalOpen.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 = this._x2 =
this._y0 = this._y1 = this._y2 = NaN;
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; break;
case 1: this._point = 2; break;
case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
case 3: this._point = 4; // proceed
default: point$1(this, x, y); break;
}
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
function cardinalOpen(context, tension) {
return new CardinalOpen(context, (tension == null ? 1 : 1 - tension) / 6);
};
var epsilon = 1e-6;
function point$2(that, x, y) {
var x1 = that._x1,
y1 = that._y1,
x2 = that._x2,
y2 = that._y2;
if (that._l01_a > epsilon) {
var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
n = 3 * that._l01_a * (that._l01_a + that._l12_a);
x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
}
if (that._l23_a > epsilon) {
var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
m = 3 * that._l23_a * (that._l23_a + that._l12_a);
x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
}
that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
};
function CatmullRom(context, alpha) {
this._context = context;
this._alpha = alpha;
}
CatmullRom.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 = this._x2 =
this._y0 = this._y1 = this._y2 = NaN;
this._l01_a = this._l12_a = this._l23_a =
this._l01_2a = this._l12_2a = this._l23_2a =
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 2: this._context.lineTo(this._x2, this._y2); break;
case 3: this.point(this, this._x2, this._y2); break;
}
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
if (this._point) {
var x23 = this._x2 - x,
y23 = this._y2 - y;
this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
}
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; break;
case 2: this._point = 3; // proceed
default: point$2(this, x, y); break;
}
this._l01_a = this._l12_a, this._l12_a = this._l23_a;
this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
function catmullRom(context, alpha) {
return (alpha = alpha == null ? 0.5 : +alpha)
? new CatmullRom(context, alpha)
: cardinal(context, 0);
};
function CatmullRomClosed(context, alpha) {
this._context = context;
this._alpha = alpha;
}
CatmullRomClosed.prototype = {
areaStart: noop,
areaEnd: noop,
lineStart: function() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
this._l01_a = this._l12_a = this._l23_a =
this._l01_2a = this._l12_2a = this._l23_2a =
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 1: {
this._context.moveTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 2: {
this._context.lineTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 3: {
this.point(this._x3, this._y3);
this.point(this._x4, this._y4);
this.point(this._x5, this._y5);
break;
}
}
},
point: function(x, y) {
x = +x, y = +y;
if (this._point) {
var x23 = this._x2 - x,
y23 = this._y2 - y;
this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
}
switch (this._point) {
case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
default: point$2(this, x, y); break;
}
this._l01_a = this._l12_a, this._l12_a = this._l23_a;
this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
function catmullRomClosed(context, alpha) {
return (alpha = alpha == null ? 0.5 : +alpha)
? new CatmullRomClosed(context, alpha)
: cardinalClosed(context, 0);
};
function CatmullRomOpen(context, alpha) {
this._context = context;
this._alpha = alpha;
}
CatmullRomOpen.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 = this._x2 =
this._y0 = this._y1 = this._y2 = NaN;
this._l01_a = this._l12_a = this._l23_a =
this._l01_2a = this._l12_2a = this._l23_2a =
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
if (this._point) {
var x23 = this._x2 - x,
y23 = this._y2 - y;
this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
}
switch (this._point) {
case 0: this._point = 1; break;
case 1: this._point = 2; break;
case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
case 3: this._point = 4; // proceed
default: point$2(this, x, y); break;
}
this._l01_a = this._l12_a, this._l12_a = this._l23_a;
this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
function catmullRomOpen(context, alpha) {
return (alpha = alpha == null ? 0.5 : +alpha)
? new CatmullRomOpen(context, alpha)
: cardinalOpen(context, 0);
};
var circle = {
draw: function(context, size) {
var r = Math.sqrt(size / pi);
context.moveTo(r, 0);
context.arc(0, 0, r, 0, tau);
}
};
var cross = {
draw: function(context, size) {
var r = Math.sqrt(size / 5) / 2;
context.moveTo(-3 * r, -r);
context.lineTo(-r, -r);
context.lineTo(-r, -3 * r);
context.lineTo(r, -3 * r);
context.lineTo(r, -r);
context.lineTo(3 * r, -r);
context.lineTo(3 * r, r);
context.lineTo(r, r);
context.lineTo(r, 3 * r);
context.lineTo(-r, 3 * r);
context.lineTo(-r, r);
context.lineTo(-3 * r, r);
context.closePath();
}
};
var tan30 = Math.sqrt(1 / 3);
var tan30_2 = tan30 * 2;
var diamond = {
draw: function(context, size) {
var y = Math.sqrt(size / tan30_2),
x = y * tan30;
context.moveTo(0, -y);
context.lineTo(x, 0);
context.lineTo(0, y);
context.lineTo(-x, 0);
context.closePath();
}
};
function LinearClosed(context) {
this._context = context;
}
LinearClosed.prototype = {
areaStart: noop,
areaEnd: noop,
lineStart: function() {
this._point = 0;
},
lineEnd: function() {
if (this._point) this._context.closePath();
},
point: function(x, y) {
x = +x, y = +y;
if (this._point) this._context.lineTo(x, y);
else this._point = 1, this._context.moveTo(x, y);
}
};
function linearClosed(context) {
return new LinearClosed(context);
};
function line() {
var x$$ = x,
y$$ = y,
defined = constant(true),
context = null,
curve = curveLinear,
output = null;
function line(data) {
var i,
n = data.length,
d,
defined0 = false,
buffer;
if (!context) output = curve(buffer = d3Path.path());
for (i = 0; i <= n; ++i) {
if (!(i < n && defined(d = data[i], i, data)) === defined0) {
if (defined0 = !defined0) output.lineStart();
else output.lineEnd();
}
if (defined0) output.point(+x$$(d, i, data), +y$$(d, i, data));
}
if (buffer) return output = null, buffer + "" || null;
}
line.x = function(_) {
return arguments.length ? (x$$ = typeof _ === "function" ? _ : constant(+_), line) : x$$;
};
line.y = function(_) {
return arguments.length ? (y$$ = typeof _ === "function" ? _ : constant(+_), line) : y$$;
};
line.defined = function(_) {
return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), line) : defined;
};
line.curve = function(_) {
return arguments.length ? (curve = bind(_, arguments), context != null && (output = curve(context)), line) : curve;
};
line.context = function(_) {
return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
};
return line;
};
function sign(x) {
return x < 0 ? -1 : 1;
}
// Calculate the slopes of the tangents (Hermite-type interpolation) based on
// the following paper: Steffen, M. 1990. A Simple Method for Monotonic
// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
// NOV(II), P. 443, 1990.
function slope3(that, x2, y2) {
var h0 = that._x1 - that._x0,
h1 = x2 - that._x1,
s0 = (that._y1 - that._y0) / h0,
s1 = (y2 - that._y1) / h1,
p = (s0 * h1 + s1 * h0) / (h0 + h1);
return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
}
// Calculate a one-sided slope.
function slope2(that, t) {
var h = that._x1 - that._x0;
return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
}
// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
// "you can express cubic Hermite interpolation in terms of cubic Bézier curves
// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
function point$3(that, t0, t1) {
var x0 = that._x0,
y0 = that._y0,
x1 = that._x1,
y1 = that._y1,
dx = (x1 - x0) / 3;
that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
}
function Monotone(context) {
this._context = context;
}
Monotone.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 =
this._y0 = this._y1 =
this._t0 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 2: this._context.lineTo(this._x1, this._y1); break;
case 3: point$3(this, this._t0, slope2(this, this._t0)); break;
}
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
var t1 = NaN;
x = +x, y = +y;
if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; break;
case 2: this._point = 3; point$3(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
default: point$3(this, this._t0, t1 = slope3(this, x, y)); break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
this._t0 = t1;
}
}
function monotone(context) {
return new Monotone(context);
};
function Natural(context) {
this._context = context;
}
Natural.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x = [];
this._y = [];
},
lineEnd: function() {
var x = this._x,
y = this._y,
n = x.length;
if (n) {
this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
if (n === 2) {
this._context.lineTo(x[1], y[1]);
} else {
var px = controlPoints(x),
py = controlPoints(y);
for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
}
}
}
if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
this._line = 1 - this._line;
this._x = this._y = null;
},
point: function(x, y) {
this._x.push(+x);
this._y.push(+y);
}
};
// See https://www.particleincell.com/2012/bezier-splines/ for derivation.
function controlPoints(x) {
var i,
n = x.length - 1,
m,
a = new Array(n),
b = new Array(n),
r = new Array(n);
a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
a[n - 1] = r[n - 1] / b[n - 1];
for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
b[n - 1] = (x[n] + a[n - 1]) / 2;
for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
return [a, b];
}
function natural(context) {
return new Natural(context);
};
function descending(a, b) {
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
};
function identity(d) {
return d;
};
function pie() {
var value = identity,
sortValues = descending,
sort = null,
startAngle = constant(0),
endAngle = constant(tau),
padAngle = constant(0);
function pie(data) {
var n = data.length,
sum = 0,
index = new Array(n),
arcs = new Array(n),
a0 = +startAngle.apply(this, arguments),
da = Math.min(tau, Math.max(-tau, endAngle.apply(this, arguments) - a0)),
a1,
p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
pa = p * (da < 0 ? -1 : 1);
for (var i = 0, v; i < n; ++i) {
if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
sum += v;
}
}
// Optionally sort the arcs by previously-computed values or by data.
if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
else if (sort !== null) index.sort(function(i, j) { return sort(data[i], data[j]); });
// Compute the arcs! They are stored in the original data's order.
for (var i = 0, j, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
data: data[j],
value: v,
startAngle: a0,
endAngle: a1,
padAngle: p
};
}
return arcs;
}
pie.value = function(_) {
return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), pie) : value;
};
pie.sortValues = function(_) {
return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
};
pie.sort = function(_) {
return arguments.length ? (sort = _, sortValues = null, pie) : sort;
};
pie.startAngle = function(_) {
return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), pie) : startAngle;
};
pie.endAngle = function(_) {
return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), pie) : endAngle;
};
pie.padAngle = function(_) {
return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), pie) : padAngle;
};
return pie;
};
function Radial(curve) {
this._curve = curve;
}
Radial.prototype = {
areaStart: function() {
this._curve.areaStart();
},
areaEnd: function() {
this._curve.areaEnd();
},
lineStart: function() {
this._curve.lineStart();
},
lineEnd: function() {
this._curve.lineEnd();
},
point: function(a, r) {
a -= halfPi, this._curve.point(r * Math.cos(a), r * Math.sin(a));
}
};
function curveRadial(curve, args) {
curve = bind(curve, args);
function radial(context) {
return new Radial(curve(context));
}
radial._curve = curve;
return radial;
};
function radialArea() {
var a = area(),
c = a.curve;
a.angle = a.x, delete a.x;
a.startAngle = a.x0, delete a.x0;
a.endAngle = a.x1, delete a.x1;
a.radius = a.y, delete a.y;
a.innerRadius = a.y0, delete a.y0;
a.outerRadius = a.y1, delete a.y1;
a.curve = function(_) {
return arguments.length ? c(curveRadial(_, arguments)) : c()._curve;
};
return a.curve(curveLinear);
};
function radialLine() {
var l = line(),
c = l.curve;
l.angle = l.x, delete l.x;
l.radius = l.y, delete l.y;
l.curve = function(_) {
return arguments.length ? c(curveRadial(_, arguments)) : c()._curve;
};
return l.curve(curveLinear);
};
var square = {
draw: function(context, size) {
var w = Math.sqrt(size),
x = -w / 2;
context.rect(x, x, w, w);
}
};
var ka = 0.89081309152928522810;
var kr = Math.sin(pi / 10) / Math.sin(7 * pi / 10);
var kx = Math.sin(tau / 10) * kr;
var ky = -Math.cos(tau / 10) * kr;
var star = {
draw: function(context, size) {
var r = Math.sqrt(size * ka),
x = kx * r,
y = ky * r;
context.moveTo(0, -r);
context.lineTo(x, y);
for (var i = 1; i < 5; ++i) {
var a = tau * i / 5,
c = Math.cos(a),
s = Math.sin(a);
context.lineTo(s * r, -c * r);
context.lineTo(c * x - s * y, s * x + c * y);
}
context.closePath();
}
};
function StepAfter(context) {
this._context = context;
}
StepAfter.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._y = NaN;
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; // proceed
default: {
this._context.lineTo(x, this._y);
this._context.lineTo(x, y);
break;
}
}
this._y = y;
}
};
function stepAfter(context) {
return new StepAfter(context);
};
function StepBefore(context) {
this._context = context;
}
StepBefore.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x = NaN;
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; // proceed
default: {
this._context.lineTo(this._x, y);
this._context.lineTo(x, y);
break;
}
}
this._x = x;
}
};
function stepBefore(context) {
return new StepBefore(context);
};
function Step(context) {
this._context = context;
}
Step.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x = this._y = NaN;
this._point = 0;
},
lineEnd: function() {
if (this._point === 2) this._context.lineTo(this._x, this._y);
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; // proceed
default: {
var x1 = (this._x + x) / 2;
this._context.lineTo(x1, this._y);
this._context.lineTo(x1, y);
break;
}
}
this._x = x, this._y = y;
}
};
function step(context) {
return new Step(context);
};
var c = -0.5;
var s = Math.sqrt(3) / 2;
var k = 1 / Math.sqrt(12);
var a = (k / 2 + 1) * 3;
var wye = {
draw: function(context, size) {
var r = Math.sqrt(size / a),
x0 = r / 2,
y0 = r * k,
x1 = x0,
y1 = r * k + r,
x2 = -x1,
y2 = y1;
context.moveTo(x0, y0);
context.lineTo(x1, y1);
context.lineTo(x2, y2);
context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
context.closePath();
}
};
var sqrt3 = Math.sqrt(3);
var triangle = {
draw: function(context, size) {
var y = -Math.sqrt(size / (sqrt3 * 3));
context.moveTo(0, y * 2);
context.lineTo(-sqrt3 * y, -y);
context.lineTo(sqrt3 * y, -y);
context.closePath();
}
};
var symbols = [
circle,
cross,
diamond,
square,
star,
triangle,
wye
];
function symbol() {
var type = constant(circle),
size = constant(64),
context = null;
function symbol() {
var buffer;
if (!context) context = buffer = d3Path.path();
type.apply(this, arguments).draw(context, +size.apply(this, arguments));
if (buffer) return context = null, buffer + "" || null;
}
symbol.type = function(_) {
return arguments.length ? (type = typeof _ === "function" ? _ : constant(_), symbol) : type;
};
symbol.size = function(_) {
return arguments.length ? (size = typeof _ === "function" ? _ : constant(+_), symbol) : size;
};
symbol.context = function(_) {
return arguments.length ? (context = _ == null ? null : _, symbol) : context;
};
return symbol;
};
var version = "0.2.0";
exports.version = version;
exports.arc = arc;
exports.area = area;
exports.basisClosed = basisClosed;
exports.basisOpen = basisOpen;
exports.basis = basis;
exports.bundle = bundle;
exports.cardinalClosed = cardinalClosed;
exports.cardinalOpen = cardinalOpen;
exports.cardinal = cardinal;
exports.catmullRomClosed = catmullRomClosed;
exports.catmullRomOpen = catmullRomOpen;
exports.catmullRom = catmullRom;
exports.circle = circle;
exports.cross = cross;
exports.diamond = diamond;
exports.linearClosed = linearClosed;
exports.linear = curveLinear;
exports.line = line;
exports.monotone = monotone;
exports.natural = natural;
exports.pie = pie;
exports.radialArea = radialArea;
exports.radialLine = radialLine;
exports.square = square;
exports.star = star;
exports.stepAfter = stepAfter;
exports.stepBefore = stepBefore;
exports.step = step;
exports.symbol = symbol;
exports.symbols = symbols;
exports.triangle = triangle;
exports.wye = wye;
}));
svg = d3.select('svg')
width = svg.node().getBoundingClientRect().width
height = svg.node().getBoundingClientRect().height
svg
.attr
viewBox: "#{-width/2} #{-height/2} #{width} #{height}"
OUTER_RADIUS = 200
INNER_RADIUS = 60
r_temp = d3.scale.linear()
.domain([-20,40])
.range([INNER_RADIUS,OUTER_RADIUS])
prec_radius = d3.scale.sqrt()
.domain([0, 100])
.range([0,32])
temp_color = d3.scale.linear()
.domain([-20,0,20,40])
.range([d3.hcl(290,70,15),d3.hcl(230,70,45),d3.hcl(80,70,75),d3.hcl(10,70,45)])
.interpolate(d3.interpolateHcl)
arc_generator = d3_shape.arc()
# reference and labels
refs_data = d3.range(-20,40,10)
refs = svg.selectAll '.ref'
.data refs_data
refs.enter().append 'circle'
.attr
class: 'ref'
r: (d) -> r_temp(d)
stroke: (d) -> if d is 0 then '#CCC' else '#EEE'
refs_labels_north = svg.selectAll '.ref_label_north'
.data refs_data
refs_labels_north.enter().append 'text'
.text (d) -> "#{d}°C"
.attr
class: 'ref_label_north'
y: (d) -> -r_temp(d)
dy: '0.35em'
fill: (d) -> if d is 0 then '#BBB' else '#DDD'
refs_labels_south = svg.selectAll '.ref_label_south'
.data refs_data
refs_labels_south.enter().append 'text'
.text (d) -> "#{d}°C"
.attr
class: 'ref_label_south'
y: (d) -> r_temp(d)
dy: '0.35em'
fill: (d) -> if d is 0 then '#BBB' else '#DDD'
svg.append 'circle'
.attr
class: 'prec_ref'
r: OUTER_RADIUS
svg.append 'text'
.text 'PISA'
.attr
class: 'title'
dy: '0.35em'
d3.csv 'pisa_2014_weather.csv', (days) ->
days.forEach (d) ->
d['Min TemperatureC'] = +d['Min TemperatureC']
d['Max TemperatureC'] = +d['Max TemperatureC']
d['Mean TemperatureC'] = +d['Mean TemperatureC']
d['Precipitationmm'] = +d['Precipitationmm']
angle = d3.scale.ordinal()
.domain(days.map (d) -> d['CET'])
.range(d3.range(Math.PI/2, 2*Math.PI+Math.PI/2, 2*Math.PI/days.length))
temp_bars = svg.selectAll '.temp_bar'
.data days
enter_temp_bars = temp_bars.enter().append 'path'
.attr
class: 'bar temp_bar'
d: (d,i) -> arc_generator {
innerRadius: r_temp(d['Min TemperatureC']),
outerRadius: r_temp(d['Max TemperatureC']),
startAngle: i*2*Math.PI/days.length, # FIXME index-based positioning, should be day-based
endAngle: (i+1)*2*Math.PI/days.length
}
fill: (d) -> temp_color(d['Mean TemperatureC'])
enter_temp_bars.append 'title'
.text (d) -> "#{d3.time.format('%Y, %B %e')(new Date(d['CET']))}\nTemperature:\n Min: #{d['Min TemperatureC']} °C\n Max: #{d['Max TemperatureC']} °C\n Mean: #{d['Mean TemperatureC']} °C"
prec_bubbles = svg.selectAll '.prec_bubble'
.data days.sort (a,b) -> d3.descending(a['Precipitationmm'], b['Precipitationmm']) # draw bubbles from largest to smallest (hover) FIXME this is ugly
enter_prec_bubbles = prec_bubbles.enter().append 'circle'
.attr
class: 'prec_bubble'
r: (d) -> prec_radius(d['Precipitationmm'])
cx: (d) -> -(OUTER_RADIUS)*Math.cos(angle(d['CET'])) # FIXME day should be converted first to a date
cy: (d) -> -(OUTER_RADIUS)*Math.sin(angle(d['CET'])) # FIXME bubbles should be centered on the day slice, not at the beginning
enter_prec_bubbles.append 'title'
.text (d) -> "#{d3.time.format('%Y, %B %e')(new Date(d['CET']))}\nPrecipitation: #{d['Precipitationmm']} mm"
# draw the hand
svg.append 'line'
.attr
class: 'hand'
x1: 0
x2: 0
y1: -INNER_RADIUS+10
y2: -OUTER_RADIUS-40
svg.append 'text'
.text '2014'
.attr
class: 'hand_label'
x: 4
y: -OUTER_RADIUS-40
dy: '0.6em'
@font-face {
font-family: "Lacuna";
src: url("lacuna.ttf");
}
@font-face {
font-family: "Antonio-Light";
src: url("Antonio-Light.ttf");
}
body, html {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
font-family: sans-serif;
font-size: 12px;
overflow: hidden;
}
svg {
width: 100%;
height: 100%;
background: white;
}
.bar {
stroke-width: 0.5;
stroke: white;
fill-opacity: 0.8;
}
.bar:hover {
fill-opacity: 1;
}
.ref, .prec_ref {
fill: none;
}
.prec_ref {
stroke: steelblue;
opacity: 0.2;
}
.ref_label_north, .ref_label_south {
text-anchor: middle;
font-size: 8px;
text-shadow: -1px -1px white, -1px 1px white, 1px 1px white, 1px -1px white, -1px 0 white, 0 1px white, 1px 0 white, 0 -1px white;
font-family: "Lacuna";
}
.prec_bubble {
fill: steelblue;
fill-opacity: 0.2;
}
.prec_bubble:hover {
fill-opacity: 0.8;
}
.title {
font-size: 32px;
text-anchor: middle;
text-shadow: -1px -1px white, -1px 1px white, 1px 1px white, 1px -1px white, -1px 0 white, 0 1px white, 1px 0 white, 0 -1px white;
fill: #999;
font-family: "Antonio-Light";
}
.hand {
stroke: #777;
stroke-dasharray: 2 2;
fill: none;
}
.hand_label {
font-size: 9px;
font-weight: bold;
font-family: "Lacuna";
fill: #555;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Weather wheel</title>
<link rel="stylesheet" href="index.css">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="d3-path.js"></script>
<script src="d3-shape.js"></script>
</head>
<body>
<svg></svg>
<script src="index.js"></script>
</body>
</html>
// Generated by CoffeeScript 1.10.0
(function() {
var INNER_RADIUS, OUTER_RADIUS, arc_generator, height, prec_radius, r_temp, refs, refs_data, refs_labels_north, refs_labels_south, svg, temp_color, width;
svg = d3.select('svg');
width = svg.node().getBoundingClientRect().width;
height = svg.node().getBoundingClientRect().height;
svg.attr({
viewBox: (-width / 2) + " " + (-height / 2) + " " + width + " " + height
});
OUTER_RADIUS = 200;
INNER_RADIUS = 60;
r_temp = d3.scale.linear().domain([-20, 40]).range([INNER_RADIUS, OUTER_RADIUS]);
prec_radius = d3.scale.sqrt().domain([0, 100]).range([0, 32]);
temp_color = d3.scale.linear().domain([-20, 0, 20, 40]).range([d3.hcl(290, 70, 15), d3.hcl(230, 70, 45), d3.hcl(80, 70, 75), d3.hcl(10, 70, 45)]).interpolate(d3.interpolateHcl);
arc_generator = d3_shape.arc();
refs_data = d3.range(-20, 40, 10);
refs = svg.selectAll('.ref').data(refs_data);
refs.enter().append('circle').attr({
"class": 'ref',
r: function(d) {
return r_temp(d);
},
stroke: function(d) {
if (d === 0) {
return '#CCC';
} else {
return '#EEE';
}
}
});
refs_labels_north = svg.selectAll('.ref_label_north').data(refs_data);
refs_labels_north.enter().append('text').text(function(d) {
return d + "°C";
}).attr({
"class": 'ref_label_north',
y: function(d) {
return -r_temp(d);
},
dy: '0.35em',
fill: function(d) {
if (d === 0) {
return '#BBB';
} else {
return '#DDD';
}
}
});
refs_labels_south = svg.selectAll('.ref_label_south').data(refs_data);
refs_labels_south.enter().append('text').text(function(d) {
return d + "°C";
}).attr({
"class": 'ref_label_south',
y: function(d) {
return r_temp(d);
},
dy: '0.35em',
fill: function(d) {
if (d === 0) {
return '#BBB';
} else {
return '#DDD';
}
}
});
svg.append('circle').attr({
"class": 'prec_ref',
r: OUTER_RADIUS
});
svg.append('text').text('PISA').attr({
"class": 'title',
dy: '0.35em'
});
d3.csv('pisa_2014_weather.csv', function(days) {
var angle, enter_prec_bubbles, enter_temp_bars, prec_bubbles, temp_bars;
days.forEach(function(d) {
d['Min TemperatureC'] = +d['Min TemperatureC'];
d['Max TemperatureC'] = +d['Max TemperatureC'];
d['Mean TemperatureC'] = +d['Mean TemperatureC'];
return d['Precipitationmm'] = +d['Precipitationmm'];
});
angle = d3.scale.ordinal().domain(days.map(function(d) {
return d['CET'];
})).range(d3.range(Math.PI / 2, 2 * Math.PI + Math.PI / 2, 2 * Math.PI / days.length));
temp_bars = svg.selectAll('.temp_bar').data(days);
enter_temp_bars = temp_bars.enter().append('path').attr({
"class": 'bar temp_bar',
d: function(d, i) {
return arc_generator({
innerRadius: r_temp(d['Min TemperatureC']),
outerRadius: r_temp(d['Max TemperatureC']),
startAngle: i * 2 * Math.PI / days.length,
endAngle: (i + 1) * 2 * Math.PI / days.length
});
},
fill: function(d) {
return temp_color(d['Mean TemperatureC']);
}
});
enter_temp_bars.append('title').text(function(d) {
return (d3.time.format('%Y, %B %e')(new Date(d['CET']))) + "\nTemperature:\n Min: " + d['Min TemperatureC'] + " °C\n Max: " + d['Max TemperatureC'] + " °C\n Mean: " + d['Mean TemperatureC'] + " °C";
});
prec_bubbles = svg.selectAll('.prec_bubble').data(days.sort(function(a, b) {
return d3.descending(a['Precipitationmm'], b['Precipitationmm']);
}));
enter_prec_bubbles = prec_bubbles.enter().append('circle').attr({
"class": 'prec_bubble',
r: function(d) {
return prec_radius(d['Precipitationmm']);
},
cx: function(d) {
return -OUTER_RADIUS * Math.cos(angle(d['CET']));
},
cy: function(d) {
return -OUTER_RADIUS * Math.sin(angle(d['CET']));
}
});
enter_prec_bubbles.append('title').text(function(d) {
return (d3.time.format('%Y, %B %e')(new Date(d['CET']))) + "\nPrecipitation: " + d['Precipitationmm'] + " mm";
});
svg.append('line').attr({
"class": 'hand',
x1: 0,
x2: 0,
y1: -INNER_RADIUS + 10,
y2: -OUTER_RADIUS - 40
});
return svg.append('text').text('2014').attr({
"class": 'hand_label',
x: 4,
y: -OUTER_RADIUS - 40,
dy: '0.6em'
});
});
}).call(this);
CET Max TemperatureC Mean TemperatureC Min TemperatureC Dew PointC MeanDew PointC Min DewpointC Max Humidity Mean Humidity Min Humidity Max Sea Level PressurehPa Mean Sea Level PressurehPa Min Sea Level PressurehPa Max VisibilityKm Mean VisibilityKm Min VisibilitykM Max Wind SpeedKm/h Mean Wind SpeedKm/h Max Gust SpeedKm/h Precipitationmm CloudCover Events WindDirDegrees
2014-1-1 12 6 -2 7 3 -2 100 89 69 1021 1020 1019 14 10 5 16 8 0.00 3 Fog 116
2014-1-2 9 7 4 8 7 3 100 90 71 1020 1016 1015 11 8 3 23 11 12.95 6 Rain 110
2014-1-3 13 10 8 11 9 7 100 93 87 1021 1019 1016 10 4 0 11 6 1.02 5 Fog-Rain 121
2014-1-4 14 12 10 12 11 9 94 89 80 1021 1015 1008 14 8 3 34 13 1.02 6 Rain-Thunderstorm 148
2014-1-5 14 11 8 12 9 5 94 84 67 1012 1005 1000 26 8 3 29 18 11.94 5 Rain-Thunderstorm 114
2014-1-6 15 9 3 9 6 2 96 88 56 1023 1019 1013 26 11 10 11 5 0.00 Fog 116
2014-1-7 13 8 3 11 6 3 100 91 75 1028 1025 1023 19 9 2 13 8 0.00 1 Fog 118
2014-1-8 13 8 3 9 6 3 100 92 76 1030 1028 1027 10 6 0 11 6 0.00 3 Fog 124
2014-1-9 14 10 6 10 7 4 94 88 73 1027 1024 1021 14 9 3 13 6 0.00 4 Fog 134
2014-1-10 14 10 7 10 8 7 94 88 75 1022 1021 1020 19 10 8 13 6 0.00 5 119
2014-1-11 14 11 7 9 8 6 94 87 68 1023 1022 1021 19 10 8 14 6 0.00 5 102
2014-1-12 15 10 5 10 8 5 100 89 71 1024 1022 1021 14 9 0 13 6 0.00 4 Fog 122
2014-1-13 11 8 4 8 6 3 100 92 80 1022 1018 1012 10 5 0 21 8 2.03 5 Fog-Rain 117
2014-1-14 12 10 8 10 8 6 94 84 66 1013 1007 1005 14 9 4 24 16 10.92 5 Rain 221
2014-1-15 13 9 6 9 7 5 100 87 64 1016 1011 1007 26 10 8 21 10 0.00 4 Fog-Rain 134
2014-1-16 11 8 4 9 7 4 94 89 79 1017 1015 1014 19 10 8 16 10 0.51 4 Fog-Rain 120
2014-1-17 13 12 10 12 11 9 94 89 74 1014 1010 1008 14 8 5 26 16 19.05 6 Rain 136
2014-1-18 14 12 11 11 11 9 94 90 82 1010 1007 1003 10 8 3 23 13 12.95 6 Rain-Thunderstorm 101
2014-1-19 14 12 10 12 11 9 94 89 79 1004 1001 998 10 9 6 24 11 32 3.05 5 Rain-Hail-Thunderstorm 117
2014-1-20 14 12 9 11 10 8 94 89 68 1001 999 999 14 10 3 21 10 0.00 5 Rain 110
2014-1-21 15 10 6 11 8 6 100 87 72 1009 1004 1000 14 10 8 14 5 0.00 4 Fog 175
2014-1-22 13 9 5 10 8 4 100 82 59 1015 1012 1009 19 10 8 55 14 0.00 4 Fog 273
2014-1-23 11 7 3 9 6 3 100 90 72 1017 1015 1013 14 9 5 24 10 0.76 5 Rain 91
2014-1-24 10 7 4 8 6 3 100 88 67 1013 1006 1003 10 7 0 13 8 0.00 5 Fog-Rain 74
2014-1-25 12 7 1 4 2 -1 100 75 32 1012 1009 1005 31 12 10 21 8 0.00 1 114
2014-1-26 14 7 0 5 2 -1 93 77 26 1012 1009 1006 31 12 10 19 8 0.00 2 126
2014-1-27 8 6 3 7 4 1 100 88 61 1007 999 996 14 10 5 23 11 3.05 5 Rain 110
2014-1-28 10 6 1 4 2 0 100 85 44 1000 998 996 19 9 3 21 8 0.00 2 Fog 120
2014-1-29 10 5 0 7 3 -1 100 83 46 1005 1002 1000 14 10 10 32 14 0.00 5 Rain 90
2014-1-30 12 9 5 11 8 4 94 92 80 1006 1004 1002 10 7 2 37 14 18.03 6 Rain 104
2014-1-31 11 10 9 10 9 7 94 91 85 1012 1008 1003 14 9 6 37 14 0.51 6 Rain 113
2014-2-1 14 11 7 11 9 7 94 88 72 1010 1008 1005 14 9 5 26 8 40 2.03 6 Rain 122
2014-2-2 12 10 8 9 8 7 94 90 65 1009 1007 1006 19 10 0 11 5 1.02 5 Fog-Rain 87
2014-2-3 14 11 8 10 9 8 94 88 67 1013 1010 1008 10 9 6 16 5 0.51 5 Rain 109
2014-2-4 14 12 9 10 9 8 94 89 75 1015 1014 1012 19 10 10 19 6 0.25 4 Rain 132
2014-2-5 12 9 7 9 8 7 94 87 68 1015 1011 1003 14 10 6 29 14 48 1.02 6 Rain-Thunderstorm 111
2014-2-6 14 10 6 9 7 5 100 85 61 1017 1012 1002 31 11 5 35 18 58 0.00 3 Rain 128
2014-2-7 14 9 4 12 8 3 94 86 68 1017 1013 1009 19 10 6 29 13 1.02 4 Rain 144
2014-2-8 14 12 10 10 8 6 94 78 55 1013 1009 1004 14 10 10 29 16 1.02 4 Rain 226
2014-2-9 13 11 8 10 8 6 94 79 53 1009 1004 1000 19 10 10 40 19 45 0.51 4 Rain 235
2014-2-10 14 11 7 12 9 6 100 92 82 1010 1002 997 10 7 2 37 18 50 28.96 6 Rain 116
2014-2-11 14 12 9 10 9 8 95 88 66 1006 1004 1002 19 10 7 23 10 7.11 5 Fog-Rain 103
2014-2-12 14 9 4 11 7 4 94 86 57 1014 1008 1005 19 7 0 23 6 0.00 3 Fog-Rain 231
2014-2-13 14 9 4 10 7 4 93 83 45 1015 1011 1006 14 10 8 35 10 0.00 4 154
2014-2-14 15 12 9 9 8 6 94 78 56 1015 1011 1006 19 11 10 50 23 63 0.00 2 259
2014-2-15 18 12 7 13 9 7 94 84 56 1016 1015 1014 19 10 10 19 8 0.00 5 138
2014-2-16 17 15 13 14 12 11 95 88 69 1016 1015 1013 14 10 10 23 8 0.00 5 141
2014-2-17 15 12 8 13 11 7 95 86 68 1020 1015 1012 19 10 10 27 13 0.00 4 Rain 244
2014-2-18 18 13 8 10 8 6 100 76 44 1020 1017 1013 14 10 10 23 10 0.00 3 110
2014-2-19 16 13 12 14 11 8 95 84 62 1013 1011 1010 14 9 3 23 13 2.03 6 Rain-Thunderstorm 144
2014-2-20 14 12 10 11 9 8 94 86 62 1014 1012 1010 14 9 5 19 8 0.51 6 Fog-Rain 98
2014-2-21 15 11 7 11 9 7 94 88 65 1014 1012 1011 19 10 4 16 8 1.02 5 Rain 144
2014-2-22 15 11 8 10 8 7 94 80 59 1018 1013 1010 18 10 2 29 14 0.76 3 Rain-Thunderstorm 234
2014-2-23 15 10 5 7 4 2 100 75 34 1023 1021 1018 31 12 10 19 10 0.00 2 121
2014-2-24 15 8 2 7 4 1 100 77 32 1023 1021 1020 26 15 10 16 6 0.00 Fog 118
2014-2-25 14 8 2 9 6 2 100 84 56 1022 1020 1020 19 11 10 16 10 0.00 2 140
2014-2-26 12 9 7 11 8 7 95 91 85 1022 1020 1019 11 10 3 29 14 11.94 4 Fog-Rain-Thunderstorm 113
2014-2-27 13 10 6 9 7 5 100 85 54 1022 1020 1018 19 9 5 19 10 0.51 4 Rain-Thunderstorm 122
2014-2-28 15 11 6 8 6 5 93 86 61 1018 1010 1002 10 8 3 32 14 6.10 6 Rain-Thunderstorm 111
2014-3-1 10 8 7 7 6 5 93 88 73 1002 996 992 10 8 1 29 23 22.10 6 Rain 101
2014-3-2 13 9 4 8 6 3 94 80 51 1002 997 993 19 10 10 21 13 0.00 3 89
2014-3-3 11 7 3 8 6 2 100 88 66 1001 996 992 14 10 8 23 11 0.51 6 Rain 111
2014-3-4 13 10 7 8 6 3 96 77 47 1001 993 989 14 10 10 27 14 0.51 5 Rain 54
2014-3-5 16 11 7 8 6 3 93 73 41 1014 1008 1001 26 11 10 16 6 0.00 4 94
2014-3-6 16 11 5 7 3 1 96 59 25 1021 1017 1014 31 11 10 27 10 0.00 3 52
2014-3-7 17 11 4 9 6 3 100 72 35 1023 1021 1020 31 12 10 19 8 0.00 2 292
2014-3-8 17 11 5 8 3 -1 100 62 21 1028 1024 1022 26 12 10 35 11 0.00 3 88
2014-3-9 18 13 8 5 3 2 76 51 23 1029 1026 1024 31 21 10 35 13 0.00 89
2014-3-10 16 10 5 6 4 3 93 62 36 1024 1021 1018 19 11 10 35 13 53 0.00 2 98
2014-3-11 16 11 7 9 5 1 81 63 40 1027 1022 1020 14 13 10 32 16 0.00 113
2014-3-12 18 10 2 6 3 1 93 62 26 1030 1028 1027 19 14 10 19 10 0.00 155
2014-3-13 20 11 2 10 5 2 100 77 27 1029 1027 1025 19 14 10 16 6 0.00 127
2014-3-14 19 12 4 10 7 4 100 81 35 1026 1024 1022 14 9 1 16 6 0.00 1 Fog 160
2014-3-15 16 10 4 12 8 4 100 88 67 1023 1019 1015 14 8 1 21 8 0.00 2 Fog 167
2014-3-16 16 10 5 12 8 -30 100 87 4 1019 1016 1014 8 5 0 23 6 0.00 3 Fog 237
2014-3-17 18 13 8 13 11 8 100 88 65 1023 1021 1018 19 6 2 16 6 0.00 2 Fog 243
2014-3-18 18 13 8 13 11 7 100 87 65 1023 1021 1020 14 6 0 16 6 0.00 3 Fog 170
2014-3-19 17 12 8 12 11 8 100 87 66 1023 1021 1020 14 9 1 13 6 0.00 4 Fog 156
2014-3-20 21 13 5 12 9 6 100 84 46 1025 1023 1022 19 4 0 16 8 0.00 2 Fog 119
2014-3-21 17 13 8 12 10 8 100 86 62 1023 1021 1020 10 7 0 16 5 0.25 4 Fog 206
2014-3-22 16 13 12 13 12 11 100 90 69 1020 1015 1008 19 9 2 16 8 0.51 6 Rain 181
2014-3-23 14 11 7 13 8 4 94 79 49 1009 1003 1000 19 10 5 48 23 66 1.02 5 Rain-Thunderstorm 228
2014-3-24 14 10 6 8 6 2 100 78 47 1011 1006 1001 26 11 10 42 16 2.03 4 Rain-Thunderstorm 161
2014-3-25 13 9 4 9 6 4 96 88 58 1011 1008 1005 26 10 8 26 11 0.51 4 Rain 110
2014-3-26 13 10 7 7 6 4 96 76 51 1008 1007 1005 19 10 10 23 10 0.51 5 Rain 70
2014-3-27 15 12 8 8 5 3 93 63 38 1008 1005 1003 19 11 10 39 19 60 0.00 6 54
2014-3-28 18 12 6 11 7 4 100 78 32 1020 1014 1008 26 12 10 19 8 0.00 2 290
2014-3-29 22 13 5 11 7 5 100 76 26 1022 1020 1019 19 12 10 24 10 0.00 1 125
2014-3-30 19 13 6 10 8 6 100 75 38 1021 1019 1017 19 12 8 16 8 0.00 152
2014-3-31 17 11 5 11 8 5 94 83 45 1019 1017 1016 19 15 10 19 8 0.00 203
2014-4-1 17 11 5 11 8 4 100 89 68 1018 1017 1017 19 7 0 23 6 0.00 4 Fog 230
2014-4-2 18 12 6 11 8 6 100 87 68 1018 1016 1014 19 10 6 19 6 0.00 2 Fog 129
2014-4-3 20 14 9 11 8 6 94 70 43 1015 1010 1006 19 11 10 26 11 0.00 2 107
2014-4-4 16 13 11 12 11 9 94 87 73 1006 1003 1000 19 10 3 24 14 7.87 4 Rain-Thunderstorm 115
2014-4-5 17 14 11 13 11 9 100 87 60 1013 1008 1005 14 10 5 19 5 0.00 6 Rain 96
2014-4-6 21 14 8 13 11 8 100 82 52 1018 1015 1013 26 11 10 16 5 0.00 3 265
2014-4-7 22 15 8 14 11 7 100 80 50 1021 1019 1018 26 19 10 21 8 0.00 245
2014-4-8 18 13 9 15 12 9 100 91 68 1021 1020 1017 19 8 0 19 6 0.51 4 Fog-Rain 221
2014-4-9 19 16 11 14 13 10 95 87 67 1019 1017 1016 19 10 8 14 6 0.00 4 227
2014-4-10 19 13 7 13 9 6 100 81 35 1020 1018 1017 19 9 4 19 8 0.00 3 Fog 181
2014-4-11 18 14 11 13 11 9 94 84 56 1018 1017 1016 26 10 6 23 8 0.00 5 253
2014-4-12 20 14 8 13 11 7 100 85 60 1017 1016 1015 14 10 10 16 6 0.00 2 193
2014-4-13 18 14 11 14 12 10 100 89 67 1017 1016 1015 11 10 6 16 6 0.25 4 Rain 263
2014-4-14 19 13 8 15 12 7 100 89 72 1018 1016 1013 19 7 0 23 10 0.00 3 Fog 209
2014-4-15 19 13 8 14 9 1 100 74 28 1015 1012 1010 14 9 2 29 8 1.02 3 Fog-Hail-Thunderstorm 102
2014-4-16 17 12 6 7 2 -2 81 52 19 1021 1018 1015 31 12 10 27 14 0.00 2 69
2014-4-17 17 10 2 10 5 0 94 70 22 1021 1017 1014 31 14 10 23 8 0.00 1 210
2014-4-18 17 11 5 12 9 5 100 86 63 1015 1010 1004 26 13 10 23 11 0.00 3 246
2014-4-19 16 13 11 12 11 9 95 89 69 1006 1002 1000 19 10 5 39 19 50 6.10 6 Fog-Rain-Thunderstorm 96
2014-4-20 18 11 5 12 9 5 100 83 53 1007 1006 1005 19 9 0 19 8 0.00 3 Fog 125
2014-4-21 17 14 11 14 11 10 100 87 63 1009 1006 1004 19 10 0 14 6 1.02 5 Fog-Rain-Thunderstorm 90
2014-4-22 20 14 9 14 12 9 100 89 61 1015 1012 1009 19 7 0 16 6 0.00 3 Fog 166
2014-4-23 22 16 10 15 12 9 100 84 55 1016 1015 1014 14 6 0 23 6 0.00 4 Fog 242
2014-4-24 19 15 11 16 14 10 100 89 75 1016 1015 1014 14 9 3 21 8 0.00 4 Fog 266
2014-4-25 21 16 11 16 13 11 94 87 64 1015 1011 1008 19 9 5 16 6 0.00 3 270
2014-4-26 20 16 11 16 13 11 100 87 72 1011 1009 1009 14 9 1 23 8 0.00 2 Fog 268
2014-4-27 15 12 10 13 12 9 94 91 80 1010 1006 1003 19 10 3 14 6 7.11 5 Rain 270
2014-4-28 16 13 12 14 12 11 100 91 81 1006 1005 1004 14 10 10 19 6 0.51 6 Rain-Thunderstorm 203
2014-4-29 18 13 9 13 11 9 100 83 59 1011 1008 1005 14 10 6 14 8 0.00 4 Fog-Rain-Thunderstorm 236
2014-4-30 17 13 9 13 11 9 94 86 68 1011 1009 1006 19 11 10 35 8 3.05 3 Rain 158
2014-5-1 19 12 6 13 10 6 95 80 48 1011 1010 1008 19 10 8 21 8 0.00 3 Fog 288
2014-5-2 16 13 11 14 11 10 94 91 77 1010 1008 1007 19 9 3 21 8 11.94 5 Rain-Thunderstorm 148
2014-5-3 19 15 11 13 11 9 94 83 48 1007 1006 1005 26 10 6 27 6 0.25 5 Rain 358
2014-5-4 21 16 11 14 11 9 94 77 54 1014 1010 1007 31 11 10 19 8 0.00 3 108
2014-5-5 20 13 7 12 9 6 100 73 32 1019 1017 1014 31 14 10 16 8 0.00 1 169
2014-5-6 21 14 8 14 11 8 100 84 48 1022 1020 1018 26 12 10 21 6 0.00 2 209
2014-5-7 21 15 9 15 12 9 100 85 57 1021 1019 1017 19 11 10 21 8 0.00 3 172
2014-5-8 23 17 11 14 13 10 94 77 43 1020 1018 1017 26 12 10 24 8 0.00 3 149
2014-5-9 21 16 10 15 13 9 94 82 55 1019 1017 1017 19 11 10 19 6 0.00 2 Fog 252
2014-5-10 21 16 10 15 13 9 100 82 55 1017 1016 1015 19 10 2 16 6 0.00 3 Fog 221
2014-5-11 22 18 13 16 14 12 94 81 62 1016 1012 1009 14 10 8 29 11 0.00 3 199
2014-5-12 19 16 12 15 13 11 100 82 57 1014 1012 1010 14 10 10 24 11 0.00 2 237
2014-5-13 20 16 11 12 10 7 94 72 51 1013 1012 1010 19 11 10 27 16 0.00 3 225
2014-5-14 22 15 8 11 7 1 94 63 24 1018 1016 1013 31 13 10 32 11 0.00 2 246
2014-5-15 21 14 7 11 6 -3 100 60 13 1019 1017 1016 31 12 10 24 10 0.00 2 224
2014-5-16 22 16 10 13 9 1 100 71 22 1016 1014 1012 31 13 10 24 8 0.00 2 210
2014-5-17 22 17 12 13 11 6 96 74 39 1017 1015 1014 26 11 10 21 8 0.00 3 214
2014-5-18 22 15 8 11 9 8 100 69 39 1018 1016 1015 19 12 10 29 10 37 0.00 1 149
2014-5-19 20 16 11 13 9 5 88 68 33 1018 1016 1015 19 11 10 26 11 0.00 5 123
2014-5-20 24 19 13 14 11 5 94 68 21 1020 1018 1017 26 12 10 23 8 0.00 4 203
2014-5-21 26 18 11 16 13 10 100 73 40 1020 1018 1016 19 12 10 21 8 0.00 2 139
2014-5-22 27 20 13 16 14 12 95 74 43 1018 1016 1014 19 11 10 27 10 0.00 2 Rain 138
2014-5-23 23 18 14 16 14 10 94 77 38 1016 1015 1013 19 10 8 23 10 0.00 4 Rain 240
2014-5-24 23 17 11 15 12 6 94 75 32 1018 1017 1016 26 12 10 21 8 0.00 1 255
2014-5-25 27 18 10 14 9 4 94 64 18 1018 1016 1014 19 12 10 26 8 0.00 2 177
2014-5-26 22 18 14 15 13 11 94 74 41 1016 1015 1014 31 11 10 27 13 0.00 3 252
2014-5-27 21 18 15 14 13 11 88 75 55 1015 1014 1013 19 11 10 37 21 0.00 4 Rain 253
2014-5-28 22 18 15 14 13 11 88 72 45 1014 1012 1011 19 11 10 27 21 0.00 3 261
2014-5-29 21 16 10 14 12 9 100 80 57 1013 1012 1012 26 11 10 24 10 0.00 2 204
2014-5-30 22 16 10 15 13 11 95 80 54 1014 1013 1013 19 11 10 21 8 0.00 2 218
2014-5-31 23 19 14 15 13 8 94 78 34 1017 1014 1013 26 11 10 19 8 1.02 4 Rain 132
2014-6-1 23 17 10 13 9 5 94 62 27 1017 1016 1015 31 12 10 23 8 0.00 2 246
2014-6-2 25 18 10 16 10 6 94 66 26 1017 1015 1013 31 14 10 23 10 0.00 1 247
2014-6-3 26 19 12 16 13 7 100 73 32 1014 1013 1012 31 14 10 21 8 0.00 2 234
2014-6-4 23 18 12 16 14 12 100 80 56 1014 1012 1012 19 11 10 23 8 0.00 2 242
2014-6-5 25 19 14 17 14 11 94 70 34 1018 1015 1013 19 11 10 23 8 0.00 2 266
2014-6-6 26 19 13 17 14 11 94 72 44 1020 1018 1017 31 15 10 16 6 0.00 2 222
2014-6-7 28 21 13 18 14 9 95 70 27 1019 1018 1017 31 18 10 21 6 9.91 226
2014-6-8 31 22 14 18 15 12 94 66 30 1020 1019 1018 26 15 10 24 8 0.00 2 296
2014-6-9 34 26 17 18 16 9 94 61 14 1019 1017 1016 31 18 10 23 10 0.00 137
2014-6-10 32 23 15 22 18 14 100 70 30 1019 1017 1017 31 17 10 21 8 0.00 1 210
2014-6-11 31 23 16 23 18 16 100 76 35 1020 1018 1017 26 12 10 21 8 0.00 2 250
2014-6-12 32 24 18 23 21 17 100 82 49 1020 1018 1016 26 11 5 23 8 0.00 3 Thunderstorm 257
2014-6-13 31 26 20 24 21 19 100 79 47 1017 1014 1011 14 10 8 21 8 0.00 2 264
2014-6-14 31 26 20 21 19 15 100 73 35 1011 1008 1005 19 10 8 23 10 29 7.87 3 Rain-Thunderstorm 118
2014-6-15 23 21 18 20 16 12 100 73 48 1012 1010 1008 19 10 6 29 14 0.51 6 Rain-Thunderstorm 58
2014-6-16 23 20 16 16 14 12 94 67 50 1012 1011 1010 31 11 10 24 18 0.00 5 Rain 72
2014-6-17 26 20 13 16 13 10 95 65 32 1013 1012 1010 26 11 10 23 10 0.00 3 84
2014-6-18 26 20 13 16 14 11 88 62 39 1014 1013 1012 31 12 10 23 10 0.00 2 41
2014-6-19 26 20 14 18 16 14 100 72 44 1015 1014 1013 26 12 10 24 10 0.00 1 255
2014-6-20 25 21 16 19 18 16 97 80 53 1015 1014 1012 14 10 10 26 10 0.00 2 272
2014-6-21 27 21 15 20 17 14 100 75 35 1017 1015 1013 26 13 10 19 8 0.00 2 235
2014-6-22 28 22 16 22 18 15 100 80 45 1021 1018 1016 31 12 10 23 8 0.00 2 202
2014-6-23 29 23 17 20 18 13 100 72 41 1021 1019 1016 31 12 10 26 8 0.00 2 149
2014-6-24 29 22 16 22 18 14 100 73 31 1017 1012 1009 26 14 10 32 11 0.00 1 163
2014-6-25 26 23 21 22 21 17 100 85 57 1011 1008 1006 19 10 5 35 11 3.05 4 Rain-Thunderstorm 265
2014-6-26 24 21 18 21 18 15 94 84 52 1013 1011 1010 19 11 5 21 10 7.11 3 Rain-Thunderstorm 291
2014-6-27 27 21 16 22 18 15 100 83 56 1018 1015 1012 31 12 10 24 8 0.00 2 194
2014-6-28 27 22 17 20 17 14 100 73 42 1019 1017 1015 31 11 7 16 8 0.00 2 238
2014-6-29 28 22 16 21 18 14 94 77 33 1016 1011 1006 26 11 8 27 11 1.02 3 Rain-Thunderstorm 156
2014-6-30 27 22 17 20 18 17 94 78 53 1015 1010 1006 19 11 10 29 13 0.00 2 258
2014-7-1 26 21 16 20 18 16 94 77 48 1018 1016 1014 26 11 10 19 10 0.00 2 288
2014-7-2 27 21 16 20 18 15 94 76 49 1022 1019 1017 31 13 10 16 8 0.00 2 230
2014-7-3 32 24 16 22 18 15 100 75 38 1024 1022 1021 31 15 10 23 8 0.00 1 113
2014-7-4 32 26 20 21 18 16 94 69 35 1021 1017 1013 26 11 10 35 11 0.00 4 Rain 154
2014-7-5 26 23 20 21 20 19 94 82 66 1015 1013 1012 14 10 10 23 11 0.00 3 242
2014-7-6 28 23 18 21 19 17 95 80 53 1016 1015 1014 26 12 10 19 8 0.00 3 229
2014-7-7 29 23 18 21 18 16 94 75 41 1016 1015 1013 31 12 6 37 8 0.25 5 Rain-Thunderstorm 151
2014-7-8 24 21 18 20 18 15 94 81 55 1014 1010 1007 19 11 6 47 21 64 7.87 4 Rain 215
2014-7-9 24 19 15 19 16 15 100 76 55 1008 1007 1006 19 11 10 42 19 55 0.51 3 Rain-Thunderstorm 222
2014-7-10 23 19 14 17 15 13 100 78 54 1008 1006 1005 31 12 10 29 13 0.00 3 Rain-Thunderstorm 194
2014-7-11 25 19 14 18 17 14 100 82 58 1010 1008 1008 26 12 10 23 10 0.00 2 216
2014-7-12 27 21 15 19 17 14 94 81 47 1012 1011 1010 26 11 10 26 8 2.03 5 Rain-Thunderstorm 126
2014-7-13 25 21 17 20 18 17 100 84 61 1013 1012 1011 26 11 10 24 8 0.00 4 Rain-Thunderstorm 194
2014-7-14 23 21 18 19 18 17 94 87 72 1015 1013 1012 19 10 6 23 10 14.99 5 Rain-Thunderstorm 266
2014-7-15 28 22 15 21 18 15 100 80 52 1017 1016 1015 31 11 3 19 6 0.00 1 Fog 294
2014-7-16 30 23 16 21 18 16 94 72 41 1018 1017 1016 26 14 10 26 8 0.00 1 294
2014-7-17 32 24 18 22 19 17 100 74 36 1019 1017 1017 31 15 10 21 8 0.00 2 262
2014-7-18 30 25 20 23 21 18 100 82 47 1019 1017 1016 26 9 0 19 8 0.00 3 Fog 238
2014-7-19 33 26 18 23 19 16 94 73 27 1017 1016 1015 19 14 10 19 6 0.00 2 197
2014-7-20 32 25 18 21 18 15 94 67 34 1016 1014 1011 31 12 10 32 10 0.00 3 Rain 123
2014-7-21 24 21 18 21 19 17 100 85 68 1012 1009 1008 14 9 1 27 11 14.99 5 Rain-Thunderstorm 213
2014-7-22 27 22 17 21 18 15 100 77 41 1009 1008 1007 31 11 2 24 11 0.00 4 Rain-Thunderstorm 307
2014-7-23 28 23 19 22 21 19 100 86 65 1011 1009 1009 26 11 10 21 8 0.00 4 Rain 263
2014-7-24 26 22 19 21 20 19 95 87 65 1012 1010 1009 26 11 8 19 6 6.10 4 Rain-Thunderstorm 145
2014-7-25 27 23 18 22 20 18 100 84 63 1014 1012 1012 19 10 3 19 6 0.00 3 Fog-Rain 173
2014-7-26 27 23 20 24 21 19 96 87 60 1013 1010 1009 19 10 1 24 8 10.92 4 Rain-Thunderstorm 142
2014-7-27 27 22 18 22 20 18 100 85 56 1012 1010 1009 19 10 5 21 8 14.99 3 Rain-Thunderstorm 174
2014-7-28 28 23 18 23 21 18 100 83 53 1013 1011 1010 26 11 8 23 8 0.00 3 Fog 214
2014-7-29 24 21 19 22 19 16 100 86 69 1010 1008 1006 19 10 2 24 13 24.89 6 Rain-Thunderstorm 277
2014-7-30 24 20 17 19 18 16 95 86 67 1009 1006 1003 19 9 3 19 8 0.25 4 Rain 288
2014-7-31 26 21 17 21 19 16 95 84 64 1012 1010 1008 19 11 10 19 8 0.00 3 239
2014-8-1 27 22 18 22 20 18 100 84 65 1012 1011 1010 19 10 3 16 6 0.00 2 Fog 255
2014-8-2 29 23 18 21 19 17 94 76 48 1012 1011 1011 31 11 5 14 6 0.00 1 Fog 200
2014-8-3 27 23 20 22 21 19 94 85 63 1014 1013 1011 19 11 8 21 11 0.51 4 Rain-Thunderstorm 196
2014-8-4 27 23 19 23 21 18 100 86 62 1016 1015 1014 19 10 0 21 8 0.00 2 Fog 222
2014-8-5 27 23 19 23 20 16 100 86 67 1015 1014 1012 19 10 6 23 8 0.00 3 Thunderstorm 155
2014-8-6 29 22 16 22 19 16 100 81 57 1015 1014 1013 31 14 10 23 6 0.00 1 282
2014-8-7 29 23 18 22 19 17 94 80 48 1014 1013 1012 31 14 10 19 8 0.00 1 215
2014-8-8 29 23 18 22 19 17 95 79 48 1015 1014 1013 19 10 2 16 6 0.00 1 193
2014-8-9 28 23 18 23 20 18 100 82 58 1016 1015 1015 19 11 10 14 8 0.00 2 192
2014-8-10 31 24 18 23 20 18 100 76 49 1017 1015 1014 31 23 10 16 8 0.00 153
2014-8-11 29 24 19 24 21 19 94 83 60 1015 1014 1012 31 12 10 21 8 0.00 2 154
2014-8-12 29 26 22 24 22 21 95 86 66 1014 1012 1010 19 10 8 21 10 0.00 3 169
2014-8-13 29 26 22 24 22 20 94 85 67 1012 1009 1007 19 10 10 35 11 0.00 3 Rain 190
2014-8-14 25 22 20 20 17 16 88 70 52 1012 1010 1008 19 11 10 37 19 0.00 3 244
2014-8-15 24 20 16 20 18 16 94 79 57 1015 1013 1012 19 10 10 35 16 48 1.02 3 Rain 231
2014-8-16 25 20 15 19 17 15 94 75 50 1017 1015 1014 26 11 10 21 10 0.00 2 135
2014-8-17 27 19 12 16 14 10 100 71 30 1019 1017 1015 31 18 10 21 8 0.00 1 111
2014-8-18 25 18 12 19 16 12 100 78 56 1016 1015 1014 31 12 10 16 6 0.00 2 203
2014-8-19 28 22 17 22 19 17 94 81 52 1014 1013 1012 26 11 10 26 11 0.00 3 145
2014-8-20 28 23 18 22 20 18 100 85 61 1014 1013 1012 19 11 10 21 8 0.00 3 200
2014-8-21 26 21 16 19 18 15 100 78 49 1016 1014 1013 26 12 10 23 10 0.00 1 227
2014-8-22 26 20 14 19 17 13 94 79 52 1016 1015 1015 26 12 10 19 8 0.00 2 172
2014-8-23 24 21 18 20 19 18 100 88 68 1016 1014 1013 14 10 10 23 8 2.03 5 Rain 136
2014-8-24 26 21 17 20 18 16 94 80 62 1016 1015 1013 19 11 10 35 11 0.00 3 257
2014-8-25 26 21 16 20 17 15 95 82 55 1019 1017 1016 19 11 10 19 8 0.00 2 185
2014-8-26 27 21 16 22 18 16 100 82 47 1017 1014 1012 26 11 10 23 10 0.00 3 Rain 156
2014-8-27 27 23 20 22 21 19 95 86 68 1013 1011 1010 19 11 10 34 13 0.00 3 199
2014-8-28 29 22 16 20 18 16 100 78 43 1016 1014 1012 19 11 8 23 10 0.00 1 135
2014-8-29 30 24 18 21 18 16 94 75 46 1017 1016 1015 19 13 10 24 10 0.00 1 294
2014-8-30 27 22 17 22 19 16 94 82 48 1017 1015 1014 19 11 10 16 6 0.00 1 229
2014-8-31 27 22 17 21 19 17 100 84 56 1015 1012 1008 19 10 3 16 6 0.00 2 212
2014-9-1 26 21 16 21 14 9 100 69 28 1009 1006 1004 19 11 10 29 11 48 0.00 3 Rain-Thunderstorm 60
2014-9-2 28 20 12 15 12 9 95 65 23 1011 1009 1008 26 12 10 24 8 0.00 1 124
2014-9-3 25 20 15 18 16 13 88 74 50 1012 1011 1011 19 11 10 21 11 0.00 2 110
2014-9-4 26 20 14 20 17 14 100 78 45 1014 1012 1012 19 11 10 13 6 0.00 2 55
2014-9-5 27 21 16 23 19 16 100 84 56 1014 1012 1011 19 10 10 19 5 9.91 4 Rain-Thunderstorm 120
2014-9-6 27 22 17 20 19 16 95 79 57 1012 1011 1010 19 11 10 16 8 0.00 2 273
2014-9-7 27 21 16 21 19 16 100 85 56 1015 1013 1012 19 10 6 19 6 0.00 2 Fog 185
2014-9-8 27 22 17 21 19 16 100 85 58 1017 1016 1014 19 11 8 16 8 0.00 2 172
2014-9-9 27 22 17 22 19 16 94 86 64 1017 1016 1014 14 8 3 16 6 0.00 2 200
2014-9-10 23 21 18 21 19 17 100 93 83 1015 1012 1010 19 10 3 23 8 7.87 6 Rain-Thunderstorm 110
2014-9-11 25 21 18 20 18 16 94 82 48 1011 1009 1007 19 10 3 26 8 0.76 4 Rain-Thunderstorm 121
2014-9-12 23 19 16 17 16 13 100 79 52 1013 1010 1008 31 12 10 34 10 0.00 3 Rain-Thunderstorm 103
2014-9-13 24 19 13 18 16 13 94 80 56 1016 1014 1013 19 11 10 16 8 0.00 1 151
2014-9-14 25 19 13 18 16 12 100 81 44 1016 1015 1014 26 14 10 19 6 0.00 1 122
2014-9-15 25 19 14 20 17 14 100 86 59 1016 1015 1015 26 11 10 13 6 0.00 3 120
2014-9-16 27 21 16 18 17 14 100 79 38 1015 1015 1014 19 11 10 19 8 0.00 2 129
2014-9-17 27 21 15 19 16 13 100 75 38 1015 1014 1013 26 12 10 23 10 0.00 2 111
2014-9-18 27 22 17 21 18 15 94 77 46 1016 1015 1014 19 11 10 23 10 0.00 3 114
2014-9-19 25 22 19 22 19 18 100 86 62 1018 1016 1015 19 10 2 23 10 39 10.92 4 Rain-Thunderstorm 112
2014-9-20 28 24 20 22 21 19 95 85 62 1017 1016 1015 26 11 6 23 8 0.00 3 Rain 222
2014-9-21 26 22 18 22 19 17 100 87 62 1017 1015 1013 14 7 0 16 8 0.00 3 Fog 169
2014-9-22 26 22 18 22 20 17 94 86 70 1013 1010 1008 19 10 10 26 14 0.00 3 219
2014-9-23 24 20 15 17 11 4 100 62 20 1016 1013 1009 26 14 10 29 14 0.00 2 101
2014-9-24 23 16 9 15 11 5 94 68 24 1017 1015 1014 19 11 10 19 10 0.00 4 122
2014-9-25 24 19 15 18 16 14 94 81 49 1018 1015 1013 19 11 10 23 10 0.00 4 Rain 120
2014-9-26 25 19 13 15 13 10 100 72 38 1022 1020 1018 26 16 10 19 8 0.00 95
2014-9-27 27 19 11 19 14 11 100 80 35 1026 1024 1021 31 20 10 14 6 0.00 121
2014-9-28 28 20 13 18 14 11 100 73 29 1028 1026 1025 19 14 10 23 10 0.00 117
2014-9-29 26 19 12 20 16 12 97 77 31 1028 1027 1026 26 12 10 21 8 0.00 1 151
2014-9-30 25 19 13 19 17 13 94 83 44 1028 1026 1025 26 11 10 19 8 0.00 3 Rain 128
2014-10-1 23 20 18 20 18 17 100 92 83 1025 1023 1021 14 9 2 23 10 13.97 5 Rain-Thunderstorm 111
2014-10-2 26 21 16 19 16 12 100 74 33 1025 1022 1021 31 12 5 27 10 0.00 2 Fog-Rain-Thunderstorm 100
2014-10-3 26 20 14 17 14 12 88 71 34 1023 1021 1019 31 16 10 26 10 0.00 1 106
2014-10-4 25 18 11 16 13 9 100 75 27 1020 1017 1015 31 14 10 23 8 0.00 1 108
2014-10-5 24 17 10 17 13 10 100 79 39 1016 1015 1014 31 15 10 19 8 0.00 1 68
2014-10-6 24 18 13 15 13 12 100 79 43 1015 1014 1013 19 12 10 16 8 0.00 2 107
2014-10-7 24 18 11 17 14 11 100 83 51 1018 1016 1015 14 10 8 19 8 0.00 4 119
2014-10-8 26 21 17 19 18 16 94 82 58 1019 1017 1017 19 10 10 26 11 0.00 3 123
2014-10-9 25 22 18 20 18 17 94 81 65 1018 1016 1016 19 10 10 24 13 0.00 3 114
2014-10-10 27 23 20 20 19 17 94 81 61 1018 1017 1016 26 11 10 21 13 0.00 4 116
2014-10-11 26 21 17 22 19 16 100 86 68 1017 1016 1014 19 10 3 24 13 7.11 4 Rain-Thunderstorm 137
2014-10-12 26 21 15 21 18 14 100 88 67 1017 1015 1014 14 10 10 23 13 0.25 3 Rain-Thunderstorm 114
2014-10-13 26 22 18 21 19 17 95 90 75 1015 1012 1009 14 10 2 32 14 10.92 6 Rain-Thunderstorm 137
2014-10-14 25 20 16 19 17 15 100 87 63 1013 1010 1008 19 10 6 21 10 0.00 4 Rain-Thunderstorm 106
2014-10-15 24 20 17 19 17 16 100 89 69 1011 1008 1007 19 10 6 16 6 0.25 4 Rain-Thunderstorm 137
2014-10-16 23 21 18 19 18 16 95 89 73 1016 1014 1010 19 10 8 19 8 1.02 5 Rain 235
2014-10-17 25 21 17 21 19 17 95 89 78 1020 1016 1015 14 10 10 34 10 0.00 5 Rain 239
2014-10-18 24 19 15 20 17 15 100 89 69 1025 1022 1019 19 8 0 13 6 0.00 2 Fog 133
2014-10-19 24 19 14 19 17 13 100 89 65 1025 1024 1023 19 5 0 14 5 0.00 3 Fog 138
2014-10-20 23 19 14 19 16 14 100 91 72 1024 1022 1018 19 7 0 16 6 0.00 3 Fog 136
2014-10-21 23 21 18 19 18 17 100 89 70 1018 1012 1005 19 10 10 23 8 0.76 4 Rain 139
2014-10-22 19 14 9 19 4 -7 94 46 9 1013 1007 1001 31 13 10 40 21 53 0.00 1 311
2014-10-23 22 14 6 10 6 1 93 59 20 1012 1009 1007 31 16 10 23 8 0.00 3 65
2014-10-24 21 14 8 11 8 5 100 70 27 1016 1012 1010 26 12 10 21 8 0.00 3 139
2014-10-25 21 14 7 10 9 7 95 75 36 1021 1018 1015 31 20 10 21 10 0.00 -1
2014-10-26 19 14 9 10 8 6 94 72 38 1023 1022 1021 19 15 10 23 6 0.00 3 -1
2014-10-27 18 14 9 9 7 6 87 66 41 1025 1023 1022 31 19 10 24 16 0.00 1 -1
2014-10-28 18 12 6 8 7 5 93 71 37 1024 1021 1019 19 14 10 26 14 0.00 1 110
2014-10-29 18 12 6 10 7 5 100 78 39 1021 1019 1018 19 13 10 23 10 0.00 1 108
2014-10-30 20 13 6 11 8 5 100 80 44 1025 1022 1020 31 14 10 13 6 0.00 2 115
2014-10-31 20 12 5 11 7 4 100 79 28 1026 1025 1024 26 16 10 13 8 0.00 109
2014-11-1 21 13 5 13 8 5 100 81 36 1025 1024 1023 31 14 8 13 6 0.00 101
2014-11-2 20 13 6 15 9 5 100 86 60 1024 1022 1020 19 9 2 14 8 0.00 2 Fog 130
2014-11-3 20 14 8 13 11 7 100 84 56 1022 1019 1015 19 8 2 21 10 0.00 2 Fog 116
2014-11-4 22 17 13 17 14 11 94 80 61 1015 1007 1002 19 10 10 34 21 52 1.02 4 Rain 132
2014-11-5 20 17 14 18 16 13 100 87 71 1005 1001 999 11 9 3 35 21 58 2.03 6 Rain-Thunderstorm 175
2014-11-6 16 14 13 14 13 12 100 93 86 1009 1007 1005 14 8 3 24 11 14.99 6 Rain 81
2014-11-7 19 16 13 14 13 12 94 89 70 1010 1008 1007 19 10 6 11 3 0.00 4 Fog 267
2014-11-8 20 15 10 14 12 9 95 86 62 1012 1011 1009 19 9 0 11 5 0.00 2 Fog 137
2014-11-9 20 14 9 15 12 8 100 87 64 1014 1013 1012 19 7 0 23 8 0.00 2 Fog 119
2014-11-10 17 15 13 15 14 12 94 89 73 1015 1014 1014 11 8 2 29 18 35.05 6 Rain-Thunderstorm 96
2014-11-11 18 16 13 15 13 13 96 89 68 1016 1012 1007 10 9 5 24 11 3.05 6 Rain-Thunderstorm 100
2014-11-12 16 14 13 14 13 12 94 92 83 1008 1004 1003 11 10 10 23 11 0.76 6 Rain 117
2014-11-13 18 14 11 14 12 11 94 89 66 1013 1008 1003 19 10 3 14 6 0.00 4 Rain 216
2014-11-14 20 17 13 14 13 12 95 88 61 1015 1014 1013 19 9 3 13 6 0.00 4 Rain 112
2014-11-15 17 15 13 15 13 11 95 86 72 1013 1007 1001 10 10 6 34 18 7.87 5 Rain 131
2014-11-16 18 14 11 12 11 9 94 77 55 1007 1006 1004 19 10 8 37 21 50 3.05 4 Rain-Thunderstorm 200
2014-11-17 12 11 9 11 10 9 94 94 88 1008 1006 1001 10 9 4 34 11 13.97 6 Rain-Thunderstorm 104
2014-11-18 16 12 9 12 10 8 100 77 59 1009 1007 1004 19 10 10 37 19 55 1.02 3 Rain-Thunderstorm 246
2014-11-19 18 13 8 11 9 7 96 82 55 1022 1015 1009 31 11 8 35 14 0.00 2 Fog-Thunderstorm 134
2014-11-20 16 11 6 11 8 5 100 87 57 1025 1023 1022 19 10 8 14 8 0.00 1 Fog 123
2014-11-21 12 9 7 11 9 7 100 92 82 1024 1023 1022 11 9 5 13 10 0.51 5 Rain 124
2014-11-22 15 13 11 13 12 10 94 91 82 1025 1023 1022 14 9 7 16 11 0.25 5 Rain 117
2014-11-23 18 14 12 14 12 11 100 88 69 1027 1025 1024 19 10 8 14 10 0.00 4 Fog 118
2014-11-24 17 13 9 14 12 9 100 92 79 1025 1023 1022 14 9 4 13 6 0.00 4 Fog 124
2014-11-25 16 14 13 14 13 12 95 92 85 1023 1020 1018 10 8 3 13 8 6.10 6 Rain 123
2014-11-26 17 15 13 15 13 12 95 93 86 1019 1015 1014 10 7 2 21 6 3.05 6 Rain-Thunderstorm 126
2014-11-27 18 15 12 14 13 11 94 90 79 1014 1012 1011 14 9 4 21 11 2.03 5 Rain-Thunderstorm 107
2014-11-28 16 14 13 13 12 10 95 84 60 1012 1010 1009 19 10 6 19 11 0.25 6 Rain-Thunderstorm 107
2014-11-29 19 16 12 14 12 10 88 82 64 1012 1011 1010 19 11 10 26 13 0.00 5 Rain 115
2014-11-30 18 16 14 14 13 11 94 81 60 1011 1007 1002 19 10 10 32 16 0.00 6 Rain 121
2014-12-1 17 14 12 15 13 11 100 91 63 1002 1000 998 11 9 3 26 13 21.08 5 Rain-Thunderstorm 93
2014-12-2 18 14 10 12 11 9 94 82 59 1005 1002 1001 14 10 10 16 6 0.00 2 122
2014-12-3 17 13 9 10 9 9 100 82 51 1010 1007 1004 19 11 10 23 8 0.00 4 139
2014-12-4 15 12 9 12 9 7 94 87 72 1013 1012 1010 14 10 10 21 13 0.00 5 Rain 112
2014-12-5 15 12 10 11 9 9 94 86 67 1014 1013 1012 19 10 10 23 16 0.25 5 Rain 108
2014-12-6 15 12 10 11 10 9 97 87 67 1014 1012 1011 19 10 6 26 14 2.03 6 Rain-Thunderstorm 87
2014-12-7 14 11 7 11 9 6 100 90 72 1015 1014 1013 19 10 10 14 6 0.00 4 Rain 129
2014-12-8 15 10 5 9 6 4 95 85 45 1017 1014 1012 19 11 10 23 5 0.00 2 111
2014-12-9 12 9 6 6 2 -2 93 62 31 1020 1013 1009 31 11 10 27 19 0.00 2 88
2014-12-10 14 8 3 6 2 -2 93 70 34 1022 1021 1019 18 11 10 14 8 0.00 3 117
2014-12-11 12 7 2 6 4 2 100 83 48 1020 1018 1017 19 11 10 14 10 0.00 2 120
2014-12-12 12 7 2 8 5 2 100 89 59 1022 1020 1019 19 10 8 16 8 0.00 4 Rain 124
2014-12-13 13 10 7 11 9 7 100 92 82 1022 1021 1020 19 10 6 19 8 1.02 6 Rain 102
2014-12-14 15 12 9 11 9 8 95 85 68 1022 1021 1020 19 11 10 21 11 0.25 4 109
2014-12-15 15 13 12 13 11 9 94 84 70 1022 1019 1016 11 10 6 26 16 5.08 5 Rain 101
2014-12-16 13 11 9 11 9 8 100 89 72 1016 1010 1007 14 10 10 26 16 0.00 5 Rain 96
2014-12-17 14 10 7 10 9 7 100 90 72 1014 1012 1008 26 10 6 13 5 0.00 3 Fog 123
2014-12-18 16 11 6 10 8 5 100 89 57 1023 1019 1014 26 8 3 13 8 0.00 2 Fog 120
2014-12-19 14 10 7 12 8 6 100 91 70 1025 1024 1023 19 9 5 11 5 0.00 3 Fog 125
2014-12-20 15 12 9 12 10 8 100 91 77 1024 1022 1021 10 7 0 11 6 0.00 4 Fog 121
2014-12-21 14 10 6 12 8 5 100 93 82 1031 1026 1023 19 4 0 13 5 0.00 3 Fog 113
2014-12-22 12 7 2 9 6 2 100 89 70 1032 1031 1030 11 9 2 13 8 0.00 3 Fog 131
2014-12-23 12 10 7 11 9 6 94 89 70 1031 1030 1029 19 10 10 13 5 0.00 5 258
2014-12-24 14 12 11 11 9 8 94 78 60 1029 1027 1026 19 10 10 19 10 0.00 6 257
2014-12-25 13 11 8 11 10 7 100 90 76 1026 1022 1019 19 10 2 11 6 0.00 4 Fog 171
2014-12-26 14 8 3 7 3 -4 100 75 23 1023 1021 1018 31 6 1 23 8 0.00 3 108
2014-12-27 11 6 -1 10 3 -1 100 90 69 1023 1010 998 19 8 1 48 11 71 33.02 5 Fog-Rain-Thunderstorm 122
2014-12-28 9 5 1 3 1 -3 100 74 42 1014 1002 998 19 9 0 24 10 0.00 2 Fog 92
2014-12-29 9 4 0 -1 -3 -7 87 61 22 1025 1022 1015 31 13 10 26 10 0.00 2 89
2014-12-30 6 1 -3 -1 -3 -6 100 61 36 1030 1028 1025 14 10 10 32 14 0.00 2 114
2014-12-31 5 1 -2 -1 -4 -8 93 64 33 1031 1028 1026 31 12 10 35 14 52 0.00 3 102
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment