diff --git a/nvd3/nvd-test-bullet.ts b/nvd3/nvd-test-bullet.ts new file mode 100644 index 000000000..7ec2363e0 --- /dev/null +++ b/nvd3/nvd-test-bullet.ts @@ -0,0 +1,46 @@ +/// +/// + +var width = 960, + height = 55, + margin = {top: 5, right: 40, bottom: 20, left: 120}; + + var chart = nv.models.bullet() + .width(width - margin.right - margin.left) + .height(height - margin.top - margin.bottom); + + var data = [ + {"title":"Revenue","subtitle":"US$, in thousands","ranges":[-150,-225,-300],"measures":[-220],"markers":[-250]} + ]; + + //TODO: to be consistent with other models, should be appending a g to an already made svg, not creating the svg element + var vis = d3.select("#chart").selectAll("svg") + .data(data) + .enter().append("svg") + .attr("class", "bullet nvd3") + .attr("width", width) + .attr("height", height); + + vis.transition().duration(1000).call(chart); + + var transition = function() { + vis.datum(randomize); + vis.transition().duration(1000).call(chart); + }; + + function randomize(d) { + if (!d.randomizer) d.randomizer = randomizer(d); + d.ranges = d.ranges.map(d.randomizer); + d.markers = d.markers.map(d.randomizer); + d.measures = d.measures.map(d.randomizer); + return d; + } + + function randomizer(d) { + var k = d3.max(d.ranges) * .2; + return function(d) { + return Math.max(0, d + k * (Math.random() - .5)); + }; + } + + d3.select('body').on('click', transition); \ No newline at end of file diff --git a/nvd3/nvd-test-bulletChart.ts b/nvd3/nvd-test-bulletChart.ts new file mode 100644 index 000000000..eb727589e --- /dev/null +++ b/nvd3/nvd-test-bulletChart.ts @@ -0,0 +1,72 @@ +/// +/// + +var width = 960, + height = 80, + margin = {top: 5, right: 40, bottom: 20, left: 120}; + +var chart = nv.models.bulletChart() + .width(width - margin.right - margin.left) + .height(height - margin.top - margin.bottom); + +var chart2 = nv.models.bulletChart() + .width(width - margin.right - margin.left) + .height(height - margin.top - margin.bottom); + +var data = [ + {"title":"Revenue","subtitle":"US$, in thousands","ranges":[150,225,300],"measures":[220],"markers":[250]}, + {"title":"Order Size","subtitle":"US$, average","ranges":[350,500,600],"measures":[100],"markers":[550]}, + {"title":"Satisfaction","subtitle":"out of 5","ranges":[3.5,4.25,5],"measures":[3.2,4.7],"markers":[4.4]} +]; + +var dataWithLabels = [{ + "title":"Revenue", + "subtitle":"US$, in thousands", + "ranges":[150,225,300], + "measures":[220], + "markers":[250, 100], + "markerLabels":['Target Inventory', 'Low Inventory'], + "rangeLabels":['Maximum Inventory','Average Inventory','Minimum Inventory'], + "measureLabels":['Current Inventory'] +}]; + +//TODO: to be consistent with other models, should be appending a g to an already made svg, not creating the svg element +var vis = d3.select("#chart").selectAll("svg") + .data(data) + .enter().append("svg") + .attr("class", "bullet nvd3") + .attr("width", width) + .attr("height", height); + +vis.transition().duration(1000).call(chart); + +var vis2 = d3.select("#chart2").selectAll("svg") + .data(dataWithLabels) + .enter().append('svg') + .attr('class',"bullet nvd3") + .attr("width",width) + .attr("height",height); + +vis2.transition().duration(1000).call(chart2); + +var transition = function() { + vis.datum(randomize).transition().duration(1000).call(chart); + vis2.datum(randomize).transition().duration(1000).call(chart2); +}; + +function randomize(d) { + if (!d.randomizer) d.randomizer = randomizer(d); + d.ranges = d.ranges.map(d.randomizer); + d.markers = d.markers.map(d.randomizer); + d.measures = d.measures.map(d.randomizer); + return d; +} + +function randomizer(d) { + var k = d3.max(d.ranges) * .2; + return function(d) { + return Math.max(0, d + k * (Math.random() - .5)); + }; + } + + d3.select('body').on('click', transition); \ No newline at end of file diff --git a/nvd3/nvd3-test-boxplot.ts b/nvd3/nvd3-test-boxplot.ts new file mode 100644 index 000000000..3b7809531 --- /dev/null +++ b/nvd3/nvd3-test-boxplot.ts @@ -0,0 +1,57 @@ +/// +/// +nv.addGraph(function() { + var chart = nv.models.boxPlotChart() + .x(function(d) { return d.label }) + .y(function(d) { return d.values.Q3 }) + .staggerLabels(true) + .maxBoxWidth(75) // prevent boxes from being incredibly wide + .yDomain([0, 500]) + ; + + d3.select('#chart1 svg') + .datum(exampleData()) + .call(chart); + + nv.utils.windowResize(chart.update); + + return chart; + }); + + function exampleData() { + return [ + { + label: "Sample A", + values: { + Q1: 120, + Q2: 150, + Q3: 200, + whisker_low: 115, + whisker_high: 210, + outliers: [50, 100, 225] + }, + }, + { + label: "Sample B", + values: { + Q1: 300, + Q2: 350, + Q3: 400, + whisker_low: 225, + whisker_high: 425, + outliers: [175] + }, + }, + { + label: "Sample C", + values: { + Q1: 50, + Q2: 100, + Q3: 125, + whisker_low: 25, + whisker_high: 175, + outliers: [0] + }, + } + ]; + } \ No newline at end of file diff --git a/nvd3/nvd3-test-historicalBar.ts b/nvd3/nvd3-test-historicalBar.ts new file mode 100644 index 000000000..dc765cdcd --- /dev/null +++ b/nvd3/nvd3-test-historicalBar.ts @@ -0,0 +1,59 @@ +/// +/// +nv.addGraph({ + generate: function() { + var chart = nv.models.historicalBar(); + + d3.select("#test1") + .datum(sinData()) + .datum(sinData()) + .transition() + .call(chart); + + return chart; + }, + callback: function(graph) { + graph.dispatch.on('elementMouseover', function(e) { + var offsetElement = document.getElementById("chart"), + left = e.pos[0], + top = e.pos[1]; + var content = '

