X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=src%2Fdygraph.js;h=e0fcb58caddd9dd73c1e4250b36ac67555efb6fa;hb=660bb307f01c14f7d7d1b839812840fb179481ec;hp=41e5cc15aedd041b090447ff7f82705baddd7c90;hpb=dd74404fac69f23183ff8e540a018ca35bab4f7a;p=dygraphs.git diff --git a/src/dygraph.js b/src/dygraph.js index 41e5cc1..e0fcb58 100644 --- a/src/dygraph.js +++ b/src/dygraph.js @@ -632,32 +632,8 @@ Dygraph.prototype.toDataXCoord = function(x) { if (!this.attributes_.getForAxis("logscale", 'x')) { return xRange[0] + (x - area.x) / area.w * (xRange[1] - xRange[0]); } else { - // TODO: remove duplicate code? - // Computing the inverse of toDomCoord. var pct = (x - area.x) / area.w; - - // Computing the inverse of toPercentXCoord. The function was arrived at with - // the following steps: - // - // Original calcuation: - // pct = (log(x) - log(xRange[0])) / (log(xRange[1]) - log(xRange[0]))); - // - // Multiply both sides by the right-side demoninator. - // pct * (log(xRange[1] - log(xRange[0]))) = log(x) - log(xRange[0]) - // - // add log(xRange[0]) to both sides - // log(xRange[0]) + (pct * (log(xRange[1]) - log(xRange[0])) = log(x); - // - // Swap both sides of the equation, - // log(x) = log(xRange[0]) + (pct * (log(xRange[1]) - log(xRange[0])) - // - // Use both sides as the exponent in 10^exp and we're done. - // x = 10 ^ (log(xRange[0]) + (pct * (log(xRange[1]) - log(xRange[0]))) - var logr0 = utils.log10(xRange[0]); - var logr1 = utils.log10(xRange[1]); - var exponent = logr0 + (pct * (logr1 - logr0)); - var value = Math.pow(utils.LOG_SCALE, exponent); - return value; + return utils.logRangeFraction(xRange[0], xRange[1], pct); } }; @@ -681,32 +657,8 @@ Dygraph.prototype.toDataYCoord = function(y, axis) { } else { // Computing the inverse of toDomCoord. var pct = (y - area.y) / area.h; - - // Computing the inverse of toPercentYCoord. The function was arrived at with - // the following steps: - // - // Original calcuation: - // pct = (log(yRange[1]) - log(y)) / (log(yRange[1]) - log(yRange[0])); - // - // Multiply both sides by the right-side demoninator. - // pct * (log(yRange[1]) - log(yRange[0])) = log(yRange[1]) - log(y); - // - // subtract log(yRange[1]) from both sides. - // (pct * (log(yRange[1]) - log(yRange[0]))) - log(yRange[1]) = -log(y); - // - // and multiply both sides by -1. - // log(yRange[1]) - (pct * (logr1 - log(yRange[0])) = log(y); - // - // Swap both sides of the equation, - // log(y) = log(yRange[1]) - (pct * (log(yRange[1]) - log(yRange[0]))); - // - // Use both sides as the exponent in 10^exp and we're done. - // y = 10 ^ (log(yRange[1]) - (pct * (log(yRange[1]) - log(yRange[0])))); - var logr0 = utils.log10(yRange[0]); - var logr1 = utils.log10(yRange[1]); - var exponent = logr1 - (pct * (logr1 - logr0)); - var value = Math.pow(utils.LOG_SCALE, exponent); - return value; + // Note reversed yRange, y1 is on top with pct==0. + return utils.logRangeFraction(yRange[1], yRange[0], pct); } }; @@ -1077,32 +1029,28 @@ Dygraph.prototype.getPropertiesForSeries = function(series_name) { */ Dygraph.prototype.createRollInterface_ = function() { // Create a roller if one doesn't exist already. - if (!this.roller_) { - this.roller_ = document.createElement("input"); - this.roller_.type = "text"; - this.roller_.style.display = "none"; - this.graphDiv.appendChild(this.roller_); + var roller = this.roller_; + if (!roller) { + this.roller_ = roller = document.createElement("input"); + roller.type = "text"; + roller.style.display = "none"; + roller.className = 'dygraph-roller'; + this.graphDiv.appendChild(roller); } var display = this.getBooleanOption('showRoller') ? 'block' : 'none'; - var area = this.plotter_.area; - var textAttr = { "position": "absolute", - "zIndex": 10, + var area = this.getArea(); + var textAttr = { "top": (area.y + area.h - 25) + "px", "left": (area.x + 1) + "px", "display": display - }; - this.roller_.size = "2"; - this.roller_.value = this.rollPeriod_; - for (var name in textAttr) { - if (textAttr.hasOwnProperty(name)) { - this.roller_.style[name] = textAttr[name]; - } - } + }; + roller.size = "2"; + roller.value = this.rollPeriod_; + utils.update(roller.style, textAttr); - var dygraph = this; - this.roller_.onchange = function() { dygraph.adjustRoll(dygraph.roller_.value); }; + roller.onchange = () => this.adjustRoll(roller.value); }; /** @@ -1762,8 +1710,8 @@ Dygraph.prototype.animateSelection_ = function(direction) { Dygraph.prototype.updateSelection_ = function(opt_animFraction) { /*var defaultPrevented = */ this.cascadeEvents_('select', { - selectedRow: this.lastRow_, - selectedX: this.lastx_, + selectedRow: this.lastRow_ === -1 ? undefined : this.lastRow_, + selectedX: this.lastx_ === -1 ? undefined : this.lastx_, selectedPoints: this.selPoints_ }); // TODO(danvk): use defaultPrevented here? @@ -1839,6 +1787,10 @@ Dygraph.prototype.updateSelection_ = function(opt_animFraction) { * Manually set the selected points and display information about them in the * legend. The selection can be cleared using clearSelection() and queried * using getSelection(). + * + * To set a selected series but not a selected point, call setSelection with + * row=false and the selected series name. + * * @param {number} row Row number that should be highlighted (i.e. appear with * hover dots on the chart). * @param {seriesName} optional series name to highlight that series with the @@ -1861,7 +1813,7 @@ Dygraph.prototype.setSelection = function(row, opt_seriesName, opt_locked) { // 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 && points[setRow].idx == row) { + if (setRow >= 0 && setRow < points.length && points[setRow].idx == row) { var point = points[setRow]; if (point.yval !== null) this.selPoints_.push(point); } else { @@ -2352,16 +2304,15 @@ Dygraph.prototype.drawGraph_ = function() { this.setIndexByName_ = {}; var labels = this.attr_("labels"); - if (labels.length > 0) { - this.setIndexByName_[labels[0]] = 0; - } var dataIdx = 0; for (var i = 1; i < points.length; i++) { - this.setIndexByName_[labels[i]] = i; if (!this.visibility()[i - 1]) continue; this.layout_.addDataset(labels[i], points[i]); this.datasetIndex_[i] = dataIdx++; } + for (var i = 0; i < labels.length; i++) { + this.setIndexByName_[labels[i]] = i; + } this.computeYAxisRanges_(extremes); this.layout_.setYAxes(this.axes_); @@ -2602,25 +2553,21 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) { } } - var maxAxisY, minAxisY; - if (logscale) { - if (ypadCompat) { + var maxAxisY = maxY, minAxisY = minY; + if (ypadCompat) { + if (logscale) { maxAxisY = maxY + ypad * span; minAxisY = minY; } else { - var logpad = Math.exp(Math.log(span) * ypad); - maxAxisY = maxY * logpad; - minAxisY = minY / logpad; - } - } else { - maxAxisY = maxY + ypad * span; - minAxisY = minY - ypad * span; - - // Backwards-compatible behavior: Move the span to start or end at zero if it's - // close to zero, but not if avoidMinZero is set. - if (ypadCompat && !this.getBooleanOption("avoidMinZero")) { - if (minAxisY < 0 && minY >= 0) minAxisY = 0; - if (maxAxisY > 0 && maxY <= 0) maxAxisY = 0; + maxAxisY = maxY + ypad * span; + minAxisY = minY - ypad * span; + + // Backwards-compatible behavior: Move the span to start or end at zero if it's + // close to zero, but not if avoidMinZero is set. + if (!this.getBooleanOption("avoidMinZero")) { + if (minAxisY < 0 && minY >= 0) minAxisY = 0; + if (maxAxisY > 0 && maxY <= 0) maxAxisY = 0; + } } } axis.extremeRange = [minAxisY, maxAxisY]; @@ -2634,21 +2581,28 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) { // This is a user-set value range for this axis. var y0 = isNullUndefinedOrNaN(axis.valueRange[0]) ? axis.extremeRange[0] : axis.valueRange[0]; var y1 = isNullUndefinedOrNaN(axis.valueRange[1]) ? axis.extremeRange[1] : axis.valueRange[1]; - if (!ypadCompat) { - if (axis.logscale) { - var logpad = Math.exp(Math.log(span) * ypad); - y0 *= logpad; - y1 /= logpad; - } else { - span = y1 - y0; - y0 -= span * ypad; - y1 += span * ypad; - } - } axis.computedValueRange = [y0, y1]; } else { axis.computedValueRange = axis.extremeRange; } + if (!axis.valueWindow && !ypadCompat) { + // When using yRangePad, adjust the upper/lower bounds to add + // padding unless the user has zoomed/panned the Y axis range. + if (logscale) { + y0 = axis.computedValueRange[0]; + y1 = axis.computedValueRange[1]; + var y0pct = ypad / (2 * ypad - 1); + var y1pct = (ypad - 1) / (2 * ypad - 1); + axis.computedValueRange[0] = utils.logRangeFraction(y0, y1, y0pct); + axis.computedValueRange[1] = utils.logRangeFraction(y0, y1, y1pct); + } else { + y0 = axis.computedValueRange[0]; + y1 = axis.computedValueRange[1]; + span = y1 - y0; + axis.computedValueRange[0] = y0 - span * ypad; + axis.computedValueRange[1] = y1 + span * ypad; + } + } if (independentTicks) { @@ -3386,7 +3340,6 @@ Dygraph.prototype.size = function() { */ Dygraph.prototype.setAnnotations = function(ann, suppressDraw) { // Only add the annotation CSS rule once we know it will be used. - Dygraph.addAnnotationRule(); this.annotations_ = ann; if (!this.layout_) { console.warn("Tried to setAnnotations before dygraph was ready. " + @@ -3477,48 +3430,6 @@ Dygraph.prototype.ready = function(callback) { }; /** - * @private - * Adds a default style for the annotation CSS classes to the document. This is - * only executed when annotations are actually used. It is designed to only be - * called once -- all calls after the first will return immediately. - */ -Dygraph.addAnnotationRule = function() { - // TODO(danvk): move this function into plugins/annotations.js? - if (Dygraph.addedAnnotationCSS) return; - - var rule = "border: 1px solid black; " + - "background-color: white; " + - "text-align: center;"; - - var styleSheetElement = document.createElement("style"); - styleSheetElement.type = "text/css"; - document.getElementsByTagName("head")[0].appendChild(styleSheetElement); - - // Find the first style sheet that we can access. - // We may not add a rule to a style sheet from another domain for security - // reasons. This sometimes comes up when using gviz, since the Google gviz JS - // adds its own style sheets from google.com. - for (var i = 0; i < document.styleSheets.length; i++) { - if (document.styleSheets[i].disabled) continue; - var mysheet = document.styleSheets[i]; - try { - if (mysheet.insertRule) { // Firefox - var idx = mysheet.cssRules ? mysheet.cssRules.length : 0; - mysheet.insertRule(".dygraphDefaultAnnotation { " + rule + " }", idx); - } else if (mysheet.addRule) { // IE - mysheet.addRule(".dygraphDefaultAnnotation", rule); - } - Dygraph.addedAnnotationCSS = true; - return; - } catch(err) { - // Was likely a security exception. - } - } - - console.warn("Unable to add default annotation CSS rule; display may be off."); -}; - -/** * Add an event handler. This event handler is kept until the graph is * destroyed with a call to graph.destroy(). *