X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=dygraph.js;h=735c99adab93427e31bd7b499f779fb5aedad32a;hb=f7f4a6c0ea5f31130ff639b53095609562dfd86f;hp=8a0ee087d6264987ad3c54352147f210dd8d9c4f;hpb=e988d192a87ace02365a765ffd5455b1d7b5b88e;p=dygraphs.git diff --git a/dygraph.js b/dygraph.js index 8a0ee08..735c99a 100644 --- a/dygraph.js +++ b/dygraph.js @@ -202,30 +202,61 @@ Dygraph.SHORT_MONTH_NAMES_ = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', ' /** * Convert a JS date to a string appropriate to display on an axis that - * is displaying values at the stated granularity. + * is displaying values at the stated granularity. This respects the + * labelsDateUTC option. * @param {Date} date The date to format * @param {number} granularity One of the Dygraph granularity constants - * @return {string} The formatted date + * @param {Dygraph} opts An options view + * @return {string} The date formatted as local time * @private */ -Dygraph.dateAxisFormatter = function(date, granularity) { +Dygraph.dateAxisLabelFormatter = function(date, granularity, opts) { + var utc = opts('labelsDateUTC'); + var year, month, day, hours, mins, secs, millis; + if (utc) { + year = date.getUTCFullYear(); + month = date.getUTCMonth(); + day = date.getUTCDate(); + hours = date.getUTCHours(); + mins = date.getUTCMinutes(); + secs = date.getUTCSeconds(); + millis = date.getUTCMilliseconds(); + } else { + year = date.getFullYear(); + month = date.getMonth(); + day = date.getDate(); + hours = date.getHours(); + mins = date.getMinutes(); + secs = date.getSeconds(); + millis = date.getMilliseconds(); + } if (granularity >= Dygraph.DECADAL) { - return '' + date.getFullYear(); + return '' + year; } else if (granularity >= Dygraph.MONTHLY) { - return Dygraph.SHORT_MONTH_NAMES_[date.getMonth()] + ' ' + date.getFullYear(); + return Dygraph.SHORT_MONTH_NAMES_[month] + ' ' + Dygraph.zeropad(year); } else { - var frac = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds() + date.getMilliseconds(); + var frac = hours * 3600 + mins * 60 + secs + 1e-3 * millis; if (frac === 0 || granularity >= Dygraph.DAILY) { // e.g. '21Jan' (%d%b) - var nd = new Date(date.getTime() + 3600*1000); - return Dygraph.zeropad(nd.getDate()) + Dygraph.SHORT_MONTH_NAMES_[nd.getMonth()]; + return Dygraph.zeropad(day) + Dygraph.SHORT_MONTH_NAMES_[month]; } else { - return Dygraph.hmsString_(date.getTime()); + return Dygraph.hmsString_(hours, mins, secs); } } }; /** + * Return a string version of a JS date for a value label. This respects the + * labelsDateUTC option. + * @param {Date} date The date to be formatted + * @param {Dygraph} opts An options view + * @private + */ +Dygraph.dateValueFormatter = function(d, opts) { + return Dygraph.dateString_(d, opts('labelsDateUTC')); +}; + +/** * Standard plotters. These may be used by clients. * Available plotters are: * - Dygraph.Plotters.linePlotter: draws central lines (most common) @@ -280,7 +311,6 @@ Dygraph.DEFAULT_ATTRS = { customBars: false, fillGraph: false, fillAlpha: 0.15, - fillStepPlot: false, connectSeparatedPoints: false, stackedGraph: false, @@ -336,8 +366,8 @@ Dygraph.DEFAULT_ATTRS = { axes: { x: { pixelsPerLabel: 60, - axisLabelFormatter: Dygraph.dateAxisFormatter, - valueFormatter: Dygraph.dateString_, + axisLabelFormatter: Dygraph.dateAxisLabelFormatter, + valueFormatter: Dygraph.dateValueFormatter, drawGrid: true, drawAxis: true, independentTicks: true, @@ -1105,6 +1135,7 @@ Dygraph.prototype.createInterface_ = function() { // TODO(danvk): any other styles that are useful to set here? this.graphDiv.style.textAlign = 'left'; // This is a CSS "reset" + this.graphDiv.style.position = 'relative'; enclosing.appendChild(this.graphDiv); // Create the canvas for interactive parts of the chart. @@ -2124,10 +2155,23 @@ Dygraph.prototype.setSelection = function(row, opt_seriesName, opt_locked) { this.lastRow_ = row; for (var setIdx = 0; setIdx < this.layout_.points.length; ++setIdx) { var points = this.layout_.points[setIdx]; + // Check if the point at the appropriate index is the point we're looking + // for. If it is, just use it, otherwise search the array for a point + // in the proper place. var setRow = row - this.getLeftBoundary_(setIdx); - if (setRow < points.length) { + if (setRow < points.length && points[setRow].idx == row) { var point = points[setRow]; if (point.yval !== null) this.selPoints_.push(point); + } else { + for (var pointIdx = 0; pointIdx < points.length; ++pointIdx) { + var point = points[pointIdx]; + if (point.idx == row) { + if (point.yval !== null) { + this.selPoints_.push(point); + } + break; + } + } } } } else { @@ -2499,6 +2543,7 @@ Dygraph.prototype.gatherDatasets_ = function(rolledSeries, dateWindow) { var extremes = {}; // series name -> [low, high] var seriesIdx, sampleIdx; var firstIdx, lastIdx; + var axisIdx; // Loop over the fields (series). Go from the last to the first, // because if they're stacked that's how we accumulate the values. @@ -2569,7 +2614,11 @@ Dygraph.prototype.gatherDatasets_ = function(rolledSeries, dateWindow) { seriesName, boundaryIds[seriesIdx-1][0]); if (this.getBooleanOption("stackedGraph")) { - Dygraph.stackPoints_(seriesPoints, cumulativeYval, seriesExtremes, + axisIdx = this.attributes_.axisForSeries(seriesName); + if (cumulativeYval[axisIdx] === undefined) { + cumulativeYval[axisIdx] = []; + } + Dygraph.stackPoints_(seriesPoints, cumulativeYval[axisIdx], seriesExtremes, this.getBooleanOption("stackedGraphNaNFill")); } @@ -2974,9 +3023,9 @@ Dygraph.prototype.detectTypeFromString_ = function(str) { Dygraph.prototype.setXAxisOptions_ = function(isDate) { if (isDate) { this.attrs_.xValueParser = Dygraph.dateParser; - this.attrs_.axes.x.valueFormatter = Dygraph.dateString_; + this.attrs_.axes.x.valueFormatter = Dygraph.dateValueFormatter; this.attrs_.axes.x.ticker = Dygraph.dateTicker; - this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisFormatter; + this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisLabelFormatter; } else { /** @private (shut up, jsdoc!) */ this.attrs_.xValueParser = function(x) { return parseFloat(x); }; @@ -3174,9 +3223,9 @@ Dygraph.prototype.parseArray_ = function(data) { if (Dygraph.isDateLike(data[0][0])) { // Some intelligent defaults for a date x-axis. - this.attrs_.axes.x.valueFormatter = Dygraph.dateString_; + this.attrs_.axes.x.valueFormatter = Dygraph.dateValueFormatter; this.attrs_.axes.x.ticker = Dygraph.dateTicker; - this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisFormatter; + this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisLabelFormatter; // Assume they're all dates. var parsedData = Dygraph.clone(data); @@ -3233,9 +3282,9 @@ Dygraph.prototype.parseDataTable_ = function(data) { var indepType = data.getColumnType(0); if (indepType == 'date' || indepType == 'datetime') { this.attrs_.xValueParser = Dygraph.dateParser; - this.attrs_.axes.x.valueFormatter = Dygraph.dateString_; + this.attrs_.axes.x.valueFormatter = Dygraph.dateValueFormatter; this.attrs_.axes.x.ticker = Dygraph.dateTicker; - this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisFormatter; + this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisLabelFormatter; } else if (indepType == 'number') { this.attrs_.xValueParser = function(x) { return parseFloat(x); }; this.attrs_.axes.x.valueFormatter = function(x) { return x; };