this.start_();
};
-Dygraph.prototype.attr_ = function(name) {
- if (typeof(this.user_attrs_[name]) != 'undefined') {
+Dygraph.prototype.attr_ = function(name, series) {
+ if (series &&
+ typeof(this.user_attrs_[series]) != 'undefined' &&
+ this.user_attrs_[series] != null &&
+ typeof(this.user_attrs_[series][name]) != 'undefined') {
+ return this.user_attrs_[series][name];
+ } else if (typeof(this.user_attrs_[name]) != 'undefined') {
return this.user_attrs_[name];
} else if (typeof(this.attrs_[name]) != 'undefined') {
return this.attrs_[name];
return ret;
};
+/**
+ * Returns the number of columns (including the independent variable).
+ */
+Dygraph.prototype.numColumns = function() {
+ return this.rawData_[0].length;
+};
+
+/**
+ * Returns the number of rows (excluding any header/label row).
+ */
+Dygraph.prototype.numRows = function() {
+ return this.rawData_.length;
+};
+
+/**
+ * Returns the value in the given row and column. If the row and column exceed
+ * the bounds on the data, returns null. Also returns null if the value is
+ * missing.
+ */
+Dygraph.prototype.getValue = function(row, col) {
+ if (row < 0 || row > this.rawData_.length) return null;
+ if (col < 0 || col > this.rawData_[row].length) return null;
+
+ return this.rawData_[row][col];
+};
+
Dygraph.addEvent = function(el, evt, fn) {
var normed_fn = function(e) {
if (!e) var e = window.event;
*/
Dygraph.prototype.updateSelection_ = function() {
// Clear the previously drawn vertical, if there is one
- var circleSize = this.attr_('highlightCircleSize');
var ctx = this.canvas_.getContext("2d");
if (this.previousVerticalX_ >= 0) {
+ // Determine the maximum highlight circle size.
+ var maxCircleSize = 0;
+ var num_series = this.attr_('labels').length;
+ for (var i = 1; i < num_series; i++) {
+ var r = this.attr_('highlightCircleSize', i);
+ if (r > maxCircleSize) maxCircleSize = r;
+ }
var px = this.previousVerticalX_;
- ctx.clearRect(px - circleSize - 1, 0, 2 * circleSize + 2, this.height_);
+ ctx.clearRect(px - maxCircleSize - 1, 0,
+ 2 * maxCircleSize + 2, this.height_);
}
var isOK = function(x) { return x && !isNaN(x); };
if (this.attr_('showLabelsOnHighlight')) {
// Set the status message to indicate the selected point(s)
for (var i = 0; i < this.selPoints_.length; i++) {
- if (!this.attr_("labelsShowZeroValues") && this.selPoints_[i].yval == 0) continue;
+ if (!this.attr_("labelsShowZeroValues") && this.selPoints_[i].yval == 0) continue;
if (!isOK(this.selPoints_[i].canvasy)) continue;
if (this.attr_("labelsSeparateLines")) {
replace += "<br/>";
ctx.save();
for (var i = 0; i < this.selPoints_.length; i++) {
if (!isOK(this.selPoints_[i].canvasy)) continue;
+ var setIdx = this.indexFromSetName(this.selPoints_[i].name);
+ var circleSize = this.attr_('highlightCircleSize', setIdx);
ctx.beginPath();
ctx.fillStyle = this.plotter_.colors[this.selPoints_[i].name];
ctx.arc(canvasx, this.selPoints_[i].canvasy, circleSize,
this.setColors_();
this.attrs_['pointSize'] = 0.5 * this.attr_('highlightCircleSize');
- var connectSeparatedPoints = this.attr_('connectSeparatedPoints');
-
// Loop over the fields (series). Go from the last to the first,
// because if they're stacked that's how we accumulate the values.
for (var i = data[0].length - 1; i >= 1; i--) {
if (!this.visibility()[i - 1]) continue;
+ var connectSeparatedPoints = this.attr_('connectSeparatedPoints', i);
+
var series = [];
for (var j = 0; j < data.length; j++) {
if (data[j][i] != null || !connectSeparatedPoints) {
var row = [];
if (typeof(data.getValue(i, 0)) === 'undefined' ||
data.getValue(i, 0) === null) {
- this.warning("Ignoring row " + i +
- " of DataTable because of undefined or null first column.");
+ this.warn("Ignoring row " + i +
+ " of DataTable because of undefined or null first column.");
continue;
}
if (attrs.valueRange) {
this.valueRange_ = attrs.valueRange;
}
+
+ // TODO(danvk): validate per-series options.
+ // Supported:
+ // strokeWidth
+ // pointSize
+ // drawPoints
+ // highlightCircleSize
+
Dygraph.update(this.user_attrs_, attrs);
Dygraph.update(this.renderOptions_, attrs);
return this.annotations_;
};
+/**
+ * Get the index of a series (column) given its name. The first column is the
+ * x-axis, so the data series start with index 1.
+ */
+Dygraph.prototype.indexFromSetName = function(name) {
+ var labels = this.attr_("labels");
+ for (var i = 0; i < labels.length; i++) {
+ if (labels[i] == name) return i;
+ }
+ return null;
+};
+
Dygraph.addAnnotationRule = function() {
if (Dygraph.addedAnnotationCSS) return;