When displaying a long noData message on High Chart, the text is not wrapping and is going out of screen/chart.
DEMO: http://jsfiddle.net/9xLyo7xj/
lang:{noData:'this is a really long sentence that is supposed to wrap around the window but somehow it is not - I would like it to wrap for easier reading'}
HTML
<button id="add">Add data</button>
<button id="remove">Remove data</button>
<button id="showCustom">Show custom message manually</button>
JS
$(function() {
var chart,
btnRemove = $('#remove'),
btnAdd = $('#add'),
btnShow = $('#showCustom');
btnAdd.click(function() {
chart.series[0].addPoint(Math.floor(Math.random() * 10 + 1)); // Return random integer between 1 and 10.
});
btnRemove.click(function() {
if (chart.series[0].points[0]) {
chart.series[0].points[0].remove();
}
});
btnShow.click(function() {
if (!chart.hasData()) {
chart.hideNoData();
chart.showNoData("Your custom error message");
}
});
$('#container').highcharts({
title: {
text: 'No data in line chart - with custom options'
},
series: [{
type: 'line',
name: 'Random data',
data: []
}],
lang: {
noData: "this is a really long sentence that is supposed to wrap around the window but somehow it is not - I would like it to wrap for easier reading"
},
noData: {
style: {
fontWeight: 'bold',
fontSize: '15px',
color: '#303030',
width: 400px
}
}
});
chart = $('#container').highcharts();
});
Related
Found a couple of posts that came close to solving this. I'm loading a chart into a widget and it's not filling it, instead it's centered and extended past the widget - about only 1/3 of the pie chart shows for example.
I found the resize options for gridster and it gets me almost there... the same problem exists when I load the page, but when I resize the widget the chart fills it in perfectly.
I've tried aligning the chart, removing width and height settings, addeing resize and stop elements to gridsters..
var gridster = null;
$(document).ready(function () {
gridster = $(".gridster ul").gridster({
widget_base_dimensions: ['auto', 140],
autogenerate_stylesheet: true,
min_cols: 1,
max_cols: 6,
widget_margins: [5, 5],
resize: {
enabled: true,
resize: function (e, ui, $widget) {
Highcharts.charts[0].reflow(); // reflow the first chart...
},
stop: function(e, ui, $widget) {
Highcharts.charts[0].reflow(); // reflow the first chart...
}
}
}).data('gridster');
$('.gridster ul').css({'padding': '0'});
});
Highcharts.chart('container', {
chart: {
type: 'pie'
},
title: {
text: 'User data',
style: {"fontSize": "15px" , "color":"red"},
},
subtitle: {
text: 'Source: Click the slices to view categories.'
},
plotOptions: {
pie: {
showInLegend: false,
dataLabels: {
formatter: function(){
console.log(this);
if (this.percentage > 5)
return this.key + ': ' + this.y;
else
this.point.visible = false;
return '';
}
}
},
series: {
dataLabels: {
enabled: true,
}
}
},
tooltip: {
headerFormat: '<span style="font-size:11px">{series.name}</span><br>',
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
when page loads the pie chart is sized to fit into the gridster widget.
Add one div wrapper around widget and add class which having height and width of that widget. It will render your highchart graph in that wrapper only.
<div class="size-1x1">
Render your graph code here
</div>
CSS:
.size-1x1 {
height:100px;
width: 120px;
}
Code is as below
chart: {
type: "funnel",
marginBottom: 25,
backgroundColor: "transparent",
events: {
load: function() {
var chart = this;
Highcharts.each(chart.series[0].data, function(p, i) {
chart.options.labels.items.push({
html: "less confident" + i,
style: { left: 550, top: 50 }
});
p.dataLabel.attr({
x: (chart.plotWidth - chart.plotLeft) / 2,
"text-anchor": "middle"
});
});
}
}
},
I see that you're trying to add a label for every point. Highcharts has build in functionality for this called data labels: https://api.highcharts.com/highcharts/series.line.dataLabels
Another approach is to use SVGRenderer.label: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#label
I am attempting to write a function to add a highchart to a page and a function that can update the data for that chart based on a streaming API. I added a setInterval to simulate the streaming api.
The issue occurs on line 80. I believe it is because I have not set the series array with the chart object properly. When I need to add new data via 'addPoint', the prototype is not there. What am I missing in my AddChart function that wires the series up to highcharts?
FIDDLE:
http://jsfiddle.net/puto3Lg0/2/
$(function () {
$(document).ready(function () {
var metrics = [];
Highcharts.setOptions({
global: {
useUTC: false
}
});
function AddChart(metric) {
$("#divMain").append('<div id="' + metric.key + '" style="min-width: 310px; height: 200px; margin: 0 auto"></div>');
$('#' + metric.key).highcharts({
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
},
title: {
text: metric.Title
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Messages'
},
plotLines: [
{
value: 0,
width: 1,
color: '#808080'
}
]
},
tooltip: {
formatter: function() {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: metric.series
});
};
function ParseData(message) {
var jsonObj = JSON.parse(message);
$.each(jsonObj.Metrics, function(index, value) {
var metricName = value.Metric.Name.replace(' ', '');
if (metrics[metricName] == undefined) {
metrics[metricName] = {
"title": value.Metric.Name,
"key": metricName,
"series": [
{
name: value.Metric.Name,
data: []
}
],
}
AddChart(metrics[metricName]);
}
metrics[metricName].series.addPoint([new Date().getTime(), parseInt(value.Metric.CurrentValue)], true, false);
});
};
setInterval(function () {
var m = "{\"Metrics\": [{\"Metric\":{\"Name\":\"Queue 01\",\"CurrentValue\":\"0\",\"TimeStamp\":\"\\\x2FDate(1415826323291)\\\x2F\"}},{\"Metric\":{\"Name\":\"Queue 02\",\"CurrentValue\":\"3\",\"TimeStamp\":\"\\\x2FDate(1415826323344)\\\x2F\"}},{\"Metric\":{\"Name\":\"Queue 03\",\"CurrentValue\":\"9\",\"TimeStamp\":\"\\\x2FDate(1415826323405)\\\x2F\"}}]}";
ParseData(m);
}, 1000);
});
});
First, you have metrics declared as an array. Should be an empty object:
var metrics = {};
Second, the data structure you've created, metrics[metricName].series is not a Highcharts series object. It's an object you created and used to supply Highcharts data. To get the real series object, you'll have to get it back from the chart.
// getting the chart from the DOM, then the first series...
$("#"+metricName).highcharts().series[0].addPoint([new Date().getTime(), parseInt(value.Metric.CurrentValue)], true, false);
Updated fiddle.
I want to make some tooltips visible in my d3 map. The tooltips are column charts generated by Highcharts regarding the chosen city. The trick is that everything is displaying correctly (axis, labels ...) except that the columns are not visible!
Here my d3 code (only the relevant parts):
var tooltip = d3.select("body")
.append("div")
.attr("id","tooltip")
.style("position", "absolute")
.style("visibility", "hidden");
cities.on("mouseover", function(d, i) {
d3.select(this).style('fill', '#95a5a6');
tooltip.html(zoomCityComm(d))
return tooltip.style("visibility", "visible")})
.on("mousemove", function(d, i){
return tooltip.style("top", (d3.event.pageY - 130) + "px").style("left",(d3.event.pageX - 120) + "px");
})
}
The function zoomCityComm is HighCharts (example of data: [5,10]):
function zoomCityComm(d) {
chart = new Highcharts.Chart({
chart : {
renderTo: 'tooltip',
type: 'column',
width:200,
height:200,
plotBackgroundColor: '#FCFFC5',
zoomType: 'xy'
},
title: {
text: "TOTO"
},
legend: {
enabled: false
},
xAxis: {
categories: ['In','Out']
},
yAxis: {
title: {
text: 'Sum',
style: {
color: '#4572A7'
}
},
labels: {
style: {
color: '#4572A7'
}
},
},
series:[{color: '#4572A7',data: res}]
});
return document.getElementById("tooltip").innerHTML;
}
When the graph is displayed in a "normal" div within the document, it appears correctly.
Sorry if my explanations are not clear but ask me for some details if needed.
Thanks
Cyril
You're setting the HTML content of the div twice, as highcharts renders it itself. In your mouseover handler function, it is enough to do
zoomCityComm(d);
instead of
tooltip.html(zoomCityComm(d));
For the interested, here's what's happening. Setting the HTML of the tooltip div from the return value of the function captures the first animation frame that highchart uses to grow the bars. As it is the first frame, the height of the bars is still 0 -- that is, the bars are there, but not visible because they have essentially no height. Replacing the HTML of the div means that the animation won't work anymore, as the elements that would be animated have been replaced.
When dragging one of the navigator handles, both dates change.
To reproduce, go to http://jsfiddle.net/rNer2/5/ and drag one of the navigator handles. In the provided test case, the problem only occurs the first time a handle is dragged. It can actually also happen in other situations, but perhaps fixing it here will fix it for the other cases as well.
See duplicate code below:
<div id="container" style="height: 400px; min-width: 600px"></div>
<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script src="http://code.highcharts.com/stock/modules/exporting.js"></script>
<div id="mindate" style="position:absolute;top:40px;left:0px;margin-left:20px;"></div>
<div id="maxdate" style="position:absolute;top:40px;right:0px;margin-right:50px;">
$(function() {
var data = [];
for (var i = 1971; i < 2020; ++i) {
data.push([Date.UTC(i, 0, 1), 1]);
}
var chart = new Highcharts.StockChart({
chart: {
renderTo: 'container',
type: 'column',
events: {
load: function() {
displayDates(this.xAxis[0].getExtremes());
}
}
},
xAxis: {
ordinal: false,
events: {
afterSetExtremes: function(e) {
displayDates(e);
}
},
min: Date.UTC(1984, 0, 1),
max: Date.UTC(1988, 0, 1)
},
series: [{
data: data
}]
});
});
function displayDates(e) {
$('#mindate').html(Highcharts.dateFormat('%m/%d/%y %I:%M:%S%p', e.min));
$('#maxdate').html(Highcharts.dateFormat('%m/%d/%y %I:%M:%S%p', e.max));
}
Please familiar with very simple example:
http://jsfiddle.net/ebLTE/
$('#container').highcharts('StockChart', {
chart:{
type:'column'
},
rangeSelector : {
selected : 1
},
title : {
text : 'AAPL Stock Price'
},
xAxis:{
min:1172707200000,
max:1175126400000
},
series : [{
name : 'AAPL',
data : data,
tooltip: {
valueDecimals: 2
}
}]
});