X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=dygraph.js;h=1012d76c3c9e79af05af5cf1ab4c4383cb854ba4;hb=a4c6a67c116af8d7f5810fb7cc7a8ded13caf707;hp=defac69158e338eeaf745aff2cd1ec24ead8a9cb;hpb=029da4b60475f7aa25f104165d4f6f4d44e41467;p=dygraphs.git diff --git a/dygraph.js b/dygraph.js index defac69..1012d76 100644 --- a/dygraph.js +++ b/dygraph.js @@ -102,6 +102,7 @@ Dygraph.DEFAULT_ATTRS = { axisLabelFontSize: 14, xAxisLabelWidth: 50, yAxisLabelWidth: 50, + xAxisLabelFormatter: Dygraph.dateAxisFormatter, rightGap: 5, showRoller: false, @@ -527,10 +528,11 @@ Dygraph.prototype.setColors_ = function() { if (!colors) { var sat = this.attr_('colorSaturation') || 1.0; var val = this.attr_('colorValue') || 0.5; + var half = Math.ceil(num / 2); for (var i = 1; i <= num; i++) { if (!this.visibility()[i-1]) continue; // alternate colors for high contrast. - var idx = i - parseInt(i % 2 ? i / 2 : (i - num)/2, 10); + var idx = i % 2 ? Math.ceil(i / 2) : (half + i / 2); var hue = (1.0 * idx/ (1 + num)); this.colors_.push(Dygraph.hsvToRGB(hue, sat, val)); } @@ -903,28 +905,32 @@ Dygraph.prototype.mouseMove_ = function(event) { var cumulative_sum = 0; // used only if we have a stackedGraph. var l = points.length; var isStacked = this.attr_("stackedGraph"); - for (var i = 0; i < l; i++) { - if (points[i].xval == lastx) { - if (!isStacked) { + if (!this.attr_("stackedGraph")) { + for (var i = 0; i < l; i++) { + if (points[i].xval == lastx) { this.selPoints_.push(points[i]); - } else { - // Clone the point, since we need to 'unstack' it below. Stacked points - // are in reverse order. + } + } + } else { + // Stacked points need to be examined in reverse order. + for (var i = l - 1; i >= 0; i--) { + if (points[i].xval == lastx) { + // Clone the point, since we need to 'unstack' it below. var p = {}; - for (var k in points[l - i - 1]) { - p[k] = points[l - i -1][k]; + for (var k in points[i]) { + p[k] = points[i][k]; } p.yval -= cumulative_sum; cumulative_sum += p.yval; + this.selPoints_.push(p); } } } if (this.attr_("highlightCallback")) { - var px = this.lastHighlightCallbackX; + var px = this.lastx_; if (px !== null && lastx != px) { // only fire if the selected point has changed. - this.lastHighlightCallbackX = lastx; this.attr_("highlightCallback")(event, lastx, this.selPoints_); } } @@ -1033,6 +1039,10 @@ Dygraph.prototype.setSelection = function(row) { * @private */ Dygraph.prototype.mouseOut_ = function(event) { + if (this.attr_("unhighlightCallback")) { + this.attr_("unhighlightCallback")(event); + } + if (this.attr_("hideOverlayOnMouseOut")) { this.clearSelection(); } @@ -1079,7 +1089,7 @@ Dygraph.zeropad = function(x) { * @return {String} A time of the form "HH:MM:SS" * @private */ -Dygraph.prototype.hmsString_ = function(date) { +Dygraph.hmsString_ = function(date) { var zeropad = Dygraph.zeropad; var d = new Date(date); if (d.getSeconds()) { @@ -1092,11 +1102,31 @@ Dygraph.prototype.hmsString_ = function(date) { } /** + * Convert a JS date to a string appropriate to display on an axis that + * is displaying values at the stated granularity. + * @param {Date} date The date to format + * @param {Number} granularity One of the Dygraph granularity constants + * @return {String} The formatted date + * @private + */ +Dygraph.dateAxisFormatter = function(date, granularity) { + if (granularity >= Dygraph.MONTHLY) { + return date.strftime('%b %y'); + } else { + var frac = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds() + date.getMilliseconds(); + if (frac == 0 || granularity >= Dygraph.DAILY) { + return new Date(date.getTime() + 3600*1000).strftime('%d%b'); + } else { + return Dygraph.hmsString_(date.getTime()); + } + } +} + +/** * 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 - * TODO(danvk): why is this part of the prototype? */ Dygraph.dateString_ = function(date, self) { var zeropad = Dygraph.zeropad; @@ -1111,7 +1141,7 @@ Dygraph.dateString_ = function(date, self) { var ret = ""; var frac = d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds(); - if (frac) ret = " " + self.hmsString_(date); + if (frac) ret = " " + Dygraph.hmsString_(date); return year + "/" + month + "/" + day + ret; }; @@ -1233,6 +1263,7 @@ Dygraph.prototype.NumXTicks = function(start_time, end_time, granularity) { // Returns an array containing {v: millis, label: label} dictionaries. // Dygraph.prototype.GetXAxis = function(start_time, end_time, granularity) { + var formatter = this.attr_("xAxisLabelFormatter"); var ticks = []; if (granularity < Dygraph.MONTHLY) { // Generate one tick mark for every fixed interval of time. @@ -1269,14 +1300,7 @@ Dygraph.prototype.GetXAxis = function(start_time, end_time, granularity) { start_time = d.getTime(); for (var t = start_time; t <= end_time; t += spacing) { - var d = new Date(t); - var frac = d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds(); - if (frac == 0 || granularity >= Dygraph.DAILY) { - // the extra hour covers DST problems. - ticks.push({ v:t, label: new Date(t + 3600*1000).strftime(format) }); - } else { - ticks.push({ v:t, label: this.hmsString_(t) }); - } + ticks.push({ v:t, label: formatter(new Date(t), granularity) }); } } else { // Display a tick mark on the first of a set of months of each year. @@ -1307,7 +1331,7 @@ Dygraph.prototype.GetXAxis = function(start_time, end_time, granularity) { var date_str = i + "/" + zeropad(1 + months[j]) + "/01"; var t = Date.parse(date_str); if (t < start_time || t > end_time) continue; - ticks.push({ v:t, label: new Date(t).strftime('%b %y') }); + ticks.push({ v:t, label: formatter(new Date(t), granularity) }); } } } @@ -1815,10 +1839,12 @@ Dygraph.prototype.detectTypeFromString_ = function(str) { this.attrs_.xValueFormatter = Dygraph.dateString_; this.attrs_.xValueParser = Dygraph.dateParser; this.attrs_.xTicker = Dygraph.dateTicker; + this.attrs_.xAxisLabelFormatter = Dygraph.dateAxisFormatter; } else { this.attrs_.xValueFormatter = function(x) { return x; }; this.attrs_.xValueParser = function(x) { return parseFloat(x); }; this.attrs_.xTicker = Dygraph.numericTicks; + this.attrs_.xAxisLabelFormatter = this.attrs_.xValueFormatter; } }; @@ -1950,6 +1976,7 @@ Dygraph.prototype.parseArray_ = function(data) { if (Dygraph.isDateLike(data[0][0])) { // Some intelligent defaults for a date x-axis. this.attrs_.xValueFormatter = Dygraph.dateString_; + this.attrs_.xAxisLabelFormatter = Dygraph.dateAxisFormatter; this.attrs_.xTicker = Dygraph.dateTicker; // Assume they're all dates. @@ -2003,10 +2030,12 @@ Dygraph.prototype.parseDataTable_ = function(data) { this.attrs_.xValueFormatter = Dygraph.dateString_; this.attrs_.xValueParser = Dygraph.dateParser; this.attrs_.xTicker = Dygraph.dateTicker; + this.attrs_.xAxisLabelFormatter = Dygraph.dateAxisFormatter; } else if (indepType == 'number') { this.attrs_.xValueFormatter = function(x) { return x; }; this.attrs_.xValueParser = function(x) { return parseFloat(x); }; this.attrs_.xTicker = Dygraph.numericTicks; + this.attrs_.xAxisLabelFormatter = this.attrs_.xValueFormatter; } else { this.error("only 'date', 'datetime' and 'number' types are supported for " + "column 1 of DataTable input (Got '" + indepType + "')");