+'use strict';
+
var DygraphsLocalTester = function() {
this.tc = null; // Selected test case
this.name = null;
}
throw 'Warnings not permitted: ' + msg;
}
- Dygraph.prototype.warn = Dygraph.warn;
};
DygraphsLocalTester.prototype.processVariables = function() {
var a = document.createElement('a');
a.href = href;
a.id = id;
- a.innerText = text;
+ a.textContent = text;
return a;
}
DygraphsLocalTester.prototype.createResultsDiv = function(summary, durationms) {
- div = document.createElement('div');
+ var div = document.createElement('div');
div.id='results';
var body = document.getElementsByTagName('body')[0];
var tdResult = document.createElement('td');
tdResult.setAttribute('class', 'outcome');
- tdResult.innerText = result.result ? 'pass' : 'fail';
+ tdResult.textContent = result.result ? 'pass' : 'fail';
tr.appendChild(tdResult);
var tdName = document.createElement('td');
tr.appendChild(tdName);
var tdDuration = document.createElement('td');
- tdDuration.innerText = result.duration + ' ms';
+ tdDuration.textContent = result.duration + ' ms';
tr.appendChild(tdDuration);
if (result.e) {
var createLink = function(parent, title, url) {
var li = createAttached('li', parent);
var a = createAttached('a', li);
- a.innerHTML = title;
+ a.textContent = title;
a.href = url;
return li;
}
if (this.tc == null) {
- description.innerHTML = 'Test cases:';
+ description.textContent = 'Test cases:';
var testCases = getAllTestCases();
createLink(list, '(run all tests)', document.URL + '?command=runAllTests');
for (var idx in testCases) {
createLink(list, entryName, document.URL + '?testCaseName=' + entryName);
}
} else {
- description.innerHTML = 'Tests for ' + name;
+ description.textContent = 'Tests for ' + name;
var names = this.tc.getTestNames();
createLink(list, 'Run All Tests', document.URL + '&command=runAllTests');
for (var idx in names) {
* type, screenX, screenY, clientX, clientY.
*/
DygraphOps.createOptsForPoint_ = function(g, type, x, y) {
- var pageX = Dygraph.findPosX(g.canvas_) + x;
- var pageY = Dygraph.findPosY(g.canvas_) + y;
+ var pos = Dygraph.findPos(g.canvas_);
+ var pageX = pos.x + x;
+ var pageY = pos.y + y;
return {
type : type,
return FakeXMLHttpRequest;
};
+/**
+ * Format a date as 2000/01/23
+ * @param {number} date_ms Millis since epoch.
+ * @return {string} The date formatted as YYYY-MM-DD.
+ */
+Util.formatDate = function(date_ms) {
+ var zeropad = function(x) { if (x < 10) return "0" + x; else return "" + x; };
+ var d = new Date(date_ms);
+
+ // Get the year:
+ var year = "" + d.getFullYear();
+ // Get a 0 padded month string
+ var month = zeropad(d.getMonth() + 1); //months are 0-offset, sigh
+ // Get a 0 padded day string
+ var day = zeropad(d.getDate());
+
+ return year + "/" + month + "/" + day;
+};
assertEquals('number', typeof(granularity));
assertEquals('function', typeof(opts));
assertEquals('[Dygraph graph]', dg.toString());
- return 'x' + x.strftime('%Y/%m/%d');
+ return 'x' + Util.fomratDate(x);
},
yAxisLabelFormatter: function(y, granularity, opts, dg) {
assertEquals('number', typeof(y));
assertEquals('function', typeof(opts));
assertEquals('string', typeof(series_name));
assertEquals('[Dygraph graph]', dg.toString());
- return 'x' + new Date(x).strftime('%Y/%m/%d');
+ return 'x' + Util.formatDate(x);
},
yValueFormatter: function(y, opts, series_name, dg) {
assertEquals('number', typeof(y));
assertEquals('number', typeof(granularity));
assertEquals('function', typeof(opts));
assertEquals('[Dygraph graph]', dg.toString());
- return 'x' + x.strftime('%Y/%m/%d');
+ return 'x' + Util.formatDate(x);
}
},
y : {
assertEquals('function', typeof(opts));
assertEquals('string', typeof(series_name));
assertEquals('[Dygraph graph]', dg.toString());
- return 'x' + new Date(x).strftime('%Y/%m/%d');
+ return 'x' + Util.formatDate(x);
}
},
y : {
};
var secondCallback = function(g, seriesName, ctx, canvasx, canvasy, color, radius) {
results.y2[seriesName] = 1;
- Dygraph.Circles.TRIANGLE(g, seriesName, ctx, canvasx, canvasy, color, radius);
+ Dygraph.Circles.DEFAULT(g, seriesName, ctx, canvasx, canvasy, color, radius);
};
g = new Dygraph(
};
var secondCallback = function(g, seriesName, ctx, canvasx, canvasy, color, radius) {
results.y2[seriesName] = 1;
- Dygraph.Circles.TRIANGLE(g, seriesName, ctx, canvasx, canvasy, color, radius);
+ Dygraph.Circles.DEFAULT(g, seriesName, ctx, canvasx, canvasy, color, radius);
};
g = new Dygraph(
assertNull(iter.next());
};
+UtilsTestCase.prototype.testToRGB = function() {
+ assertEquals({r: 255, g: 200, b: 150}, Dygraph.toRGB_('rgb(255,200,150)'));
+ assertEquals({r: 255, g: 200, b: 150}, Dygraph.toRGB_('#FFC896'));
+ assertEquals({r: 255, g: 0, b: 0}, Dygraph.toRGB_('red'));
+};
+
/*
UtilsTestCase.prototype.testDateSet = function() {
var base = new Date(1383455100000);
*/
/*jshint globalstrict: true */
-/*global Dygraph:false,RGBColorParser:false */
+/*global Dygraph:false */
"use strict";
var fillGraph = g.getBooleanOption("fillGraph", setName);
if (fillGraph) {
- g.warn("Can't use fillGraph option with error bars");
+ Dygraph.warn("Can't use fillGraph option with error bars");
}
var ctx = e.drawingContext;
var prevY = NaN;
var prevYs = [-1, -1];
// should be same color as the lines but only 15% opaque.
- var rgb = new RGBColorParser(color);
+ var rgb = Dygraph.toRGB_(color);
var err_color =
'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')';
ctx.fillStyle = err_color;
var prevYs = [-1, -1];
var newYs;
// should be same color as the lines but only 15% opaque.
- var rgb = new RGBColorParser(color);
+ var rgb = Dygraph.toRGB_(color);
var err_color =
'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')';
ctx.fillStyle = err_color;
// This list needs to be kept in sync w/ the one in generate-combined.sh
// and the one in jsTestDriver.conf.
var source_files = [
- "strftime/strftime-min.js",
- "rgbcolor/rgbcolor.js",
"stacktrace.js",
"dashed-canvas.js",
"dygraph-options.js",
for (var i = 0; i < ann.length; i++) {
var a = {};
if (!ann[i].xval && ann[i].x === undefined) {
- this.dygraph_.error("Annotations must have an 'x' property");
+ Dygraph.error("Annotations must have an 'x' property");
return;
}
if (ann[i].icon &&
!(ann[i].hasOwnProperty('width') &&
ann[i].hasOwnProperty('height'))) {
- this.dygraph_.error("Must set width and height when setting " +
- "annotation.icon property");
+ Dygraph.error("Must set width and height when setting " +
+ "annotation.icon property");
return;
}
Dygraph.update(a, ann[i]);
axis.ylogrange = Dygraph.log10(axis.maxyval) - Dygraph.log10(axis.minyval);
axis.ylogscale = (axis.ylogrange !== 0 ? 1.0 / axis.ylogrange : 1.0);
if (!isFinite(axis.ylogrange) || isNaN(axis.ylogrange)) {
- axis.g.error('axis ' + i + ' of graph at ' + axis.g +
- ' can\'t be displayed in log scale for range [' +
- axis.minyval + ' - ' + axis.maxyval + ']');
+ Dygraph.error('axis ' + i + ' of graph at ' + axis.g +
+ ' can\'t be displayed in log scale for range [' +
+ axis.minyval + ' - ' + axis.maxyval + ']');
}
}
}
Dygraph.WARNING = 3;
Dygraph.ERROR = 3;
+// <REMOVE_FOR_COMBINED>
// Set this to log stack traces on warnings, etc.
// This requires stacktrace.js, which is up to you to provide.
// A copy can be found in the dygraphs repo, or at
// https://github.com/eriwen/javascript-stacktrace
Dygraph.LOG_STACK_TRACES = false;
+// </REMOVE_FOR_COMBINED>
/** A dotted line stroke pattern. */
Dygraph.DOTTED_LINE = [2, 2];
* @private
*/
Dygraph.log = function(severity, message) {
+ // <REMOVE_FOR_COMBINED>
var st;
if (typeof(printStackTrace) != 'undefined') {
try {
// Oh well, it was worth a shot!
}
}
+ // </REMOVE_FOR_COMBINED>
if (typeof(window.console) != 'undefined') {
// In older versions of Firefox, only console.log is defined.
}
}
+ // <REMOVE_FOR_COMBINED>
if (Dygraph.LOG_STACK_TRACES) {
window.console.log(st.join('\n'));
}
+ // </REMOVE_FOR_COMBINED>
};
/**
Dygraph.info = function(message) {
Dygraph.log(Dygraph.INFO, message);
};
-/**
- * @param {string} message
- * @private
- */
-Dygraph.prototype.info = Dygraph.info;
/**
* @param {string} message
Dygraph.warn = function(message) {
Dygraph.log(Dygraph.WARNING, message);
};
-/**
- * @param {string} message
- * @private
- */
-Dygraph.prototype.warn = Dygraph.warn;
/**
* @param {string} message
Dygraph.error = function(message) {
Dygraph.log(Dygraph.ERROR, message);
};
-/**
- * @param {string} message
- * @private
- */
-Dygraph.prototype.error = Dygraph.error;
/**
* Return the 2d context for a dygraph canvas.
// ... and modifications to support scrolling divs.
/**
- * Find the x-coordinate of the supplied object relative to the left side
- * of the page.
+ * Find the coordinates of an object relative to the top left of the page.
+ *
* TODO(danvk): change obj type from Node -> !Node
* @param {Node} obj
- * @return {number}
+ * @return {{x:number,y:number}}
* @private
*/
-Dygraph.findPosX = function(obj) {
- var curleft = 0;
- if(obj.offsetParent) {
+Dygraph.findPos = function(obj) {
+ var curleft = 0, curtop = 0;
+ if (obj.offsetParent) {
var copyObj = obj;
- while(1) {
+ while (1) {
// NOTE: the if statement here is for IE8.
- var borderLeft = "0";
+ var borderLeft = "0", borderTop = "0";
if (window.getComputedStyle) {
- borderLeft = window.getComputedStyle(copyObj, null).borderLeft || "0";
+ var computedStyle = window.getComputedStyle(copyObj, null);
+ borderLeft = computedStyle.borderLeft || "0";
+ borderTop = computedStyle.borderTop || "0";
}
curleft += parseInt(borderLeft, 10) ;
- curleft += copyObj.offsetLeft;
- if(!copyObj.offsetParent) {
- break;
- }
- copyObj = copyObj.offsetParent;
- }
- } else if(obj.x) {
- curleft += obj.x;
- }
- // This handles the case where the object is inside a scrolled div.
- while(obj && obj != document.body) {
- curleft -= obj.scrollLeft;
- obj = obj.parentNode;
- }
- return curleft;
-};
-
-/**
- * Find the y-coordinate of the supplied object relative to the top of the
- * page.
- * TODO(danvk): change obj type from Node -> !Node
- * TODO(danvk): consolidate with findPosX and return an {x, y} object.
- * @param {Node} obj
- * @return {number}
- * @private
- */
-Dygraph.findPosY = function(obj) {
- var curtop = 0;
- if(obj.offsetParent) {
- var copyObj = obj;
- while(1) {
- // NOTE: the if statement here is for IE8.
- var borderTop = "0";
- if (window.getComputedStyle) {
- borderTop = window.getComputedStyle(copyObj, null).borderTop || "0";
- }
curtop += parseInt(borderTop, 10) ;
+ curleft += copyObj.offsetLeft;
curtop += copyObj.offsetTop;
- if(!copyObj.offsetParent) {
+ if (!copyObj.offsetParent) {
break;
}
copyObj = copyObj.offsetParent;
}
- } else if(obj.y) {
- curtop += obj.y;
+ } else {
+ // TODO(danvk): why would obj ever have these properties?
+ if (obj.x) curleft += obj.x;
+ if (obj.y) curtop += obj.y;
}
+
// This handles the case where the object is inside a scrolled div.
- while(obj && obj != document.body) {
+ while (obj && obj != document.body) {
+ curleft -= obj.scrollLeft;
curtop -= obj.scrollTop;
obj = obj.parentNode;
}
- return curtop;
+ return {x: curleft, y: curtop};
};
/**
};
/**
+ * Convert a JS date (millis since epoch) to YYYY/MM/DD
+ * @param {number} date The JavaScript date (ms since epoch)
+ * @return {string} A date of the form "YYYY/MM/DD"
+ * @private
+ */
+Dygraph.dateString_ = function(date) {
+ var zeropad = Dygraph.zeropad;
+ var d = new Date(date);
+
+ // Get the year:
+ var year = "" + d.getFullYear();
+ // Get a 0 padded month string
+ var month = zeropad(d.getMonth() + 1); //months are 0-offset, sigh
+ // Get a 0 padded day string
+ var day = zeropad(d.getDate());
+
+ var ret = "";
+ var frac = d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds();
+ if (frac) ret = " " + Dygraph.hmsString_(date);
+
+ return year + "/" + month + "/" + day + ret;
+};
+
+/**
* Round a number to the specified number of digits past the decimal point.
* @param {number} num The number to round
* @param {number} places The number of decimals to which to round
return requiresNewPoints;
};
-/**
- * Compares two arrays to see if they are equal. If either parameter is not an
- * array it will return false. Does a shallow compare
- * Dygraph.compareArrays([[1,2], [3, 4]], [[1,2], [3,4]]) === false.
- * @param {!Array.<T>} array1 first array
- * @param {!Array.<T>} array2 second array
- * @return {boolean} True if both parameters are arrays, and contents are equal.
- * @template T
- */
-Dygraph.compareArrays = function(array1, array2) {
- if (!Dygraph.isArrayLike(array1) || !Dygraph.isArrayLike(array2)) {
- return false;
- }
- if (array1.length !== array2.length) {
- return false;
- }
- for (var i = 0; i < array1.length; i++) {
- if (array1[i] !== array2[i]) {
- return false;
- }
- }
- return true;
-};
-
-/**
- * @param {!CanvasRenderingContext2D} ctx the canvas context
- * @param {number} sides the number of sides in the shape.
- * @param {number} radius the radius of the image.
- * @param {number} cx center x coordate
- * @param {number} cy center y coordinate
- * @param {number=} rotationRadians the shift of the initial angle, in radians.
- * @param {number=} delta the angle shift for each line. If missing, creates a
- * regular polygon.
- * @private
- */
-Dygraph.regularShape_ = function(
- ctx, sides, radius, cx, cy, rotationRadians, delta) {
- rotationRadians = rotationRadians || 0;
- delta = delta || Math.PI * 2 / sides;
-
- ctx.beginPath();
- var initialAngle = rotationRadians;
- var angle = initialAngle;
-
- var computeCoordinates = function() {
- var x = cx + (Math.sin(angle) * radius);
- var y = cy + (-Math.cos(angle) * radius);
- return [x, y];
- };
-
- var initialCoordinates = computeCoordinates();
- var x = initialCoordinates[0];
- var y = initialCoordinates[1];
- ctx.moveTo(x, y);
-
- for (var idx = 0; idx < sides; idx++) {
- angle = (idx == sides - 1) ? initialAngle : (angle + delta);
- var coords = computeCoordinates();
- ctx.lineTo(coords[0], coords[1]);
- }
- ctx.fill();
- ctx.stroke();
-};
-
-/**
- * TODO(danvk): be more specific on the return type.
- * @param {number} sides
- * @param {number=} rotationRadians
- * @param {number=} delta
- * @return {Function}
- * @private
- */
-Dygraph.shapeFunction_ = function(sides, rotationRadians, delta) {
- return function(g, name, ctx, cx, cy, color, radius) {
- ctx.strokeStyle = color;
- ctx.fillStyle = "white";
- Dygraph.regularShape_(ctx, sides, radius, cx, cy, rotationRadians, delta);
- };
-};
-
Dygraph.Circles = {
DEFAULT : function(g, name, ctx, canvasx, canvasy, color, radius) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(canvasx, canvasy, radius, 0, 2 * Math.PI, false);
ctx.fill();
- },
- TRIANGLE : Dygraph.shapeFunction_(3),
- SQUARE : Dygraph.shapeFunction_(4, Math.PI / 4),
- DIAMOND : Dygraph.shapeFunction_(4),
- PENTAGON : Dygraph.shapeFunction_(5),
- HEXAGON : Dygraph.shapeFunction_(6),
- CIRCLE : function(g, name, ctx, cx, cy, color, radius) {
- ctx.beginPath();
- ctx.strokeStyle = color;
- ctx.fillStyle = "white";
- ctx.arc(cx, cy, radius, 0, 2 * Math.PI, false);
- ctx.fill();
- ctx.stroke();
- },
- STAR : Dygraph.shapeFunction_(5, 0, 4 * Math.PI / 5),
- PLUS : function(g, name, ctx, cx, cy, color, radius) {
- ctx.strokeStyle = color;
-
- ctx.beginPath();
- ctx.moveTo(cx + radius, cy);
- ctx.lineTo(cx - radius, cy);
- ctx.closePath();
- ctx.stroke();
-
- ctx.beginPath();
- ctx.moveTo(cx, cy + radius);
- ctx.lineTo(cx, cy - radius);
- ctx.closePath();
- ctx.stroke();
- },
- EX : function(g, name, ctx, cx, cy, color, radius) {
- ctx.strokeStyle = color;
-
- ctx.beginPath();
- ctx.moveTo(cx + radius, cy + radius);
- ctx.lineTo(cx - radius, cy - radius);
- ctx.closePath();
- ctx.stroke();
-
- ctx.beginPath();
- ctx.moveTo(cx + radius, cy - radius);
- ctx.lineTo(cx - radius, cy + radius);
- ctx.closePath();
- ctx.stroke();
}
+ // For more shapes, include extras/stars.js
};
/**
}
}
};
+
+/**
+ * Converts any valid CSS color (hex, rgb(), named color) to an RGB tuple.
+ *
+ * @param {!string} color_str Any valid CSS color string.
+ * @return {{r:number,g:number,b:number}} Parsed RGB tuple.
+ * @private
+ */
+Dygraph.toRGB_ = function(color_str) {
+ // TODO(danvk): cache color parses to avoid repeated DOM manipulation.
+ var div = document.createElement('div');
+ div.style.backgroundColor = color_str;
+ div.style.visibility = 'hidden';
+ document.body.appendChild(div);
+ var rgb_str = window.getComputedStyle(div).backgroundColor;
+ document.body.removeChild(div);
+ var bits = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(rgb_str);
+ return {
+ r: parseInt(bits[1], 10),
+ g: parseInt(bits[2], 10),
+ b: parseInt(bits[3], 10)
+ };
+};
// Old versions of dygraphs took in the series labels as a constructor
// parameter. This doesn't make sense anymore, but it's easy to continue
// to support this usage.
- this.warn("Using deprecated four-argument dygraph constructor");
+ Dygraph.warn("Using deprecated four-argument dygraph constructor");
this.__old_init__(div, data, opts, opt_fourth_param);
} else {
this.__init__(div, data, opts);
Dygraph.prototype.attr_ = function(name, seriesName) {
// <REMOVE_FOR_COMBINED>
if (typeof(Dygraph.OPTIONS_REFERENCE) === 'undefined') {
- this.error('Must include options reference JS for testing');
+ Dygraph.error('Must include options reference JS for testing');
} else if (!Dygraph.OPTIONS_REFERENCE.hasOwnProperty(name)) {
- this.error('Dygraphs is using property ' + name + ', which has no entry ' +
- 'in the Dygraphs.OPTIONS_REFERENCE listing.');
+ Dygraph.error('Dygraphs is using property ' + name + ', which has no ' +
+ 'entry in the Dygraphs.OPTIONS_REFERENCE listing.');
// Only log this error once.
Dygraph.OPTIONS_REFERENCE[name] = true;
}
event.cancelBubble = true;
}
- contextB.px = Dygraph.findPosX(g.canvas_);
- contextB.py = Dygraph.findPosY(g.canvas_);
+ var canvasPos = DygraphafindPos(g.canvas_);
+ contextB.px = canvasPos.x;
+ contextB.py = canvasPos.y;
contextB.dragStartX = g.dragGetX_(event, contextB);
contextB.dragStartY = g.dragGetY_(event, contextB);
contextB.cancelNextDblclick = false;
if (event.offsetX && event.offsetY) {
return [ event.offsetX, event.offsetY ];
} else {
- var canvasx = Dygraph.pageX(event) - Dygraph.findPosX(this.mouseEventElement_);
- var canvasy = Dygraph.pageY(event) - Dygraph.findPosY(this.mouseEventElement_);
+ var eventElementPos = Dygraph.findPosX(this.mouseEventElement_)
+ var canvasx = Dygraph.pageX(event) - eventElementPos.x;
+ var canvasy = Dygraph.pageY(event) - eventElementPos.y;
return [canvasx, canvasy];
}
};
if (opt_line !== null && opt_line_no !== null) {
msg += " on line " + (1+opt_line_no) + " ('" + opt_line + "') of CSV.";
}
- this.error(msg);
+ Dygraph.error(msg);
return null;
};
// TODO(danvk): figure out an appropriate way to flag parse errors.
vals = inFields[j].split("/");
if (vals.length != 2) {
- this.error('Expected fractional "num/den" values in CSV data ' +
- "but found a value '" + inFields[j] + "' on line " +
- (1 + i) + " ('" + line + "') which is not of this form.");
+ Dygraph.error('Expected fractional "num/den" values in CSV data ' +
+ "but found a value '" + inFields[j] + "' on line " +
+ (1 + i) + " ('" + line + "') which is not of this form.");
fields[j] = [0, 0];
} else {
fields[j] = [this.parseFloat_(vals[0], i, line),
} else if (this.getBooleanOption("errorBars")) {
// If there are error bars, values are (value, stddev) pairs
if (inFields.length % 2 != 1) {
- this.error('Expected alternating (value, stdev.) pairs in CSV data ' +
- 'but line ' + (1 + i) + ' has an odd number of values (' +
- (inFields.length - 1) + "): '" + line + "'");
+ Dygraph.error('Expected alternating (value, stdev.) pairs in CSV data ' +
+ 'but line ' + (1 + i) + ' has an odd number of values (' +
+ (inFields.length - 1) + "): '" + line + "'");
}
for (j = 1; j < inFields.length; j += 2) {
fields[(j + 1) / 2] = [this.parseFloat_(inFields[j], i, line),
this.parseFloat_(vals[1], i, line),
this.parseFloat_(vals[2], i, line) ];
} else {
- this.warn('When using customBars, values must be either blank ' +
- 'or "low;center;high" tuples (got "' + val +
- '" on line ' + (1+i));
+ Dygraph.warn('When using customBars, values must be either blank ' +
+ 'or "low;center;high" tuples (got "' + val +
+ '" on line ' + (1+i));
}
}
}
}
if (fields.length != expectedCols) {
- this.error("Number of columns in line " + i + " (" + fields.length +
- ") does not agree with number of labels (" + expectedCols +
- ") " + line);
+ Dygraph.error("Number of columns in line " + i + " (" + fields.length +
+ ") does not agree with number of labels (" + expectedCols +
+ ") " + line);
}
// If the user specified the 'labels' option and none of the cells of the
if (fields[j]) all_null = false;
}
if (all_null) {
- this.warn("The dygraphs 'labels' option is set, but the first row of " +
- "CSV data ('" + line + "') appears to also contain labels. " +
- "Will drop the CSV labels and use the option labels.");
+ Dygraph.warn("The dygraphs 'labels' option is set, but the first row " +
+ "of CSV data ('" + line + "') appears to also contain " +
+ "labels. Will drop the CSV labels and use the option " +
+ "labels.");
continue;
}
}
}
if (outOfOrder) {
- this.warn("CSV is out of order; order it correctly to speed loading.");
+ Dygraph.warn("CSV is out of order; order it correctly to speed loading.");
ret.sort(function(a,b) { return a[0] - b[0]; });
}
Dygraph.prototype.parseArray_ = function(data) {
// Peek at the first x value to see if it's numeric.
if (data.length === 0) {
- this.error("Can't plot empty data set");
+ Dygraph.error("Can't plot empty data set");
return null;
}
if (data[0].length === 0) {
- this.error("Data set cannot contain an empty row");
+ Dygraph.error("Data set cannot contain an empty row");
return null;
}
var i;
if (this.attr_("labels") === null) {
- this.warn("Using default labels. Set labels explicitly via 'labels' " +
- "in the options parameter");
+ Dygraph.warn("Using default labels. Set labels explicitly via 'labels' " +
+ "in the options parameter");
this.attrs_.labels = [ "X" ];
for (i = 1; i < data[0].length; i++) {
this.attrs_.labels.push("Y" + i); // Not user_attrs_.
} else {
var num_labels = this.attr_("labels");
if (num_labels.length != data[0].length) {
- this.error("Mismatch between number of labels (" + num_labels +
- ") and number of columns in array (" + data[0].length + ")");
+ Dygraph.error("Mismatch between number of labels (" + num_labels + ")" +
+ " and number of columns in array (" + data[0].length + ")");
return null;
}
}
var parsedData = Dygraph.clone(data);
for (i = 0; i < data.length; i++) {
if (parsedData[i].length === 0) {
- this.error("Row " + (1 + i) + " of data is empty");
+ Dygraph.error("Row " + (1 + i) + " of data is empty");
return null;
}
if (parsedData[i][0] === null ||
typeof(parsedData[i][0].getTime) != 'function' ||
isNaN(parsedData[i][0].getTime())) {
- this.error("x value in row " + (1 + i) + " is not a Date");
+ Dygraph.error("x value in row " + (1 + i) + " is not a Date");
return null;
}
parsedData[i][0] = parsedData[i][0].getTime();
this.attrs_.axes.x.ticker = Dygraph.numericLinearTicks;
this.attrs_.axes.x.axisLabelFormatter = this.attrs_.axes.x.valueFormatter;
} else {
- this.error("only 'date', 'datetime' and 'number' types are supported for " +
- "column 1 of DataTable input (Got '" + indepType + "')");
+ Dygraph.error("only 'date', 'datetime' and 'number' types are supported " +
+ "for column 1 of DataTable input (Got '" + indepType + "')");
return null;
}
}
hasAnnotations = true;
} else {
- this.error("Only 'number' is supported as a dependent type with Gviz." +
- " 'string' is only supported if displayAnnotations is true");
+ Dygraph.error("Only 'number' is supported as a dependent type with Gviz." +
+ " 'string' is only supported if displayAnnotations is true");
}
}
var row = [];
if (typeof(data.getValue(i, 0)) === 'undefined' ||
data.getValue(i, 0) === null) {
- this.warn("Ignoring row " + i +
- " of DataTable because of undefined or null first column.");
+ Dygraph.warn("Ignoring row " + i +
+ " of DataTable because of undefined or null first column.");
continue;
}
}
if (outOfOrder) {
- this.warn("DataTable is out of order; order it correctly to speed loading.");
+ Dygraph.warn("DataTable is out of order; order it correctly to speed loading.");
ret.sort(function(a,b) { return a[0] - b[0]; });
}
this.rawData_ = ret;
req.send(null);
}
} else {
- this.error("Unknown data format: " + (typeof data));
+ Dygraph.error("Unknown data format: " + (typeof data));
}
};
this.resize_lock = true;
if ((width === null) != (height === null)) {
- this.warn("Dygraph.resize() should be called with zero parameters or " +
- "two non-NULL parameters. Pretending it was zero.");
+ Dygraph.warn("Dygraph.resize() should be called with zero parameters or " +
+ "two non-NULL parameters. Pretending it was zero.");
width = height = null;
}
Dygraph.prototype.setVisibility = function(num, value) {
var x = this.visibility();
if (num < 0 || num >= x.length) {
- this.warn("invalid series number in setVisibility: " + num);
+ Dygraph.warn("invalid series number in setVisibility: " + num);
} else {
x[num] = value;
this.predraw_();
Dygraph.addAnnotationRule();
this.annotations_ = ann;
if (!this.layout_) {
- this.warn("Tried to setAnnotations before dygraph was ready. " +
- "Try setting them in a ready() block. See " +
- "dygraphs.com/tests/annotation.html");
+ Dygraph.warn("Tried to setAnnotations before dygraph was ready. " +
+ "Try setting them in a ready() block. See " +
+ "dygraphs.com/tests/annotation.html");
return;
}
}
}
- this.warn("Unable to add default annotation CSS rule; display may be off.");
+ Dygraph.warn("Unable to add default annotation CSS rule; display may be off.");
};
--- /dev/null
+/**
+ * @license
+ * Copyright 2011 Dan Vanderkam (danvdk@gmail.com)
+ * MIT-licensed (http://opensource.org/licenses/MIT)
+ */
+
+/**
+ * @fileoverview
+ * Including this file will add several additional shapes to Dygraph.Circles
+ * which can be passed to drawPointCallback.
+ * See tests/custom-circles.html for usage.
+ */
+
+(function() {
+
+/**
+ * @param {!CanvasRenderingContext2D} ctx the canvas context
+ * @param {number} sides the number of sides in the shape.
+ * @param {number} radius the radius of the image.
+ * @param {number} cx center x coordate
+ * @param {number} cy center y coordinate
+ * @param {number=} rotationRadians the shift of the initial angle, in radians.
+ * @param {number=} delta the angle shift for each line. If missing, creates a
+ * regular polygon.
+ */
+var regularShape = function(
+ ctx, sides, radius, cx, cy, rotationRadians, delta) {
+ rotationRadians = rotationRadians || 0;
+ delta = delta || Math.PI * 2 / sides;
+
+ ctx.beginPath();
+ var initialAngle = rotationRadians;
+ var angle = initialAngle;
+
+ var computeCoordinates = function() {
+ var x = cx + (Math.sin(angle) * radius);
+ var y = cy + (-Math.cos(angle) * radius);
+ return [x, y];
+ };
+
+ var initialCoordinates = computeCoordinates();
+ var x = initialCoordinates[0];
+ var y = initialCoordinates[1];
+ ctx.moveTo(x, y);
+
+ for (var idx = 0; idx < sides; idx++) {
+ angle = (idx == sides - 1) ? initialAngle : (angle + delta);
+ var coords = computeCoordinates();
+ ctx.lineTo(coords[0], coords[1]);
+ }
+ ctx.fill();
+ ctx.stroke();
+};
+
+/**
+ * TODO(danvk): be more specific on the return type.
+ * @param {number} sides
+ * @param {number=} rotationRadians
+ * @param {number=} delta
+ * @return {Function}
+ * @private
+ */
+var shapeFunction = function(sides, rotationRadians, delta) {
+ return function(g, name, ctx, cx, cy, color, radius) {
+ ctx.strokeStyle = color;
+ ctx.fillStyle = "white";
+ regularShape(ctx, sides, radius, cx, cy, rotationRadians, delta);
+ };
+};
+
+Dygraph.update(Dygraph.Circles, {
+ TRIANGLE : shapeFunction(3),
+ SQUARE : shapeFunction(4, Math.PI / 4),
+ DIAMOND : shapeFunction(4),
+ PENTAGON : shapeFunction(5),
+ HEXAGON : shapeFunction(6),
+ CIRCLE : function(g, name, ctx, cx, cy, color, radius) {
+ ctx.beginPath();
+ ctx.strokeStyle = color;
+ ctx.fillStyle = "white";
+ ctx.arc(cx, cy, radius, 0, 2 * Math.PI, false);
+ ctx.fill();
+ ctx.stroke();
+ },
+ STAR : shapeFunction(5, 0, 4 * Math.PI / 5),
+ PLUS : function(g, name, ctx, cx, cy, color, radius) {
+ ctx.strokeStyle = color;
+
+ ctx.beginPath();
+ ctx.moveTo(cx + radius, cy);
+ ctx.lineTo(cx - radius, cy);
+ ctx.closePath();
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(cx, cy + radius);
+ ctx.lineTo(cx, cy - radius);
+ ctx.closePath();
+ ctx.stroke();
+ },
+ EX : function(g, name, ctx, cx, cy, color, radius) {
+ ctx.strokeStyle = color;
+
+ ctx.beginPath();
+ ctx.moveTo(cx + radius, cy + radius);
+ ctx.lineTo(cx - radius, cy - radius);
+ ctx.closePath();
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(cx + radius, cy - radius);
+ ctx.lineTo(cx - radius, cy + radius);
+ ctx.closePath();
+ ctx.stroke();
+ }
+});
+
+});
var valueRange = [0, 100];
function setPoint(event, g, context) {
- var canvasx = Dygraph.pageX(event) - Dygraph.findPosX(g.graphDiv);
- var canvasy = Dygraph.pageY(event) - Dygraph.findPosY(g.graphDiv);
+ var graphPos = Dygraph.findPos(g.graphDiv);
+ var canvasx = Dygraph.pageX(event) - graphPos.x;
+ var canvasy = Dygraph.pageY(event) - graphPos.y;
var xy = g.toDataCoords(canvasx, canvasy);
var x = xy[0], value = xy[1];
var rows = g.numRows();
});
window.onmouseup = finishDraw;
}
- });
\ No newline at end of file
+ });
var RANGE = 7;
if (v4Active) {
- var canvasx = Dygraph.pageX(event) - Dygraph.findPosX(g.graphDiv);
- var canvasy = Dygraph.pageY(event) - Dygraph.findPosY(g.graphDiv);
+ var graphPos = Dygraph.findPos(g.graphDiv);
+ var canvasx = Dygraph.pageX(event) - graphPos.x;
+ var canvasy = Dygraph.pageY(event) - graphPos.y;
var rows = g.numRows();
// Row layout:
# This list needs to be kept in sync w/ the one in dygraph-dev.js
# and the one in jsTestDriver.conf. Order matters, except for the plugins.
for F in \
- strftime/strftime-min.js \
- rgbcolor/rgbcolor.js \
- stacktrace.js \
dashed-canvas.js \
dygraph-options.js \
dygraph-layout.js \
try {
div.style[name] = messagestyle[name];
} catch (e) {
- this.warn("You are using unsupported css properties for your " +
+ Dygraph.warn("You are using unsupported css properties for your " +
"browser in labelsDivStyles");
}
}
// Range selector and animatedZooms have a bad interaction. See issue 359.
if (this.getOption_('animatedZooms')) {
- this.dygraph_.warn('Animated zooms and range selector are not compatible; disabling animatedZooms.');
+ Dygraph.warn('Animated zooms and range selector are not compatible; disabling animatedZooms.');
this.dygraph_.updateOptions({animatedZooms: false}, true);
}
var plotArea = this.dygraph_.layout_.getPlotArea();
var xAxisLabelHeight = 0;
- if(this.dygraph_.getOptionForAxis('drawAxis', 'x')) {
+ if (this.dygraph_.getOptionForAxis('drawAxis', 'x')) {
xAxisLabelHeight = this.getOption_('xAxisHeight') || (this.getOption_('axisLabelFontSize') + 2 * this.getOption_('axisTickSize'));
}
this.canvasRect_ = {
<script type="text/javascript" src="dygraph-combined.js"></script>
-->
<script type="text/javascript" src="../dygraph-dev.js"></script>
+ <script type="text/javascript" src="../extras/stars.js"></script>
</head>
<body>
var RANGE = 7;
if (v4Active) {
- var canvasx = Dygraph.pageX(event) - Dygraph.findPosX(g.graphDiv);
- var canvasy = Dygraph.pageY(event) - Dygraph.findPosY(g.graphDiv);
+ var graphPos = Dygraph.findPos(g.graphDiv);
+ var canvasx = Dygraph.pageX(event) - graphPos.x;
+ var canvasy = Dygraph.pageY(event) - graphPos.y;
var rows = g.numRows();
// Row layout: