var opts = {
width: 480,
height: 320,
- xValueFormatter: function(x, opts, dg) {
+ xValueFormatter: function(x, opts, series_name, dg) {
assertEquals('number', typeof(x));
assertEquals('function', typeof(opts));
+ assertEquals('string', typeof(series_name));
assertEquals('[Dygraph graph]', dg.toString());
return 'x' + x;
},
- yValueFormatter: function(y, opts, dg) {
+ yValueFormatter: function(y, opts, series_name, dg) {
assertEquals('number', typeof(y));
assertEquals('function', typeof(opts));
+ assertEquals('string', typeof(series_name));
assertEquals('[Dygraph graph]', dg.toString());
return 'y' + y;
},
var opts = {
width: 480,
height: 320,
- xValueFormatter: function(x, opts, dg) {
+ xValueFormatter: function(x, opts, series_name, dg) {
assertEquals('number', typeof(x));
assertEquals('function', typeof(opts));
+ assertEquals('string', typeof(series_name));
assertEquals('[Dygraph graph]', dg.toString());
return 'x' + new Date(x).strftime('%Y/%m/%d');
},
- yValueFormatter: function(y, opts, dg) {
+ yValueFormatter: function(y, opts, series_name, dg) {
assertEquals('number', typeof(y));
assertEquals('function', typeof(opts));
+ assertEquals('string', typeof(series_name));
assertEquals('[Dygraph graph]', dg.toString());
return 'y' + y;
},
* and maxNumberWidth options.
* @param {Number} x The number to be formatted
* @param {Dygraph} opts An options view
+ * @param {String} name The name of the point's data series
* @param {Dygraph} g The dygraph object
*/
-Dygraph.numberValueFormatter = function(x, opts, g) {
+Dygraph.numberValueFormatter = function(x, opts, pt, g) {
var sigFigs = opts('sigFigs');
if (sigFigs !== null) {
var xOptView = this.optionsViewForAxis_('x');
var xvf = xOptView('valueFormatter');
- var html = xvf(x, xOptView, this) + ":";
+ var html = xvf(x, xOptView, this.attr_('labels')[0], this) + ":";
var yOptViews = [];
var num_axes = this.numAxes();
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);
+ var yval = fmtFunc(pt.yval, yOptView, pt.name, this);
// TODO(danvk): use a template string here and make it an attribute.
html += " <b><span style='color: " + c + ";'>"
--- /dev/null
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9">
+ <title>multi-scale</title>
+ <!--[if IE]>
+ <script type="text/javascript" src="../excanvas.js"></script>
+ <![endif]-->
+ <script type="text/javascript" src="../dygraph-dev.js"></script>
+ </head>
+ <body style="max-width: 700px;">
+ <p>Gridlines and axis labels make charts easier to understand. They give
+ the lines a clear scale. Unless you tell it otherwise, dygraphs will choose
+ a y-axis and set of gridlines which include all of your data.</p>
+
+ <p>If you have many series with different scales, this will compress the
+ variation in all but the largest one. Standard ways to deal with this
+ include <a href="two-axes.html">secondary y-axes</a> and <a
+ href="logscale.html">log scales</a>.</p>
+
+ <p>If neither of these is to your liking, you can manually rescale your
+ series and undo that scaling for the hover values. This demo shows how to
+ do it.</p>
+
+ <div id="demodiv"></div>
+
+ <p>Hover over to see the original values. This is what the data looks
+ like without any rescaling:</p>
+
+ <div id="reference_div"></div>
+
+ <script type="text/javascript">
+ var zp = function(x) { if (x < 10) return "0"+x; else return x; };
+ var labels = ["date","parabola","line","another line","sine wave"];
+ var data = [];
+ for (var i=1; i<=31; i++) {
+ var row = [];
+ row.push(new Date("2006/10/" + zp(i)));
+ row.push(10*(i*(31-i)));
+ row.push(100*(8*i));
+ row.push(1000*(250 - 8*i));
+ row.push(10000*(125 + 125 * Math.sin(0.3*i)));
+ data.push(row);
+ }
+
+ var scales = {
+ "parabola": 1,
+ "line": 10,
+ "another line": 100,
+ "sine wave": 1000
+ };
+ var rescaled_data = [];
+ for (var i = 0; i < data.length; i++) {
+ var src = data[i];
+ var row = [];
+ row.push(src[0]);
+ for (var j = 1; j < src.length; j++) {
+ row.push(src[j] / scales[labels[j]]);
+ }
+ rescaled_data.push(row);
+ }
+
+ g = new Dygraph(
+ document.getElementById("demodiv"),
+ rescaled_data,
+ {
+ legend: 'always',
+ labels: labels,
+ width: 640,
+ height: 480,
+ title: 'Four series on different scales',
+ xlabel: 'Date',
+ ylabel: 'Count',
+ yValueFormatter: function(y, opts, series_name) {
+ var unscaled = y * scales[series_name];
+ if (series_name == 'sine wave') return unscaled.toPrecision(4);
+ return unscaled;
+ }
+ }
+ );
+
+ g_orig = new Dygraph(
+ document.getElementById("reference_div"),
+ data,
+ {
+ legend: 'always',
+ labels: labels,
+ width: 640,
+ height: 480,
+ title: 'Four series on the same scale',
+ xlabel: 'Date',
+ ylabel: 'Count',
+ yAxisLabelWidth: 80
+ }
+ );
+ </script>
+</body>
+</html>