From 50b05ef1245d209faaeb327d87c12370215be472 Mon Sep 17 00:00:00 2001 From: Dan Vanderkam Date: Wed, 10 Aug 2011 14:18:20 -0400 Subject: [PATCH] fix a few bugs, add a few tests --- TODO | 6 ++- auto_tests/tests/axis_labels.js | 26 +++++++++ docs/per-axis.html | 110 +++++++++++++++++++++++++++++++++++++++ dygraph.js | 16 +++++- tests/value-axis-formatters.html | 93 +++++++++++++++++++++++++++++++++ 5 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 docs/per-axis.html create mode 100644 tests/value-axis-formatters.html diff --git a/TODO b/TODO index a2b01c2..fdec3b7 100644 --- a/TODO +++ b/TODO @@ -13,6 +13,8 @@ x Update all options in the options-reference: x axisLabelFormatter x pixelsPerLabel -- Write per-axis.html explaining how this works. +x Write per-axis.html explaining how this works. -- Write some (non-auto) tests +x Write some (non-auto) tests + +x Test for axisLabelFormatter set at top level. diff --git a/auto_tests/tests/axis_labels.js b/auto_tests/tests/axis_labels.js index 802d1c6..151cefe 100644 --- a/auto_tests/tests/axis_labels.js +++ b/auto_tests/tests/axis_labels.js @@ -378,3 +378,29 @@ AxisLabelsTestCase.prototype.testAxisLabelFormatterIncremental = function () { g.setSelection(9); assertEquals("xvf9: y:yvf18", getLegend()); }; + +AxisLabelsTestCase.prototype.testGlobalFormatters = function() { + var opts = { + width: 480, + height: 320, + labels: ['x', 'y'], + valueFormatter: function(x) { + return 'vf' + x; + }, + axisLabelFormatter: function(x) { + return 'alf' + x; + } + }; + var data = []; + for (var i = 0; i < 10; i++) { + data.push([i, 2 * i]); + } + var graph = document.getElementById("graph"); + var g = new Dygraph(graph, data, opts); + + assertEquals(['alf0','alf2','alf4','alf6','alf8'], getXLabels()); + assertEquals(['alf0','alf2','alf4','alf6','alf8','alf10','alf12','alf14','alf16','alf18'], getYLabels()); + + g.setSelection(9); + assertEquals("vf9: y:vf18", getLegend()); +}; diff --git a/docs/per-axis.html b/docs/per-axis.html new file mode 100644 index 0000000..25f632b --- /dev/null +++ b/docs/per-axis.html @@ -0,0 +1,110 @@ + + + + + dygraphs per-series and per-axis options + + + +

dygraphs per-series and per-axis options

+ +

When you create a Dygraph object, your code looks something like + this:

+ + + g = new Dygraph(document.getElementById("div"), + data, + { options }); + + +

This document is about some of the values you can put in the + options parameter.

+ +

per-series options

+ +

Typically, an option applies to the whole chart: if you set the + strokeWidth option, it will apply to all data-series equally:

+ + + g = new Dygraph(document.getElementById("div"), + "X,Y1,Y2,Y3\n" + + "1,2,3,4\n" + + ..., + { + strokeWidth: 5 + }); + + +

Some options, however, can be applied on a per-series or a per-axis + basis. For instance, to set three different strokeWidths, you could + write:

+ + + g = new Dygraph(document.getElementById("div"), + "X,Y1,Y2,Y3\n" + + "1,2,3,4\n" + + ..., + { + strokeWidth: 5, // default stroke width + 'Y1': { + strokeWidth: 3 // Y1 gets a special value. + }, + 'Y3': { + strokeWidth: 1 // so does Y3. + } + }); + + +

The result of these options is that Y1 will have a strokeWidth of 1, Y2 will have a strokeWidth of 5 and Y3 will have a strokeWidth of 1. You can see a demonstration of this here.

+ +

per-axis options

+ +

Some options make more sense when applied to an entire axis, rather than to individual series. For instance, the axisLabelFormatter option lets you specify a function for format the labels on axis tick marks for display. You might want one function for the x-axis and another one for the y-axis.

+ +

Here's how you can do that:

+ + + g = new Dygraph(document.getElementById("div"), + "X,Y1,Y2,Y3\n" + + "1,2,3,4\n" + + ..., + { + axes: { + x: { + axisLabelFormatter: function(x) { + return 'x' + x; + } + }, + y: { + axisLabelFormatter: function(y) { + return 'y' + y; + } + } + } + }); + + +

The keys in the 'axes' option are always 'x', 'y' and, if you have a + secondary y-axis, 'y2'. If you set the "axisLabelFormatter" option at the + top level, it will apply to all axes.

+ +

To see this in practice, check out the two-axes test.

+ + + + + diff --git a/dygraph.js b/dygraph.js index 944e5f8..d25764b 100644 --- a/dygraph.js +++ b/dygraph.js @@ -457,6 +457,12 @@ Dygraph.prototype.optionsViewForAxis_ = function(axis) { if (axis_opts && axis_opts[axis] && axis_opts[axis][opt]) { return axis_opts[axis][opt]; } + // user-specified attributes always trump defaults, even if they're less + // specific. + if (typeof(self.user_attrs_[opt]) != 'undefined') { + return self.user_attrs_[opt]; + } + axis_opts = self.attrs_['axes']; if (axis_opts && axis_opts[axis] && axis_opts[axis][opt]) { return axis_opts[axis][opt]; @@ -1369,8 +1375,11 @@ Dygraph.prototype.generateLegendHTML_ = function(x, sel_points) { var xvf = xOptView('valueFormatter'); var html = xvf(x, xOptView, this) + ":"; - var yOptView = this.optionsViewForAxis_('y'); - var fmtFunc = yOptView('valueFormatter'); + var yOptViews = []; + var num_axes = this.numAxes(); + for (var i = 0; i < num_axes; i++) { + yOptViews[i] = this.optionsViewForAxis_('y' + (i ? 1 + i : '')); + } var showZeros = this.attr_("labelsShowZeroValues"); var sepLines = this.attr_("labelsSeparateLines"); for (var i = 0; i < this.selPoints_.length; i++) { @@ -1379,8 +1388,11 @@ Dygraph.prototype.generateLegendHTML_ = function(x, sel_points) { if (!Dygraph.isOK(pt.canvasy)) continue; if (sepLines) html += "
"; + var yOptView = yOptViews[this.seriesToAxisMap_[pt.name]]; + var fmtFunc = yOptView('valueFormatter'); var c = this.plotter_.colors[pt.name]; var yval = fmtFunc(pt.yval, yOptView, this); + // TODO(danvk): use a template string here and make it an attribute. html += " " + pt.name + ":" diff --git a/tests/value-axis-formatters.html b/tests/value-axis-formatters.html new file mode 100644 index 0000000..193c48e --- /dev/null +++ b/tests/value-axis-formatters.html @@ -0,0 +1,93 @@ + + + + + valueFormatter and axisLabelFormatter + + + + + + +

Multiple y-axes

+

This demonstrates how the valueFormatter and axisLabelFormatter options work. The valueFormatter controls the display of the legend. The axisLabelFormatter controls the display of axis tick marks. These can be set on a per-axis basis.

+
+ + + + + + -- 2.7.4