http://git-wip-us.apache.org/repos/asf/stratos/blob/53c98dd9/extensions/das/metering-service/capps/stratos-metering-service/Gadget_Member_Status/Member_Status/js/vega.js ---------------------------------------------------------------------- diff --git a/extensions/das/metering-service/capps/stratos-metering-service/Gadget_Member_Status/Member_Status/js/vega.js b/extensions/das/metering-service/capps/stratos-metering-service/Gadget_Member_Status/Member_Status/js/vega.js deleted file mode 100644 index 019e421..0000000 --- a/extensions/das/metering-service/capps/stratos-metering-service/Gadget_Member_Status/Member_Status/js/vega.js +++ /dev/null @@ -1,7986 +0,0 @@ -// Define module using Universal Module Definition pattern -// https://github.com/umdjs/umd/blob/master/amdWeb.js - -(function (factory) { - if (typeof define === 'function' && define.amd) { - // Support AMD. Register as an anonymous module. - // NOTE: List all dependencies in AMD style - define(['d3', 'topojson'], factory); - } else { - // No AMD. Set module as a global variable - // NOTE: Pass dependencies to factory function - // (assume that both d3 and topojson are also global.) - var tj = (typeof topojson === 'undefined') ? null : topojson; - vg = factory(d3, tj); - } -}( -//NOTE: The dependencies are passed to this function - function (d3, topojson) { -//--------------------------------------------------- -// BEGIN code for this module -//--------------------------------------------------- - - var vg = { - version: "1.4.3", // semantic versioning - d3: d3, // stash d3 for use in property functions - topojson: topojson // stash topojson similarly - }; -// type checking functions - var toString = Object.prototype.toString; - - vg.isObject = function (obj) { - return obj === Object(obj); - }; - - vg.isFunction = function (obj) { - return toString.call(obj) == '[object Function]'; - }; - - vg.isString = function (obj) { - return toString.call(obj) == '[object String]'; - }; - - vg.isArray = Array.isArray || function (obj) { - return toString.call(obj) == '[object Array]'; - }; - - vg.isNumber = function (obj) { - return toString.call(obj) == '[object Number]'; - }; - - vg.isBoolean = function (obj) { - return toString.call(obj) == '[object Boolean]'; - }; - - vg.isTree = function (obj) { - return obj && obj.__vgtree__; - }; - - vg.tree = function (obj, children) { - var d = [obj]; - d.__vgtree__ = true; - d.children = children || "children"; - return d; - }; - - vg.number = function (s) { - return +s; - }; - - vg.boolean = function (s) { - return !!s; - }; - -// utility functions - - vg.identity = function (x) { - return x; - }; - - vg.true = function () { - return true; - }; - - vg.extend = function (obj) { - for (var x, name, i = 1, len = arguments.length; i < len; ++i) { - x = arguments[i]; - for (name in x) { - obj[name] = x[name]; - } - } - return obj; - }; - - vg.duplicate = function (obj) { - return JSON.parse(JSON.stringify(obj)); - }; - - vg.field = function (f) { - return f.split("\\.") - .map(function (d) { - return d.split("."); - }) - .reduce(function (a, b) { - if (a.length) { - a[a.length - 1] += "." + b.shift(); - } - a.push.apply(a, b); - return a; - }, []); - }; - - vg.accessor = function (f) { - var s; - return (vg.isFunction(f) || f == null) - ? f : vg.isString(f) && (s = vg.field(f)).length > 1 - ? function (x) { - return s.reduce(function (x, f) { - return x[f]; - }, x); - } - : function (x) { - return x[f]; - }; - }; - - vg.mutator = function (f) { - var s; - return vg.isString(f) && (s = vg.field(f)).length > 1 - ? function (x, v) { - for (var i = 0; i < s.length - 1; ++i) x = x[s[i]]; - x[s[i]] = v; - } - : function (x, v) { - x[f] = v; - }; - }; - - vg.comparator = function (sort) { - var sign = []; - if (sort === undefined) sort = []; - sort = vg.array(sort).map(function (f) { - var s = 1; - if (f[0] === "-") { - s = -1; - f = f.slice(1); - } - else if (f[0] === "+") { - s = +1; - f = f.slice(1); - } - sign.push(s); - return vg.accessor(f); - }); - return function (a, b) { - var i, n, f, x, y; - for (i = 0, n = sort.length; i < n; ++i) { - f = sort[i]; - x = f(a); - y = f(b); - if (x < y) return -1 * sign[i]; - if (x > y) return sign[i]; - } - return 0; - }; - }; - - vg.cmp = function (a, b) { - return a < b ? -1 : a > b ? 1 : 0; - }; - - vg.numcmp = function (a, b) { - return a - b; - }; - - vg.array = function (x) { - return x != null ? (vg.isArray(x) ? x : [x]) : []; - }; - - vg.values = function (x) { - return (vg.isObject(x) && !vg.isArray(x) && x.values) ? x.values : x; - }; - - vg.str = function (x) { - return vg.isArray(x) ? "[" + x.map(vg.str) + "]" - : vg.isObject(x) ? JSON.stringify(x) - : vg.isString(x) ? ("'" + vg_escape_str(x) + "'") : x; - }; - - var escape_str_re = /(^|[^\\])'/g; - - function vg_escape_str(x) { - return x.replace(escape_str_re, "$1\\'"); - } - - vg.keys = function (x) { - var keys = []; - for (var key in x) keys.push(key); - return keys; - }; - - vg.unique = function (data, f, results) { - if (!vg.isArray(data) || data.length == 0) return []; - f = f || vg.identity; - results = results || []; - for (var v, i = 0, n = data.length; i < n; ++i) { - v = f(data[i]); - if (results.indexOf(v) < 0) results.push(v); - } - return results; - }; - - vg.minIndex = function (data, f) { - if (!vg.isArray(data) || data.length == 0) return -1; - f = f || vg.identity; - var idx = 0, min = f(data[0]), v = min; - for (var i = 1, n = data.length; i < n; ++i) { - v = f(data[i]); - if (v < min) { - min = v; - idx = i; - } - } - return idx; - }; - - vg.maxIndex = function (data, f) { - if (!vg.isArray(data) || data.length == 0) return -1; - f = f || vg.identity; - var idx = 0, max = f(data[0]), v = max; - for (var i = 1, n = data.length; i < n; ++i) { - v = f(data[i]); - if (v > max) { - max = v; - idx = i; - } - } - return idx; - }; - - vg.truncate = function (s, length, pos, word, ellipsis) { - var len = s.length; - if (len <= length) return s; - ellipsis = ellipsis || "..."; - var l = Math.max(0, length - ellipsis.length); - - switch (pos) { - case "left": - return ellipsis + (word ? vg_truncateOnWord(s, l, 1) : s.slice(len - l)); - case "middle": - case "center": - var l1 = Math.ceil(l / 2), l2 = Math.floor(l / 2); - return (word ? vg_truncateOnWord(s, l1) : s.slice(0, l1)) + ellipsis - + (word ? vg_truncateOnWord(s, l2, 1) : s.slice(len - l2)); - default: - return (word ? vg_truncateOnWord(s, l) : s.slice(0, l)) + ellipsis; - } - } - - function vg_truncateOnWord(s, len, rev) { - var cnt = 0, tok = s.split(vg_truncate_word_re); - if (rev) { - s = (tok = tok.reverse()) - .filter(function (w) { - cnt += w.length; - return cnt <= len; - }) - .reverse(); - } else { - s = tok.filter(function (w) { - cnt += w.length; - return cnt <= len; - }); - } - return s.length ? s.join("").trim() : tok[0].slice(0, len); - } - - var vg_truncate_word_re = /([\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u2028\u2029\u3000\uFEFF])/; - -// Logging - - function vg_write(msg) { - vg.config.isNode - ? process.stderr.write(msg + "\n") - : console.log(msg); - } - - vg.log = function (msg) { - vg_write("[Vega Log] " + msg); - }; - - vg.error = function (msg) { - msg = "[Vega Err] " + msg; - vg_write(msg); - if (typeof alert !== "undefined") alert(msg); - }; - vg.config = {}; - -// are we running in node.js? -// via timetler.com/2012/10/13/environment-detection-in-javascript/ - vg.config.isNode = typeof exports !== 'undefined' && this.exports !== exports; - -// Allows domain restriction when using data loading via XHR. -// To enable, set it to a list of allowed domains -// e.g., ['wikipedia.org', 'eff.org'] - vg.config.domainWhiteList = false; - -// If true, disable potentially unsafe transforms (filter, formula) -// involving possible JavaScript injection attacks. - vg.config.safeMode = false; - -// base url for loading external data files -// used only for server-side operation - vg.config.baseURL = ""; - -// version and namepsaces for exported svg - vg.config.svgNamespace = - 'version="1.1" xmlns="http://www.w3.org/2000/svg" ' + - 'xmlns:xlink="http://www.w3.org/1999/xlink"'; - -// inset padding for automatic padding calculation - vg.config.autopadInset = 5; - -// extensible scale lookup table -// all d3.scale.* instances also supported - vg.config.scale = { - time: d3.time.scale, - utc: d3.time.scale.utc - }; - -// default rendering settings - vg.config.render = { - lineWidth: 1, - lineCap: "butt", - font: "sans-serif", - fontSize: 11 - }; - -// default axis properties - vg.config.axis = { - orient: "bottom", - ticks: 10, - padding: 3, - axisColor: "#000", - gridColor: "#d8d8d8", - tickColor: "#000", - tickLabelColor: "#000", - axisWidth: 1, - tickWidth: 1, - tickSize: 6, - tickLabelFontSize: 11, - tickLabelFont: "sans-serif", - titleColor: "#000", - titleFont: "sans-serif", - titleFontSize: 11, - titleFontWeight: "bold", - titleOffset: 35 - }; - -// default legend properties - vg.config.legend = { - orient: "right", - offset: 10, - padding: 3, - gradientStrokeColor: "#888", - gradientStrokeWidth: 1, - gradientHeight: 16, - gradientWidth: 100, - labelColor: "#000", - labelFontSize: 10, - labelFont: "sans-serif", - labelAlign: "left", - labelBaseline: "middle", - labelOffset: 8, - symbolShape: "circle", - symbolSize: 50, - symbolColor: "#888", - symbolStrokeWidth: 1, - titleColor: "#000", - titleFont: "sans-serif", - titleFontSize: 11, - titleFontWeight: "bold" - }; - -// default color values - vg.config.color = { - rgb: [128, 128, 128], - lab: [50, 0, 0], - hcl: [0, 0, 50], - hsl: [0, 0, 0.5] - }; - -// default scale ranges - vg.config.range = { - category10: [ - "#1f77b4", - "#ff7f0e", - "#2ca02c", - "#d62728", - "#9467bd", - "#8c564b", - "#e377c2", - "#7f7f7f", - "#bcbd22", - "#17becf" - ], - category20: [ - "#1f77b4", - "#aec7e8", - "#ff7f0e", - "#ffbb78", - "#2ca02c", - "#98df8a", - "#d62728", - "#ff9896", - "#9467bd", - "#c5b0d5", - "#8c564b", - "#c49c94", - "#e377c2", - "#f7b6d2", - "#7f7f7f", - "#c7c7c7", - "#bcbd22", - "#dbdb8d", - "#17becf", - "#9edae5" - ], - shapes: [ - "circle", - "cross", - "diamond", - "square", - "triangle-down", - "triangle-up" - ] - }; - vg.Bounds = (function () { - var bounds = function (b) { - this.clear(); - if (b) this.union(b); - }; - - var prototype = bounds.prototype; - - prototype.clear = function () { - this.x1 = +Number.MAX_VALUE; - this.y1 = +Number.MAX_VALUE; - this.x2 = -Number.MAX_VALUE; - this.y2 = -Number.MAX_VALUE; - return this; - }; - - prototype.set = function (x1, y1, x2, y2) { - this.x1 = x1; - this.y1 = y1; - this.x2 = x2; - this.y2 = y2; - return this; - }; - - prototype.add = function (x, y) { - if (x < this.x1) this.x1 = x; - if (y < this.y1) this.y1 = y; - if (x > this.x2) this.x2 = x; - if (y > this.y2) this.y2 = y; - return this; - }; - - prototype.expand = function (d) { - this.x1 -= d; - this.y1 -= d; - this.x2 += d; - this.y2 += d; - return this; - }; - - prototype.round = function () { - this.x1 = Math.floor(this.x1); - this.y1 = Math.floor(this.y1); - this.x2 = Math.ceil(this.x2); - this.y2 = Math.ceil(this.y2); - return this; - }; - - prototype.translate = function (dx, dy) { - this.x1 += dx; - this.x2 += dx; - this.y1 += dy; - this.y2 += dy; - return this; - }; - - prototype.rotate = function (angle, x, y) { - var cos = Math.cos(angle), - sin = Math.sin(angle), - cx = x - x * cos + y * sin, - cy = y - x * sin - y * cos, - x1 = this.x1, x2 = this.x2, - y1 = this.y1, y2 = this.y2; - - return this.clear() - .add(cos * x1 - sin * y1 + cx, sin * x1 + cos * y1 + cy) - .add(cos * x1 - sin * y2 + cx, sin * x1 + cos * y2 + cy) - .add(cos * x2 - sin * y1 + cx, sin * x2 + cos * y1 + cy) - .add(cos * x2 - sin * y2 + cx, sin * x2 + cos * y2 + cy); - } - - prototype.union = function (b) { - if (b.x1 < this.x1) this.x1 = b.x1; - if (b.y1 < this.y1) this.y1 = b.y1; - if (b.x2 > this.x2) this.x2 = b.x2; - if (b.y2 > this.y2) this.y2 = b.y2; - return this; - }; - - prototype.encloses = function (b) { - return b && ( - this.x1 <= b.x1 && - this.x2 >= b.x2 && - this.y1 <= b.y1 && - this.y2 >= b.y2 - ); - }; - - prototype.intersects = function (b) { - return b && !( - this.x2 < b.x1 || - this.x1 > b.x2 || - this.y2 < b.y1 || - this.y1 > b.y2 - ); - }; - - prototype.contains = function (x, y) { - return !( - x < this.x1 || - x > this.x2 || - y < this.y1 || - y > this.y2 - ); - }; - - prototype.width = function () { - return this.x2 - this.x1; - }; - - prototype.height = function () { - return this.y2 - this.y1; - }; - - return bounds; - })(); - vg.Gradient = (function () { - - function gradient(type) { - this.id = "grad_" + (vg_gradient_id++); - this.type = type || "linear"; - this.stops = []; - this.x1 = 0; - this.x2 = 1; - this.y1 = 0; - this.y2 = 0; - }; - - var prototype = gradient.prototype; - - prototype.stop = function (offset, color) { - this.stops.push({ - offset: offset, - color: color - }); - return this; - }; - - return gradient; - })(); - - var vg_gradient_id = 0; - vg.canvas = {}; - vg.canvas.path = (function () { - - // Path parsing and rendering code taken from fabric.js -- Thanks! - var cmdLength = {m: 2, l: 2, h: 1, v: 1, c: 6, s: 4, q: 4, t: 2, a: 7}, - re = [/([MLHVCSQTAZmlhvcsqtaz])/g, /###/, /(\d)-/g, /\s|,|###/]; - - function parse(path) { - var result = [], - currentPath, - chunks, - parsed; - - // First, break path into command sequence - path = path.slice().replace(re[0], '###$1').split(re[1]).slice(1); - - // Next, parse each command in turn - for (var i = 0, j, chunksParsed, len = path.length; i < len; i++) { - currentPath = path[i]; - chunks = currentPath.slice(1).trim().replace(re[2], '$1###-').split(re[3]); - chunksParsed = [currentPath.charAt(0)]; - - for (var j = 0, jlen = chunks.length; j < jlen; j++) { - parsed = parseFloat(chunks[j]); - if (!isNaN(parsed)) { - chunksParsed.push(parsed); - } - } - - var command = chunksParsed[0].toLowerCase(), - commandLength = cmdLength[command]; - - if (chunksParsed.length - 1 > commandLength) { - for (var k = 1, klen = chunksParsed.length; k < klen; k += commandLength) { - result.push([chunksParsed[0]].concat(chunksParsed.slice(k, k + commandLength))); - } - } - else { - result.push(chunksParsed); - } - } - - return result; - } - - function drawArc(g, x, y, coords, bounds, l, t) { - var rx = coords[0]; - var ry = coords[1]; - var rot = coords[2]; - var large = coords[3]; - var sweep = coords[4]; - var ex = coords[5]; - var ey = coords[6]; - var segs = arcToSegments(ex, ey, rx, ry, large, sweep, rot, x, y); - for (var i = 0; i < segs.length; i++) { - var bez = segmentToBezier.apply(null, segs[i]); - g.bezierCurveTo.apply(g, bez); - bounds.add(bez[0] - l, bez[1] - t); - bounds.add(bez[2] - l, bez[3] - t); - bounds.add(bez[4] - l, bez[5] - t); - } - } - - function boundArc(x, y, coords, bounds) { - var rx = coords[0]; - var ry = coords[1]; - var rot = coords[2]; - var large = coords[3]; - var sweep = coords[4]; - var ex = coords[5]; - var ey = coords[6]; - var segs = arcToSegments(ex, ey, rx, ry, large, sweep, rot, x, y); - for (var i = 0; i < segs.length; i++) { - var bez = segmentToBezier.apply(null, segs[i]); - bounds.add(bez[0], bez[1]); - bounds.add(bez[2], bez[3]); - bounds.add(bez[4], bez[5]); - } - } - - var arcToSegmentsCache = {}, - segmentToBezierCache = {}, - join = Array.prototype.join, - argsStr; - - // Copied from Inkscape svgtopdf, thanks! - function arcToSegments(x, y, rx, ry, large, sweep, rotateX, ox, oy) { - argsStr = join.call(arguments); - if (arcToSegmentsCache[argsStr]) { - return arcToSegmentsCache[argsStr]; - } - - var th = rotateX * (Math.PI / 180); - var sin_th = Math.sin(th); - var cos_th = Math.cos(th); - rx = Math.abs(rx); - ry = Math.abs(ry); - var px = cos_th * (ox - x) * 0.5 + sin_th * (oy - y) * 0.5; - var py = cos_th * (oy - y) * 0.5 - sin_th * (ox - x) * 0.5; - var pl = (px * px) / (rx * rx) + (py * py) / (ry * ry); - if (pl > 1) { - pl = Math.sqrt(pl); - rx *= pl; - ry *= pl; - } - - var a00 = cos_th / rx; - var a01 = sin_th / rx; - var a10 = (-sin_th) / ry; - var a11 = (cos_th) / ry; - var x0 = a00 * ox + a01 * oy; - var y0 = a10 * ox + a11 * oy; - var x1 = a00 * x + a01 * y; - var y1 = a10 * x + a11 * y; - - var d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0); - var sfactor_sq = 1 / d - 0.25; - if (sfactor_sq < 0) sfactor_sq = 0; - var sfactor = Math.sqrt(sfactor_sq); - if (sweep == large) sfactor = -sfactor; - var xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0); - var yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0); - - var th0 = Math.atan2(y0 - yc, x0 - xc); - var th1 = Math.atan2(y1 - yc, x1 - xc); - - var th_arc = th1 - th0; - if (th_arc < 0 && sweep == 1) { - th_arc += 2 * Math.PI; - } else if (th_arc > 0 && sweep == 0) { - th_arc -= 2 * Math.PI; - } - - var segments = Math.ceil(Math.abs(th_arc / (Math.PI * 0.5 + 0.001))); - var result = []; - for (var i = 0; i < segments; i++) { - var th2 = th0 + i * th_arc / segments; - var th3 = th0 + (i + 1) * th_arc / segments; - result[i] = [xc, yc, th2, th3, rx, ry, sin_th, cos_th]; - } - - return (arcToSegmentsCache[argsStr] = result); - } - - function segmentToBezier(cx, cy, th0, th1, rx, ry, sin_th, cos_th) { - argsStr = join.call(arguments); - if (segmentToBezierCache[argsStr]) { - return segmentToBezierCache[argsStr]; - } - - var a00 = cos_th * rx; - var a01 = -sin_th * ry; - var a10 = sin_th * rx; - var a11 = cos_th * ry; - - var cos_th0 = Math.cos(th0); - var sin_th0 = Math.sin(th0); - var cos_th1 = Math.cos(th1); - var sin_th1 = Math.sin(th1); - - var th_half = 0.5 * (th1 - th0); - var sin_th_h2 = Math.sin(th_half * 0.5); - var t = (8 / 3) * sin_th_h2 * sin_th_h2 / Math.sin(th_half); - var x1 = cx + cos_th0 - t * sin_th0; - var y1 = cy + sin_th0 + t * cos_th0; - var x3 = cx + cos_th1; - var y3 = cy + sin_th1; - var x2 = x3 + t * sin_th1; - var y2 = y3 - t * cos_th1; - - return (segmentToBezierCache[argsStr] = [ - a00 * x1 + a01 * y1, a10 * x1 + a11 * y1, - a00 * x2 + a01 * y2, a10 * x2 + a11 * y2, - a00 * x3 + a01 * y3, a10 * x3 + a11 * y3 - ]); - } - - function render(g, path, l, t) { - var current, // current instruction - previous = null, - x = 0, // current x - y = 0, // current y - controlX = 0, // current control point x - controlY = 0, // current control point y - tempX, - tempY, - tempControlX, - tempControlY, - bounds = new vg.Bounds(); - if (l == undefined) l = 0; - if (t == undefined) t = 0; - - g.beginPath(); - - for (var i = 0, len = path.length; i < len; ++i) { - current = path[i]; - - switch (current[0]) { // first letter - - case 'l': // lineto, relative - x += current[1]; - y += current[2]; - g.lineTo(x + l, y + t); - bounds.add(x, y); - break; - - case 'L': // lineto, absolute - x = current[1]; - y = current[2]; - g.lineTo(x + l, y + t); - bounds.add(x, y); - break; - - case 'h': // horizontal lineto, relative - x += current[1]; - g.lineTo(x + l, y + t); - bounds.add(x, y); - break; - - case 'H': // horizontal lineto, absolute - x = current[1]; - g.lineTo(x + l, y + t); - bounds.add(x, y); - break; - - case 'v': // vertical lineto, relative - y += current[1]; - g.lineTo(x + l, y + t); - bounds.add(x, y); - break; - - case 'V': // verical lineto, absolute - y = current[1]; - g.lineTo(x + l, y + t); - bounds.add(x, y); - break; - - case 'm': // moveTo, relative - x += current[1]; - y += current[2]; - g.moveTo(x + l, y + t); - bounds.add(x, y); - break; - - case 'M': // moveTo, absolute - x = current[1]; - y = current[2]; - g.moveTo(x + l, y + t); - bounds.add(x, y); - break; - - case 'c': // bezierCurveTo, relative - tempX = x + current[5]; - tempY = y + current[6]; - controlX = x + current[3]; - controlY = y + current[4]; - g.bezierCurveTo( - x + current[1] + l, // x1 - y + current[2] + t, // y1 - controlX + l, // x2 - controlY + t, // y2 - tempX + l, - tempY + t - ); - bounds.add(x + current[1], y + current[2]); - bounds.add(controlX, controlY); - bounds.add(tempX, tempY); - x = tempX; - y = tempY; - break; - - case 'C': // bezierCurveTo, absolute - x = current[5]; - y = current[6]; - controlX = current[3]; - controlY = current[4]; - g.bezierCurveTo( - current[1] + l, - current[2] + t, - controlX + l, - controlY + t, - x + l, - y + t - ); - bounds.add(current[1], current[2]); - bounds.add(controlX, controlY); - bounds.add(x, y); - break; - - case 's': // shorthand cubic bezierCurveTo, relative - // transform to absolute x,y - tempX = x + current[3]; - tempY = y + current[4]; - // calculate reflection of previous control points - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - g.bezierCurveTo( - controlX + l, - controlY + t, - x + current[1] + l, - y + current[2] + t, - tempX + l, - tempY + t - ); - bounds.add(controlX, controlY); - bounds.add(x + current[1], y + current[2]); - bounds.add(tempX, tempY); - - // set control point to 2nd one of this command - // "... the first control point is assumed to be the reflection of the second control point on the previous command relative to the current point." - controlX = x + current[1]; - controlY = y + current[2]; - - x = tempX; - y = tempY; - break; - - case 'S': // shorthand cubic bezierCurveTo, absolute - tempX = current[3]; - tempY = current[4]; - // calculate reflection of previous control points - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - g.bezierCurveTo( - controlX + l, - controlY + t, - current[1] + l, - current[2] + t, - tempX + l, - tempY + t - ); - x = tempX; - y = tempY; - bounds.add(current[1], current[2]); - bounds.add(controlX, controlY); - bounds.add(tempX, tempY); - // set control point to 2nd one of this command - // "... the first control point is assumed to be the reflection of the second control point on the previous command relative to the current point." - controlX = current[1]; - controlY = current[2]; - - break; - - case 'q': // quadraticCurveTo, relative - // transform to absolute x,y - tempX = x + current[3]; - tempY = y + current[4]; - - controlX = x + current[1]; - controlY = y + current[2]; - - g.quadraticCurveTo( - controlX + l, - controlY + t, - tempX + l, - tempY + t - ); - x = tempX; - y = tempY; - bounds.add(controlX, controlY); - bounds.add(tempX, tempY); - break; - - case 'Q': // quadraticCurveTo, absolute - tempX = current[3]; - tempY = current[4]; - - g.quadraticCurveTo( - current[1] + l, - current[2] + t, - tempX + l, - tempY + t - ); - x = tempX; - y = tempY; - controlX = current[1]; - controlY = current[2]; - bounds.add(controlX, controlY); - bounds.add(tempX, tempY); - break; - - case 't': // shorthand quadraticCurveTo, relative - - // transform to absolute x,y - tempX = x + current[1]; - tempY = y + current[2]; - - if (previous[0].match(/[QqTt]/) === null) { - // If there is no previous command or if the previous command was not a Q, q, T or t, - // assume the control point is coincident with the current point - controlX = x; - controlY = y; - } - else if (previous[0] === 't') { - // calculate reflection of previous control points for t - controlX = 2 * x - tempControlX; - controlY = 2 * y - tempControlY; - } - else if (previous[0] === 'q') { - // calculate reflection of previous control points for q - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - - tempControlX = controlX; - tempControlY = controlY; - - g.quadraticCurveTo( - controlX + l, - controlY + t, - tempX + l, - tempY + t - ); - x = tempX; - y = tempY; - controlX = x + current[1]; - controlY = y + current[2]; - bounds.add(controlX, controlY); - bounds.add(tempX, tempY); - break; - - case 'T': - tempX = current[1]; - tempY = current[2]; - - // calculate reflection of previous control points - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - g.quadraticCurveTo( - controlX + l, - controlY + t, - tempX + l, - tempY + t - ); - x = tempX; - y = tempY; - bounds.add(controlX, controlY); - bounds.add(tempX, tempY); - break; - - case 'a': - drawArc(g, x + l, y + t, [ - current[1], - current[2], - current[3], - current[4], - current[5], - current[6] + x + l, - current[7] + y + t - ], bounds, l, t); - x += current[6]; - y += current[7]; - break; - - case 'A': - drawArc(g, x + l, y + t, [ - current[1], - current[2], - current[3], - current[4], - current[5], - current[6] + l, - current[7] + t - ], bounds, l, t); - x = current[6]; - y = current[7]; - break; - - case 'z': - case 'Z': - g.closePath(); - break; - } - previous = current; - } - return bounds.translate(l, t); - } - - function bounds(path, bounds) { - var current, // current instruction - previous = null, - x = 0, // current x - y = 0, // current y - controlX = 0, // current control point x - controlY = 0, // current control point y - tempX, - tempY, - tempControlX, - tempControlY; - - for (var i = 0, len = path.length; i < len; ++i) { - current = path[i]; - - switch (current[0]) { // first letter - - case 'l': // lineto, relative - x += current[1]; - y += current[2]; - bounds.add(x, y); - break; - - case 'L': // lineto, absolute - x = current[1]; - y = current[2]; - bounds.add(x, y); - break; - - case 'h': // horizontal lineto, relative - x += current[1]; - bounds.add(x, y); - break; - - case 'H': // horizontal lineto, absolute - x = current[1]; - bounds.add(x, y); - break; - - case 'v': // vertical lineto, relative - y += current[1]; - bounds.add(x, y); - break; - - case 'V': // verical lineto, absolute - y = current[1]; - bounds.add(x, y); - break; - - case 'm': // moveTo, relative - x += current[1]; - y += current[2]; - bounds.add(x, y); - break; - - case 'M': // moveTo, absolute - x = current[1]; - y = current[2]; - bounds.add(x, y); - break; - - case 'c': // bezierCurveTo, relative - tempX = x + current[5]; - tempY = y + current[6]; - controlX = x + current[3]; - controlY = y + current[4]; - bounds.add(x + current[1], y + current[2]); - bounds.add(controlX, controlY); - bounds.add(tempX, tempY); - x = tempX; - y = tempY; - break; - - case 'C': // bezierCurveTo, absolute - x = current[5]; - y = current[6]; - controlX = current[3]; - controlY = current[4]; - bounds.add(current[1], current[2]); - bounds.add(controlX, controlY); - bounds.add(x, y); - break; - - case 's': // shorthand cubic bezierCurveTo, relative - // transform to absolute x,y - tempX = x + current[3]; - tempY = y + current[4]; - // calculate reflection of previous control points - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - bounds.add(controlX, controlY); - bounds.add(x + current[1], y + current[2]); - bounds.add(tempX, tempY); - - // set control point to 2nd one of this command - // "... the first control point is assumed to be the reflection of the second control point on the previous command relative to the current point." - controlX = x + current[1]; - controlY = y + current[2]; - - x = tempX; - y = tempY; - break; - - case 'S': // shorthand cubic bezierCurveTo, absolute - tempX = current[3]; - tempY = current[4]; - // calculate reflection of previous control points - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - x = tempX; - y = tempY; - bounds.add(current[1], current[2]); - bounds.add(controlX, controlY); - bounds.add(tempX, tempY); - // set control point to 2nd one of this command - // "... the first control point is assumed to be the reflection of the second control point on the previous command relative to the current point." - controlX = current[1]; - controlY = current[2]; - - break; - - case 'q': // quadraticCurveTo, relative - // transform to absolute x,y - tempX = x + current[3]; - tempY = y + current[4]; - - controlX = x + current[1]; - controlY = y + current[2]; - - x = tempX; - y = tempY; - bounds.add(controlX, controlY); - bounds.add(tempX, tempY); - break; - - case 'Q': // quadraticCurveTo, absolute - tempX = current[3]; - tempY = current[4]; - - x = tempX; - y = tempY; - controlX = current[1]; - controlY = current[2]; - bounds.add(controlX, controlY); - bounds.add(tempX, tempY); - break; - - case 't': // shorthand quadraticCurveTo, relative - - // transform to absolute x,y - tempX = x + current[1]; - tempY = y + current[2]; - - if (previous[0].match(/[QqTt]/) === null) { - // If there is no previous command or if the previous command was not a Q, q, T or t, - // assume the control point is coincident with the current point - controlX = x; - controlY = y; - } - else if (previous[0] === 't') { - // calculate reflection of previous control points for t - controlX = 2 * x - tempControlX; - controlY = 2 * y - tempControlY; - } - else if (previous[0] === 'q') { - // calculate reflection of previous control points for q - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - - tempControlX = controlX; - tempControlY = controlY; - - x = tempX; - y = tempY; - controlX = x + current[1]; - controlY = y + current[2]; - bounds.add(controlX, controlY); - bounds.add(tempX, tempY); - break; - - case 'T': - tempX = current[1]; - tempY = current[2]; - - // calculate reflection of previous control points - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - - x = tempX; - y = tempY; - bounds.add(controlX, controlY); - bounds.add(tempX, tempY); - break; - - case 'a': - boundArc(x, y, [ - current[1], - current[2], - current[3], - current[4], - current[5], - current[6] + x, - current[7] + y - ], bounds); - x += current[6]; - y += current[7]; - break; - - case 'A': - boundArc(x, y, [ - current[1], - current[2], - current[3], - current[4], - current[5], - current[6], - current[7] - ], bounds); - x = current[6]; - y = current[7]; - break; - - case 'z': - case 'Z': - break; - } - previous = current; - } - return bounds; - } - - function area(items) { - var o = items[0]; - var area; - - if (o.orient === "horizontal") { - area = d3.svg.area() - .y(function (d) { - return d.y; - }) - .x0(function (d) { - return d.x; - }) - .x1(function (d) { - return d.x + d.width; - }); - } else { - area = d3.svg.area() - .x(function (d) { - return d.x; - }) - .y1(function (d) { - return d.y; - }) - .y0(function (d) { - return d.y + d.height; - }); - } - - if (o.interpolate) area.interpolate(o.interpolate); - if (o.tension != null) area.tension(o.tension); - return area(items); - } - - function line(items) { - var o = items[0]; - var line = d3.svg.line() - .x(function (d) { - return d.x; - }) - .y(function (d) { - return d.y; - }); - if (o.interpolate) line.interpolate(o.interpolate); - if (o.tension != null) line.tension(o.tension); - return line(items); - } - - return { - parse: parse, - render: render, - bounds: bounds, - area: area, - line: line - }; - - })(); - vg.canvas.marks = (function () { - - var parsePath = vg.canvas.path.parse, - renderPath = vg.canvas.path.render, - halfpi = Math.PI / 2, - sqrt3 = Math.sqrt(3), - tan30 = Math.tan(30 * Math.PI / 180), - tmpBounds = new vg.Bounds(); - - // path generators - - function arcPath(g, o) { - var x = o.x || 0, - y = o.y || 0, - ir = o.innerRadius || 0, - or = o.outerRadius || 0, - sa = (o.startAngle || 0) - Math.PI / 2, - ea = (o.endAngle || 0) - Math.PI / 2; - g.beginPath(); - if (ir === 0) g.moveTo(x, y); - else g.arc(x, y, ir, sa, ea, 0); - g.arc(x, y, or, ea, sa, 1); - g.closePath(); - } - - function areaPath(g, items) { - var o = items[0], - m = o.mark, - p = m.pathCache || (m.pathCache = parsePath(vg.canvas.path.area(items))); - renderPath(g, p); - } - - function linePath(g, items) { - var o = items[0], - m = o.mark, - p = m.pathCache || (m.pathCache = parsePath(vg.canvas.path.line(items))); - renderPath(g, p); - } - - function pathPath(g, o) { - if (o.path == null) return; - var p = o.pathCache || (o.pathCache = parsePath(o.path)); - return renderPath(g, p, o.x, o.y); - } - - function symbolPath(g, o) { - g.beginPath(); - var size = o.size != null ? o.size : 100, - x = o.x, y = o.y, r, t, rx, ry; - - if (o.shape == null || o.shape === "circle") { - r = Math.sqrt(size / Math.PI); - g.arc(x, y, r, 0, 2 * Math.PI, 0); - g.closePath(); - return; - } - - switch (o.shape) { - case "cross": - r = Math.sqrt(size / 5) / 2; - t = 3 * r; - g.moveTo(x - t, y - r); - g.lineTo(x - r, y - r); - g.lineTo(x - r, y - t); - g.lineTo(x + r, y - t); - g.lineTo(x + r, y - r); - g.lineTo(x + t, y - r); - g.lineTo(x + t, y + r); - g.lineTo(x + r, y + r); - g.lineTo(x + r, y + t); - g.lineTo(x - r, y + t); - g.lineTo(x - r, y + r); - g.lineTo(x - t, y + r); - break; - - case "diamond": - ry = Math.sqrt(size / (2 * tan30)); - rx = ry * tan30; - g.moveTo(x, y - ry); - g.lineTo(x + rx, y); - g.lineTo(x, y + ry); - g.lineTo(x - rx, y); - break; - - case "square": - t = Math.sqrt(size); - r = t / 2; - g.rect(x - r, y - r, t, t); - break; - - case "triangle-down": - rx = Math.sqrt(size / sqrt3); - ry = rx * sqrt3 / 2; - g.moveTo(x, y + ry); - g.lineTo(x + rx, y - ry); - g.lineTo(x - rx, y - ry); - break; - - case "triangle-up": - rx = Math.sqrt(size / sqrt3); - ry = rx * sqrt3 / 2; - g.moveTo(x, y - ry); - g.lineTo(x + rx, y + ry); - g.lineTo(x - rx, y + ry); - } - g.closePath(); - } - - function lineStroke(g, items) { - var o = items[0], - lw = o.strokeWidth, - lc = o.strokeCap; - g.lineWidth = lw != null ? lw : vg.config.render.lineWidth; - g.lineCap = lc != null ? lc : vg.config.render.lineCap; - linePath(g, items); - } - - function ruleStroke(g, o) { - var x1 = o.x || 0, - y1 = o.y || 0, - x2 = o.x2 != null ? o.x2 : x1, - y2 = o.y2 != null ? o.y2 : y1, - lw = o.strokeWidth, - lc = o.strokeCap; - - g.lineWidth = lw != null ? lw : vg.config.render.lineWidth; - g.lineCap = lc != null ? lc : vg.config.render.lineCap; - g.beginPath(); - g.moveTo(x1, y1); - g.lineTo(x2, y2); - } - - // drawing functions - - function drawPathOne(path, g, o, items) { - var fill = o.fill, stroke = o.stroke, opac, lc, lw; - - path(g, items); - - opac = o.opacity == null ? 1 : o.opacity; - if (opac == 0 || !fill && !stroke) return; - - if (fill) { - g.globalAlpha = opac * (o.fillOpacity == null ? 1 : o.fillOpacity); - g.fillStyle = color(g, o, fill); - g.fill(); - } - - if (stroke) { - lw = (lw = o.strokeWidth) != null ? lw : vg.config.render.lineWidth; - if (lw > 0) { - g.globalAlpha = opac * (o.strokeOpacity == null ? 1 : o.strokeOpacity); - g.strokeStyle = color(g, o, stroke); - g.lineWidth = lw; - g.lineCap = (lc = o.strokeCap) != null ? lc : vg.config.render.lineCap; - g.vgLineDash(o.strokeDash || null); - g.vgLineDashOffset(o.strokeDashOffset || 0); - g.stroke(); - } - } - } - - function drawPathAll(path, g, scene, bounds) { - var i, len, item; - for (i = 0, len = scene.items.length; i < len; ++i) { - item = scene.items[i]; - if (bounds && !bounds.intersects(item.bounds)) - continue; // bounds check - drawPathOne(path, g, item, item); - } - } - - function drawRect(g, scene, bounds) { - if (!scene.items.length) return; - var items = scene.items, - o, fill, stroke, opac, lc, lw, x, y, w, h; - - for (var i = 0, len = items.length; i < len; ++i) { - o = items[i]; - if (bounds && !bounds.intersects(o.bounds)) - continue; // bounds check - - x = o.x || 0; - y = o.y || 0; - w = o.width || 0; - h = o.height || 0; - - opac = o.opacity == null ? 1 : o.opacity; - if (opac == 0) continue; - - if (fill = o.fill) { - g.globalAlpha = opac * (o.fillOpacity == null ? 1 : o.fillOpacity); - g.fillStyle = color(g, o, fill); - g.fillRect(x, y, w, h); - } - - if (stroke = o.stroke) { - lw = (lw = o.strokeWidth) != null ? lw : vg.config.render.lineWidth; - if (lw > 0) { - g.globalAlpha = opac * (o.strokeOpacity == null ? 1 : o.strokeOpacity); - g.strokeStyle = color(g, o, stroke); - g.lineWidth = lw; - g.lineCap = (lc = o.strokeCap) != null ? lc : vg.config.render.lineCap; - g.vgLineDash(o.strokeDash || null); - g.vgLineDashOffset(o.strokeDashOffset || 0); - g.strokeRect(x, y, w, h); - } - } - } - } - - function drawRule(g, scene, bounds) { - if (!scene.items.length) return; - var items = scene.items, - o, stroke, opac, lc, lw, x1, y1, x2, y2; - - for (var i = 0, len = items.length; i < len; ++i) { - o = items[i]; - if (bounds && !bounds.intersects(o.bounds)) - continue; // bounds check - - x1 = o.x || 0; - y1 = o.y || 0; - x2 = o.x2 != null ? o.x2 : x1; - y2 = o.y2 != null ? o.y2 : y1; - - opac = o.opacity == null ? 1 : o.opacity; - if (opac == 0) continue; - - if (stroke = o.stroke) { - lw = (lw = o.strokeWidth) != null ? lw : vg.config.render.lineWidth; - if (lw > 0) { - g.globalAlpha = opac * (o.strokeOpacity == null ? 1 : o.strokeOpacity); - g.strokeStyle = color(g, o, stroke); - g.lineWidth = lw; - g.lineCap = (lc = o.strokeCap) != null ? lc : vg.config.render.lineCap; - g.vgLineDash(o.strokeDash || null); - g.vgLineDashOffset(o.strokeDashOffset || 0); - g.beginPath(); - g.moveTo(x1, y1); - g.lineTo(x2, y2); - g.stroke(); - } - } - } - } - - function drawImage(g, scene, bounds) { - if (!scene.items.length) return; - var renderer = this, - items = scene.items, o; - - for (var i = 0, len = items.length; i < len; ++i) { - o = items[i]; - if (bounds && !bounds.intersects(o.bounds)) - continue; // bounds check - - if (!(o.image && o.image.url === o.url)) { - o.image = renderer.loadImage(o.url); - o.image.url = o.url; - } - - var x, y, w, h, opac; - w = o.width || (o.image && o.image.width) || 0; - h = o.height || (o.image && o.image.height) || 0; - x = (o.x || 0) - (o.align === "center" - ? w / 2 : (o.align === "right" ? w : 0)); - y = (o.y || 0) - (o.baseline === "middle" - ? h / 2 : (o.baseline === "bottom" ? h : 0)); - - if (o.image.loaded) { - g.globalAlpha = (opac = o.opacity) != null ? opac : 1; - g.drawImage(o.image, x, y, w, h); - } - } - } - - function drawText(g, scene, bounds) { - if (!scene.items.length) return; - var items = scene.items, - o, fill, stroke, opac, lw, x, y, r, t; - - for (var i = 0, len = items.length; i < len; ++i) { - o = items[i]; - if (bounds && !bounds.intersects(o.bounds)) - continue; // bounds check - - g.font = vg.scene.fontString(o); - g.textAlign = o.align || "left"; - g.textBaseline = o.baseline || "alphabetic"; - - opac = o.opacity == null ? 1 : o.opacity; - if (opac == 0) continue; - - x = o.x || 0; - y = o.y || 0; - if (r = o.radius) { - t = (o.theta || 0) - Math.PI / 2; - x += r * Math.cos(t); - y += r * Math.sin(t); - } - - if (o.angle) { - g.save(); - g.translate(x, y); - g.rotate(o.angle * Math.PI / 180); - x = o.dx || 0; - y = o.dy || 0; - } else { - x += (o.dx || 0); - y += (o.dy || 0); - } - - if (fill = o.fill) { - g.globalAlpha = opac * (o.fillOpacity == null ? 1 : o.fillOpacity); - g.fillStyle = color(g, o, fill); - g.fillText(o.text, x, y); - } - - if (stroke = o.stroke) { - lw = (lw = o.strokeWidth) != null ? lw : 1; - if (lw > 0) { - g.globalAlpha = opac * (o.strokeOpacity == null ? 1 : o.strokeOpacity); - g.strokeStyle = color(o, stroke); - g.lineWidth = lw; - g.strokeText(o.text, x, y); - } - } - - if (o.angle) g.restore(); - } - } - - function drawAll(pathFunc) { - return function (g, scene, bounds) { - drawPathAll(pathFunc, g, scene, bounds); - } - } - - function drawOne(pathFunc) { - return function (g, scene, bounds) { - if (!scene.items.length) return; - if (bounds && !bounds.intersects(scene.items[0].bounds)) - return; // bounds check - drawPathOne(pathFunc, g, scene.items[0], scene.items); - } - } - - function drawGroup(g, scene, bounds) { - if (!scene.items.length) return; - var items = scene.items, group, axes, legends, - renderer = this, gx, gy, gb, i, n, j, m; - - drawRect(g, scene, bounds); - - for (i = 0, n = items.length; i < n; ++i) { - group = items[i]; - axes = group.axisItems || []; - legends = group.legendItems || []; - gx = group.x || 0; - gy = group.y || 0; - - // render group contents - g.save(); - g.translate(gx, gy); - if (group.clip) { - g.beginPath(); - g.rect(0, 0, group.width || 0, group.height || 0); - g.clip(); - } - - if (bounds) bounds.translate(-gx, -gy); - - for (j = 0, m = axes.length; j < m; ++j) { - if (axes[j].def.layer === "back") { - renderer.draw(g, axes[j], bounds); - } - } - for (j = 0, m = group.items.length; j < m; ++j) { - renderer.draw(g, group.items[j], bounds); - } - for (j = 0, m = axes.length; j < m; ++j) { - if (axes[j].def.layer !== "back") { - renderer.draw(g, axes[j], bounds); - } - } - for (j = 0, m = legends.length; j < m; ++j) { - renderer.draw(g, legends[j], bounds); - } - - if (bounds) bounds.translate(gx, gy); - g.restore(); - } - } - - function color(g, o, value) { - return (value.id) - ? gradient(g, value, o.bounds) - : value; - } - - function gradient(g, p, b) { - var w = b.width(), - h = b.height(), - x1 = b.x1 + p.x1 * w, - y1 = b.y1 + p.y1 * h, - x2 = b.x1 + p.x2 * w, - y2 = b.y1 + p.y2 * h, - grad = g.createLinearGradient(x1, y1, x2, y2), - stop = p.stops, - i, n; - - for (i = 0, n = stop.length; i < n; ++i) { - grad.addColorStop(stop[i].offset, stop[i].color); - } - return grad; - } - - // hit testing - - function pickGroup(g, scene, x, y, gx, gy) { - if (scene.items.length === 0 || - scene.bounds && !scene.bounds.contains(gx, gy)) { - return false; - } - var items = scene.items, subscene, group, hit, dx, dy, - handler = this, i, j; - - for (i = items.length; --i >= 0;) { - group = items[i]; - dx = group.x || 0; - dy = group.y || 0; - - g.save(); - g.translate(dx, dy); - for (j = group.items.length; --j >= 0;) { - subscene = group.items[j]; - if (subscene.interactive === false) continue; - hit = handler.pick(subscene, x, y, gx - dx, gy - dy); - if (hit) { - g.restore(); - return hit; - } - } - g.restore(); - } - - return scene.interactive - ? pickAll(hitTests.group, g, scene, x, y, gx, gy) - : false; - } - - function pickAll(test, g, scene, x, y, gx, gy) { - if (!scene.items.length) return false; - var o, b, i; - - if (g._ratio !== 1) { - x *= g._ratio; - y *= g._ratio; - } - - for (i = scene.items.length; --i >= 0;) { - o = scene.items[i]; - b = o.bounds; - // first hit test against bounding box - if ((b && !b.contains(gx, gy)) || !b) continue; - // if in bounding box, perform more careful test - if (test(g, o, x, y, gx, gy)) return o; - } - return false; - } - - function pickArea(g, scene, x, y, gx, gy) { - if (!scene.items.length) return false; - var items = scene.items, - o, b, i, di, dd, od, dx, dy; - - b = items[0].bounds; - if (b && !b.contains(gx, gy)) return false; - if (g._ratio !== 1) { - x *= g._ratio; - y *= g._ratio; - } - if (!hitTests.area(g, items, x, y)) return false; - return items[0]; - } - - function pickLine(g, scene, x, y, gx, gy) { - if (!scene.items.length) return false; - var items = scene.items, - o, b, i, di, dd, od, dx, dy; - - b = items[0].bounds; - if (b && !b.contains(gx, gy)) return false; - if (g._ratio !== 1) { - x *= g._ratio; - y *= g._ratio; - } - if (!hitTests.line(g, items, x, y)) return false; - return items[0]; - } - - function pick(test) { - return function (g, scene, x, y, gx, gy) { - return pickAll(test, g, scene, x, y, gx, gy); - }; - } - - function textHit(g, o, x, y, gx, gy) { - if (!o.fontSize) return false; - if (!o.angle) return true; // bounds sufficient if no rotation - - var b = vg.scene.bounds.text(o, tmpBounds, true), - a = -o.angle * Math.PI / 180, - cos = Math.cos(a), - sin = Math.sin(a), - x = o.x, - y = o.y, - px = cos * gx - sin * gy + (x - x * cos + y * sin), - py = sin * gx + cos * gy + (y - x * sin - y * cos); - - return b.contains(px, py); - } - - var hitTests = { - text: textHit, - rect: function (g, o, x, y) { - return true; - }, // bounds test is sufficient - image: function (g, o, x, y) { - return true; - }, // bounds test is sufficient - group: function (g, o, x, y) { - return o.fill || o.stroke; - }, - rule: function (g, o, x, y) { - if (!g.isPointInStroke) return false; - ruleStroke(g, o); - return g.isPointInStroke(x, y); - }, - line: function (g, s, x, y) { - if (!g.isPointInStroke) return false; - lineStroke(g, s); - return g.isPointInStroke(x, y); - }, - arc: function (g, o, x, y) { - arcPath(g, o); - return g.isPointInPath(x, y); - }, - area: function (g, s, x, y) { - areaPath(g, s); - return g.isPointInPath(x, y); - }, - path: function (g, o, x, y) { - pathPath(g, o); - return g.isPointInPath(x, y); - }, - symbol: function (g, o, x, y) { - symbolPath(g, o); - return g.isPointInPath(x, y); - } - }; - - return { - draw: { - group: drawGroup, - area: drawOne(areaPath), - line: drawOne(linePath), - arc: drawAll(arcPath), - path: drawAll(pathPath), - symbol: drawAll(symbolPath), - rect: drawRect, - rule: drawRule, - text: drawText, - image: drawImage, - drawOne: drawOne, // expose for extensibility - drawAll: drawAll // expose for extensibility - }, - pick: { - group: pickGroup, - area: pickArea, - line: pickLine, - arc: pick(hitTests.arc), - path: pick(hitTests.path), - symbol: pick(hitTests.symbol), - rect: pick(hitTests.rect), - rule: pick(hitTests.rule), - text: pick(hitTests.text), - image: pick(hitTests.image), - pickAll: pickAll // expose for extensibility - } - }; - - })(); - vg.canvas.Renderer = (function () { - var renderer = function () { - this._ctx = null; - this._el = null; - this._imgload = 0; - }; - - var prototype = renderer.prototype; - - prototype.initialize = function (el, width, height, pad) { - this._el = el; - - if (!el) return this; // early exit if no DOM element - - // select canvas element - var canvas = d3.select(el) - .selectAll("canvas.marks") - .data([1]); - - // create new canvas element if needed - canvas.enter() - .append("canvas") - .attr("class", "marks"); - - // remove extraneous canvas if needed - canvas.exit().remove(); - - return this.resize(width, height, pad); - }; - - prototype.resize = function (width, height, pad) { - this._width = width; - this._height = height; - this._padding = pad; - - if (this._el) { - var canvas = d3.select(this._el).select("canvas.marks"); - - // initialize canvas attributes - canvas - .attr("width", width + pad.left + pad.right) - .attr("height", height + pad.top + pad.bottom); - - // get the canvas graphics context - var s; - this._ctx = canvas.node().getContext("2d"); - this._ctx._ratio = (s = scaleCanvas(canvas.node(), this._ctx) || 1); - this._ctx.setTransform(s, 0, 0, s, s * pad.left, s * pad.top); - } - - initializeLineDash(this._ctx); - return this; - }; - - function scaleCanvas(canvas, ctx) { - // get canvas pixel data - var devicePixelRatio = window.devicePixelRatio || 1, - backingStoreRatio = ( - ctx.webkitBackingStorePixelRatio || - ctx.mozBackingStorePixelRatio || - ctx.msBackingStorePixelRatio || - ctx.oBackingStorePixelRatio || - ctx.backingStorePixelRatio) || 1, - ratio = devicePixelRatio / backingStoreRatio; - - if (devicePixelRatio !== backingStoreRatio) { - var w = canvas.width, h = canvas.height; - // set actual and visible canvas size - canvas.setAttribute("width", w * ratio); - canvas.setAttribute("height", h * ratio); - canvas.style.width = w + 'px'; - canvas.style.height = h + 'px'; - } - return ratio; - } - - function initializeLineDash(ctx) { - if (ctx.vgLineDash) return; // already set - - var NODASH = []; - if (ctx.setLineDash) { - ctx.vgLineDash = function (dash) { - this.setLineDash(dash || NODASH); - }; - ctx.vgLineDashOffset = function (off) { - this.lineDashOffset = off; - }; - } else if (ctx.webkitLineDash !== undefined) { - ctx.vgLineDash = function (dash) { - this.webkitLineDash = dash || NODASH; - }; - ctx.vgLineDashOffset = function (off) { - this.webkitLineDashOffset = off; - }; - } else if (ctx.mozDash !== undefined) { - ctx.vgLineDash = function (dash) { - this.mozDash = dash; - }; - ctx.vgLineDashOffset = function (off) { /* unsupported */ - }; - } else { - ctx.vgLineDash = function (dash) { /* unsupported */ - }; - ctx.vgLineDashOffset = function (off) { /* unsupported */ - }; - } - } - - prototype.context = function (ctx) { - if (ctx) { - this._ctx = ctx; - return this; - } - else return this._ctx; - }; - - prototype.element = function () { - return this._el; - }; - - prototype.pendingImages = function () { - return this._imgload; - }; - - function translatedBounds(item, bounds) { - var b = new vg.Bounds(bounds); - while ((item = item.mark.group) != null) { - b.translate(item.x || 0, item.y || 0); - } - return b; - } - - function getBounds(items) { - return !items ? null : - vg.array(items).reduce(function (b, item) { - return b.union(translatedBounds(item, item.bounds)) - .union(translatedBounds(item, item['bounds:prev'])); - }, new vg.Bounds()); - } - - function setBounds(g, bounds) { - var bbox = null; - if (bounds) { - bbox = (new vg.Bounds(bounds)).round(); - g.beginPath(); - g.rect(bbox.x1, bbox.y1, bbox.width(), bbox.height()); - g.clip(); - } - return bbox; - } - - prototype.render = function (scene, items) { - var g = this._ctx, - pad = this._padding, - w = this._width + pad.left + pad.right, - h = this._height + pad.top + pad.bottom, - bb = null, bb2; - - // setup - this._scene = scene; - g.save(); - bb = setBounds(g, getBounds(items)); - g.clearRect(-pad.left, -pad.top, w, h); - - // render - this.draw(g, scene, bb); - - // render again to handle possible bounds change - if (items) { - g.restore(); - g.save(); - bb2 = setBounds(g, getBounds(items)); - if (!bb.encloses(bb2)) { - g.clearRect(-pad.left, -pad.top, w, h); - this.draw(g, scene, bb2); - } - } - - // takedown - g.restore(); - this._scene = null; - }; - - prototype.draw = function (ctx, scene, bounds) { - var marktype = scene.marktype, - renderer = vg.canvas.marks.draw[marktype]; - renderer.call(this, ctx, scene, bounds); - }; - - prototype.renderAsync = function (scene) { - // TODO make safe for multiple scene rendering? - var renderer = this; - if (renderer._async_id) { - clearTimeout(renderer._async_id); - } - renderer._async_id = setTimeout(function () { - renderer.render(scene); - delete renderer._async_id; - }, 50); - }; - - prototype.loadImage = function (uri) { - var renderer = this, - scene = renderer._scene, - image = null, url; - - renderer._imgload += 1; - if (vg.config.isNode) { - image = new (require("canvas").Image)(); - vg.data.load(uri, function (err, data) { - if (err) { - vg.error(err); - return; - } - image.src = data; - image.loaded = true; - renderer._imgload -= 1; - }); - } else { - image = new Image(); - url = vg.config.baseURL + uri; - image.onload = function () { - vg.log("LOAD IMAGE: " + url); - image.loaded = true; - renderer._imgload -= 1; - renderer.renderAsync(scene); - }; - image.src = url; - } - - return image; - }; - - return renderer; - })(); - vg.canvas.Handler = (function () { - var handler = function (el, model) { - this._active = null; - this._handlers = {}; - if (el) this.initialize(el); - if (model) this.model(model); - }; - - var prototype = handler.prototype; - - prototype.initialize = function (el, pad, obj) { - this._el = d3.select(el).node(); - this._canvas = d3.select(el).select("canvas.marks").node(); - this._padding = pad; - this._obj = obj || null; - - // add event listeners - var canvas = this._canvas, that = this; - events.forEach(function (type) { - canvas.addEventListener(type, function (evt) { - prototype[type].call(that, evt); - }); - }); - - return this; - }; - - prototype.padding = function (pad) { - this._padding = pad; - return this; - }; - - prototype.model = function (model) { - if (!arguments.length) return this._model; - this._model = model; - return this; - }; - - prototype.handlers = function () { - var h = this._handlers; - return vg.keys(h).reduce(function (a, k) { - return h[k].reduce(function (a, x) { - return (a.push(x), a); - }, a); - }, []); - }; - - // setup events - var events = [ - "mousedown", - "mouseup", - "click", - "dblclick", - "wheel", - "keydown", - "keypress", - "keyup", - "mousewheel" - ]; - events.forEach(function (type) { - prototype[type] = function (evt) { - this.fire(type, evt); - }; - }); - events.push("mousemove"); - events.push("mouseout"); - - function eventName(name) { - var i = name.indexOf("."); - return i < 0 ? name : name.slice(0, i); - } - - prototype.mousemove = function (evt) { - var pad = this._padding, - b = evt.target.getBoundingClientRect(), - x = evt.clientX - b.left, - y = evt.clientY - b.top, - a = this._active, - p = this.pick(this._model.scene(), x, y, x - pad.left, y - pad.top); - - if (p === a) { - this.fire("mousemove", evt); - return; - } else if (a) { - this.fire("mouseout", evt); - } - this._active = p; - if (p) { - this.fire("mouseover", evt); - } - }; - - prototype.mouseout = function (evt) { - if (this._active) { - this.fire("mouseout", evt); - } - this._active = null; - }; - - // to keep firefox happy - prototype.DOMMouseScroll = function (evt) { - this.fire("mousewheel", evt); - }; - - // fire an event - prototype.fire = function (type, evt) { - var a = this._active, - h = this._handlers[type]; - if (a && h) { - for (var i = 0, len = h.length; i < len; ++i) { - h[i].handler.call(this._obj, evt, a); - } - } - }; - - // add an event handler - prototype.on = function (type, handler) { - var name = eventName(type), - h = this._handlers; - h = h[name] || (h[name] = []); - h.push({ - type: type, - handler: handler - }); - return this; - }; - - // remove an event handler - prototype.off = function (type, handler) { - var name = eventName(type), - h = this._handlers[name]; - if (!h) return; - for (var i = h.length; --i >= 0;) { - if (h[i].type !== type) continue; - if (!handler || h[i].handler === handler) h.splice(i, 1); - } - return this; - }; - - // retrieve the current canvas context - prototype.context = function () { - return this._canvas.getContext("2d"); - }; - - // find the scenegraph item at the current mouse position
<TRUNCATED>
