Util.getYLabels());
};
+// Same sa testLabelKMG2 but specifies the option at the
+// top of the option dictionary.
+AxisLabelsTestCase.prototype.testLabelKMG2_top = function() {
+ var data = [];
+ data.push([0,0]);
+ data.push([1,2000]);
+ data.push([2,1000]);
+
+ var g = new Dygraph(
+ document.getElementById("graph"),
+ data,
+ {
+ labels: [ 'X', 'bar' ],
+ labelsKMG2: true
+ }
+ );
+
+ assertEquals(
+ ["0","256","512","768","1k","1.25k","1.5k","1.75k","2k"],
+ Util.getYLabels());
+};
+
/**
* Verify that log scale axis range is properly specified.
*/
*/
var CustomBarsTestCase = TestCase("custom-bars");
+var _origFunc = Dygraph.getContext;
CustomBarsTestCase.prototype.setUp = function() {
document.body.innerHTML = "<div id='graph'></div>";
+ Dygraph.getContext = function(canvas) {
+ return new Proxy(_origFunc(canvas));
+ }
};
CustomBarsTestCase.prototype.tearDown = function() {
+ Dygraph.getContext = _origFunc;
};
// This test used to reliably produce an infinite loop.
var sampler = new PixelSampler(g);
assertEquals([0, 255, 0, 38], sampler.colorAtCoordinate(5, 60));
};
+
+// Tests that custom bars work with log scale.
+CustomBarsTestCase.prototype.testCustomBarsLogScale = function() {
+ var g = new Dygraph(document.getElementById("graph"),
+ [
+ [1, [10, 10, 100]],
+ [5, [15,120, 80]],
+ [9, [10, 50, 100]]
+ ], {
+ width: 500, height: 350,
+ customBars: true,
+ errorBars: true,
+ valueRange: [1, 120],
+ drawXGrid: false,
+ drawYGrid: false,
+ drawXAxis: false,
+ drawYAxis: false,
+ fillAlpha: 1.0,
+ logscale: true,
+ colors: [ '#00FF00' ]
+ });
+
+ // The following assertions describe the sides of the custom bars, which are
+ // drawn in two halves.
+ CanvasAssertions.assertConsecutiveLinesDrawn(
+ g.hidden_ctx_,
+ [[0, 13.329014086362069],
+ [247.5, 29.64240889852502],
+ [247.5, 152.02209814465604],
+ [0, 181.66450704318103]],
+ { fillStyle: "#00ff00" });
+
+ CanvasAssertions.assertConsecutiveLinesDrawn(
+ g.hidden_ctx_,
+ [[247.5, 29.64240889852502],
+ [495, 13.329014086362069],
+ [495, 181.66450704318103],
+ [247.5, 152.02209814465604]],
+ { fillStyle: "#00ff00" });
+};
this.checkForInverses(g);
}
+
+ToDomCoordsTestCase.prototype.testYAxisLabelWidth = function() {
+ var opts = {
+ yAxisLabelWidth: 100,
+ axisTickSize: 0,
+ rightGap: 0,
+ valueRange: [0, 100],
+ dateWindow: [0, 100],
+ width: 500,
+ height: 500
+ }
+
+ var graph = document.getElementById("graph");
+ g = new Dygraph(graph, [ [0,0], [100,100] ], opts);
+
+ assertEquals([100, 0], g.toDomCoords(0, 100));
+ assertEquals([500, 486], g.toDomCoords(100, 0));
+
+ g.updateOptions({ yAxisLabelWidth: 50 });
+ assertEquals([50, 0], g.toDomCoords(0, 100));
+ assertEquals([500, 486], g.toDomCoords(100, 0));
+}
+
+ToDomCoordsTestCase.prototype.testAxisTickSize = function() {
+ var opts = {
+ yAxisLabelWidth: 100,
+ axisTickSize: 0,
+ rightGap: 0,
+ valueRange: [0, 100],
+ dateWindow: [0, 100],
+ width: 500,
+ height: 500
+ }
+
+ var graph = document.getElementById("graph");
+ g = new Dygraph(graph, [ [0,0], [100,100] ], opts);
+
+ assertEquals([100, 0], g.toDomCoords(0, 100));
+ assertEquals([500, 486], g.toDomCoords(100, 0));
+
+ g.updateOptions({ axisTickSize : 50 });
+ assertEquals([200, 0], g.toDomCoords(0, 100));
+ assertEquals([500, 386], g.toDomCoords(100, 0));
+}
var yRange = g.yAxisRange(i);
// TODO(konigsberg): These values should be in |context|.
// In log scale, initialTopValue, dragValueRange and unitsPerPixel are log scale.
- if (axis.logscale) {
+ var logscale = g.attributes_.getForAxis("logscale", i);
+ if (logscale) {
axis_data.initialTopValue = Dygraph.log10(yRange[1]);
axis_data.dragValueRange = Dygraph.log10(yRange[1]) - Dygraph.log10(yRange[0]);
} else {
minValue = maxValue - axis_data.dragValueRange;
}
}
- if (axis.logscale) {
+ var logscale = g.attributes_.getForAxis("logscale", i);
+ if (logscale) {
axis.valueWindow = [ Math.pow(Dygraph.LOG_SCALE, minValue),
Math.pow(Dygraph.LOG_SCALE, maxValue) ];
} else {
if (context.touchDirections.y) {
for (i = 0; i < 1 /*g.axes_.length*/; i++) {
var axis = g.axes_[i];
- if (axis.logscale) {
+ var logscale = g.attributes_.getForAxis("logscale", i);
+ if (logscale) {
// TODO(danvk): implement
} else {
axis.valueWindow = [
}
};
-DygraphLayout._calcYNormal = function(axis, value) {
- if (axis.logscale) {
+DygraphLayout._calcYNormal = function(axis, value, logscale) {
+ if (logscale) {
return 1.0 - ((Dygraph.log10(value) - Dygraph.log10(axis.minyval)) * axis.ylogscale);
} else {
return 1.0 - ((value - axis.minyval) * axis.yscale);
var dataset = this.datasets[setIdx];
var setName = this.setNames[setIdx];
var axis = this.dygraph_.axisPropertiesForSeries(setName);
+ // TODO (konigsberg): use optionsForAxis instead.
+ var logscale = this.dygraph_.attributes_.getForSeries("logscale", setIdx);
// Preallocating the size of points reduces reallocations, and therefore,
// calls to collect garbage.
// Range from 0-1 where 0 represents left and 1 represents right.
var xNormal = (xValue - this.minxval) * this.xscale;
// Range from 0-1 where 0 represents top and 1 represents bottom
- var yNormal = DygraphLayout._calcYNormal(axis, yValue);
+ var yNormal = DygraphLayout._calcYNormal(axis, yValue, logscale);
// TODO(danvk): drop the point in this case, don't null it.
// The nulls create complexity in DygraphCanvasRenderer._drawSeries.
var dataset = this.datasets[setIdx];
var setName = this.setNames[setIdx];
var axis = this.dygraph_.axisPropertiesForSeries(setName);
+ // TODO (konigsberg): use optionsForAxis instead.
+ var logscale = this.dygraph_.attributes_.getForSeries("logscale", setIdx);
+
for (j = 0; j < dataset.length; j++, i++) {
var item = dataset[j];
var xv = DygraphLayout.parseFloat_(item[0]);
var yv_minus = yv - errorMinus;
var yv_plus = yv + errorPlus;
- points[j].y_top = DygraphLayout._calcYNormal(axis, yv_minus);
- points[j].y_bottom = DygraphLayout._calcYNormal(axis, yv_plus);
+ points[j].y_top = DygraphLayout._calcYNormal(axis, yv_minus, logscale);
+ points[j].y_bottom = DygraphLayout._calcYNormal(axis, yv_plus, logscale);
}
}
}
var yRange = this.yAxisRange(axis);
var pct;
- if (!this.axes_[axis].logscale) {
+ var logscale = this.attributes_.getForAxis("logscale", axis);
+ if (!logscale) {
// yRange[1] - y is unit distance from the bottom.
// yRange[1] - yRange[0] is the scale of the range.
// (yRange[1] - y) / (yRange[1] - yRange[0]) is the % from the bottom.
}
// TODO(konigsberg): REMOVE THIS SILLINESS this should just come from DygraphOptions.
- // TODO(konigsberg): Add tests for all of these. Currently just tests for
- // includeZero and logscale.
+ // TODO(konigsberg): Add tests for all of these.
// all options which could be applied per-axis:
var axisOptions = [
- 'includeZero',
'valueRange',
- 'labelsKMB',
- 'labelsKMG2',
'pixelsPerYLabel',
- 'yAxisLabelWidth',
'axisLabelFontSize',
- 'axisTickSize',
- 'logscale'
];
// Copy global axis options over to the first axis.
// Compute extreme values, a span and tick marks for each axis.
for (var i = 0; i < numAxes; i++) {
var axis = this.axes_[i];
-
+ var logscale = this.attributes_.getForAxis("logscale", i);
+ var includeZero = this.attributes_.getForAxis("includeZero", i);
series = this.attributes_.seriesForAxis(i);
if (series.length == 0) {
maxY = Math.max(extremeMaxY, maxY);
}
}
- if (axis.includeZero && minY > 0) minY = 0;
+ if (includeZero && minY > 0) minY = 0;
// Ensure we have a valid scale, otherwise default to [0, 1] for safety.
if (minY == Infinity) minY = 0;
if (span === 0) { span = maxY; }
var maxAxisY, minAxisY;
- if (axis.logscale) {
+ if (logscale) {
maxAxisY = maxY + 0.1 * span;
minAxisY = minY;
} else {
isDate = true;
}
+ this.setXAxisOptions_(isDate);
+};
+
+Dygraph.prototype.setXAxisOptions_ = function(isDate) {
if (isDate) {
this.attrs_.xValueParser = Dygraph.dateParser;
this.attrs_.axes.x.valueFormatter = Dygraph.dateString_;
this.attrs_.axes.x.ticker = Dygraph.numericLinearTicks;
this.attrs_.axes.x.axisLabelFormatter = this.attrs_.axes.x.valueFormatter;
}
-};
+}
/**
* Parses the value as a floating point number. This is like the parseFloat()
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.axisLabelFormatter = Dygraph.dateAxisFormatter;
this.attrs_.axes.x.ticker = Dygraph.dateTicker;
+ this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisFormatter;
// Assume they're all dates.
var parsedData = Dygraph.clone(data);
// Some intelligent defaults for a numeric x-axis.
/** @private (shut up, jsdoc!) */
this.attrs_.axes.x.valueFormatter = function(x) { return x; };
- this.attrs_.axes.x.axisLabelFormatter = Dygraph.numberAxisLabelFormatter;
this.attrs_.axes.x.ticker = Dygraph.numericLinearTicks;
+ this.attrs_.axes.x.axisLabelFormatter = Dygraph.numberAxisLabelFormatter;
return data;
}
};