' + e.point.y + '

'; + + nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's'); + }); + + graph.dispatch.on('elementMouseout', function(e) { + nv.tooltip.cleanup(); + }); + } +}); + +//Simple test data generators +function sinAndCos() { + var sin = [], + cos = []; + + for (var i = 0; i < 100; i++) { + sin.push({x: i, y: Math.sin(i/10)}); + cos.push({x: i, y: .5 * Math.cos(i/10)}); + } + + return [ + {values: sin, key: "Sine Wave", color: "#ff7f0e"}, + {values: cos, key: "Cosine Wave", color: "#2ca02c"} + ]; +} + +function sinData() { + var sin = []; + + for (var i = 0; i < 100; i++) { + sin.push({x: i, y: Math.sin(i/10)}); + } + + return [{ + values: sin, + key: "Sine Wave", + color: "#ff7f0e" + }]; +} \ No newline at end of file diff --git a/nvd3/nvd3-test-historicalBarChart.ts b/nvd3/nvd3-test-historicalBarChart.ts new file mode 100644 index 000000000..dfd8a30ae --- /dev/null +++ b/nvd3/nvd3-test-historicalBarChart.ts @@ -0,0 +1,165 @@ +/// +/// +var data = [{ + values : [] + }]; + + var i, x; + var gap = false; + var prevVal = 3000; + var tickCount = 100; + var probEnterGap = 0.1; + var probExitGap = 0.2; + var barTimespan = 30 * 60; // thirty minutes in seconds + var startOfTime = 1425096000; + for (i = 0; i < tickCount; i++) { + x = startOfTime + i * barTimespan; + if (!gap) { + if (Math.random() > probEnterGap) { + prevVal += (Math.random() - 0.5) * 500; + if (prevVal <= 0) { + prevVal = Math.random() * 100; + } + data[0].values.push({x: x * 1000, y: prevVal}); + } + else { + gap = true; + } + } + else { + if (Math.random() < probExitGap) { + gap = false; + } + } + } + + var chart : nv.HistoricalBarChart; + + var halfBarXMin = data[0].values[0].x - barTimespan / 2 * 1000; + var halfBarXMax = data[0].values[data[0].values.length-1].x + barTimespan / 2 * 1000; + + function renderChart(location, meaning) { + nv.addGraph(function() { + chart = nv.models.historicalBarChart(); + chart + .xScale(d3.time.scale()) // use a time scale instead of plain numbers in order to get nice round default values in the axis + .color(['#68c']) + .forceX([halfBarXMin, halfBarXMax]) // fix half-bar problem on the first and last bars + .useInteractiveGuideline(true) // check out the css that turns the guideline into this nice thing + .margin({"left": 80, "right": 50, "top": 20, "bottom": 30}) + .duration(0) + ; + + var tickMultiFormat = d3.time.format.multi([ + ["%-I:%M%p", function(d) { return d.getMinutes(); }], // not the beginning of the hour + ["%-I%p", function(d) { return d.getHours(); }], // not midnight + ["%b %-d", function(d) { return d.getDate() != 1; }], // not the first of the month + ["%b %-d", function(d) { return d.getMonth(); }], // not Jan 1st + ["%Y", function() { return true; }] + ]); + chart.xAxis + .showMaxMin(false) + .tickPadding(10) + .tickFormat(function (d) { return tickMultiFormat(new Date(d)); }) + ; + + chart.yAxis + .showMaxMin(false) + .tickFormat(d3.format(",.0f")) + ; + + var svgElem = d3.select(location); + svgElem + .datum(data) + .transition() + .call(chart); + + // make our own x-axis tick marks because NVD3 doesn't provide any + var tickY2 = chart.yAxis.scale().range()[1]; + var lineElems = svgElem + .select('.nv-x.nv-axis.nvd3-svg') + .select('.nvd3.nv-wrap.nv-axis') + .select('g') + .selectAll('.tick') + .data(chart.xScale().ticks()) + .append('line') + .attr('class', 'x-axis-tick-mark') + .attr('x2', 0) + .attr('y1', tickY2 + 4) + .attr('y2', tickY2) + .attr('stroke-width', 1) + ; + + // set up the tooltip to display full dates + var tsFormat = d3.time.format('%b %-d, %Y %I:%M%p'); + var contentGenerator = chart.interactiveLayer.tooltip.contentGenerator(); + var tooltip = chart.interactiveLayer.tooltip; + tooltip.contentGenerator(function (d) { d.value = d.series[0].data.x; return contentGenerator(d); }); + tooltip.headerFormatter(function (d) { return tsFormat(new Date(d)); }); + + // common stuff for the sections below + var xScale = chart.xScale(); + var xPixelFirstBar = xScale(data[0].values[0].x); + var xPixelSecondBar = xScale(data[0].values[0].x + barTimespan * 1000); + var barWidth = xPixelSecondBar - xPixelFirstBar; // number of pixels representing time delta per bar + + // fix the bar widths so they don't overlap when there are gaps + function fixBarWidths(barSpacingFraction) { + svgElem + .selectAll('.nv-bars') + .selectAll('rect') + .attr('width', (1 - barSpacingFraction) * barWidth) + .attr('transform', function(d, i) { + var deltaX = xScale(data[0].values[i].x) - xPixelFirstBar; + deltaX += barSpacingFraction / 2 * barWidth; + return 'translate(' + deltaX + ', 0)'; + }) + ; + } + + /* + If you're representing sample measurements spaced a certain time apart, the tick marks should + be in the middle of the bars and some spacing between bars is recommended to aid with interpretation. + On the other hand, if you want to represent a quantity measured over a span of time (one bar), you're + better off placing the ticks on the edge of the bar and leaving no gap in between bars. + */ + function shiftXAxis() { + var xAxisElem = svgElem.select('.nv-axis.nv-x'); + var transform = xAxisElem.attr('transform'); + var xShift = -barWidth/2; + transform = transform.replace('0,', xShift + ','); + xAxisElem.attr('transform', transform); + } + + if (meaning === 'instant') { + fixBarWidths(0.2); + } + else if (meaning === 'timespan') { + fixBarWidths(0.0); + shiftXAxis(); + } + + return chart; + }); + } + + renderChart('#test1', 'instant'); + renderChart('#test2', 'timespan'); + + window.setTimeout(function() { + window.setTimeout(function() { + document.getElementById('sc-one').style.display = 'block'; + document.getElementById('sc-two').style.display = 'none'; + }, 0); + }, 0); + + function switchChartStyle(style) { + if (style === 'instant') { + document.getElementById('sc-one').style.display = 'block'; + document.getElementById('sc-two').style.display = 'none'; + } + else if (style === 'timespan') { + document.getElementById('sc-one').style.display = 'none'; + document.getElementById('sc-two').style.display = 'block'; + } + } diff --git a/nvd3/nvd3-test-legend.ts b/nvd3/nvd3-test-legend.ts new file mode 100644 index 000000000..81f39d2da --- /dev/null +++ b/nvd3/nvd3-test-legend.ts @@ -0,0 +1,67 @@ +/// +/// +var width = 500, + height = 20; + + var legend = nv.models.legend(); + + d3.select('#test1') + .attr('width', width) + .attr('height', height) + .datum(sinAndCos()); + + var legend2 = nv.models.legend() + .align(false); + + d3.select('#test2') + .attr('width', width) + .attr('height', height) + .datum(sinAndCos()).call(legend2); + + var legend3 = nv.models.legend() + .width(900) + .padding(70); + + d3.select('#test3') + .attr('width', 900) + .attr('height', 200) + .datum(sinAndCos()).call(legend3); + + var update = function() { + d3.select('#test1').call(legend); + } + + update(); + legend.dispatch.on('stateChange', function(d) { + console.log(d); + update(); + }); + + d3.select('#changeData').on('click', function() { + d3.select('#test1') + .datum(differentData()) + .call(legend); + }); + + function sinAndCos() { + return [ + {key: "Sine Wave"}, + {key: "A Very Long Label With Over Twenty Characters"}, + {key: "A Very Long Series Label With Over Twenty Characters"}, + {key: "A Very Long Series Label With Over Twenty Characters"}, + {key: "Cosine Wave"}, + {key: "Another test label"} + ]; + } + + function differentData() { + return [ + {key: "Fixed Income"}, + {key: "Derivatives"}, + {key: "Credit Default Swaps"}, + {key: "Equities"}, + {key: "Bonds"}, + {key: "Stocks"}, + {key: "Apple"} + ]; + } diff --git a/nvd3/nvd3-test-ohlcChart.ts b/nvd3/nvd3-test-ohlcChart.ts new file mode 100644 index 000000000..b62027f63 --- /dev/null +++ b/nvd3/nvd3-test-ohlcChart.ts @@ -0,0 +1,36 @@ +/// +/// +var data = [{values: [ + {"date": 15707, "open": 145.11, "high": 146.15, "low": 144.73, "close": 146.06, "volume": 192059000, "adjusted": 144.65}, + {"date": 15953, "open": 165.85, "high": 166.4, "low": 165.73, "close": 165.96, "volume": 62930500, "adjusted": 165.96} + ]}]; + +nv.addGraph(function() { + var chart = nv.models.ohlcBarChart() + .x(function(d) { return d['date'] }) + .y(function(d) { return d['close'] }) + .duration(250) + .margin({left: 75, bottom: 50}); + + // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately + chart.xAxis + .axisLabel("Dates") + .tickFormat(function(d) { + // I didn't feel like changing all the above date values + // so I hack it to make each value fall on a different date + return d3.time.format('%x')(new Date(new Date().valueOf() - (20000 * 86400000) + (d * 86400000))); + }); + + chart.yAxis + .axisLabel('Stock Price') + .tickFormat(function(d,i){ return '$' + d3.format(',.1f')(d); }); + + + + d3.select("#chart1 svg") + .datum(data) + .transition().duration(500) + .call(chart); + nv.utils.windowResize(chart.update); + return chart; +}); \ No newline at end of file diff --git a/nvd3/nvd3-test-tooltip.ts b/nvd3/nvd3-test-tooltip.ts new file mode 100644 index 000000000..ee45f9ea7 --- /dev/null +++ b/nvd3/nvd3-test-tooltip.ts @@ -0,0 +1,55 @@ +/// +/// +var width = 500, + height = 20; + + var tooltip = nv.models.tooltip(); + tooltip.duration(0); + + d3.select('.tooltip_me') + .on('mouseover', function(d,i) { + console.log("mouseover", d, i); + var data = {series: { + key: "title", + value: "the value", + color: "#229922" + }}; + tooltip.data(data).hidden(false); + }) + .on('mouseout', function(d,i) { + console.log("mouseout", d, i); + tooltip.hidden(true); + }) + .on('mousemove', function(d,i) { + console.log("mousemove", d, i); + tooltip.position({top: d3.event.pageY, left: d3.event.pageX})(); + }); + + + // we must also test the scatter/line way of getting position + // Wrapping in nv.addGraph allows for '0 timeout render', stores rendered charts in nv.graphs, and may do more in the future... it's NOT required + var chart; + nv.addGraph(function() { + chart = nv.models.lineChart() + .showXAxis(false) + .showLegend(false) + .clipVoronoi(false) + .showVoronoi(true) + .showYAxis(false); + d3.select('#test2') + .datum(sinAndCos()) + .call(chart); + return chart; + }); + + function sinAndCos() { + var cos = []; + for (var i = 0; i < 5; i++) { + cos.push({x: i, y: Math.round(.5 * Math.cos(i/10) * 100) / 100}); + } + return [{ + values: cos, + key: "Cosine Wave", + color: "#2ca02c" + }]; + } diff --git a/nvd3/nvd3.d.ts b/nvd3/nvd3.d.ts new file mode 100644 index 000000000..0fb9db4ed --- /dev/null +++ b/nvd3/nvd3.d.ts @@ -0,0 +1,252 @@ +// Type definitions for nvd3 1.8.1 +// Project: https://github.com/novus/nvd3 +// Definitions by: Maxime LUCE +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// +declare module nv { + +// interface Datum{ +// values: any[], +// key: string, +// color: string +// } + + interface Margin { + left?: number, + right?: number, + top?: number, + bottom?: number + } + + interface Legend extends Chart { + key(): any; + key(value: any): Legend; + align(): boolean; + align(value: boolean): Legend; + maxKeyLength(): number; + maxKeyLength(value: number): Legend; + rightAlign(): boolean; + rightAlign(value: boolean): Legend; + //define how much space between legend items. - recommend 32 for furious version + padding(): number; + //define how much space between legend items. - recommend 32 for furious version + padding(value: number): Legend; + //If true, legend will update data.disabled and trigger a 'stateChange' dispatch. + updateState(): boolean; + //If true, legend will update data.disabled and trigger a 'stateChange' dispatch. + updateState(value: boolean): Legend; + //If true, clicking legend items will cause it to behave like a radio button. (only one can be selected at + radioButtonMode(): boolean; + //If true, clicking legend items will cause it to behave like a radio button. (only one can be selected at + radioButtonMode(value: boolean): Legend; + expanded(): boolean; + expanded(value: boolean): Legend; + //Options are "classic" and "furious" + vers(): string; + //Options are "classic" and "furious" + vers(value: string): Legend; + } + + /** + *NVD3 extension of D3 Axis + */ + interface NvAxis extends d3.svg.Axis { + (selection: d3.Selection): void; + (selection: d3.Transition): void; + + scale(): any; + scale(scale: any): NvAxis; + + orient(): string; + orient(orientation: string): NvAxis; + + ticks(): any[]; + ticks(...args: any[]): NvAxis; + + tickValues(): any[]; + tickValues(values: any[]): NvAxis; + + tickSize(): number; + tickSize(size: number): NvAxis; + tickSize(inner: number, outer: number): NvAxis; + + innerTickSize(): number; + innerTickSize(size: number): NvAxis; + + outerTickSize(): number; + outerTickSize(size: number): NvAxis; + + tickPadding(): number; + tickPadding(padding: number): NvAxis; + + tickFormat(): (t: any) => string; + tickFormat(format: (t: any) => string): NvAxis; + tickFormat(format:string): NvAxis; + tickFormat(format: (t: any, i: any) => string): NvAxis; + + showMaxMin(value: boolean) : NvAxis; + axisLabel(value: string) : NvAxis; + + } + + interface InteractiveLayer { + tooltip : Tooltip + } + + interface ContentGenerator { + (arg: any) :string + } + + interface Tooltip { + + show([left , top]: [number,number], content: string, gravity: string) //todo sort out use on nv.tooltip. + cleanup():void; //todo sort out use on nv.tooltip. + contentGenerator(): ContentGenerator; + contentGenerator(func: (any) => string): void; + headerFormatter(func: (any)=> string): void; + } + + interface Utils { + windowResize(listener: (ev: Event) => any): void; + } + + interface ChartBase { + update(): void; + interactiveLayer :InteractiveLayer; + + (transition: d3.Transition, ...args: any[]) :any; + (selection: d3.Selection, ...args: any[]) :any; + (transition: d3.Transition, ...args: any[]) :any; + (selection: d3.Selection, ...args: any[]) :any; + } + + interface Chart extends ChartBase { + margin() : Margin; + margin(value: Margin) : TChart; + width(): number; + width(value: number) : TChart; + height(): number; + height(value: number) : TChart; + color(value:string[]) : TChart; + color(value:string) : TChart; + dispatch : d3.Dispatch; + + } + + interface TwoDimensionalChart extends Chart + { + xAxis : NvAxis; + yAxis : NvAxis; + x(func: (any)=> any) : TChart; + y(func: (any)=> any) : TChart; + xScale(scale: d3.time.Scale) : TChart; + xScale() : d3.time.Scale; + yScale(scale: d3.time.Scale) : TChart; + yScale() : d3.time.Scale + forceX([xMin, xMax] : [number,number]) : TChart; + forceY([xMin, xMax] : [number,number]) : TChart; + + } + + interface HistoricalBarBase extends TwoDimensionalChart{ + + + } + + interface HistoricalBar extends HistoricalBarBase{ + + } + + interface HistoricalBarChart extends HistoricalBarBase{ + bars: HistoricalBar; + legend: Legend; + noData(): any //todo; + noData(value: any): HistoricalBarChart //todo; + defaultState(): any //todo; + defaultState(value: any): HistoricalBarChart //todo; + showXAxis(): boolean //todo; + showXAxis(value: boolean): HistoricalBarChart //todo; + showLegend(): boolean //todo; + showLegend(value: boolean): HistoricalBarChart //todo; + showYAxis(): boolean //todo; + showYAxis(value: boolean): HistoricalBarChart //todo; + rightAlignYAxis(): boolean //todo; + rightAlignYAxis(value: boolean): HistoricalBarChart //todo; + useInteractiveGuideline(value : boolean) : HistoricalBarChart; + duration(value: number) : HistoricalBarChart; + interactiveLayer :InteractiveLayer; + } + + + + + + interface BoxPlotChart extends TwoDimensionalChart{ + useInteractiveGuideline(value : boolean) : BoxPlotChart; + duration(value: number) : BoxPlotChart; + + staggerLabels(value : boolean) : BoxPlotChart; + maxBoxWidth(value: number) : BoxPlotChart; + yDomain([xMin, xMax] : [number,number]): BoxPlotChart; + xDomain([xMin, xMax] : [number,number]): BoxPlotChart; + showXAxis(): boolean //todo; + showXAxis(value: boolean): BoxPlotChart //todo; + showYAxis(): boolean //todo; + showYAxis(value: boolean): BoxPlotChart //todo; + rightAlignYAxis(): boolean //todo; + rightAlignYAxis(value: boolean): BoxPlotChart //todo; + } + + interface BulletBase extends Chart { + orient(): string; + orient(orientation: string): TBullet; + tickFormat(): (t: any) => string; + tickFormat(format: (t: any) => string): TBullet; + tickFormat(format:string): NvAxis; + tickFormat(format: (t: any, i: any) => string): TBullet; + forceX([xMin, xMax] : [number,number]) : TBullet; + ranges(): any //todo; + ranges(value: any): TBullet //todo; + markers(): any //todo; + markers(value: any): TBullet //todo; + measures(): any //todo; + measures(value: any): TBullet //todo; + } + + interface Bullet extends BulletBase{ + + } + interface BulletChart extends BulletBase{ + bullet: Bullet + ticks(): any //todo; + ticks(value: any): BulletChart //todo; + noData(): any //todo; + noData(value: any): BulletChart //todo; + } + interface Models{ + historicalBar(): HistoricalBar; + historicalBarChart(bar_model?: HistoricalBar): HistoricalBarChart; + ohlcBarChart(): HistoricalBarChart; + bullet(): Bullet; + bulletChart(): BulletChart; + boxPlotChart(): BoxPlotChart; + legend(): Legend; + tooltip(): Tooltip; + } + + interface ChartFactory { + generate: ()=> Chart; + callback?: (chart:Chart)=> void; + } + + + interface nvStatic{ + models: Models; + tooltip: Tooltip; + utils: Utils; + addGraph(factory: ChartFactory); + addGraph(generate : ()=> Chart, callBack?: (chart:Chart)=> void) ; + } +} +declare var nv : nv.nvStatic; \ No newline at end of file