Highmaps - how i can have a seperate legend by different report? - javascript

I have two (or more) reports, i want to combine this two reports and show in one map by a separate legend.
Please see example.
Also the result shared in tooltip when legends are visible.
$(function () {
// Initiate the chart
$('#container').highcharts('Map', {
plotOptions : {
map : {
mapData: Highcharts.maps['countries/ir/ir-all'],
joinBy: 'hc-key',
states: {
hover: {
color: '#BADA55'
}
},
dataLabels: {
enabled: true,
format: '{point.name}'
}
}
},
title : {
text : 'Highmaps basic demo'
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
series : [{
name : 'Report 1',
data : [{
'hc-key' : "ir-ea",
value : 1000,
},{
'hc-key' : "ir-kv",
value : 1000,
},{
'hc-key' : "ir-kd",
value : 1000,
},{
'hc-key' : "ir-wa",
value : 1000,
}],
mapData: Highcharts.maps['countries/ir/ir-all'],
joinBy: 'hc-key',
states: {
hover: {
color: '#BADA55'
}
},
dataLabels: {
enabled: true,
style : {
textShadow : '',
},
format: '<span style="color:black">{point.name}</span>',
}
},{
name : 'Report 2',
data : [{
'hc-key' : "ir-wa",
value : '3000',
},{
'hc-key' : "ir-ea",
value : '3000',
}],
mapData: Highcharts.maps['countries/ir/ir-all'],
joinBy: 'hc-key',
states: {
hover: {
color: '#BADA55'
}
},
dataLabels: {
enabled: true,
style : {
textShadow : '',
},
format: '<span style="color:black">{point.name}</span>',
}
}]
});
});

this is not end answer, only a better solution.
i added legendItemClick event for better view.
Please see example.
events : {
legendItemClick : function(){
for(i=0; i < this.chart.series.length; i++) {
this.chart.series[i].hide();
}
},
},
but i want share same province data. for example, i have value = 1 in Golestan province in report 1 and i have value = 3 in Golestan province in report 2. sum of result tooltip is :
Report 1
Golestan : 1
Report 2
Golestan : 3
Sum
Goelstan : 4

Try this. What I have missed so far is to make the tooltip appear even if there is no value for the currently selected report.
This code in jsfiddle. Is this what you are trying to establish?
$(function() {
// Initiate the chart
$('#container').highcharts('Map', {
plotOptions: {
map: {
mapData: Highcharts.maps['countries/ir/ir-all'],
joinBy: 'hc-key',
states: {
hover: {
color: '#BADA55'
}
},
dataLabels: {
enabled: true,
format: '{point.name}'
},
events: {
legendItemClick: function() {
for (i = 0; i < this.chart.series.length; i++) {
this.chart.series[i].hide();
}
},
},
}
},
title: {
text: 'Highmaps basic demo'
},
tooltip: {
formatter: function() {
var pointName = this.point.name;
function filterByName(value) {
return (value.hasOwnProperty("name") && typeof value.name !== "undefined" && value.name === pointName);
}
var result = "<b>" + this.point.name + "</b><br>";
var allSeries = this.series.chart.series;
var curSeries, curValue;
for (var i = 0; i < allSeries.length; i++) {
curSeries = allSeries[i];
curValue = curSeries.points.filter(filterByName);
if (curValue.length === 0 || (curValue[0].hasOwnProperty("value") && curValue[0].value == null)) {
return result;
}
curValue = curValue[0].value;
result += '<br><b>' + curSeries.name + '</b> ' + curValue;
}
return result;
}
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
series: [{
name: 'Report 1',
visible: false,
data: [{
'hc-key': "ir-ea",
value: 1000,
}, {
'hc-key': "ir-kv",
value: 1000,
}, {
'hc-key': "ir-kd",
value: 1000,
}, {
'hc-key': "ir-wa",
value: 1000,
}],
mapData: Highcharts.maps['countries/ir/ir-all'],
joinBy: 'hc-key',
states: {
hover: {
color: '#BADA55'
}
},
dataLabels: {
enabled: true,
style: {
textShadow: '',
},
format: '<span style="color:black">{point.name}</span>',
}
}, {
name: 'Report 2',
data: [{
'hc-key': "ir-wa",
value: '3000',
}, {
'hc-key': "ir-ea",
value: '3000',
}],
mapData: Highcharts.maps['countries/ir/ir-all'],
joinBy: 'hc-key',
states: {
hover: {
color: '#BADA55'
}
},
dataLabels: {
enabled: true,
style: {
textShadow: '',
},
format: '<span style="color:black">{point.name}</span>',
}
}]
});
});

Related

I'm getting an error when drawing a chart using echarts JS

When I try to draw a graph, I get an error:echarts.min.js:45 Uncaught TypeError: Bind must be called on a function at bind (<anonymous>) at Bd (echarts.min.js:45:130031)
My echarts-init.js:
let domTemp = document.getElementById("main");
let mytempChart = echarts.init(domTemp, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
var option;
runDaysDatas(sens_data_result, sens_name_list);
function runDaysDatas(sens_data_result, sens_name_list) {
const sens_names = sens_name_list;
const datasetWithFilters = [];
const seriesList = [];
echarts.util.each(sens_names, function (sens) {
var datasetId = 'dataset_' + sens;
datasetWithFilters.push({
id: datasetId,
fromDatasetId: sens_data_result,
transform: {
type: 'filter',
config: {
and: [
{ dimension: 'Uid', '=': sens }
]
}
}
});
seriesList.push({
type: 'line',
datasetId: datasetId,
showSymbol: false,
name: sens,
endLabel: {
show: true,
formatter: function (params) {
return params.value[3] + ': ' + params.value[0];
}
},
labelLayout: {
moveOverlap: 'shiftY'
},
emphasis: {
focus: 'series'
},
encode: {
x: 'Date',
y: 'Temperature',
label: ['Name', 'Temperature'],
itemName: 'Date',
tooltip: ['Temperature']
}
});
});
option = {
animationDuration: 10000,
dataset: [
{
id: 'dataset_sens_names',
source: sens_data_result
},
...datasetWithFilters
],
title: {
text: 'Temperature for Day'
},
tooltip: {
order: 'valueDesc',
trigger: 'axis'
},
xAxis: {
type: 'category',
nameLocation: 'middle'
},
yAxis: {
name: 'Temperature'
},
grid: {
right: 140
},
series: seriesList
};
mytempChart.setOption(option);
}
In sens_data_result i pass data from api.
In sens_name_list i pass names of the sensors.
The console does not send errors to my script, it swears at the library. I took an example from the official site and remade it for my task, displaying the temperature by time of day with the name of the sensor. There can be N number of graphs on one chart.
Thnx for help!
Okey, i'm a solved the problem, this is decision:
let url = '/api/sensdata';
let domTemp = document.getElementById("main");
let mytempChart = echarts.init(domTemp, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
var option;
$.get(
url,
sensors_uid,
(_rawData) => {
runDaysDatas(_rawData, sens_name_list);
}
);
function runDaysDatas(_rawData, sens_names) {
const datasetWithFilters = [];
const seriesList = [];
_rawData.unshift(['Name', 'Date', 'Humidity', 'Temperature']);
echarts.util.each(sens_names, function (sens) {
var datasetId = 'dataset_' + sens;
datasetWithFilters.push({
id: datasetId,
fromDatasetId: 'dataset_raw',
transform: {
type: 'filter',
config: {
and: [
{ dimension: 'Name', '=': sens }
]
}
}
});
seriesList.push({
type: 'line',
datasetId: datasetId,
showSymbol: false,
name: sens,
endLabel: {
show: true,
formatter: function (params) {
return 'Uid ' + params.value[0] + ': ' + params.value[3] + '°C';
}
},
labelLayout: {
moveOverlap: 'shiftY'
},
emphasis: {
focus: 'series'
},
encode: {
x: 'Date',
y: 'Temperature',
label: ['Name', 'Temperature'],
itemName: 'Temperature',
tooltip: ['Temperature']
},
});
});
console.log(seriesList);
option = {
toolbox: {
show : true,
feature : {
magicType : {show: true, type: ['line', 'bar']},
restore : {show: true},
saveAsImage : {show: true}
}
},
legend: {},
dataset: [
{
id: 'dataset_raw',
source: _rawData
},
...datasetWithFilters
],
tooltip: {
order: 'valueDesc',
trigger: 'axis'
},
xAxis: {
type: 'time',
nameLocation: 'middle',
axisLabel: {
formatter: (function(value){
moment.locales('RU_ru');
return moment(value).format('MM/DD HH:mm');
})
}
},
yAxis: [
{
type : 'value',
axisLabel : {
formatter: '{value} °C'
}
}
],
grid: {
right: 140
},
series: seriesList
};
mytempChart.clear();
mytempChart.setOption(option);
}
window.addEventListener('resize', mytempChart.resize);

highstock shows wrong dates in selectorRange buttons

enter image description herei get dates from server and convert all date to timestamp as required highcharts. But, rangeSelector buttons show wrong date. For, example if i have dateBegin = 02/07/2017, and dateEnd 09/07/2017, highstock dateRange shows wrong date like as 01/07/2017 - 08/07/2017. It seems that highstock show always date - 1 day. How can i fix it?
this is my init of config
onInitConfig = ({ series, periodId, height }) => {
const { onSelectRange } = this.props
moment.locale('ru', localization)
const heightChart = `${ height }px`
const config = {
chart: {
height: heightChart,
events: {
redraw: function(event) {
const currentDateBegin = Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.rangeSelector.minInput.HCTime)
const currentDateEnd = Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.rangeSelector.maxInput.HCTime)
onSelectRange && onSelectRange({ currentDateBegin, currentDateEnd })
}
}
},
rangeSelector: {
buttons: [{
type: 'week',
count: '1',
text: 'н'
},{
type: 'month',
count: 1,
text: 'м',
},{
type: 'month',
count: 3,
text: 'кв'
}, {
type: 'month',
count: '6',
text: 'пг'
},{
type: 'year',
count: 1,
text: 'г'
}],
buttonSpacing: 2,
selected: periodId - 1,
inputDateFormat: '%d/%m/%Y',
labelStyle: {
fontFamily: 'HelveticaLight',
fontSize: '14px',
}
},
title: {
align: 'left',
text: '',
},
navigation: {
buttonOptions: {
enabled: false,
}
},
navigator: {
xAxis: {
labels: {
formatter: function () {
return moment(this.value).format('DD MMMM')
},
style: {
fontFamily: 'HelveticaLight',
fontSize: '14px',
}
}
},
},
xAxis: {
labels: {
formatter: function () {
return moment(this.value).format('DD MMMM')
},
style: {
fontFamily: 'HelveticaLight',
fontSize: '14px',
}
}
},
plotOptions: {
series: {
compare: 'percent',
showInNavigator: true
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',
valueDecimals: 2,
split: true
},
series: series
}
return config
}
this is my input
order.map((id) => {
const { dateBegin, dateEnd, valueAmount, valueCount, valueQuantity, valueCountCheck, valueCountCustomers } = data[id] || {}
const dateTimeBegin = moment(dateBegin, 'DD.MM.YYYY').toDate().getTime()
const dateTimeEnd = moment(dateBegin, 'DD.MM.YYYY').toDate().getTime()
_.merge( dataCheckCount, { [id]: { id, x: dateTimeBegin, y: valueCount } })
_.merge( dataCheckCount, { [id + 1]: { id: id + 1, x: dateTimeEnd, y: valueCount } })
}
The problem was in timezoneOffset. I add next code to global setOptions and the problem is fixed.
global: {
useUTC: false,
},

Highcharts error #13 when trying to create a map

I'm trying to create a Highcharts map but I can't get past the #13 error which states that the rendering container can't be found. All my other charts that's not a map chart works and it uses the same container class but I can't get maps to work at all.
Config object that gets passed to the initMapChart function (the map chart uses the same config as the normal charts):
highcharts.config = {
chart: {
type: highcharts.getTypeFromId(graph.type)
},
plotOptions: {
series: {
stickyTracking: false,
events: {
click: function (e) {
this.chart.myTooltip.refresh(e.point, e);
}
}
},
pie: {
cursor: 'pointer',
dataLabels: {
enabled: true,
formatter: function() {
return this.series.isLabelsVisible ? this.y : '';
}
},
showInLegend: true
},
line: {
cursor: 'pointer',
dataLabels: {
enabled: true
}
},
area: {
cursor: 'pointer',
dataLabels: {
enabled: true,
formatter: function() {
return this.series.isLabelsVisible ? this.y : '';
}
}
},
areaspline: {
cursor: 'pointer',
dataLabels: {
enabled: true,
formatter: function() {
return this.series.isLabelsVisible ? this.y : '';
}
}
},
column: {
stacking: false,
cursor: 'pointer',
dataLabels: {
enabled: true,
formatter: function() {
return this.series.isLabelsVisible ? this.y : '';
}
}
},
map: {
mapData: Highcharts.maps['custom/world'],
joinBy: ['name'],
cursor: 'pointer',
dataLabels: {
enabled: true
}
}
},
exporting: {
buttons: {
contextButton: {
enabled: false
}
}
},
toggleModify: false,
title: {
text: ''
},
xAxis: {
categories: null,
labels: {
format: graph.span === 0 && graph.isTime && graph.childTarget === null ? '{value:%Y-%m-%d}' : '{value}'
}
},
yAxis: {
title: {
text: ''
},
labels: {}
},
series: null,
credits: {
enabled: false
}
};
I wait for the series to be created first before I try creating the charts, here is where I also set the renderTo property:
scope.$on('highchartsConfigUpdated', function(e, config) {
initDataType();
bindDataTypes();
var target = element[0].querySelector('.highcharts-target');
config.chart.renderTo = target;
if (scope.graph.type === 6) {
initMapChart(config);
}
else {
initChart(config);
}
});
This function will be run for all charts with the type of 6, which means they're a map chart:
function initMapChart(config) {
console.log(config.chart.renderTo);
new Highcharts.Chart('Map', config, function(chart) {
initLabels(chart);
bindLabels(chart);
});
};
From the console log I get this which should mean that it can in fact find the element:
<div id="chart-b2b2d164-b41c-40fc-a739-00cb1bc074ba" class="highcharts-target"></div>
So I think the issue is rather in the instantiation of the chart itself, how do you create a map chart without using jQuery?

TypeError: Highcharts[h] is not a function

My Plnkr link: http://plnkr.co/edit/S0BKjrgxz564oCPs9nCw?p=preview
Any idea why I would be getting this error? Not sure where Highcharts[h] is...
Controller Code
(function() {
angular.module('highChartTest', ['ui.bootstrap', 'highcharts-ng'])
.controller('MyHighChart', ['$scope', '$timeout', MyHighChart]);
// HighCharts Column Chart
function MyHighChart($scope, $timeout) {
var vs = $scope;
ticker = 'GOOG',
vs.chartObject = {};
var dayHolder = [];
var count = 0;
_.times(97, function() {
dayHolder.push({
'x': count++,
'y': count++
});
});
// Default data fed into navigator:
vs.navigatorData = dayHolder;
this.config = {
options: {
ignoreHiddenSeries: false,
credits: { enabled: true, text: 'www.tickertags.com' },
legend: {
itemStyle: {
color : "#333333",
cursor : "pointer",
fontSize : "10px",
fontWeight : "normal"
},
enabled : true,
floating : true,
align : 'left',
verticalAlign: 'top',
x: 60
},
chart : {
title : { text: '' },
subtitle : { text: '' },
renderTo : 'chart1',
zoomType : 'x',
events: {
load: function () {
// HighChart loaded callback:
broadcastChartLoaded();
console.log('config.chart.events.load...');
},
redraw: function(event) {
// console.log(' chart events redraw fired');
}
}
},
scrollbar: {
enabled : false,
liveRedraw : false
},
navigator : {
enabled: true,
adaptToUpdatedData: true,
// enabled: false,
// adaptToUpdatedData: false,
series : {
data : vs.navigatorData
}
},
rangeSelector: {
enabled: false,
},
exporting: { enabled: false }
},
exporting: { enabled: false },
useHighStocks: true,
xAxis : {
ordinal: false,
dateTimeLabelFormats : {
hour : '%I %p',
minute : '%I:%M %p'
},
events : {
// afterSetExtremes : afterSetExtremes,
// setExtremes : setExtremes
},
minRange: 3600 * 1000 // one hour
},
yAxis: [{ // Primary yAxis
labels: {
format: '${value:.2f}',
style: {
color: '#4C73FF',
}
},
title: {
text: 'Price',
style: {
color: '#4C73FF',
}
}
},
{ // Secondary yAxis
gridLineWidth: 0,
title: {
text: 'Mentions',
style: {
color: '#FDE18D'
// Pick one - "#FDE18D", "#7DD0FA", "#58A6EC"
}
},
opposite: false
}],
func: function(chart) {
vs.chartObject = chart;
},
series : [{
zIndex: 1000,
yAxis: 0,
showInLegend: true,
color: '#4C73FF',
data: dayHolder,
type: 'line',
name: 'SPY',
dataGrouping: {
enabled: true
}
}]
};
function broadcastChartLoaded() {
console.log('broadcastChartLoaded!!!');
}
$timeout(function() {
console.log('inside timeout, now add 1st series');
var quoteData = vs.navigatorData;
vs.chartObject.addSeries({
zIndex : 1000,
yAxis : 0,
name : ticker,
data : quoteData,
type : 'line',
color : '#4C73FF',
showInLegend : true,
dataGrouping : {
enabled: true
}
}, true);
}, 2000);
}
})();
You were using highcharts, and not the highstock.js library, but specifying highstock in the config.
http://plnkr.co/edit/mr4STsk3ekVOwXpZVgk0?p=preview
<script data-require="highstock#4.2.3" data-semver="4.2.3" src="//cdnjs.cloudflare.com/ajax/libs/highstock/4.2.3/highstock.js"></script>

How do I attach a click event handler to null data points on HighMaps

I have already tried changing the data (null to some out of range number) and toying with colorAxis min and mas and color stops and while that works if it where a single map, it does not work for what I am doing.
I really need to be able to hang code on a click event.
Thanks
https://jsfiddle.net/alex_at_pew/nbz9npyg/5/
$(function () {
// Instantiate the map
$('#container').highcharts('Map', {
plotOptions: {
map: {
events: {
mouseOver: function (e) {
console.log(e);
}
}
}
},
chart : {
borderWidth : 1
},
title : {
text : 'Nordic countries'
},
subtitle : {
text : 'Demo of drawing all areas in the map, only highlighting partial data'
},
legend: {
enabled: false
},
colorAxis: {
dataClasses: [{
from: -100,
to: 1,
color: '#C40401',
name: 'pseudonull(1s are the new null)'
}],
},
series : [{
name: 'Country',
mapData: Highcharts.maps['custom/europe'],
data: [
{
code: 'DE',
value: 1
}, {
code: 'IS',
value: 2
}, {
code: 'NO',
value: 2
}, {
code: 'SE',
value: 2
}, {
code: 'FI',
value: 2
}, {
code: 'DK',
value: 2
}
],
joinBy: ['iso-a2', 'code'],
dataLabels: {
enabled: true,
color: 'white',
formatter: function () {
if (this.point.value > 1) {
return this.point.name;
} else if(this.point.value == 1) {
return 'this is "null"';
}
}
},
tooltip: {
headerFormat: '',
pointFormat: '{point.name}'
}
}]
});
});
I am not very sure about what you try to achieve, but from my understanding, you want to attach click events to countries with NULL values.
I have created this example here: http://jsfiddle.net/on6v5vhr/
Apparently, if a country has a NULL value, it won't be able to have click events, but what I've done is to simulate this behaviour so I went through these steps:
Process your data and give all the null value the same particular value (France was null so I gave it the value of -999)
{code: 'FR', value: -999}
Show datalabels only for the countries that have a value and that values is different than -999
formatter: function() {
if (this.point.value && (this.point.value !== -999)) {
return this.point.name;
}
}
Show tooltip only for the countries that have a value different than -999
tooltip: {
formatter: function() {
if (this.point.value !== -999) {
return this.point.name;
} else {
return false;
}
}
}
Manually set the color same as the NULL color for all countries that have the value of -999
colorAxis: {
dataClasses: [{
from: -100,
to: 1,
color: '#C40401',
name: 'pseudonull(1s are the new null)'
}, {
from: -999,
to: -999,
color: 'rgba(0,0,0,0)',
name: 'No data'
}],
}

Categories

Resources