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,
},
Related
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);
I'm using apex charts for react in my reactJS progressive web app, and have had no issues with it for static data, but I"m now trying to take a returned array from my database and use the array for the graph and it's not working.
I'm logging the array returned from the database, which is in this structure:
And in my code, I'm setting this to the third series option of my chart named "Trends" but when the graph loads the line for that data is 'Nan'
What am I doing wrong here?
class TrendsComponent extends Component {
constructor(props) {
super(props);
this.state = {
maxCalories: '',
calorieRecord: {
caloriesConsumed: '',
caloriesBurned: '',
createdAt: undefined,
updatedAt: undefined
},
options: {
fill: {
colors: ['#FF756D', '#85DE77', '#FFF49C']
},
dataLabels: {
enabled: true,
textAnchor: 'middle',
distributed: false,
offsetX: 0,
offsetY: 0,
style: {
fontSize: '14px',
fontFamily: 'Helvetica, Arial, sans-serif',
fontWeight: 'bold',
colors: ["#FF756D", "#85DE77", "#FFF49C"]
},
background: {
enabled: true,
foreColor: '#fff',
padding: 4,
borderRadius: 2,
borderWidth: 1,
borderColor: '#fff',
opacity: 0.9,
},
dropShadow: {
enabled: true,
top: 1,
left: 1,
blur: 1,
color: '#000',
opacity: 0.8
}
},
colors: ["#FF756D", "#85DE77", "#FFF49C"],
chart: {
toolbar: {
show:false
},
id: "basic-bar"
},
xaxis: {
categories: ['3/20', '3/21', '3/22', '3/23', '3/24', '3/25','3/26']
}
},
series: [
{
name: "Baseline",
data: [250,500,234,389,644,245,590]
},
{
name: "Optimal",
data: [2250,2250,2250,2250,2250,2250,2250]
},
{
//this is the line where I'm getting NaN
name: "Trend (tracked)",
data: [this.maxCalories]
}
]
};
}
...
UPDATE:
Upon component mounting, I use these functions to set MaxCalories which is the data array I'm using for the chart
getMax = () => {
this.state.caloriesDB.db.createIndex({
index: {
fields: ['_id','caloriesBurned']
}
}).then(result => {
console.log(result);
this.setMax();
}).catch((err) =>{
console.log(err);
});
}
setMax = () => {
this.state.caloriesDB.db.find({
selector: {
$and: [
{_id: {"$gte": null}},
{caloriesBurned: {$exists: true}},
]
},
fields: ['caloriesBurned'],
sort: [{'_id':'desc'}],
limit: 7
}).then(result => {
console.log('max');
console.log(result);
const newDocs = result.docs;
this.setState({
maxCalories: newDocs.map(docs => docs)
});
console.log('maxCalories');
console.log(this.state.maxCalories);
}).catch((err) =>{
console.log(err);
});
}
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>',
}
}]
});
});
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>
i get my JSON object from my php code in this format (JSONlint ok) :
[
[1375653600000,3.20104,175.00,116.00,11.00,31.00],[...],[1376776800000,2.85625,10.00,1.00,0.00,8.00]
]
i Have to split in 5 different series:
[1375653600000, 3.201014]
[1375653600000, 175.00]
[1375653600000, 116.00]
[1375653600000, 11.00]
[1375653600000, 31.00]
...
and (obviously) each array is for a different highcharts series.
i follow this post to get an idea about split the JSON:
Retrieving JSON data for Highcharts with multiple series?
This is my code:
$(function() {
// See source code from the JSONP handler at https://github.com/highslide-software/highcharts.com/blob/master/samples/data/from-sql.php
$.getJSON('grafico_nuovo.php?callback=?', function(data) {
// Add a null value for the end date
data = [].concat(data, [[Date.UTC(2012, 9, 14, 19, 59), null, null, null, null]]);
// create the chart
$('#container').highcharts('StockChart', {
chart : {
type: 'spline',
zoomType: 'xy'
},
navigator : {
adaptToUpdatedData: false,
series : {
data : data
}
},
scrollbar: {
liveRedraw: false
},
title: {
text: 'analisi consumi e temperature'
},
subtitle: {
text: 'Analisi test solo temperatura media'
},
rangeSelector : {
buttons: [{
type: 'hour',
count: 1,
text: '1h'
}, {
type: 'day',
count: 2,
text: '2d'
}, {
type: 'week',
count: 1,
text: '1w'
},{
type: 'month',
count: 1,
text: '1m'
}, {
type: 'year',
count: 1,
text: '1y'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: true, // it supports only days
selected : 2 // day
},
/*xAxis : {
events : {
afterSetExtremes : afterSetExtremes
},
minRange: 3600 * 1000 // one hour
},*/
xAxis: {
events : {
afterSetExtremes : afterSetExtremes
},
minRange: 3600 * 1000, // one hour
type: 'datetime',
dateTimeLabelFormats: { minute: '%H:%M', day: '%A. %e/%m' },
// minRange: 15*60*1000,
//maxZoom: 48 * 3600 * 1000,
labels: {
rotation: 330,
y:20,
staggerLines: 1 }
},
yAxis: [{ // Primary yAxis
labels: {
format: '{value}°C',
style: {
color: '#89A54E'
}
},
title: {
text: 'Temperature',
style: {
color: '#89A54E'
}
}
}, { // Secondary yAxis
title: {
text: 'Consumo',
style: {
color: '#4572A7'
}
},
labels: {
format: '{value} Kw',
style: {
color: '#4572A7'
}
},
opposite: true
}],
series: [{
name: 'val1',
data: []
}, {
name: 'val2',
data: []
},
{
name: 'val3',
data: []
},
{
name: 'val4',
data: []
},
{
name: 'val5',
data: []
}]
});
});
});
/**
* Load new data depending on the selected min and max
*/
function afterSetExtremes(e) {
var currentExtremes = this.getExtremes(),
range = e.max - e.min,
chart = $('#container').highcharts();
chart.showLoading('Loading data from server...');
$.getJSON('grafico_nuovo.php?start='+ Math.round(e.min) +
'&end='+ Math.round(e.max) +'&callback=?', function(data) {
val1 = [];
val2 = [];
val3 = [];
val4 = [];
val5 = [];
$.each(data, function(key,value) {
val1.push([value[0], value[1]]);
val2.push([value[0], value[2]]);
val3.push([value[0], value[3]]);
val4.push([value[0], value[4]]);
val5.push([value[0], value[5]]);
});
console.log('val1');
chart.series[0].setData(val1);
chart.series[1].setData(val2);
chart.series[2].setData(val3);
chart.series[3].setData(val4);
chart.series[4].setData(val5);
chart.hideLoading();
});
}
The navigator works fine (with little trouble after 3-4 clicks) but the other series doesn't show.
Everything should be ok, but i've probably missed something