1
|
nv.models.axis=function(){"use strict";function m(r){r.each(function(r){var m=d3.select(this);var g=m.selectAll("g.nv-wrap.nv-axis").data([r]);var y=g.enter().append("g").attr("class","nvd3 nv-wrap nv-axis");var b=y.append("g");var w=g.select("g");if(h!==null)e.ticks(h);else if(e.orient()=="top"||e.orient()=="bottom")e.ticks(Math.abs(i.range()[1]-i.range()[0])/100);w.transition().call(e);v=v||e.scale();var E=e.tickFormat();if(E==null){E=v.tickFormat()}var S=w.selectAll("text.nv-axislabel").data([s||null]);S.exit().remove();switch(e.orient()){case"top":S.enter().append("text").attr("class","nv-axislabel");var x=i.range().length==2?i.range()[1]:i.range()[i.range().length-1]+(i.range()[1]-i.range()[0]);S.attr("text-anchor","middle").attr("y",0).attr("x",x/2);if(o){var T=g.selectAll("g.nv-axisMaxMin").data(i.domain());T.enter().append("g").attr("class","nv-axisMaxMin").append("text");T.exit().remove();T.attr("transform",function(e,t){return"translate("+i(e)+",0)"}).select("text").attr("dy","0em").attr("y",-e.tickPadding()).attr("text-anchor","middle").text(function(e,t){var n=e;if(p){n=Math.pow(10,n);n=E(n)}else n=E(n);return(""+n).match("NaN")?"":n});T.transition().attr("transform",function(e,t){return"translate("+i.range()[t]+",0)"})}break;case"bottom":var N=36;var C=30;var k=w.selectAll("g").select("text");if(a%360){k.each(function(e,t){var n=this.getBBox().width;if(n>C)C=n});var L=Math.abs(Math.sin(a*Math.PI/180));var N=(L?L*C:C)+30;k.attr("transform",function(e,t,n){return"rotate("+a+" 0,0)"}).style("text-anchor",a%360>0?"start":"end")}S.enter().append("text").attr("class","nv-axislabel");var x=i./* Tooltip rendering model for nvd3 charts.
window.nv.models.tooltip is the updated,new way to render tooltips.
window.nv.tooltip.show is the old tooltip code.
window.nv.tooltip.* also has various helper methods.
*/
(function() {
"use strict";
window.nv.tooltip = {};
/* Model which can be instantiated to handle tooltip rendering.
Example usage:
var tip = nv.models.tooltip().gravity('w').distance(23)
.data(myDataObject);
tip(); //just invoke the returned function to render tooltip.
*/
window.nv.models.tooltip = function() {
var content = null //HTML contents of the tooltip. If null, the content is generated via the data variable.
, data = null /* Tooltip data. If data is given in the proper format, a consistent tooltip is generated.
Format of data:
{
key: "Date",
value: "August 2009",
series: [
{
key: "Series 1",
value: "Value 1",
color: "#000"
},
{
key: "Series 2",
value: "Value 2",
color: "#00f"
}
]
}
*/
, gravity = 'w' //Can be 'n','s','e','w'. Determines how tooltip is positioned.
, distance = 50 //Distance to offset tooltip from the mouse location.
, snapDistance = 25 //Tolerance allowed before tooltip is moved from its current position (creates 'snapping' effect)
, fixedTop = null //If not null, this fixes the top position of the tooltip.
, classes = null //Attaches additional CSS classes to the tooltip DIV that is created.
, chartContainer = null //Parent DIV, of the SVG Container that holds the chart.
, tooltipElem = null //actual DOM element representing the tooltip.
, position = {left: null, top: null} //Relative position of the tooltip inside chartContainer.
, enabled = true //True -> tooltips are rendered. False -> don't render tooltips.
//Generates a unique id when you create a new tooltip() object
, id = "nvtooltip-" + Math.floor(Math.random() * 100000)
;
//CSS class to specify whether element should not have mouse events.
var nvPointerEventsClass = "nv-pointer-events-none";
//Format function for the tooltip values column
var valueFormatter = function(d,i) {
return d;
};
//Format function for the tooltip header value.
var headerFormatter = function(d) {
return d;
};
//By default, the tooltip model renders a beautiful table inside a DIV.
//You can override this function if a custom tooltip is desired.
var contentGenerator = function(d) {
if (content != null) return content;
if (d == null) return '';
var table = d3.select(document.createElement("table"));
var theadEnter = table.selectAll("thead")
.data([d])
.enter().append("thead");
theadEnter.append("tr")
.append("td")
.attr("colspan",3)
.append("strong")
.classed("x-value",true)
.html(headerFormatter(d.value));
var tbodyEnter = table.selectAll("tbody")
.data([d])
.enter().append("tbody");
var trowEnter = tbodyEnter.selectAll("tr")
.data(function(p) { return p.series})
.enter()
.append("tr")
.classed("highlight", function(p) { return p.highlight})
;
trowEnter.append("td")
.classed("legend-color-guide",true)
.append("div")
.style("background-color", function(p) { return p.color});
trowEnter.append("td")
.classed("key",true)
.html(function(p) {return p.key});
trowEnter.append("td")
.classed("value",true)
.html(function(p,i) { return valueFormatter(p.value,i) });
trowEnter.selectAll("td").each(function(p) {
if (p.highlight) {
var opacityScale = d3.scale.linear().domain([0,1]).range(["#fff",p.color]);
var opacity = 0.6;
d3.select(this)
.style("border-bottom-color", opacityScale(opacity))
.style("border-top-color", opacityScale(opacity))
;
}
});
var html = table.node().outerHTML;
if (d.footer !== undefined)
html += "<div class='footer'>" + d.footer + "</div>";
return html;
};
var dataSeriesExists = function(d) {
if (d && d.series && d.series.length > 0) return true;
return false;
};
//In situations where the chart is in a 'viewBox', re-position the tooltip based on how far chart is zoomed.
function convertViewBoxRatio() {
if (chartContainer) {
var svg = d3.select(chartContainer);
if (svg.node().tagName !== "svg") {
svg = svg.select("svg");
}
var viewBox = (svg.node()) ? svg.attr('viewBox') : null;
if (viewBox) {
viewBox = viewBox.split(' ');
var ratio = parseInt(svg.style('width')) / viewBox[2];
position.left = position.left * ratio;
position.top = position.top * ratio;
}
}
}
//Creates new tooltip container, or uses existing one on DOM.
function getTooltipContainer(newContent) {
var body;
if (chartContainer)
body = d3.select(chartContainer);
else
body = d3.select("body");
var container = body.select(".nvtooltip");
if (container.node() === null) {
//Create new tooltip div if it doesn't exist on DOM.
container = body.append("div")
.attr("class", "nvtooltip " + (classes? classes: "xy-tooltip"))
.attr("id",id)
;
}
container.node().innerHTML = newContent;
container.style("top",0).style("left",0).style("opacity",0);
container.selectAll("div, table, td, tr").classed(nvPointerEventsClass,true)
container.classed(nvPointerEventsClass,true);
return container.node();
}
//Draw the tooltip onto the DOM.
function nvtooltip() {
if (!enabled) return;
if (!dataSeriesExists(data)) return;
convertViewBoxRatio();
var left = position.left;
var top = (fixedTop != null) ? fixedTop : position.top;
var container = getTooltipContainer(contentGenerator(data));
tooltipElem = container;
if (chartContainer) {
var svgComp = chartContainer.getElementsByTagName("svg")[0];
var boundRect = (svgComp) ? svgComp.getBoundingClientRect() : chartContainer.getBoundingClientRect();
var svgOffset = {left:0,top:0};
if (svgComp) {
var svgBound = svgComp.getBoundingClientRect();
var chartBound = chartContainer.getBoundingClientRect();
var svgBoundTop = svgBound.top;
//Defensive code. Sometimes, svgBoundTop can be a really negative
// number, like -134254. That's a bug.
// If such a number is found, use zero instead. FireFox bug only
if (svgBoundTop < 0) {
var containerBound = chartContainer.getBoundingClientRect();
svgBoundTop = (Math.abs(svgBoundTop) > containerBound.height) ? 0 : svgBoundTop;
}
svgOffset.top = Math.abs(svgBoundTop - chartBound.top);
svgOffset.left = Math.abs(svgBound.left - chartBound.left);
}
//If the parent container is an overflow <div> with scrollbars, subtract the scroll offsets.
//You need to also add any offset between the <svg> element and its containing <div>
//Finally, add any offset of the containing <div> on the whole page.
left += chartContainer.offsetLeft + svgOffset.left - 2*chartContainer.scrollLeft;
top += chartContainer.offsetTop + svgOffset.top - 2*chartContainer.scrollTop;
}
if (snapDistance && snapDistance > 0) {
top = Math.floor(top/snapDistance) * snapDistance;
}
nv.tooltip.calcTooltipPosition([left,top], gravity, distance, container);
return nvtooltip;
};
nvtooltip.nvPointerEventsClass = nvPointerEventsClass;
nvtooltip.content = function(_) {
if (!arguments.length) return content;
content = _;
return nvtooltip;
};
//Returns tooltipElem...not able to set it.
nvtooltip.tooltipElem = function() {
return tooltipElem;
};
nvtooltip.contentGenerator = function(_) {
if (!arguments.length) return contentGenerator;
if (typeof _ === 'function') {
contentGenerator = _;
}
return nvtooltip;
};
nvtooltip.data = function(_) {
if (!arguments.length) return data;
data = _;
return nvtooltip;
};
nvtooltip.gravity = function(_) {
if (!arguments.length) return gravity;
gravity = _;
return nvtooltip;
};
nvtooltip.distance = function(_) {
if (!arguments.length) return distance;
distance = _;
return nvtooltip;
};
nvtooltip.snapDistance = function(_) {
if (!arguments.length) return snapDistance;
snapDistance = _;
return nvtooltip;
};
nvtooltip.classes = function(_) {
if (!arguments.length) return classes;
classes = _;
return nvtooltip;
};
nvtooltip.chartContainer = function(_) {
if (!arguments.length) return chartContainer;
chartContainer = _;
return nvtooltip;
};
nvtooltip.position = function(_) {
if (!arguments.length) return position;
position.left = (typeof _.left !== 'undefined') ? _.left : position.left;
position.top = (typeof _.top !== 'undefined') ? _.top : position.top;
return nvtooltip;
};
nvtooltip.fixedTop = function(_) {
if (!arguments.length) return fixedTop;
fixedTop = _;
return nvtooltip;
};
nvtooltip.enabled = function(_) {
if (!arguments.length) return enabled;
enabled = _;
return nvtooltip;
};
nvtooltip.valueFormatter = function(_) {
if (!arguments.length) return valueFormatter;
if (typeof _ === 'function') {
valueFormatter = _;
}
return nvtooltip;
};
nvtooltip.headerFormatter = function(_) {
if (!arguments.length) return headerFormatter;
if (typeof _ === 'function') {
headerFormatter = _;
}
return nvtooltip;
};
//id() is a read-only function. You can't use it to set the id.
nvtooltip.id = function() {
return id;
};
return nvtooltip;
};
//Original tooltip.show function. Kept for backward compatibility.
// pos = [left,top]
nv.tooltip.show = function(pos, content, gravity, dist, parentContainer, classes) {
//Create new tooltip div if it doesn't exist on DOM.
var container = document.createElement('div');
container.className = 'nvtooltip ' + (classes ? classes : 'xy-tooltip');
var body = parentContainer;
if ( !parentContainer || parentContainer.tagName.match(/g|svg/i)) {
//If the parent element is an SVG element, place tooltip in the <body> element.
body = document.getElementsByTagName('body')[0];
}
container.style.left = 0;
container.style.top = 0;
container.style.opacity = 0;
container.innerHTML = content;
body.appendChild(container);
//If the parent container is an overflow <div> with scrollbars, subtract the scroll offsets.
if (parentContainer) {
pos[0] = pos[0] - parentContainer.scrollLeft;
pos[1] = pos[1] - parentContainer.
|