How to change the labels of hover info in Plotly.js? - javascript

In a chart I render using Plotly.js, I define titles for each axis. When mouse hovering the items within the chart, a popup is shown, but the "labels" shown do not use the titles I had defined.
For example, the default value for the x axis is x. I defined hellox as title and that value is show in the chart, but not when mouse hovering a value (x is still shown).
See a live example here of what I mean: https://codepen.io/anon/pen/qoGQvx
I've been looking a the documentation and I didn't find anything so far that did exactly what I wanted: simply change the labels in the popup.

Also the question is quite old, I would like to write a solution I came up when facing the same problem. I did define a var text array for hover info which I filled with the labels for x, y and z values. Please have a look at the following fiddle where I use a heatmap plot for demonstration (this is what I am using in my project, but it can be easily adapted for your chart option): http://jsfiddle.net/zLc5y63g/
This is the html code:
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<body>
<br><br>
<!-- Source and on-click event for plotly.js -->
<div id="plotly_chart" style="width: 90%; height: 270px"></div>
And this the JavaScript:
var zValues = [[1, 20, 30], [20, 1, 60], [30, 60, 1]];
var yValues = ['data1', 'data2', 'data3'];
var xValues = ['condition1', 'condition2', 'condition3'];
var config = {
displaylogo: false
};
// fill in 'text' array for hover
var text = zValues.map (function(zValues, i) { return zValues.map (function (value, j) {
return ` ID: ${yValues[i]}<br> Condition: ${xValues[j]}<br> Value: ${value.toFixed(2)} `
});
});
Plotly.newPlot('plotly_chart', [{x: xValues, y: yValues, z: zValues, text: text, hoverinfo: 'text', hoverlabel: {bgcolor: '#41454c'}, type: 'heatmap', colorscale: 'Viridis'}], config );
Maybe this is still useful.

Related

c3js bar chart, align data to x tick start position (not centered)

