displaying custom tooltip when hovering over a point in flot - javascript

From the example here, I kind of know how to create a Flot graph that shows tooltips when hovering. But the examples only show to how to display tooltips containing the x value, y value, label, etc., and I can't figure out how to create more customized tooltips.
Is there someplace I can attach custom data, that I can access when creating the tooltip?
For example, to simplify, let's suppose my code looks like:
var d = [ { label: "Fake!", data: [ [1290802154, 0.3], [1292502155, 0.1] ] } ];
var options = {
xaxis: { mode: "time" },
series: {
lines: { show: true },
points: { show: true }
},
grid: { hoverable: true, clickable: true }
};
$.plot($("#placeholder"), d, options);
Now, when clicking on the first datapoint, I want the tooltip to show "Hello", and when clicking on the second datapoint I want to show "Bye". How do I do this? When binding the plothover event
$(".placeholder").bind("plothover", function (event, pos, item) { /* etc. */ };
I'm not sure what "item" refers to, and how to attach data to it.

You can add data to the series simply by adding it to the data array.
Instead of
$.plot(element, [[1, 2], [2, 4]] ...)
You can
$.plot(element, [[1, 2, "label"], [2, 4, "another label"]] ...)
And then use that information to show a custom label.
See this fiddle for a full example:
http://jsfiddle.net/UtcBK/328/
$(function() {
var sin = [],
cos = [];
for (var i = 0; i < 14; i += 0.5) {
sin.push([i, Math.sin(i), 'some custom label ' + i]);
cos.push([i, Math.cos(i), 'another custom label ' + i]);
}
var plot = $.plot($("#placeholder"), [{
data: sin,
label: "sin(x)"
},
{
data: cos,
label: "cos(x)"
}
], {
series: {
lines: {
show: true
},
points: {
show: true
}
},
grid: {
hoverable: true,
clickable: true
},
yaxis: {
min: -1.2,
max: 1.2
}
});
$("#placeholder").bind("plothover", function(event, pos, item) {
$("#tooltip").remove();
if (item) {
var tooltip = item.series.data[item.dataIndex][2];
$('<div id="tooltip">' + tooltip + '</div>')
.css({
position: 'absolute',
display: 'none',
top: item.pageY + 5,
left: item.pageX + 5,
border: '1px solid #fdd',
padding: '2px',
'background-color': '#fee',
opacity: 0.80
})
.appendTo("body").fadeIn(200);
showTooltip(item.pageX, item.pageY, tooltip);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://people.iola.dk/olau/flot/jquery.flot.js"></script>
<div id="placeholder" style="width:600px;height:300px"></div>

Here is a rough JSFiddle example that I whipped up. Not sure if it's functioning exactly how you like but might spark an idea...
[update]
you'll want to bind to the
$("#placeholder").bind("plotclick", function (event, pos, item) {/* code */});
event for clicking events
[update2] Updated Example
I've adjusted the example to use your test data and to work more with what you have described above. As for the item object it seems that it is generated on the fly so, from what I can tell, you can not add additional data to it. However, you can create an array to cache the item objects when clicked and add additional data to them and use them for the hover event.
This new example does just that, it shows the normal tooltip when nothing is clicked. but once clicked it determines if the point clicked was the first or second and adds an addition property to the item object called alternateText and stores it in an array called itemsClicked.
Now when a point is hovered over it checks to see if there is a cached item object within the array based on the same index of the current item object, which is obtained via item.dataIndex. If there is a matching index in the cache array itemsClicked it will grab the item object from it and use the alternateText property that was added during the click event earlier.
The first point's item object would look something like this:
item : {
dataIndex: 0,
datapoint: [
1290802154,
0.3
],
pageX: 38,
pageY: 82,
series: {/* properties of the series that this point is in */},
seriesIndex: 0
}
Once clicked it would then look like this and be stored in the itemsClicked array:
item : {
alternateText: 'hello',
dataIndex: 0,
datapoint: [
1290802154,
0.3
],
pageX: 38,
pageY: 82,
series: {/* properties of the series that this point is in */},
seriesIndex: 0
}
Please let me know if any of this is helpful or not, if not I'll shut up and stop updating my answer :P

Also you can try following code:
function showTooltip(x, y, contents, z) {
$('<div id="tooltip">' + contents + '</div>').css({
position: 'absolute',
display: 'none',
top: y - 30,
left: x - 110,
'font-weight': 'bold',
border: '1px solid rgb(255, 221, 221)',
padding: '2px',
'background-color': z,
opacity: '0.8'
}).appendTo("body").show();
};
$(document).ready(
$(function() {
var data = [{
"label": "scott",
"data": [
[1317427200000 - 5000000 * 3, "17017"],
[1317513600000 - 5000000 * 5, "77260"]
]
},
{
"label": "martin",
"data": [
[1317427200000 - 5000000 * 2, "96113"],
[1317513600000 - 5000000 * 4, "33407"]
]
},
{
"label": "solonio",
"data": [
[1317427200000 - 5000000, "13041"],
[1317513600000 - 5000000 * 3, "82943"]
]
},
{
"label": "swarowsky",
"data": [
[1317427200000, "83479"],
[1317513600000 - 5000000 * 2, "96357"],
[1317600000000 - 5000000, "55431"]
]
},
{
"label": "elvis",
"data": [
[1317427200000 + 5000000, "40114"],
[1317513600000 - 5000000 * 1, "47065"]
]
},
{
"label": "alan",
"data": [
[1317427200000 + 5000000 * 2, "82504"],
[1317513600000, "46577"]
]
},
{
"label": "tony",
"data": [
[1317513600000 + 5000000, "88967"]
]
},
{
"label": "bill",
"data": [
[1317513600000 + 5000000 * 2, "60187"],
[1317600000000, "39090"]
]
},
{
"label": "tim",
"data": [
[1317513600000 + 5000000 * 3, "95382"],
[1317600000000 + 5000000, "89699"]
]
},
{
"label": "britney",
"data": [
[1317513600000 + 5000000 * 4, "76772"]
]
},
{
"label": "logan",
"data": [
[1317513600000 + 5000000 * 5, "88674"]
]
}
];
var options = {
series: {
bars: {
show: true,
barWidth: 60 * 60 * 1000,
align: 'center'
}
},
points: {
show: true
},
lines: {
show: true
},
grid: {
hoverable: true,
clickable: true
},
yaxes: {
min: 0
},
xaxis: {
mode: 'time',
timeformat: "%b %d",
minTickSize: [1, "month"],
tickSize: [1, "day"],
autoscaleMargin: .10
}
};
$(function() {
$.plot($('#placeholder'), data, options);
});
$(function() {
var previousPoint = null;
$("#placeholder").bind("plothover", function(event, pos, item) {
if (item) {
if (previousPoint != item.datapoint) {
previousPoint = item.datapoint;
$("#tooltip").remove();
var x = item.datapoint[0],
y = item.datapoint[1] - item.datapoint[2];
debugger;
showTooltip(item.pageX, item.pageY, y + " " + item.series.label, item.series.color);
}
} else {
$("#tooltip").remove();
previousPoint = null;
}
})
});
})
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script src="http://people.iola.dk/olau/flot/jquery.flot.js"></script>
<div id="content">
<div class="demo-container">
<div id="placeholder" class="demo-placeholder" style="width:800px;height:600px;"></div>
</div>
</div>

Related

Plotline (vertical line) in highcharts scatter chart

https://jsfiddle.net/7zL0v5oq/
I would like to have a plotline at today's date. The list can get quite long and in that case it helps with having an oversight. I fear it doesn't work because it is a scatter chart but I don't know what the problem is. I've searched all over the place but everything leads to plotlines, which clearly doesn't work. I would also be thankful if anyone knew, whether there was an easy way to filter my data the way I have it (standard highcharts filtering is deactivated but doesn't really help because of the static y values, so I get a huge, white space in the middle unless I filter at the edges. Thank you in advance for your help.
data = [{
"id": 1,
"release": "Software1",
"routine_failure_analysis_ended_on": null,
"sw_maintenance_releases_ended_on": "2014-04-01",
"sale_ended_on": "2013-04-01",
"security_vul_support_ended_on": "2015-04-01",
"service_contract_renewal_ended_on": null,
"svc_attach_ended_on": null,
"support_ended_on": "2018-03-31",
"updated_dates_on": "2012-10-03",
"created_at": "2018-05-04T18:53:21.301+02:00",
"updated_at": "2018-05-16T08:36:24.940+02:00"
},
{
"id": 2,
"release": "Software2",
"routine_failure_analysis_ended_on": null,
"sw_maintenance_releases_ended_on": "2019-07-24",
"sale_ended_on": "2017-07-31",
"security_vul_support_ended_on": "2020-07-24",
"service_contract_renewal_ended_on": null,
"svc_attach_ended_on": null,
"support_ended_on": "2022-07-31",
"updated_dates_on": "2015-08-14",
"created_at": "2018-05-05T04:00:44.170+02:00",
"updated_at": "2018-05-16T08:36:29.325+02:00"
},
{
"id": 3,
"release": "Software3",
"routine_failure_analysis_ended_on": null,
"sw_maintenance_releases_ended_on": "2018-03-01",
"sale_ended_on": "2017-03-01",
"security_vul_support_ended_on": "2018-12-01",
"service_contract_renewal_ended_on": null,
"svc_attach_ended_on": null,
"support_ended_on": "2022-02-28",
"updated_dates_on": "2016-09-02",
"created_at": "2018-05-05T04:00:44.401+02:00",
"updated_at": "2018-05-16T08:36:31.643+02:00"
}
];
const colors = ["#516", "#1781e3", "#25b252", "#20c997", "#ffc107", "#ff8b2e", "#dd1122"];
//Change to store y value paired to release/pid
var change = {};
//Which y values need to be displayed
var ticks = [0];
//Description of events
var sale = "Sale";
var support = "Support";
var svc = " SVC attach";
var sw = "Software maintenance";
var routine = "Routine failure analysis";
var service = "Service contract renewal";
var security = "Security vulnerability support";
//Data array for series
var high = [];
data.sort(function(a, b) {
return Date.parse(a.support_ended_on) < Date.parse(b.support_ended_on) ? 1 : -1
})
for (var i = 0; i < data.length; i++) {
var arr = [{
x: Date.parse(data[i].sale_ended_on),
y: (i + 1) * 20,
color: colors[0],
myValue: sale
},
{
x: Date.parse(data[i].sw_maintenance_releases_ended_on),
y: (i + 1) * 20,
color: colors[1],
myValue: sw
},
{
x: Date.parse(data[i].security_vul_support_ended_on),
y: (i + 1) * 20,
color: colors[2],
myValue: security
},
{
x: Date.parse(data[i].svc_attach_ended_on),
y: (i + 1) * 20,
color: colors[3],
myValue: svc
},
{
x: Date.parse(data[i].routine_failure_analysis_ended_on),
y: (i + 1) * 20,
color: colors[4],
myValue: routine
},
{
x: Date.parse(data[i].service_contract_renewal_ended_on),
y: (i + 1) * 20,
color: colors[5],
myValue: service
},
{
x: Date.parse(data[i].support_ended_on),
y: (i + 1) * 20,
color: colors[6],
myValue: support
}
];
var key, value;
line = [{
x: Date.parse(data[i].sale_ended_on),
y: (i + 1) * 20
}, {
x: Date.parse(data[i].support_ended_on),
y: (i + 1) * 20
}]
//Adding to change list, so we can add release/pid as label to y axis
key = (i + 1) * 20;
ticks.push(key);
if (data[i].pid) {
value = data[i].pid;
} else {
value = data[i].release;
}
change[key] = value;
//Expanding high (which is used for the highcharts series) with arr (all points for one pid)
if (data[i].pid) {
high.push({
label: data[i].pid,
name: data[i].pid,
type: 'scatter',
data: arr
}, {
type: 'line',
data: line,
linkedTo: ":previous"
});
} else {
high.push({
label: data[i].release,
name: data[i].release,
type: 'scatter',
data: arr,
showInLegend: false
}, {
type: 'line',
data: line,
linkedTo: ":previous"
});
}
}
Highcharts.chart("container", {
chart: {
height: data.length * 75
},
credits: {
enabled: false
},
yAxis: {
title: {
text: null
},
tickPositions: ticks,
visible: true,
labels: {
formatter: function() {
var value = change[this.value];
return value !== 'undefined' ? value : this.value;
}
}
},
xAxis: {
plotlines: [{
color: "#dd1122",
width: 2,
value: +new Date()
}],
type: 'datetime',
},
plotOptions: {
scatter: {
marker: {
symbol: 'circle',
radius: 7,
lineWidth: 2
}
},
line: {
enableMouseTracking: false,
marker: {
enabled: false
},
color: '#bbb',
lineWidth: 3
}
},
tooltip: {
formatter: function() {
var str = '<b>' + this.series.name + '</b><br/>'
if (this.point.myValue) {
str += this.point.myValue;
} else {
str += "Corrupted data!";
}
if (this.point.x < Date.parse(new Date))
return str += " ended on:<br/>" + Highcharts.dateFormat('%e %b %Y', new Date(this.x));
else
return str += " will end on:<br/>" + Highcharts.dateFormat('%e %b %Y', new Date(this.x));
},
shared: false
},
series: high
})
You have a typo, use plotLines instead of plotlines:
xAxis: {
plotLines: [{
...
}],
...
}
Live demo: https://jsfiddle.net/BlackLabel/p3u8ejtb/
API Reference: https://api.highcharts.com/highcharts/xAxis.plotLines

Changing xaxis label from echarts library

var data = [];
var dataCount = 10;
var startTime = +new Date();
var categories = ['categoryA', 'categoryB', 'categoryC'];
var types = [
{name: 'JS Heap', color: '#7b9ce1'},
{name: 'Documents', color: '#bd6d6c'},
{name: 'Nodes', color: '#75d874'},
{name: 'Listeners', color: '#e0bc78'},
{name: 'GPU Memory', color: '#dc77dc'},
{name: 'GPU', color: '#72b362'}
];
// Generate mock data
echarts.util.each(categories, function (category, index) {
var baseTime = startTime;
for (var i = 0; i < dataCount; i++) {
var typeItem = types[Math.round(Math.random() * (types.length - 1))];
var duration = Math.round(Math.random() * 10000);
data.push({
name: typeItem.name,
value: [
index,
baseTime,
baseTime += duration,
duration
],
itemStyle: {
normal: {
color: typeItem.color
}
}
});
baseTime += Math.round(Math.random() * 2000);
}
});
function renderItem(params, api) {
var categoryIndex = api.value(0);
var start = api.coord([api.value(1), categoryIndex]);
var end = api.coord([api.value(2), categoryIndex]);
var height = api.size([0, 1])[1] * 0.6;
var rectShape = echarts.graphic.clipRectByRect({
x: start[0],
y: start[1] - height / 2,
width: end[0] - start[0],
height: height
}, {
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
});
return rectShape && {
type: 'rect',
shape: rectShape,
style: api.style()
};
}
option = {
tooltip: {
formatter: function (params) {
return params.marker + params.name + ': ' + params.value[3] + ' ms';
}
},
title: {
text: 'Profile',
left: 'center'
},
dataZoom: [{
type: 'slider',
filterMode: 'weakFilter',
showDataShadow: false,
top: 400,
height: 10,
borderColor: 'transparent',
backgroundColor: '#e2e2e2',
handleIcon: 'M10.7,11.9H9.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z', // jshint ignore:line
handleSize: 20,
handleStyle: {
shadowBlur: 6,
shadowOffsetX: 1,
shadowOffsetY: 2,
shadowColor: '#aaa'
},
labelFormatter: ''
}, {
type: 'inside',
filterMode: 'weakFilter'
}],
grid: {
height:300
},
xAxis: {
min: startTime,
scale: true,
axisLabel: {
formatter: function (val) {
return Math.max(0, val - startTime) + ' ms';
}
}
},
yAxis: {
data: categories
},
series: [{
type: 'custom',
renderItem: renderItem,
itemStyle: {
normal: {
opacity: 0.8
}
},
encode: {
x: [1, 2],
y: 0
},
data: data
}]
};
Hi, everyone!! I am working on the echarts library, the only thing i want to change data is the axisLabel from Xaxis part.
What i mean is, for example, "2019-11-5, 2019-11-6...."and so on. So, i hope someone can help me out, thank you so much!!!
Hi, everyone!! I am working on the echarts library, the only thing i want to change data is the axisLabel from Xaxis part.
What i mean is, for example, "2019-11-5, 2019-11-6...."and so on. So, i hope someone can help me out, thank you so much!!!
First, create an array of dates like
var dates = ['2019-11-5','2019-10-3','2019-2-2','2019-1-4','2019-12-5'];
then in xAxis -> axisLabel return date
axisLabel: {
formatter: function (val,index) {
return dates[index];
}
}

Simplify JavaScript array variable

I'm looking to simplify this code. Any way to it so? Spring MVC + Apex Charts
var d = /*[[${s0}]]*/ null`; <-- It is sent via the Spring Framework. Basically represents datetime(in millis) at `d[0]`, `d[3]`,... Temperature at `d[1]`, `d[4]`,... and Humidity at `d[2]`, `d[5]`,...
<script type="text/javascript" th:inline="javascript">
var d = /*[[${s0}]]*/ null;
var options = {
chart: {
type: 'area',
height: 300
},
series: [
{
name: 'Temperature',
data: [
[d[0], d[1]],
[d[3], d[4]],
[d[6], d[7]],
[d[9], d[10]],
[d[12], d[13]],
[d[15], d[16]],
[d[18], d[19]],
[d[21], d[22]],
[d[24], d[25]],
[d[27], d[28]],
[d[30], d[31]],
[d[33], d[34]],
[d[36], d[37]],
[d[39], d[40]],
[d[42], d[43]],
[d[45], d[46]],
[d[48], d[49]],
[d[51], d[52]],
[d[54], d[55]],
[d[57], d[58]],
[d[60], d[61]],
[d[63], d[64]],
[d[66], d[67]],
[d[69], d[70]]
]
},
{
name: "Humidity",
data: [
[d[0], d[2]],
[d[3], d[5]],
[d[6], d[8]],
[d[9], d[11]],
[d[12], d[14]],
[d[15], d[17]],
[d[18], d[20]],
[d[21], d[23]],
[d[24], d[26]],
[d[27], d[29]],
[d[30], d[32]],
[d[33], d[35]],
[d[36], d[38]],
[d[39], d[41]],
[d[42], d[44]],
[d[45], d[47]],
[d[48], d[50]],
[d[51], d[53]],
[d[54], d[56]],
[d[57], d[59]],
[d[60], d[62]],
[d[63], d[65]],
[d[66], d[68]],
[d[69], d[71]]
]
}
],
xaxis: {
type: 'datetime'
},
yaxis: [
{
axisTicks: {
show: true
},
axisBorder: {
show: true,
},
title: {
text: "Temperature"
}
}, {
min: 0,
max: 100,
opposite: true,
axisTicks: {
show: true
},
axisBorder: {
show: true,
},
title: {
text: "Humidity"
}
}
],
legend: {
position: 'top',
horizontalAlign: 'center'
},
tooltip: {
x: {
format: 'HH:mm dd/MM/yy'
},
}
}
var chart = new ApexCharts(document.querySelector("#chart0"), options);
chart.render();
</script>
I just need to simplify sending data via d[0], d[1] etc. Is there any kind of loop or anything else I can use?
You could take a function which takes the data and a pattern for the wanted elements and an offset for increment for the next row.
function mapByPattern(data, pattern, offset) {
var result = [], i = 0;
while (i < data.length) {
result.push(pattern.map(j => data[i + j]));
i += offset;
}
return result;
}
var data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
result = { series: [
{ name: 'Temperature', data: mapByPattern(data, [0, 1], 3) },
{ name: "Humidity", data: mapByPattern(data, [0, 2], 3) }
]};
console.log(result);
Thank You, Nina. Code code didn't work exactly as i wanted but was so helpful to fix my own. Thanks alot! Here's some fixed code :)
var data = /*[[${s0}]]*/ null;
function mapByPattern(data, pattern, offset) {
var result = [], i = 0;
while (i < data.length) {
result.push(pattern.map(j => data[i + j]));
i += offset;
}
return result;
}
var options = {
chart: {
type: 'area',
height: 300
},
series: [
{
name: 'Temperature',
data: mapByPattern(data, [0, 1], 3)
},
{
name: "Humidity",
data: mapByPattern(data, [0, 2], 3)
}
],
xaxis: {
type: 'datetime'
},
yaxis: [
{
axisTicks: {
show: true
},
axisBorder: {
show: true,
},
title: {
text: "Temperature"
}
}, {
min: 0,
max: 100,
opposite: true,
axisTicks: {
show: true
},
axisBorder: {
show: true,
},
title: {
text: "Humidity"
}
}
],
legend: {
position: 'top',
horizontalAlign: 'center'
},
tooltip: {
x: {
format: 'HH:mm dd/MM/yy'
},
}
}
var chart = new ApexCharts(document.querySelector("#chart0"), options);
chart.render();

HighCharts inside of a javascript function

I'm trying to draw a 3d box after a user has selected some data from the server.
When I put the highcharts inside of a js function, it throws some errors.
My code is:
Chart It<br/>
<div id="container" style="height: 400px"></div>
<script>
var chart;
function chart3d() {
// Give the points a 3D feel by adding a radial gradient
Highcharts.getOptions().colors = $.map(Highcharts.getOptions().colors, function (color) {
return {
radialGradient: {
cx: 0.4,
cy: 0.3,
r: 0.5
},
stops: [
[0, color],
[1, Highcharts.Color(color).brighten(-0.2).get('rgb')]
]
};
});
// Set up the chart
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
margin: 100,
type: 'scatter',
options3d: {
enabled: true,
alpha: 10,
beta: 30,
depth: 250,
viewDistance: 5,
fitToPlot: false,
frame: {
bottom: {
size: 1,
color: 'rgba(0,0,0,0.02)'
},
back: {
size: 1,
color: 'rgba(0,0,0,0.04)'
},
side: {
size: 1,
color: 'rgba(0,0,0,0.06)'
}
}
}
},
title: {
text: 'Draggable box'
},
subtitle: {
text: 'Click and drag the plot area to rotate in space'
},
plotOptions: {
scatter: {
width: 10,
height: 10,
depth: 10
}
},
yAxis: {
min: 0,
max: 10,
title: null
},
xAxis: {
min: 0,
max: 10,
gridLineWidth: 1
},
zAxis: {
min: 0,
max: 10,
showFirstLabel: false
},
legend: {
enabled: false
},
series: [{
planeProjection: {
enabled: false,
},
lineProjection: {
enabled: 'hover',
colorByPoint: true
},
name: 'Reading',
colorByPoint: true,
data: darray
}]
});
// Add mouse events for rotation
$(chart.container).on('mousedown.hc touchstart.hc', function (eStart) {
eStart = chart.pointer.normalize(eStart);
var posX = eStart.pageX,
posY = eStart.pageY,
alpha = chart.options.chart.options3d.alpha,
beta = chart.options.chart.options3d.beta,
newAlpha,
newBeta,
sensitivity = 5; // lower is more sensitive
$(document).on({
'mousemove.hc touchdrag.hc': function (e) {
// Run beta
newBeta = beta + (posX - e.pageX) / sensitivity;
chart.options.chart.options3d.beta = newBeta;
// Run alpha
newAlpha = alpha + (e.pageY - posY) / sensitivity;
chart.options.chart.options3d.alpha = newAlpha;
chart.redraw(false);
},
'mouseup touchend': function () {
$(document).off('.hc');
}
});
});
}
</script>
This loads fine if I do not put it inside of the chart3d function. Is there a way to get this working. The error message I get is:
highcharts.js:10 Uncaught Error: Highcharts error #13: www.highcharts.com/errors/13
at Object.a.error (highcharts.js:10)
at a.Chart.getContainer (highcharts.js:256)
at a.Chart.firstRender (highcharts.js:271)
at a.Chart.init (highcharts.js:247)
at a.Chart.getArgs (highcharts.js:246)
at new a.Chart (highcharts.js:246)
at chart3d (graphingCustom.js:26)
at HTMLAnchorElement.onclick (VM599 :643)
As they say:
Highcharts Error #13
Rendering div not found
This error occurs if the chart.renderTo option is misconfigured so that
Highcharts is unable to find the HTML element to render the chart in.
You don't have a div with the id=container at the time you are calling the method.

How to get percentage axes in a Highcharts Treemap?

I have a HighCharts Treemap showing a set of categories containing subcategories. The point of the graph is to show how much of the data is in Category A, and how much of Category A is in Subcategory A1.
I have created this as follows:
http://jsfiddle.net/jbcfk93m/
$(function () {
$('#container').highcharts({
series: [{
colorByPoint: true,
layoutAlgorithm: "stripes",
alternateStartingDirection: true,
allowPointSelect: true,
point: {
events: {
click: function () {
alert(this.name + ": " + this.value);
}
}
},
dataLabels: {
},
type: "treemap",
levels: [{
level: 1,
dataLabels: {
enabled: true,
align: 'right',
rotation: 30,
crop: false,
overflow: 'none',
inside: false,
style: {
fontSize: '15px',
fontWeight: 'bold'
}
}
}, {
level: 2,
dataLabels: {
style: {
}
},
layoutAlgorithm: "stripes",
}],
data: [{
// Add parents without values
id: 'CategoryA',
name: 'Category A'
}, {
id: 'CategoryB',
name: 'Category B',
}, {
// And the children with values
name: 'Subcat A1',
value: 4,
parent: 'CategoryA'
}, {
name: 'Subcat A2',
value: 6,
parent: 'CategoryA'
}, {
name: 'Subcat B1',
value: 6,
parent: 'CategoryB'
}, {
name: 'Subcat B2',
value: 2,
parent: 'CategoryB'
}
]
}],
title: {
text: 'Treemap',
margin: 100
},
xAxis: {
min: 0,
max: 100
}
});
});
I want to get both the X- and Y axes in the graph to show percentages so I can more easily see how much of my data is in a certain category.
Does anyone know how to do this?
I didn't find anything about axis on treemaps and i'm not really sure if showing a percentage on X and Y axis would help you that much, because you basically have to multiply the values on X and Y(eg. if your subcat B1 is from 20% to 100% on X axis and from 60% to 100% on the Y axis then you would have to do (100% - 20%) * (100% - 60%) = 32%).
I did implement however a tooltip formatter that will show you the percentage when you hover over the subcategories.
formatter: function () {
var total = 0;
for (var i = 0; i < this.series.data.length; i++)
{
if (this.series.data[i].node.children.length == 0)
total+=this.series.data[i].node.val;
}
var value;
if (this.point.node.children.length == 0)
{
value = this.point.options.value;
}
else
{
value = this.point.node.childrenTotal;
}
return this.key + " " + (value / total) *100 + " %";
}
Here is the working fiddle http://jsfiddle.net/jbcfk93m/4/

Categories

Resources