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
Related
Let's say I have the following code in dc.js to create a pie chart:
var chart = dc.pieChart("#test");
d3.csv("morley.csv", function(error, experiments) {
var ndx = crossfilter(experiments),
runDimension = ndx.dimension(function(d) {return "run-"+d.Run;})
speedSumGroup = runDimension.group().reduceSum(function(d) {return d.Speed * d.Run;});
chart
.width(768)
.height(480)
.slicesCap(4)
.innerRadius(100)
.dimension(runDimension)
.group(speedSumGroup)
.legend(dc.legend())
// workaround for #703: not enough data is accessible through .label() to display percentages
.on('pretransition', function(chart) {
chart.selectAll('text.pie-slice').text(function(d) {
return d.data.key + ' ' + dc.utils.printSingleValue((d.endAngle - d.startAngle) / (2*Math.PI) * 100) + '%';
})
});
chart.render();
});
What I want to do is rotate the label, but when I do so, all of the labels translate to the center of the pie.
chart.renderlet(function (chart) {
chart.selectAll('text.pie-slice')
.attr('transform', 'rotate(315)');
});
Is there a way to rotate the labels without changing their position on the graph?
The problem is that you're replacing the transform attribute for these elements, which is currently used to "translate" the labels in position.
Since it's hard to dig into the calculations used here, I think the best approach is to pull the existing transform attribute and modify it, like this:
chart.on('renderlet', function (chart) {
chart.selectAll('text.pie-slice')
.attr('transform', function(d) {
var translate = d3.select(this).attr('transform');
var ang = ((d.startAngle + d.endAngle) / 2 * 180 / Math.PI)%360;
if(ang<180) ang -= 90; else ang += 90;
return translate + ' rotate(' + ang + ')';
});
});
For my own entertainment, I've also rotated the labels using the start and end angles of the pie slices.
It's unfortunate you can't do this as a pretransition event and avoid the "jump". It will just get overwritten by the animations. Doing this properly would require some changes to dc.js - file an issue if you're interested.
addition to Gordon's answer, for all pieCharts to have this feature; i changed labelPosition function in dc.js.
return 'translate(' + centroid + ')';
to
var ang = ((d.startAngle + d.endAngle) / 2 * 180 / Math.PI)%360;
if(ang<180) ang -= 90; else ang += 90;
return 'translate(' + centroid + ') rotate(' + ang +')';
I am working with highcharts at the moment, I have a tooltip on by bar chart that is being cut off by a overflow:hidden setting, this is fine and understand I need that setting however the positioning of the tooltip is not overly intelligant, is there a way to position the tooltip relative to the width of the column, i.e if the tooltip is going cause a scrollbar can I decrease the offset? I don't have a code example, but I have attached an image of my problem,
Use tooltip positioner function in your tooltip. Adjust tooltipX and tooltipY accroding to your display requiremets :
positioner: function(labelWidth, labelHeight, point) {
var tooltipX, tooltipY;
if (point.plotX + labelWidth > this.chart.plotWidth) {
tooltipX = point.plotX + this.chart.plotLeft - labelWidth - 40;
} else {
tooltipX = point.plotX + this.chart.plotLeft + 40;
}
tooltipY = point.plotY + this.chart.plotTop - 20;
return {
x: tooltipX,
y: tooltipY
};
}
I am using highcharts to create graphics in my website, however this tooltip covers my bars, Is there a way to tell the tooltip todisplay on top of the bar instead that ‘ON’ it?
here is what I am seeing:
There are many s question around tool-tip positioning on StackOverflow ,The way I used in my chart was to show tooltip left or right on hover of column using positioner.
tooltip: {
positioner: function(labelWidth, labelHeight, point) {
var tooltipX, tooltipY;
if (point.plotX + labelWidth > this.chart.plotWidth) {
tooltipX = point.plotX + this.chart.plotLeft - labelWidth - 40;
} else {
tooltipX = point.plotX + this.chart.plotLeft + 40;
}
tooltipY = point.plotY + this.chart.plotTop - 20;
return {
x: tooltipX,
y: tooltipY
};
} }
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'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.