X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=dygraph.js;h=09a668453608de16a6a82c6f14f29176621b2685;hb=eca085ecfb71db2647c00a9f4e528128878d8372;hp=41145e17fda807e782ad94ca5eec702d6f68ddae;hpb=2769de626609e47b4137ce89eeb95391cf08c8e7;p=dygraphs.git diff --git a/dygraph.js b/dygraph.js index 41145e1..09a6684 100644 --- a/dygraph.js +++ b/dygraph.js @@ -533,24 +533,51 @@ DateGraph.prototype.mouseOut_ = function(event) { }; /** + * Return a string version of the hours, minutes and seconds portion of a date. + * @param {Number} date The JavaScript date (ms since epoch) + * @return {String} A time of the form "HH:MM:SS" + * @private + */ +DateGraph.prototype.hmsString_ = function(date) { + var zeropad = function(x) { + if (x < 10) return "0" + x; else return "" + x; + }; + var d = new Date(date); + if (d.getSeconds()) { + return zeropad(d.getHours()) + ":" + + zeropad(d.getMinutes()) + ":" + + zeropad(d.getSeconds()); + } else if (d.getMinutes()) { + return zeropad(d.getHours()) + ":" + zeropad(d.getMinutes()); + } else { + return zeropad(d.getHours()); + } +} + +/** * 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 */ DateGraph.prototype.dateString_ = function(date) { + var zeropad = function(x) { + if (x < 10) return "0" + x; else return "" + x; + }; var d = new Date(date); // Get the year: var year = "" + d.getFullYear(); // Get a 0 padded month string - var month = "" + (d.getMonth() + 1); //months are 0-offset, sigh - if (month.length < 2) month = "0" + month; + var month = zeropad(d.getMonth() + 1); //months are 0-offset, sigh // Get a 0 padded day string - var day = "" + d.getDate(); - if (day.length < 2) day = "0" + day; + var day = zeropad(d.getDate()); - return year + "/" + month + "/" + day; + var ret = ""; + var frac = d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds(); + if (frac) ret = " " + this.hmsString_(date); + + return year + "/" + month + "/" + day + ret; }; /** @@ -636,7 +663,7 @@ DateGraph.prototype.dateTicker = function(startDate, endDate) { scale.push(day * ONE_DAY); } } else { // hourly - for (var hour = (startDate - 1) * 24; + for (var hour = Math.floor(startDate - 1) * 24; hour < (endDate + 1) * 24; hour += 1) { scale.push(hour * 60*60*1000); } @@ -656,11 +683,18 @@ DateGraph.prototype.dateTicker = function(startDate, endDate) { } } else { for (var i = 0; i < scale.length; i++) { - var date = new Date(scale[i]); - var year = date.getFullYear().toString(); - var label = this.months[date.getMonth()] + date.getDate(); - label += "'" + year.substr(year.length - 2, 2); - xTicks.push( {label: label, v: date} ); + // TODO(danvk): this is _gross_. Unify all this with dateString_. + var d = new Date(scale[i]); + var frac = d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds(); + var label; + if (frac == 0) { + var year = d.getFullYear().toString(); + var label = this.months[d.getMonth()] + d.getDate(); + label += "'" + year.substr(year.length - 2, 2); + } else { + label = this.hmsString_(d); + } + xTicks.push( {label: label, v: d} ); } } return xTicks; @@ -1025,6 +1059,50 @@ DateGraph.prototype.parseCSV_ = function(data) { }; /** + * Parses a DataTable object from gviz. + * The data is expected to have a first column that is either a date or a + * number. All subsequent columns must be numbers. If there is a clear mismatch + * between this.xValueParser_ and the type of the first column, it will be + * fixed. Returned value is in the same format as return value of parseCSV_. + * @param {Array.} data See above. + * @private + */ +DateGraph.prototype.parseDataTable_ = function(data) { + var cols = data.getNumberOfColumns(); + var rows = data.getNumberOfRows(); + + // Read column labels + var labels = []; + for (var i = 0; i < cols; i++) { + labels.push(data.getColumnLabel(i)); + } + labels.shift(); // a "date" parameter is assumed. + this.labels_ = labels; + // regenerate automatic colors. + this.setColors_(this.attrs_); + this.renderOptions_.colorScheme = this.colors_; + MochiKit.Base.update(this.plotter_.options, this.renderOptions_); + MochiKit.Base.update(this.layoutOptions_, this.attrs_); + + // Assume column 1 is a date type for now. + if (data.getColumnType(0) != 'date') { + alert("only date type is support for column 1 of DataTable input."); + return null; + } + + var ret = []; + for (var i = 0; i < rows; i++) { + var row = []; + row.push(data.getValue(i, 0).getTime()); + for (var j = 1; j < cols; j++) { + row.push(data.getValue(i, j)); + } + ret.push(row); + } + return ret; +} + +/** * Get the CSV data. If it's in a function, call that function. If it's in a * file, do an XMLHttpRequest to get it. * @private @@ -1033,6 +1111,11 @@ DateGraph.prototype.start_ = function() { if (typeof this.file_ == 'function') { // Stubbed out to allow this to run off a filesystem this.loadedEvent_(this.file_()); + } else if (typeof this.file_ == 'object' && + typeof this.file_.getColumnRange == 'function') { + // must be a DataTable from gviz. + this.rawData_ = this.parseDataTable_(this.file_); + this.drawGraph_(this.rawData_); } else { var req = new XMLHttpRequest(); var caller = this; @@ -1101,3 +1184,17 @@ DateGraph.prototype.adjustRoll = function(length) { this.rollPeriod_ = length; this.drawGraph_(this.rawData_); }; + + +/** + * A wrapper around DateGraph that implements the gviz API. + * @param {Object} container The DOM object the visualization should live in. + */ +DateGraph.GVizChart = function(container) { + this.container = container; +} + +DateGraph.GVizChart.prototype.draw = function(data, options) { + this.container.innerHTML = ''; + this.date_graph = new DateGraph(this.container, data, null, options || {}); +}