I have built a map based on a standard map provided by Highcharts. However, it has been customized to show two sets of data on the tooltip instead of one and also so that when one clicks on a state they are linked to another page with information for that state. The problem I am facing is I need to change the name of one of the states. I have the code to do that, but since I've already customized the map, I'm having a hard time getting everything to work together. Basically when I add the code for the name change, it removes one of sets of data in the tooltip for all the states. Anyone able to help me out with this (the great #ppotaczek perhaps :) ? Specifically, I need to change Distrito Federal to CDMX in the tooltip while not removing the the two data sets from the tooltip.
Here's a jsfiddle: https://jsfiddle.net/sstoker/3cdaqkyx/6/#save
Here's the relevant javascript code:
// Prepare demo data
// Data is joined to map using value of 'hc-key' property by default.
// See API docs for 'joinBy' for more info on linking data and map.
const data = [
['mx-3622', 0.00],
['mx-bc', 5.59],
['mx-bs', 4.05],
['mx-so', 4.77],
['mx-cl', 6.91],
['mx-na', 8.88],
['mx-cm', 8.01],
['mx-qr', 4.87],
['mx-mx', 5.01],
['mx-mo', 0.089],
['mx-df', 8.12],
['mx-qt', 7.32],
['mx-tb', 3.17],
['mx-cs', 1.15],
['mx-nl', 6.88],
['mx-si', 6.64],
['mx-ch', 2.19],
['mx-ve', 0.66],
['mx-za', 8.03],
['mx-ag', 10],
['mx-ja', 3.35],
['mx-mi', 3.91],
['mx-oa', 0.8],
['mx-pu', 1.53],
['mx-gr', 0.0],
['mx-tl', 2.95],
['mx-tm', 5.47],
['mx-co', 9.46],
['mx-yu', 8.62],
['mx-dg', 4.47],
['mx-gj', 8.33],
['mx-sl', 4.35],
['mx-hg', 4.75]
];
const data1 = [
['mx-3622', 0.0],
['mx-bc', 13],
['mx-bs', 21],
['mx-so', 17],
['mx-cl', 10],
['mx-na', 3],
['mx-cm', 8],
['mx-qr', 16],
['mx-mx', 15],
['mx-mo', 31],
['mx-df', 6],
['mx-qt', 9],
['mx-tb', 24],
['mx-cs', 28],
['mx-nl', 11],
['mx-si', 12],
['mx-ch', 26],
['mx-ve', 30],
['mx-za', 7],
['mx-ag', 1],
['mx-ja', 23],
['mx-mi', 22],
['mx-oa', 29],
['mx-pu', 27],
['mx-gr', 32],
['mx-tl', 25],
['mx-tm', 14],
['mx-co', 2],
['mx-yu', 4],
['mx-dg', 19],
['mx-gj', 5],
['mx-sl', 20],
['mx-hg', 18]
];
data.forEach(function(el, i) {
el.push(data1[i][1])
});
// Create the chart
var chart = Highcharts.mapChart('container', {
chart: {
backgroundColor: '#f3f7fa',
map: 'countries/mx/mx-all',
},
title: {
text: ''
},
subtitle: {
text: ''
},
legend: {
title: {
text:'<span style="font-size:9.5px"> \< Bajo | Desarrollo democrático | Alto \> </span>',
}
},
plotOptions: { //For point links
map: {
point: {
events: {
click: function() {
$('#map1').trigger(this['hc-key']);
}
}
}
}
},
exporting: {
buttons: {
contextButton: {
align: 'center',
x: 0
}
},
chartOptions: {
chart: {
events: {
load: function() {
this.renderer.image('http://165.22.82.145/wp-content/uploads/2019/09/IDDMEX-Logo.svg',
480, // x
335, // y
75, // width
40, // height
).add();
}
}
}
}
},
mapNavigation: {
enabled: false,
buttonOptions: {
verticalAlign: 'bottom'
}
},
colorAxis: {
min: 0,
maxColor: 'blue',
stops: [
[.0,'#6497b1'],
[.249,'#6497b1'],
[.25,'#005b96'],
[.499,'#005b96'],
[.5,' #03396c'],
[.749,'#03396c'],
[.75,'#011f4b']
]
},
series: [{
keys: ['hc-key', 'value', 'rank'],
data: data,
name: 'Índice 2018',
states: {
hover: {
color: '#f3bbd3'
},
},
dataLabels: {
enabled: false,
format: '{point.name}',
}
}],
tooltip: {
pointFormat: ' {point.name} {point.value} <br>Ranking: {point.rank}'
},
});
});
and here is some javascript code that changes the name, but that is removing the second data series when I add it.
tooltip: {
pointFormatter: function() {
if (this['hc-key'] === 'mx-df') {
return 'CDMX: ' + this.value;
}
return this.name + ' ' + this.value;
}
}
Here's a solution to this problem. Add this code to the tooltip object.
pointFormatter: function() {
var firstRow = (this['hc-key'] === 'mx-df')
? "CDMX"
: this.name;
firstRow = firstRow + " " + this.value;
var secondRow = "Ranking: " + this.rank;
return (firstRow + "<br />" + secondRow);
}
Related
Im really not sure how to go about this. I am using a jQuery plotting chart to take in values from a array result set.
I am reading the results from live data read from a mysql table, the expected data. Example value: 2044.67 - I use Math.floor to remove decimal for int type. item.speed is a rapidly changing value (AJAX).
And this takes in the array and produces a plot chart. I use it to refresh the js and get results from ajax every 5 seconds in a function.
$.ajax({
url: 'filedownload.php',
method: 'GET',
dataType: 'JSON',
success: function(data) {
var graphData = [];
$.each(data, function (i, item) {
graphData.push(item.speed);
});
});
Here, how can I use the test array and still provide a structure like this from AJAX? This array is the only way the chart reads anything and provides plots.
var graphData = [{
data: [ [6, 1300], [7, 1600], [8, 1900], [9, 2100], [10, 2500], [11, 2200], [12, 2000], [13, 1950], [14, 1900], [15, 2000] ],
color: '#71c73e'
}
];
As it appears, I need to iterate a bunch of keys/values and build the array but then the plotting does not read it at all.
I am getting this
Expected result (the longer array)
$.plot($('#graph-lines'), graphData, { // <---- graphData[] Called Here!
series: {
points: {
show: true,
radius: 5
},
lines: {
show: true
},
shadowSize: 0
},
grid: {
color: '#646464',
borderColor: 'transparent',
borderWidth: 20,
hoverable: true
},
xaxis: {
tickColor: 'transparent',
tickDecimals: 2
},
yaxis: {
tickSize: 1000
}
});
$('#graph-bars').hide();
$('#lines').on('click', function(e) {
$('#bars').removeClass('active');
$('#graph-bars').fadeOut();
$(this).addClass('active');
$('#graph-lines').fadeIn();
e.preventDefault();
});
var previousPoint = null;
$('#graph-lines, #graph-bars').bind('plothover', function(event, pos, item) {
if(item) {
if(previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
$('#tooltip').remove();
var x = item.datapoint[0],
y = item.datapoint[1];
showTooltip(item.pageX, item.pageY, y + ' visitors at ' + x + '.00h');
}
} else {
$('#tooltip').remove();
previousPoint = null;
}
});
}
});
Any help is appreciated.
Original Code - interactivegraph
I have built a customized map using Highmaps by Highcharts. I need to change the periods (decimal point) to commas. I know how to do it normally using setOptions, like this:
Highcharts.setOptions({
lang: {
drillUpText: "< < Regresar",
decimalPoint: ',',
thousandsSep: '.'
},
});
However, the map's code has been customized to change the tooltip information and setOptions is no longer working to change the periods to commas. I suspect its an easy fix for someone more advanced that I. Are there any JavaScript experts out there that can help me out with this? Here's a jsfiddle: http://jsfiddle.net/sstoker/L60jg274/
Here's the relevant JS code:
$(function() { //For point links
(function(H) {
H.Legend.prototype.setItemEvents = null;
})(Highcharts)
// Prepare demo data
// Data is joined to map using value of 'hc-key' property by default.
// See API docs for 'joinBy' for more info on linking data and map.
const data = [
['mx-3622', 0.00],
['mx-bc', 5.59],
['mx-bs', 4.05],
['mx-so', 4.77],
['mx-cl', 6.91],
['mx-na', 8.88],
['mx-cm', 8.01],
['mx-qr', 4.87],
['mx-mx', 5.01],
['mx-mo', 0.089],
['mx-df', 8.12],
['mx-qt', 7.32],
['mx-tb', 3.17],
['mx-cs', 1.15],
['mx-nl', 6.88],
['mx-si', 6.64],
['mx-ch', 2.19],
['mx-ve', 0.66],
['mx-za', 8.03],
['mx-ag', 10],
['mx-ja', 3.35],
['mx-mi', 3.91],
['mx-oa', 0.8],
['mx-pu', 1.53],
['mx-gr', 0.0],
['mx-tl', 2.95],
['mx-tm', 5.47],
['mx-co', 9.46],
['mx-yu', 8.62],
['mx-dg', 4.47],
['mx-gj', 8.33],
['mx-sl', 4.35],
['mx-hg', 4.75]
];
const data1 = [
['mx-3622', 0.0],
['mx-bc', 13],
['mx-bs', 21],
['mx-so', 17],
['mx-cl', 10],
['mx-na', 3],
['mx-cm', 8],
['mx-qr', 16],
['mx-mx', 15],
['mx-mo', 31],
['mx-df', 6],
['mx-qt', 9],
['mx-tb', 24],
['mx-cs', 28],
['mx-nl', 11],
['mx-si', 12],
['mx-ch', 26],
['mx-ve', 30],
['mx-za', 7],
['mx-ag', 1],
['mx-ja', 23],
['mx-mi', 22],
['mx-oa', 29],
['mx-pu', 27],
['mx-gr', 32],
['mx-tl', 25],
['mx-tm', 14],
['mx-co', 2],
['mx-yu', 4],
['mx-dg', 19],
['mx-gj', 5],
['mx-sl', 20],
['mx-hg', 18]
];
// Create the chart
var chart = Highcharts.mapChart('container', {
chart: {
backgroundColor: '#f3f7fa',
map: 'countries/mx/mx-all',
},
title: {
text: ''
},
subtitle: {
text: ''
},
plotOptions: { //For point links
series: {
events: {
legendItemClick: function(e) {
return false;
}
}
},
map: {
point: {
events: {
click: function() {
$('#map1').trigger(this['hc-key']);
}
}
}
}
},
exporting: {
buttons: {
contextButton: {
align: 'center',
x: 0
}
},
chartOptions: {
chart: {
events: {
load: function() {
this.renderer.image('http://165.22.82.145/wp-content/uploads/2019/09/IDDMEX-Logo.svg',
480, // x
335, // y
75, // width
40, // height
).add();
}
}
}
}
},
mapNavigation: {
enabled: false,
buttonOptions: {
verticalAlign: 'bottom'
}
},
colorAxis: {
min: 0,
maxColor: 'blue',
events: {
legendItemClick: function() {
console.log(this)
}
},
dataClasses: [{
from: 0,
to: 3.000,
color: '#6497b1'
}, {
from: 3.001,
to: 4.500,
color: '#005b96'
}, {
from: 4.510,
to: 7.000,
color: '#03396c'
}, {
from: 7.001,
to: 10.000,
color: '#011f4b'
}]
},
legend: {
title: {
text: 'Desarrollo',
style: {
color: ( // theme
Highcharts.defaultOptions &&
Highcharts.defaultOptions.legend &&
Highcharts.defaultOptions.legend.title &&
Highcharts.defaultOptions.legend.title.style &&
Highcharts.defaultOptions.legend.title.style.color
) || 'black'
}
},
align: 'left',
verticalAlign: 'bottom',
floating: true,
layout: 'vertical',
valueDecimals: 3,
symbolRadius: 5,
symbolHeight: 14
},
series: [{
keys: ['hc-key', 'value', 'rank'],
data: data,
name: 'Índice 2018',
states: {
hover: {
color: '#f3bbd3'
},
},
dataLabels: {
enabled: false,
format: '{point.name}'
}
}],
tooltip: {
pointFormat: ' {point.name} {point.value} <br>Ranking: {point.rank}',
pointFormatter: function() {
var firstRow = (this['hc-key'] === 'mx-df') ?
"CDMX" :
this.name;
firstRow = firstRow + " " + this.value;
var secondRow = "Ranking: " + this.rank;
return (firstRow + "<br />" + secondRow);
}
},
});
});
setOptions usage is the correct solution. Next step is to use Highcharts.numberFormat function.
Demo: http://jsfiddle.net/BlackLabel/ay8m4pug/
Relevant code:
Highcharts.setOptions({
lang: {
decimalPoint: ',',
...
}
});
...
tooltip: {
...
pointFormatter: function() {
...
firstRow = firstRow + " " + Highcharts.numberFormat(this.value);
...
}
},
I'm having trouble on reload chart with updated details, I'm showing graph based on user activity on daily basis, on initial load with preset values the graph is formed precisely
Here I'm using flot chart library, in that flot chart library I'm using line graph
This is initial graph
But when I use custom values instead of loading a new graph with updated values, the custom values is get appended to the right end of x-axis on the graph.
When I use the custom values, the graph looks like,
In second graph, the included data will added to its old data at right side instead of showing it in correct order
here is my code for first graph, input data in vm.allsessionReport
input data will get by programmatic
vm.allSessionReport = [];
vm.sessionData = [{
"color": "#7dc7df",
"data": vm.allSessionReport
}];
vm.allSessionReport = [
["2017-06-30", 0],
["2017-07-01", 0],
["2017-07-02", 0],
["2017-07-03", 0],
["2017-07-04", 17],
["2017-07-05", 0],
["2017-07-06", 0],
["2017-07-07", 0]
]
vm.sessionData = [{
"color": "#7dc7df",
"data": vm.allSessionReport
}];
console.log('session data 2nd', vm.sessionData)
vm.sessionOptions = {
series: {
lines: {
show: true,
fill: 0.01
},
points: {
show: true,
radius: 4
}
},
grid: {
borderColor: '#eee',
borderWidth: 1,
hoverable: true,
backgroundColor: '#fcfcfc'
},
tooltip: true,
tooltipOpts: {
content: function (label, x, y) { return x + ' : ' + y; }
},
xaxis: {
position: ($scope.app.layout.isRTL ? 'top' : 'bottom'),
tickColor: '#eee',
mode: 'categories'
},
yaxis: {
position: ($scope.app.layout.isRTL ? 'right' : 'left'),
tickColor: '#eee'
},
shadowSize: 0
};
code for my second graph, input data has changed to
vm.allSessionReport = [];
vm.sessionData = [{
"color": "#7dc7df",
"data": vm.allSessionReport
}];
vm.allSessionReport = [
["2017-06-28", 0],
["2017-06-29", 0],
["2017-06-30", 0],
["2017-07-01", 0],
["2017-07-02", 0],
["2017-07-03", 0],
["2017-07-04", 17],
["2017-07-05", 0],
["2017-07-06", 0],
["2017-07-07", 0]
]
vm.sessionData = [{
"color": "#7dc7df",
"data": vm.allSessionReport
}];
console.log('session data 2nd', vm.sessionData)
vm.sessionOptions = {
series: {
lines: {
show: true,
fill: 0.01
},
points: {
show: true,
radius: 4
}
},
grid: {
borderColor: '#eee',
borderWidth: 1,
hoverable: true,
backgroundColor: '#fcfcfc'
},
tooltip: true,
tooltipOpts: {
content: function (label, x, y) { return x + ' : ' + y; }
},
xaxis: {
position: ($scope.app.layout.isRTL ? 'top' : 'bottom'),
tickColor: '#eee',
mode: 'categories'
},
yaxis: {
position: ($scope.app.layout.isRTL ? 'right' : 'left'),
tickColor: '#eee'
},
shadowSize: 0
};
I'm trying to create a bar chart with a hover effect using Highcharts software. The chart should look like this: http://www.computerbase.de/2016-02/directx-12-benchmarks-ashes-of-the-singularity-beta/#diagramm-ashes-of-the-singularity-1920-1080
As you can see the data label values change into percentages once you hover the chart, showing the relative values.
Creating the chart itself is not the issue. Changing the data labels however is. How can I loop over all data labels, calculate the relative value and update the labels? The API does not say much.
$('#container').highcharts({
chart: {
type: 'bar'
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
},
series: {
point: {
events: {
mouseOver: function() {
// change text of all data labels
console.log(this);
console.log(this.chart);
}
}
}
}
}
});
It is possible to do Series.setData() with data that has new labels set on mouseOver event of point. Use dataLabels format option to get labels from point data and key setting in your series to set label info.
Example: http://jsfiddle.net/pov2dt0q/
$(function() {
var startingData = [
[1, '1'],
[2, '2'],
[3, '3']
],
percentData = [
[
[1, 'x 100%'],
[2, '200%'],
[3, '300%']
],
[
[1, '50%'],
[2, 'x 100%'],
[3, '150%']
],
[
[1, '33%'],
[2, '66%'],
[3, 'x 100%']
]
];
$('#container').highcharts({
series: [{
type: 'bar',
dataLabels: {
enabled: true,
inside: true,
align: 'right',
x: -5,
format: '{point.label}'
},
data: $.extend([], startingData),
keys: ['y', 'label'],
point: {
events: {
mouseOver: function() {
this.series.setData(percentData[this.x]);
},
mouseOut: function() {
this.series.setData(startingData);
}
}
}
}]
});
});
You may try this:
chart.tooltip.options.formatter = function() {
var xyArr=[];
$.each(this.points,function(){
xyArr.push('Serie: ' + this.series.name + ', ' +'X: ' + this.x + ', Y: ' +this.y);
});
return xyArr.join('<br/>');
}
Example:
http://jsfiddle.net/jugal/zAGGT/
I am hoping someone out there can tell me if what I am trying to do is even possible with the FLOT Javascript library. I am trying to show a chart (below) with dual axis and three data sets. One data set is on the left axis and two data sets on the right axis. What I really want to be able to do is stack the two data sets on the right axis since they should show cumulatively. Thus far I have been unable to get this chart to respond to the stack: true setting at all.
If anyone could help me out with it I would GREATLY appreciate it. My code and a snapshot of the chart currently. I am trying to stack the blue and green areas which correspond to the right axis (y2).
$(function () {
var previousPoint;
var completes = [[1346954400000, 5], [1346997600000, 5], [1347040800000, 7], [1347084000000, 9], [1347127200000, 12], [1347170400000, 15], [1347213600000, 16], [1347256800000, 20], [1347300000000, 20], [1347343200000, 20], [1347386400000, 25]];
var holds = [[1346954400000, 2], [1346997600000, 2], [1347040800000, 6], [1347084000000, 12], [1347127200000, 12], [1347170400000, 15], [1347213600000, 24], [1347256800000, 24], [1347300000000, 24], [1347343200000, 24], [1347386400000, 25]];
var screeners = [[1346954400000, 10298], [1346997600000, 7624], [1347040800000, 5499], [1347084000000, 2100], [1347127200000, 8075], [1347170400000, 4298], [1347213600000, 1134], [1347256800000, 507], [1347300000000, 0], [1347343200000, 800], [1347386400000, 120]];
var ds = new Array();
ds.push({
data:completes,
label: "Complete",
yaxis: 2,
lines: {
show: true,
fill: true,
order: 2,
}
});
ds.push({
data:screeners,
label: "Pre-Screened",
yaxis: 1,
lines: {
show: true,
fill: true,
order: 1,
}
});
ds.push({
data:holds,
label: "Holds",
yaxis: 2,
lines: {
show: true,
fill: true,
order: 3,
}
});
//tooltip function
function showTooltip(x, y, contents, areAbsoluteXY) {
var rootElt = 'body';
$('<div id="tooltip2" class="tooltip">' + contents + '</div>').css( {
position: 'absolute',
display: 'none',
top: y - 35,
left: x - 5,
border: '1px solid #000',
padding: '1px 5px',
'z-index': '9999',
'background-color': '#202020',
'color': '#fff',
'font-size': '11px',
opacity: 0.8
}).prependTo(rootElt).show();
}
//Display graph
$.plot($("#placeholder1"), ds, {
grid:{
hoverable:true
},
xaxes: [ { mode: 'time', twelveHourClock: true, timeformat: "%m/%d %H:%M" } ],
yaxes: [ { min: 0,
tickFormatter: function numberWithCommas(x)
{
return x.toString().replace(/\B(?=(?:\d{3})+(?!\d))/g, ",");
},
}
],
y2axis: [ ],
legend: { show: true }
});
});
This is very straightforward. The stacking plugin isn't well documented, but in the source code, you can see there are two ways to specify that you want stacking turned on.
Two or more series are stacked when their "stack" attribute is set to
the same key (which can be any number or string or just "true"). To
specify the default stack, you can set
series: {
stack: null or true or key (number/string) }
or specify it for a specific series
$.plot($("#placeholder"), [{ data: [ ... ], stack: true }])
In this case, we want to specify it within the two series objects that we want stacked, which would look like this:
ds.push({
data:completes,
label: "Complete",
yaxis: 2,
stack: true, //added
lines: {
show: true,
fill: true,
order: 2,
}
});
ds.push({
data:screeners,
label: "Pre-Screened",
yaxis: 1,
lines: {
show: true,
fill: true,
order: 1,
}
});
ds.push({
data:holds,
label: "Holds",
yaxis: 2,
stack: true, //added
lines: {
show: true,
fill: true,
order: 3,
}
});
Add those two stack:true bits and include the stack plugin into your javascript sources and that will do it. See it in action here: http://jsfiddle.net/ryleyb/zNXBd/