If you take a normal bar chart from c3js, the bars will be centered at the x-tick position. I have a chart which goes hourly, so any timespan between 00-24 (usually like 8-16). If I have a line-chart or scatter plot it will align it self exactly on the x-tick nicely, but not as a step-chart or a bar chart.
var chart = c3.generate({
data: {
x: 'x',
columns: [
['x', 8, 9, 10, 11, 12, 13, 14, 15, 16],
['data1', 1, 1, 0, 1, 0, 0, 1, 1, 1],
],
type: "bar"
},
axis: {
x: {
type: "category",
categories: [],
}
}
});
See this fiddle: https://jsfiddle.net/jvcarphe/1/
I've been trying with all sorts of culling / tick values / time series etc. but I can't for the love of god figure out how to do it. If the type in the fiddle is changed to "line" it does exactly what I want, beside it's not a bar.
I've had to do this before and there doesn't seem to be a simple setting that does it, but a bit of d3 manipulation works. I came to the conclusion it's easier to move the ticks than the bars:
If you know the width of your bar, you can set a css rule to offset the ticks, just change the -10px to whatever is necessary -->
.c3-axis-x .tick line, .c3-axis-x .tick text {
transform: translate(-10px,0);
}
(can't just apply the rule to .tick as c3 overrides its transform style)
If you don't know the width then you need to find it out by querying one of the bars and applying the same style rule dynamically in c3's onrendered callback:
onrendered: function () {
var thisChart = d3.select(this.config.bindto);
var barWidth = thisChart.select(".c3-bar-0").node().getBoundingClientRect().width / 2;
thisChart.selectAll(".c3-axis-x .tick line,.c3-axis-x .tick text").style("transform", "translate(-"+barWidth+"px,0)");
}
Fiddle edited as newer version of c3 didn't work in the fiddle:
https://jsfiddle.net/15w50f06/4/

Customizing Chart.js troubleshoot

Have some trouble with Chart.js
1) is it possible to move bottom labels on top of the chart?
2) is it possible to hide left labels with first grey line?
3) is it possible to set up permanent tooltips(to show temperature) on every point instead of hover tooltips?
Here is my chart http://jsfiddle.net/JohnnyJuarez/ojc09hv4/:
<canvas id="weeksChart" width="651" height="335"></canvas>
var dayTemperatureArray = [-5, 14, 15, 15, 17, 18, 19, 21, 22, 25, 24, 20, 19, 16];
var nightTemperatureArray = [-10, 4, 5, 6, 8, 11, 12, 15, 17, 15, 13, 12, 11, 9];
var dataWeeks = {
labels: ["16.02", "17.02", "18.02", "19.02", "20.02", "21.02", "22.02", "23.02", "24.02", "25.02", "26.02", "27.02", "28.02", "01.03"],
datasets: [
{
label: "Days temperature chart",
fillColor: "transparent",
strokeColor: "rgba(244, 6, 6, 1)",
data: dayTemperatureArray
},
{
label: "Nights temperature chart",
strokeColor: "#3f6bf5",
data: nightTemperatureArray
}
]
};
var ctx = document.getElementById("weeksChart").getContext("2d");
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
responsive: true,
pointDot: true,
datasetStrokeWidth: 0.5,
scaleSteps: 2,
scaleLabel: "<%=value + '°'%>",
tooltipTemplate: "<%= value %>",
showTooltips: true
});
Thanx a lot in advance!
p.s. please avoid jquery, if it's possible :-)
Let's start with the easiest one first
2) is it possible to hide left labels with first grey line?
I assume you meant the y axis labels. You can set the scaleShowLabels option to false in the chart options to hide the y axis labels
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
scaleShowLabels: false,
...
1) is it possible to move bottom labels on top of the chart?
I assume you mean the x axis labels. Chart.js doesn't have a direct option to do this. However you can hide the actual x axis labels and draw the x axis labels at the top of the chart by yourself.
Again, Chart.js doesn't have an option to hide x axis labels, but luckily there is an option to control the scale font color. Just set it to transparent and your original x axis labels are now hidden!
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
scaleFontColor: "transparent",
...
Now the drawing of the x axis labels at the top of the chart. To save us the trouble of extending the chart, we can add a post animation event handler and do this in that, like so
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
onAnimationComplete: function () {
animationComplete.apply(this)
}
...
with
var animationComplete = function () {
var self = this;
Chart.helpers.each(self.datasets[0].points, function (point, index) {
self.chart.ctx.font = Chart.helpers.fontString(self.fontSize, self.fontStyle, self.fontFamily)
self.chart.ctx.textAlign = 'center';
self.chart.ctx.textBaseline = "middle";
self.chart.ctx.fillStyle = "#666";
self.chart.ctx.fillText(point.label, point.x, self.scale.startPoint);
});
};
We just loop through all points in one of the dataset and add the labels (scale.startPoint is the top edge of the chart area)
Note - why do we set the font, alignment, etc. every iteration? That's for when we add the tooltips.
3) is it possible to set up permanent tooltips(to show temperature) on every point instead of hover tooltips?
The first step would be to actually show the tooltips. This is fairly simple, though a bit tedious. We loop through all the x axis point, build the label (by going through each dataset) and then construct a tooltip (fortunately, we can use Chart.MultiTooltip function for this.
We add it into the same loop we used to construct the new x axis labels. Since we need to color our tooltips, we need to get and store the set of colors in an array (which we pass on to the MultiTooltip function - we need to do this only once, so we take it out of the loop.
The modified animationComplete function is now this
var animationComplete = function () {
var self = this;
var tooltipColors = []
Chart.helpers.each(self.datasets, function (dataset) {
tooltipColors.push({
fill: dataset.strokeColor,
stroke: dataset.strokeColor
})
});
Chart.helpers.each(self.datasets[0].points, function (point, index) {
var labels = []
var total = 0;
Chart.helpers.each(self.datasets, function (dataset) {
labels.push(dataset.points[index].value)
total += Number(dataset.points[index].y);
});
new Chart.MultiTooltip({
x: point.x,
y: total / 2,
xPadding: self.options.tooltipXPadding,
yPadding: self.options.tooltipYPadding,
xOffset: self.options.tooltipXOffset,
fillColor: self.options.tooltipFillColor,
textColor: self.options.tooltipFontColor,
fontFamily: self.options.tooltipFontFamily,
fontStyle: self.options.tooltipFontStyle,
fontSize: self.options.tooltipFontSize,
titleTextColor: self.options.tooltipTitleFontColor,
titleFontFamily: self.options.tooltipTitleFontFamily,
titleFontStyle: self.options.tooltipTitleFontStyle,
titleFontSize: self.options.tooltipTitleFontSize,
cornerRadius: self.options.tooltipCornerRadius,
labels: labels,
legendColors: tooltipColors,
legendColorBackground: self.options.multiTooltipKeyBackground,
title: point.label,
chart: self.chart,
ctx: self.chart.ctx,
custom: self.options.customTooltips
}).draw()
self.chart.ctx.font = Chart.helpers.fontString(self.fontSize, self.fontStyle, self.fontFamily)
self.chart.ctx.textAlign = 'center';
self.chart.ctx.textBaseline = "middle";
self.chart.ctx.fillStyle = "#666";
self.chart.ctx.fillText(point.label, point.x, self.scale.startPoint);
});
};
It looks complex, but all we are doing is passing a options that we copy from the chart instance options to the MultiTooltip function.
The tooltips all show up when the animation is complete. HOWEVER, once you move your mouse over the chart they all up and disappear! That's because the chart instance listens for multiple events to decide whether to start checking if tooltips should be shown - one of these is mousemove (and that causes it to redraw the chart, wiping out all our hard drawn tooltips and, if we are lucky, it draws a tooltip based on the point our mouse is hovering over)
This is a configurable option. So, all we have to do is remove all such events.
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
tooltipEvents: []
...
Working fiddle - http://jsfiddle.net/fuodxsfv/
Unless your chart is wide enough, you will have tooltips (mostly the middle 2 ones) overlap (of course you could incorporate logic into the above loop to handle that), but anyhoo, those were actually meant to be tooltips!

jqplot set data series from table

I am using jqplot to create a pie chart from an HTML table.
However, when attempting to set a var the chart doesn't plot.
If i simply set a number for the var, such as:
var DataTest = 22;
then the chart works fine.
However, when I get the value from the table it doesn't, as below:
var DataTest = $(dataID + ' td:nth-child(46)').text();
The pie chart wont display.
The pie chart series is being set through a var also:
var PieChartS1 = [ ['Label', DataTest] ];
Then included in the chart code as follows:
var PieChartPlot = $.jqplot('PieChart', [PieChartS1, PieChartS2 ], {
seriesDefaults: {
renderer:$.jqplot.DonutRenderer,
rendererOptions:{
sliceMargin: 1,
startAngle: -145,
showDataLabels: true,
dataLabels: 'label',
padding: '5',
ringMargin: '5',
dataLabelThreshold: '1',
highlightMouseOver: true,
}
},
grid: {background: 'transparent', borderWidth: '0', cursor: 'pointer',},
});
I'm wondering whether it is a format issue?
Thanks for any help
Richard
Update:
Am wondering whether the graph is being formed by the script before the data has been obtained, so it is just showing blank as it is finding no data. Perhaps I need to delay the graph formation until the 'get data' scripts are fully executed?
Had some help from elsewhere.
It needs to be specified as an integer, so the change needs to be:
var DataTest = parseInt($(dataID + ' td:nth-child(46)').text());
This works fine.

Finding the Y axis value for a plot line in HIghCharts.js

I am trying to size a background image on a HighCharts line chart dynamically depending on the position of the top plot line. The image I am trying to size is the bell curve in the image below.
I can't set the height of the image as a static value because the size of the screen can change and the top plot line also changes over time.
At the moment I am setting the position of the plot lines with external functions like this:
plotLines: [
value: upperControl3()}, {
color: '#ccc',
zIndex: 3,
width: 1,
label: {
text: '-2s',
x: 520,
y: 3
}
The closest thing to the y value of the top plot line I have been able to find is a dataMax value but this stays the same on every chart load.
I have been trying to overlay and size the image with a function at the end of the chart like this:
function(chart) {
console.log(chart.yAxis[0].plotLinesAndBands[7].axis.plotLinesAndBands[0].axis);
var h = chart.yAxis[0].plotLinesAndBands[7].axis.plotLinesAndBands[0].axis.dataMax;
var y = chart.yAxis[0].axisTitle.y + extra;
// X, Y, Width, Height
chart.renderer.image('images/bell.jpg', 60, y, 200, h).add();
}
Is the any way to find the coordinates of a plot line in highcharts?
You can use plotLinesAndBands object, where plotlines are kept. In the options you have value, whcih can be translated into pixels value by toPixels function.
var $button = $('#button'),
$report = $('#report'),
chart = $('#container').highcharts();
$button.click(function () {
chart.xAxis[0].addPlotLine({
value: 5.5,
color: 'red',
width: 2,
id: 'plot-line-1'
});
var plotline = chart.xAxis[0].plotLinesAndBands[0];
$report.html('Value: ' + plotline.options.value + ' Pixels: ' + chart.xAxis[0].toPixels(plotline.options.value));
});
http://jsfiddle.net/HhP39/1/
If you know which plot line (by index) it is, you can do this:
chart.yAxis[0].plotLinesAndBands[0].options.value
Of course, you need to make sure your data is actually normally distributed, or else that normal curve means nothing :)
And zero-bounded data is not usually normally distributed.

How to draw a column chart with one single field and multiple colors using google charts

Here is my code: jsfiddle
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
function drawColumnChart(container, data) {
var data = google.visualization.arrayToDataTable(data);
var chart = new google.visualization.ColumnChart(container);
var options = {fontSize: 16};
chart.draw(data, options);
}
$(document).ready(function(){
drawColumnChart($("#satisfactionBarGraph")[0], [
['satisfaction', 'percent'],
['大変満足', 10 ],
['満足', 22 ],
['やや満足', 30 ],
['やや不満', 10 ],
['不満', 5 ]
]);
});
</script>
</head>
<body>
<div id="satisfactionBarGraph" style="width: 524px; height: 370px;" class="chartContainer"></div>
</body>
</html>
And this is what I really want:
I have two problems:
(1) I want the text below the x-axis to align top bottom
I have run through the document but cannot find the option
(2) I want the columns to be in different colors
Because I have only one filed, so all of them are in the same color. I'm wondering whether I used the right chart.
And suggestion will be appreciated
Thanks a lot for all your answers. I combined your solutions and finally figured it out:
final result
Hope this can help anyone who meets the same problem
The Google Visualization API's ColumnCharts color data by series, so if you want multiple colors for your bars, you have to split them into different series.
function drawColumnChart(container, data) {
var data = google.visualization.arrayToDataTable(data);
var columns = [0];
for (var i = 0; i < data.getNumberOfRows(); i++) {
columns.push({
type: 'number',
label: data.getColumnLabel(1),
calc: (function (x) {
return function (dt, row) {
return (row == x) ? dt.getValue(row, 1) : null;
}
})(i)
});
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
var chart = new google.visualization.ColumnChart(container);
var options = {
fontSize: 16,
// set the "isStacked" option to true to make the column spacing work
isStacked: true
};
chart.draw(view, options);
}
// use the callback from the google loader to draw the chart rather than document ready
google.load("visualization", "1", {packages:["corechart"], callback: function () {
drawColumnChart($("#satisfactionBarGraph")[0], [
['satisfaction', 'percent'],
['大変満足', 10],
['満足', 22],
['やや満足', 30],
['やや不満', 10],
['不満', 5]
]);
}});
Here's a jsfiddle of this code: http://jsfiddle.net/asgallant/Rrhak/
I don't think the Visualization API supports vertical writing like that. You can rotate text to be aligned vertically, but that's not what you are trying to achieve here.
You can get vertical labels like you want with a little bit of finagling.
I put a sample here:
I hope this answer makes you 大変満足.
Add Spaces
Your data needs to have each character with a space between it so that they can be broken up in to separate lines:
['satisfaction', 'percent'],
['大 変 満 足', 10 ],
['満 足', 22 ],
['や や 満 足', 30 ],
['や や 不 満', 10 ],
['不 満', 5 ]
Change Axis Display Values
For the hAxis you need to set the following options:
maxTextLines: 5,
slantedText: false,
showTextEvery: 1,
minTextSpacing: 40,
maxAlternation: 1
maxTextLines will allow your labels to be broken up in to multiple vertical lines. 4 would likely work as well as 5 here, since you only have 4 characters.
slantedText ends up being used over splitting up over multiple lines for some reason. So I turned it off manually.
showTextEvery prevents it from showing horizontal labels on one line by only display a subset of your axis labels.
minTextSpacing ensures that even though your lines are one character wide, the chart is fooled in to thinking that it needs to add line breaks.
maxAlternation prevents you from having two 'levels' of labels so that they all line up flush with the axis.
Adjust the Height of the Chart
If you leave the chart height as default, there is only space for 2 lines of labels, so you end up with labels that say
や
や
…
To prevent that, you need to artificially increase the height of the chart. There are a dozen ways to do this, I just set the height property manually.

Categories