return this.__repr__();
};
++/**
++ * Number formatting function which mimicks the behavior of %g in printf, i.e.
++ * either exponential or fixed format (without trailing 0s) is used depending on
++ * the length of the generated string. The advantage of this format is that
++ * there is a predictable upper bound on the resulting string length and
++ * significant figures are not dropped.
++ *
++ * NOTE: JavaScript's native toPrecision() is NOT a drop-in replacement for %g.
++ * It creates strings which are too long for absolute values between 10^-4 and
++ * 10^-6. See tests/number-format.html for examples.
++ *
++ * @param {Number} x The number to format
++ * @param {Number} opt_precision The precision to use, default 2.
++ * @return {String} A string formatted like %g in printf. The max generated
++ * string length should be precision +
++ */
++Dygraph.defaultFormat = function(x, opt_precision) {
++ // Avoid invalid precision values; [1, 21] is the valid range.
++ var p = Math.min(Math.max(1, opt_precision || 2), 21);
++
++ // This is deceptively simple. The actual algorithm comes from:
++ //
++ // Max allowed length = p + 4
++ // where 4 comes from 'e+n' and '.'.
++ //
++ // Length of fixed format = 2 + y + p
++ // where 2 comes from '0.' and y = # of leading zeroes.
++ //
++ // Equating the two and solving for y yields y = 2, or 0.00xxxx which is
++ // 1.0e-3.
++ //
++ // Since the behavior of toPrecision() is identical for larger numbers, we
++ // don't have to worry about the other bound.
++ //
++ // Finally, the argument for toExponential() is the number of trailing digits,
++ // so we take off 1 for the value before the '.'.
++ return (Math.abs(x) < 1.0e-3 && x != 0.0) ?
++ x.toExponential(p - 1) : x.toPrecision(p);
++};
++
// Various default values
Dygraph.DEFAULT_ROLL_PERIOD = 1;
Dygraph.DEFAULT_WIDTH = 480;
labelsKMG2: false,
showLabelsOnHighlight: true,
- yValueFormatter: function(x, opt_numDigits) {
- return x.toPrecision(Math.min(21, Math.max(1, opt_numDigits || 2)));
- },
- yValueFormatter: function(x) { return Dygraph.round_(x, 2); },
++ yValueFormatter: Dygraph.defaultFormat,
strokeWidth: 1.0,
Dygraph.numericTicks(axis.computedValueRange[0],
axis.computedValueRange[1],
this, axis, tick_values);
+ axis.ticks = ret.ticks;
+ this.numYDigits_ = ret.numDigits;
}
}
+
+ return [this.axes_, this.seriesToAxisMap_];
};
/**
--- /dev/null
--- /dev/null
++<html>
++ <head>
++ <title>Benchmarking for Plots with Many Points</title>
++ <!--[if IE]>
++ <script type="text/javascript" src="../excanvas.js"></script>
++ <![endif]-->
++ <script type="text/javascript" src="../strftime/strftime-min.js"></script>
++ <script type="text/javascript" src="../rgbcolor/rgbcolor.js"></script>
++ <script type="text/javascript" src="../dygraph-canvas.js"></script>
++ <script type="text/javascript" src="../dygraph.js"></script>
++ </head>
++ <body>
++ <p>Plot which can be easily generated with different numbers of points for
++ benchmarking/profiling and improving performance of dygraphs.</p>
++ <p>Number of points:
++ <input type="text" id="num_points_input" size="20"
++ onchange="updatePlot();"></p>
++ <p>Roll period (in points):
++ <input type="text" id="roll_period_input" size="20"
++ onchange="updatePlot();"></p>
++ <br>
++ <br>
++ <div id="plot"></div>
++
++ <script type="text/javascript">
++ var plot;
++
++ updatePlot = function() {
++ var plotDiv = document.getElementById('plot');
++ plotDiv.innerHTML = 'Redrawing...';
++ var numPoints =
++ parseInt(document.getElementById('num_points_input').value);
++ var data = [];
++ var xmin = 0.0;
++ var xmax = 2.0 * Math.PI;
++ var delta = (xmax - xmin) / (numPoints - 1);
++
++ for (var i = 0; i < numPoints; ++i) {
++ var x = xmin + delta * i;
++ var y = Math.sin(x);
++ data[i] = [x, y];
++ }
++
++ var rollPeriod = parseInt(
++ document.getElementById('roll_period_input').value);
++ var opts = {labels: ['x', 'sin(x)'], rollPeriod: rollPeriod};
++ plot = new Dygraph(plotDiv, data, opts);
++ };
++
++ document.getElementById('num_points_input').value = '100';
++ document.getElementById('roll_period_input').value = '1';
++ updatePlot();
++ </script>
++ </body>
++</html>
--- /dev/null
--- /dev/null
++<html>
++ <head>
++ <title>Test of number formatting</title>
++ <!--[if IE]>
++ <script type="text/javascript" src="../excanvas.js"></script>
++ <![endif]-->
++ <script type="text/javascript" src="../strftime/strftime-min.js"></script>
++ <script type="text/javascript" src="../rgbcolor/rgbcolor.js"></script>
++ <script type="text/javascript" src="../dygraph-canvas.js"></script>
++ <script type="text/javascript" src="../dygraph.js"></script>
++ </head>
++ <body>
++ <p>The default formatting mimicks printf with %.<i>p</i>g where <i>p</i> is
++ the precision to use. It turns out that JavaScript's toPrecision()
++ method is almost but not exactly equal to %g; they differ for values
++ with small absolute values (10^-1 to 10^-5 or so), with toPrecision()
++ yielding strings that are longer than they should be (i.e. using fixed
++ point where %g would use exponential).</p>
++
++ <p>This test is intended to check that our formatting works properly for a
++ variety of precisions.</p>
++
++ <p>Precision to use (1 to 21):
++ <input type="text" id="p_input" size="20" onchange="updateTable();"></p>
++ <br>
++ <br>
++ <div id="content" style="font-family:'Courier New',monospace"></div>
++
++ <script type="text/javascript">
++ // Helper functions for generating an HTML table for holding the test
++ // results.
++ createRow = function(columnType, columns) {
++ var row = document.createElement('tr');
++ for (var i = 0; i < columns.length; i ++) {
++ var th = document.createElement(columnType);
++ var text = document.createTextNode(columns[i]);
++ th.appendChild(text);
++ row.appendChild(th);
++ };
++ return row;
++ };
++
++ createHeaderRow = function(columns) {
++ return createRow('th', columns);
++ };
++
++ createDataRow = function(columns) {
++ return createRow('td', columns);
++ };
++
++ createTable = function(headerColumns, dataColumnsList) {
++ var table = document.createElement('table');
++ table.appendChild(createHeaderRow(headerColumns));
++ for (var i = 0; i < dataColumnsList.length; i++) {
++ table.appendChild(createDataRow(dataColumnsList[i]));
++ }
++ return table;
++ };
++
++ updateTable = function() {
++ var headers = ['Dygraph.defaultFormat()', 'toPrecision()',
++ 'Dygraph.defaultFormat()', 'toPrecision()'];
++ var numbers = [];
++ var p = parseInt(document.getElementById('p_input').value);
++
++ for (var i = -10; i <= 10; i++) {
++ var n = Math.pow(10, i);
++ numbers.push([Dygraph.defaultFormat(n, p),
++ n.toPrecision(p),
++ Dygraph.defaultFormat(Math.PI * n, p),
++ (Math.PI * n).toPrecision(p)]);
++ }
++
++ // Check exact values of 0.
++ numbers.push([Dygraph.defaultFormat(0.0, p),
++ 0.0.toPrecision(p)]);
++
++ var elem = document.getElementById('content');
++ elem.innerHTML = '';
++ elem.appendChild(createTable(headers, numbers));
++ };
++
++ document.getElementById('p_input').value = '4';
++ updateTable();
++ </script>
++ </body>
++</html>