I'm using NVD3.js to display a multi-line chart.
I would like the yAxis to display to 2 decimal numbers
edited answer
var chart;
nv.addGraph(function () {
chart = nv.models.lineChart()
.options({
margin: { left: 140, bottom: 50 },
x: function (d, i) {
return i;
},
showXAxis: true,
showYAxis: true,
transitionDuration: 250,
tooltips: true,
tooltipContent: function (key, x, y, e, graph) {
return '<h3>' + key + '</h3>' +
'<p>' + e.point.y + ' at ' + x + '</p>'
}
});
// chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately
chart.xAxis
.axisLabel("Maturity")
.tickFormat(function(d) { return pivotedData[0].values[d].x; });
chart.yAxis
.axisLabel('Model Spread').tickFormat(d3.format(',.2f'));
d3.select('#chart1 svg')
.datum(pivotedData)
.call(chart);
//TODO: Figure out a good way to do this automatically
nv.utils.windowResize(chart.update);
chart.dispatch.on('stateChange', function (e) { nv.log('New State:', JSON.stringify(e)); });
return chart;
});
But in the tool tip on the lines i would like to display to 12 decimals places.
Is this possible?
You can set the function that is called to format the contents of a tooltip through .tooltipContent of the chart object. The default function is defined as follows.
tooltip = function(key, x, y, e, graph) {
return '<h3>' + key + '</h3>' +
'<p>' + y + ' at ' + x + '</p>'
}
You can format the value of y in there to your liking. Note that y is defined as
yAxis.tickFormat()(lines.y()(e.point, e.pointIndex))
This means that the tick formatting for the axis will affect it, so in order to achieve a higher precision there, you need to get the value directly -- lines can be accessed through chart.lines.
In the nvd3 source they have lines like so (Line Chart):
interactiveLayer.dispatch.on('elementMousemove', function(e) {
...
var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex));
interactiveLayer.tooltip
.position({left: pointXLocation + margin.left, top: e.mouseY + margin.top})
...
.valueFormatter(function(d,i) {
return yAxis.tickFormat()(d);
})
.data(
{
value: xValue,
series: allData
}
)();
...
}
So if you want to override something like tooltip.contentGenerator you are stuck with the data it gives you. I think a good way to do this would be to have a setter for tooltip x formatter or something then it will use that over the axis formatter. Or simply sending over the raw data along with the value and series.
My usecase is that I am showing a timescale of 7 days on the graph I only tick the start of each day. However on the tooltip I want to give a more detailed view of that data.
Here is my pull request specific to the guidelines tooltip
https://github.com/novus/nvd3/pull/444
Calling: chart.tooltipXAxisFormatter(d3.time.format(toolTipFormat)); will set it.
Related
I want to rotate the labels in yellow color.
image for the labels
i have gone through this link
rotate x axis text in d3
but in this link the values being passed to the translate function are static values.
<text transform="translate(200,100)rotate(180)">Hello!</text>
i want to pass dynamic values returned by a function.
so in this code the x and y are taking values from functions so i want to pass these values to the translate attribute but getting error in the console
d3.min.js:1 Error: Invalid value for attribute transform="translate(\"function(d){ return xScale(d.country) + xScale.rangeBand()/2; }\",\"function(d){ return yScale(d.populationValue)+ 12; }\")rotate(-90)"
.attr({
"x": function(d){ return xScale(d.country) + xScale.rangeBand()/2; },
"y": function(d){ return yScale(d.populationValue)+ 12; },
"text-anchor": 'middle',
"fill": 'yellow',
"transform": 'translate("function(d){ return xScale(d.country) + xScale.rangeBand()/2; }","function(d){ return yScale(d.populationValue)+ 12; }")rotate(-90)'
expected output
You have to return all the translate string using the function:
"transform": function(d){
return "translate(" + xScale(d.country) + xScale.rangeBand()/2
+ "," + yScale(d.populationValue) + 12 + ")rotate(-90)"
};
PS: after you do this, I bet that the result will not be what you expect... but that will be another problem, for another SO question.
Is there a zooming function in nvd3 that I can directly type in my R source code (doesn't matter if it requires javascript as long as I don't have to change nvd3 source code)? I tried the lineWithFocusChart, but that only zooms along the x-axis, whereas I would like to ideally draw a box around the zoom section and it will zoom to where I drew the box. Even if that's not possible, if nvd3 supports any kind of 2-d zoom, that would be awesome! I have provided a reproducible example of what I have so far, but I have not found a feature for the zoom I am looking for yet. Thank you!
library(rCharts)
temp <- data.frame(x = 1:100, y = 1:100, z = c(rep(1,50), rep(0,50)))
g <- nPlot(y ~ x, group = "z", data = temp, type = "lineChart")
g$templates$script <- "http://timelyportfolio.github.io/rCharts_nvd3_templates/chartWithTitle_styled.html"
g$set(title = "Example")
g$chart(transitionDuration = -1,
tooltipContent = "#! function(key, x, y) {
return 'z: ' + key + '<br/>' + 'x: ' + x + '<br/>' + 'y: ' + y
}!#",
showLegend = FALSE, margin = list(left = 200,
right = 100,
bottom = 100,
top = 100))
g$xAxis(axisLabel = "x")
g$yAxis(axisLabel = "y", width = 40)
g
You could use Highcharts with the zoomType option.
For example:
require(rCharts)
names(iris) = gsub("\\.", "", names(iris))
g<-hPlot(SepalLength ~ SepalWidth, data = iris, color = 'Species', type = 'line')
g$chart(zoomType = 'xy')
g
You can then drag and hold on the plot to zoom in an area.
I have a pie chart. And I need to format DataLabels in someway. So I use:
dataLabels: {
useHTML : true,
formatter: function () {
if(this.point.id == 'razr') {
return '<div><b>' + this.point.y + '</b></div><div style="left: -140px; text-align: center; position: absolute"><b>sum is:<br/>' + this.point.summ + ' </b></div>';
} else return '<b>' + this.point.y + '<b>';
}
}
And what I got:
My problem is here style="left: -140px;. The position is static. I can't find any way to position my sum label at the center of a green point of a chart. I've been searching the properties of a point (like plotX, graphic attr), nothing helps. If I remove style="left: -140px; datalabel will moves to the right. How can I get coordinates of my green point?
To be honest, it's not easy. I see two possible solutions:
1) Easy (but dirty workaround): create second pie chart under the first one with the same values, but render just one label. Then the second pie chart can have dataLabel inside the slice.
2) Hard (more generic solution): calculate required top/left offsets. It's hard because you don't know bounding box of the label. I suggest to set fixed width+height for that part of the label - so you can find center of that label's part. Then calculate position using series.center and point.labelPos arrays. These are inner options and can change between versions, so keep an eye on these options before upgrading. Example: http://jsfiddle.net/zwb5toe9/2/
dataLabels: {
useHTML: true,
formatter: function () {
var point = this.point,
width = 50,
height = 50,
series = point.series,
center = series.center, //center of the pie
startX = point.labelPos[4], //connector X starts here
endX = point.labelPos[0] + 5, //connector X ends here
left = -(endX - startX + width / 2), //center label over right edge
startY = point.labelPos[5], //connector Y starts here
endY = point.labelPos[1] - 5, //connector Y ends here
top = -(endY - startY + height / 2); //center label over right edge
// now move inside the slice:
left += (center[0] - startX)/2;
top += (center[1] - startY)/2;
if (point.id == 'razr') {
console.log(this);
return '<div><b>' + point.y + '</b></div><div style="width: ' + width + 'px; left:' + left + 'px;top:' + top + 'px; text-align: center; position: absolute"><b>sum is:<br/>' + point.summ + ' </b></div>';
} else return '<b>' + point.y + '<b>';
}
}
I have used area stacked Highchart in my application.
This is my FIDDLE
I have converted the y axis values by place the below code in y axis - labels, but unable to format the tooltip to the same % values
formatter: function(){
return Math.round(100*this.value / $(this.axis.tickPositions).last()[0]) + '%';
}
But when I tried to apply the same for tool tip, the tooltip itself went invisible. How to apply the percentage to tool tip also. I have tried the below code.
tooltip: {
shared: false,
formatter: function() {
var text = '';
var pcnt = (this.y / dataSum) * 100;
text = this.x + ' : <b>'+ Highcharts.numberFormat(pcnt) +' M</b>';
return text;
}
},
Thanks in advance
We have a graph that when all data is zero, shows the zero dollar value in the middle of the y-axis, and a few negative values below. It would be better to have the zero at the bottom, with dollar values up the side.
Here's the graph code:
nv.addGraph(function() {
var chart = nv.models.multiBarChart()
.transitionDuration(350)
.reduceXTicks(false)
.rotateLabels(0)
.showControls(false) //Allow user to switch between 'Grouped' and 'Stacked' mode.
.groupSpacing(0.1)
.tooltipContent(function (key, y, e, graph) {
return '<p> Total Cost: $' + graph.value + '</p>';
})
;
chart.xAxis
.tickFormat(function(d) { return d3.time.format('%b, %y')(new Date(d)); });
chart.yAxis
.tickFormat(function(d) { return '$' + d3.format(',f')(d) });
d3.select('#hardware_costs_graph svg')
.datum(exampleData())
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
How can the baseline be changed so that no negative values show?
Thanks Lars. I did search for this answer for a while, and could not find it.
Here is the solution for anyone who needs it.
Added forceY to chart instantiation:
var chart = nv.models.multiBarChart()
.transitionDuration(350)
.reduceXTicks(false)
.rotateLabels(0)
.showControls(false) //Allow user to switch between 'Grouped' and 'Stacked' mode.
.groupSpacing(0.1)
.tooltipContent(function (key, y, e, graph) {
return '<p> Total Cost: $' + graph.value + '</p>';
})
.forceY([0,5])
;