<!DOCTYPE html> <meta charset="utf-8"> <link href="../src/nv.d3.css" rel="stylesheet" type="text/css"> <link href="teststyle.css" rel="stylesheet" type='text/css'> <style> #chart13, #chart14 { overflow: scroll; width: 500px; height: 300px; } #chart13 svg, #chart14 svg { width: 700px; height: 400px; } </style> <body> <h3>Line chart test cases - feel free to add more tests</h3> <div style='position:relative;'> <div class='navigation'> Tests: <a href="lineChartTest.html">Line Chart</a> <a href="stackedAreaChartTest.html">Stacked Area</a> <a href="../examples/cumulativeLineChart.html">Cumulative Line</a> <a href="ScatterChartTest.html">Scatter</a> <a href="pieChartTest.html">Pie chart</a> <a href="realTimeChartTest.html">Real time test</a> <a href="polylinearTest.html">Polylinear test</a> <a href="interactiveBisectTest.html">nv.interactiveBisect unit tests</a> </div> <div class='chart full' id='chart1'> Example of chart with many series', and new interactive guideline plus tooltip. A chunk of data was purposely removed to show how the chart handles it. <button>Select chart</button> <svg></svg> </div> <div class='chart half with-transitions' id='chart2'> Chart with old tooltip style (with-transitions). <button>Select chart</button> <svg></svg> </div> <div class='chart half' id='chart3'> Chart with three data points. <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart4'> Chart where two series have different number of points. <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart5'> Chart with one point. <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart6'> Chart with 1000 points. <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart7'> Chart with no data. <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart8'> All points random. No order. <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart9'> Points do not increase linearly. <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart10'> Chart with 15 series' <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart11'> Data points go backwards <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart12'> Duplicate X coordinate points. <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart16'> Duplicate Y coordinate points. <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart13'> Chart in a overflow div with scrolls (new tooltips) <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart14'> Chart in a overflow div with scrolls (old tooltips) <button>Select chart</button> <svg></svg> </div> <div style='clear:both;'></div> <div class='chart third' id='chart15'> What if there are null, Infinity and NaN values in points? <button>Select chart</button> <svg></svg> </div> <div class='chart third' id='chart17'> Chart with very small, 1e-10, points (old tooltips) <button>Select chart</button> <svg></svg> </div> </div> <script src="../lib/d3.v3.js"></script> <script src="../nv.d3.js"></script> <script src="../src/tooltip.js"></script> <script src="../src/utils.js"></script> <script src="../src/interactiveLayer.js"></script> <script src="../src/models/legend.js"></script> <script src="../src/models/axis.js"></script> <script src="../src/models/scatter.js"></script> <script src="../src/models/line.js"></script> <script src="../src/models/lineChart.js"></script> <script src="testScript.js"></script> <script> d3.select("body").on("keydown",function() { if (d3.event.ctrlKey && d3.event.which === 75) { alert("keydowned"); } }); //------------ CHART 1 defaultChartConfig("chart1", dummyStocks(),true, true, {forceY:false}); //-------------- CHART 2 --- Chart without the interactive guideline. nv.addGraph(function() { var chart; chart = nv.models.lineChart().useInteractiveGuideline(false); chart .x(function(d,i) { return d.x }); chart.xAxis // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately .tickFormat(d3.format(',.1f')); chart.yAxis .axisLabel('Voltage (v)') .tickFormat(d3.format(',.4f')); chart.showXAxis(true).showYAxis(true).rightAlignYAxis(true).margin({right: 90}); d3.select('#chart2 svg') //.datum([]) //for testing noData .datum(dummyStocks(50)) .transition().duration(500) .call(chart); nv.utils.windowResize(chart.update); return chart; }); defaultChartConfig("chart3", smallDataSet(3)); defaultChartConfig("chart4", badDataSet()); defaultChartConfig("chart5", smallDataSet(1)); defaultChartConfig("chart6", normalDist()); defaultChartConfig("chart7", smallDataSet(0)); defaultChartConfig("chart8", allRandom(),false); defaultChartConfig("chart9", fibonacci()); defaultChartConfig("chart10", lotsofSeries()); defaultChartConfig("chart11", backwards(),false); defaultChartConfig("chart12", duplicateX(),false); defaultChartConfig("chart13",hyperbole(), true, false, {width: 700, height: 400}); defaultChartConfig("chart14",hyperbole(), false, false, {width: 700, height: 400}); defaultChartConfig("chart15", withNaNs()); defaultChartConfig("chart16", duplicateY(), false); defaultChartConfig("chart17", tinyPoints(), false); function defaultChartConfig(containerid, data, guideline, useDates, auxOptions) { if (auxOptions === undefined) auxOptions = {}; if (guideline === undefined) guideline = true; nv.addGraph(function() { var chart; chart = nv.models.lineChart().useInteractiveGuideline(guideline); chart .x(function(d,i) { return d.x; }); if (auxOptions.width) chart.width(auxOptions.width); if (auxOptions.height) chart.height(auxOptions.height); if (auxOptions.forceY) chart.forceY([0]); var formatter; if (useDates !== undefined) { formatter = function(d,i) { var now = (new Date()).getTime() - 86400 * 1000 * 365; now = new Date(now + d * 86400 * 1000); return d3.time.format('%b %d %Y')(now ); } } else { formatter = d3.format(",.1f"); } chart.margin({right: 40}); chart.xAxis // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately .tickFormat( formatter ); chart.yAxis .axisLabel('Voltage (v)') .tickFormat(d3.format(',.2f')); d3.select('#' + containerid + ' svg') .datum(data) .transition().duration(500) .call(chart); nv.utils.windowResize(chart.update); return chart; }); } function sinAndCos() { var sin = [], cos = [], rand = [], rand2 = [] ; var now = (new Date()).getTime(); for (var i = 0; i < 100; i++) { sin.push({x: i, y: i % 10 == 5 ? null : Math.sin(i/10) }); //the nulls are to show how defined works cos.push({x: i, y: .5 * Math.cos(i/10)}); rand.push({x:i, y: Math.random() / 10}); rand2.push({x: i, y: Math.cos(i/10) + Math.random() / 10 }) } return [ { area: true, values: sin, key: "Sine Wave", color: "#ff7f0e" }, { values: cos, key: "Cosine Wave", color: "#2ca02c" }, { values: rand, key: "Random Points", color: "#2222ff" } , { values: rand2, key: "Random Cosine", color: "#667711" } ]; } function hyperbole() { var series1 = [], series2 = [], series3 = []; for(var i = 1; i < 100; i++) { series1.push({x: i, y: 1 / i}); series2.push({x: i, y: 5 / i}); series3.push({x: i, y: -8 / i}); } return [ {values: series1, key: "Series 1"}, {values: series2, key: "Series 2"}, {values: series3, key: "Series 3"} ]; } function smallDataSet(n) { var series = []; for(var i = 0; i < n; i++) { series.push({x: i, y: i * 0.3 + 2}) } return [ {values: series, key: "Line 1"} ]; } function badDataSet() { var series1 = [], series2 = []; for(var i =0; i < 30; i++) { series1.push({x:i, y: i*0.3 + 12}); } for(i = 0; i < 30; i += 5) { series2.push({x:i, y: i*0.7 + 8}); } return [ {values: series1, key:"Series 1"}, {values: series2, key:"Series 2"} ]; } function normalDist() { var series1 = [], series2 = []; for(var i = -500; i < 500; i += 1) { var x = i / 100; var y = 0.3989 * Math.pow(2.71, -0.5*x*x); series1.push({x:i, y:y}); series2.push({x:i, y:y*2}); } return [ {values: series1, key:"Normal 1", area:true}, {values: series2, key:"Normal 2"}]; } function allRandom() { var series = []; for(var i = 0; i < 20; i++) { series.push({x: Math.floor(Math.random()*20), y: Math.floor(Math.random()*20) }); } return [{values: series,area:true, key: "Total Chaos"}]; } function fibonacci() { var series = [ {x:1, y:1}, {x:2, y:2.5}, {x:3, y:4}, {x:5, y:6.7}, {x:8, y:10.1}, {x:13, y:20.1}, {x:21, y:35.1}, {x:34, y:60.0}, {x:55, y:70.9}, {x:89, y:100.3} ]; return [{values: series,area:true,color: "#22fb88", key: "Fibonacci"}]; } function lotsofSeries() { var rval = []; for(var n = 0; n < 15; n++) { var values = []; var slope = Math.random() * 5; for(var i =0; i < 30; i++) { values.push( {x: i, y: i * slope + Math.random()*5} ); } var isArea = (Math.random() > 0.5); rval.push({key: "Series " + n, area: isArea, values: values}); } return rval; } function backwards() { var series = []; for(var i = 30; i >= 1; i--) { series.push({x: i, y: Math.sqrt(i) }); } return [{values: series, key: "Backwards series", area:true}]; } function duplicateX() { return [ {key: "Duplicate X", area: true, values: [ {x: 4, y: 10}, {x: 4, y: 11}, {x: 4, y: 12}, {x: 4, y: 13} ] } ]; } function duplicateY() { return [ {key: "Duplicate Y", values: [ {x: 0, y: 10}, {x:1, y:10},{x:2, y:10},{x:3, y:10} ] } ]; } function withNaNs() { return [ {key: "NaN Points", values: [ {x: 1, y: NaN}, {x: 2, y: undefined}, {x: 3, y: false}, {x: 4, y: null}, {x: 5, y: "Hello"}, {x: NaN, y: NaN}, {x: null, y: null}, {x: undefined, y: undefined}, {x: "Hello", y: "World"}, {x: Infinity, y: Infinity} ] } ] } function tinyPoints() { var rval = {key: "Tiny points", values: []}; for(var i =1; i < 20; i++) { rval.values.push({ x: i, y: Math.random() * 1e-10 }); } return [rval]; } function dummyStocks(numPoints) { numPoints = numPoints || 200; function volatileChart(key,startPrice, volatility, isArea) { var rval = {key: key, values: []}; if (isArea) rval.area = true; for(var i = 1; i < numPoints; i++) { rval.values.push({x: i, y: (i > 110 && i < 130) ? null : startPrice}); var rnd = Math.random(); var changePct = 2 * volatility * rnd; if ( changePct > volatility) { changePct -= (2*volatility); } startPrice = startPrice + startPrice * changePct; } return rval; } var stocks = []; stocks.push(volatileChart("APPL",5.00, 0.02)); stocks.push(volatileChart("GOOG", 6.01,0.024)); stocks.push(volatileChart("MSFT", 2.01, 0.012)); stocks.push(volatileChart("IBM US", 2.5, 0.08, true)); return stocks; } </script>