Last label on xaxis disappears when resize - javascript

I am trying to force highcharts to show last label on x-axis when "step" is enabled. Code below works but it hides last label when I change device width (let's say open chrome console). Problem arises on mobile devices when I scroll down after the chart, last label disappears.
chart:
{
renderTo: "container",
type: "line",
events:{
load:function(){
var ticks = $.map(this.axes[0].ticks, function(t){return t;});
ticks[ticks.length-2].render(0);
}
}
}

First of all the last label 2020 is appearing because of your logic in load event. Ideally that label shouldn't be appearing because your step value is 3. Anyways, you need to add the same logic of load in redraw event to get the last label on resize.
const df = [
{ Period: 2009, value: 1056043 },
{ Period: 2010, value: 1278495 },
{ Period: 2011, value: 1482508 },
{ Period: 2012, value: 1545703 },
{ Period: 2013, value: 1579593 },
{ Period: 2014, value: 1620531.9 },
{ Period: 2015, value: 1502572.2 },
{ Period: 2016, value: 1451010.7 },
{ Period: 2017, value: 1546273 },
{ Period: 2018, value: 1663982.3 },
{ Period: 2019, value: 1643160.9 },
{ Period: 2020, value: 1431638.4 }
];
var chart = new Highcharts.Chart({
chart: {
renderTo: "container",
height: 300,
type: "areaspline",
events: {
load: function () {
var ticks = $.map(this.axes[0].ticks, function (t) {
return t;
});
ticks[ticks.length - 2].render(0);
},
redraw: function () {
var ticks = $.map(this.axes[0].ticks, function (t) {
return t;
});
ticks[ticks.length - 2].render(0);
}
}
},
title: {
text: "Emissions of CO2 - from Fossil Fuels - Total (CDIAC)"
},
xAxis: {
categories: df.map((o) => o.Period),
labels: {
step: 3,
style: {
fontFamily: "Arial, Helvetica, sans-serif;",
fontSize: "0.8rem",
fontWeight: "600",
background: "#000000",
whiteSpace: "nowrap",
textOverflow: "none"
}
},
showLastLabel: true,
endOnTick: true,
overflow: "allow"
},
yAxis: {
min: 0
},
series: [
{
data: df.map((o) => o.value),
name: "Germany"
}
]
});

Related

Show quarter markers instead of years in JSCharting Gantt Chart

I am new to this JSCharting library and working with it to create a Gantt Chart. When I map my data on the chart, it slices the Y Axis based on years. I am trying to slice it based on 3 months intervals. Instead of 2021, 2022, 2023, I want to show Q1, Q2, Q3, Q4 for each year.
One quick and dirty solution I found is below, to create markers on Y Axis like this:
{
yAxis: {
markers: [2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028].reduce(
(all: { label: { text: string; color: string }; value: string }[], year) => {
return [
...all,
...[1, 4, 7, 10].map((month) => ({
label: {
text: month === 1 ? "Q1" : month === 4 ? "Q2" : month === 7 ? "Q3" : "Q4",
color: "#ddd",
},
color: "#ddd",
value: `${month}/1/${year}`,
legendEntry: {
visible: false,
},
})),
];
},
[]
),
},
}
However, when I do that, first line of data covers the quarter labels like so.
Is there a proper way to do this and show it in the bottom with along with years? I'd appreciate any help.
You can use calendar patterns to create ticks for quarters and months more easily. Here's an example.
var chart = JSC.chart('chartDiv', {
debug: true,
axisToZoom: 'x',
margin_right: 10,
xAxis: {
scale_type: 'time',
defaultTick_enabled: false,
customTicks: [
{
value_pattern: 'month',
label_text: '%min'
},
{
value_pattern: 'quarter',
label_text: qTickText
},
{
value_pattern: 'year',
label_text: '%min'
}
]
},
legend_visible: false,
title_label_text:
'Apple iPhone sales (in million units)',
series: [
{
type: 'line spline',
defaultPoint: {
marker: {
outline: { width: 2, color: 'white' }
}
},
points: [
{ x: '04/1/2016', y: 74.78 },
{ x: '07/1/2016', y: 51.19 },
{ x: '10/1/2016', y: 40.4 },
{ x: '1/1/2017', y: 45.51 },
{ x: '04/1/2017', y: 78.29 },
{ x: '07/1/2017', y: 50.76 },
{ x: '10/1/2017', y: 41.03 },
{ x: '1/1/2018', y: 46.68 },
{ x: '04/1/2018', y: 67.32 },
{ x: '07/1/2018', y: 52.22 },
{ x: '10/1/2018', y: 41.3 },
{ x: '1/1/2019', y: 46.89 }
]
}
]
});
function qTickText(v) {
return dateToQuarter(v[0]);
}
function dateToQuarter(d) {
d = new Date(d);
return 'Q' + (Math.floor(d.getMonth() / 3) + 1);
}

How to change UTC timestamp on the Highstock charts?

I have an API at https://gmlews.com/api/data. And my code for highstock charts in http://jsfiddle.net/estri012/b5nhezLs/8/ .
My problem is my timestamp look like this "2020-03-15T11:46:10+07:00". So on the chart it should shows 15 March 11:46 instead of 15 March 04:46. But the chart show UTC time. How to fix it, so the chart show the local same time with mine? And the last three data on the chart show 18 March instead of 19 March. In my API, the last three data must be 19 March not 18 March.
$(function () {
$.getJSON('https://gmlews.com/api/data', function (data) {
console.log(data);
function format_two_digits(n) {
return n < 10 ? '0' + n : n;
}
var accelero_x = [], timestamp = [];
for (var i=0; i<data.length; i++){
let inArr = [];
inArr.push(Date.parse(data[i].timestamp));
inArr.push(data[i].accelero_x);
accelero_x.push(inArr);
timestamp.push(data[i].timestamp);
}
console.log(accelero_x);
console.log(timestamp);
// Create the chart
window.chart = new Highcharts.StockChart({
chart: {
renderTo: 'container'
},
rangeSelector: {
inputEnabled: true,
buttons: [{
type: 'day',
count: 1,
text: '1D',
},
{
type: 'week',
count: 1,
text: '1W',
},
{
type: 'month',
count: 1,
text: '1M',
},
{
type: 'year',
count: 1,
text: '1Y',
}, {
type: 'all',
count: 1,
text: 'All',
}],
inputDateFormat: '%d-%m-%Y',
inputDateParser: function (value) {
value = value.split('-');
return Date.UTC(
parseInt(value[2]),
parseInt(value[1]) - 1,
parseInt(value[0])
);
},
},
title: {
text: 'Accelero X'
},
xAxis: {
type: "datetime",
labels: {
/* format: '{value:%Y-%m-%d}', */
formatter: (currData) => {
const currDate = new Date(currData.value);
return format_two_digits(currDate.getHours()) + ':' + format_two_digits(currDate.getMinutes());
},
rotation: 45,
align: 'left'
}
},
series: [{
name: 'Accelero X',
data: accelero_x,
type: 'spline',
tooltip: {
valueDecimals: 2
}
}]
}, function (chart) {
// apply the date pickers
setTimeout(function () {
$('input.highcharts-range-selector', $('#' + chart.options.chart.renderTo)).datepicker();
}, 0)
});
});
// Set the datepicker's date format
$.datepicker.setDefaults({
dateFormat: 'dd-mm-yy',
beforeShow: function() {
var date = $(this).val().split('-');
$('input.highcharts-range-selector').datepicker("setDate", new Date(parseFloat(date[0]), parseFloat(date[1]) - 1, parseFloat(date[2])));
},
onSelect: function (dateText) {
this.onchange();
this.onblur();
}
});
});
Try to set time.useUTC to false - https://api.highcharts.com/highcharts/time.useUTC
Demo: http://jsfiddle.net/BlackLabel/avhw7km8/
time: {
useUTC: false
},

Canvasjs: different settings according to screen size

I'm using CanvasJs for a bar chart, but I would like to have different settings according to screen size.
For example, I would like to hide labels completely on the axisY for screens < 480px. How can this be done?
It seems that media queries and css can't be used to customize the charts.
Here's an example:
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Understanding Labels"
},
axisY: {
labelFontSize: 20
},
axisX: {
labelAngle: -30
},
data: [
{
type: "column",
dataPoints: [
{ y: 10, label: "Apples" },
{ y: 15, label: "Mangos" },
{ y: 25, label: "Oranges" },
{ y: 30, label: "Grapes" },
{ y: 28, label: "Bananas" }
]
}
]
});
chart.render();
}
</script>
I experimented with something like this which obviously doesn't work:
axisY: {
labelFormatter: function(e) {
if ($(window).width() < 480) {
return "";
},
},
},
You can define a function for labelFormatter outside of axisY object.
axisY: {
labelFormatter: axisYLabels,
},
You can modify the labels of axisY here based on width of the window.
function axisYLabels(e) {
if ($(window).width() < 480) {
return "";
} else {
return e.value;
}
}
You can see a working fiddle here.

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/

How to add multiple series dynamically and update its data dynamically

my task is to add series dynamically and keep updating their data, which is received by ajax calls.
i know series can be added dynamically by declaring highchart funciton global. and using series.addseries() function , and also data can be updated by using settimout request to ajax call and updating points by using series.addpoint() function.
i have done both the work separably. but when i combine both the technique, data is not added to highchart. i have done lot of research on this, and i am not finding reason for not adding the data. infact script hang the browser.
i have checked the series object, which show x-data and y-data are processed. only difference i find is isDirty field and isDirtydata field are set to true. dont know the reason.
here is the full code
var serverUrl = 'http://'+window.location.hostname+':8000'
Highcharts.setOptions({
global: {
useUTC: false
}
});
data={}
$(document).ready(function(){
$(function () {
console.log("highcharts")
$('#first').highcharts({
chart: {
type: 'spline',
//marginRight: 150,
marginBottom: 5,
events: {
load: requestData(data)
}
},
title: {
text: 'Server Monitroting Tool'
},
subtitle: {
text: 'Cpu usage, Memory Usage,Disk Usage,Mongo Usage'
},
xAxis: {
type: 'datetime',
categories: ['TIME'],
dateTimeLabelFormats : {
hour: '%I %p',
minute: '%I:%M %p'
}
},
yAxis:{
showEmpty:false
},
legend:
{
backgroundColor: '#F5F5F5',
layout: 'horizontal',
floating: true,
align: 'left',
verticalAlign: 'bottom',
x: 60,
y: 9,
shadow: false,
border: 0,
borderRadius: 0,
borderWidth: 0
},
series: {}
});
});
from_date=new Date().getTime()-60000;
function requestData(data)
{
if(!data)
{
console.log("default ")
}
else
{
console.log("requesting")
$.ajax({
url:serverUrl+'/api/fetch_params/',
type:'GET',
data:data,
success:function(response)
{
console.log("in success")
//data = {'type':TypeOfParameter,'hostname':hostname,'sub-type':sub_type,'param':sub_type_parameter,'from-date':from_date}
var id=data['sub-type']+data['param']
var series = chart.get(id)
shift = series.data.length > 100; // shift if the series is longer than 300 (drop oldest point)
response= $.parseJSON(response)
var x=data['sub-type']
all_data=response.response.data[x]
// console.log(new Date(from_date),'latest timestamp')
console.log(series)
console.log("data",all_data)
from_date=all_data[all_data.length-1][0]
// console.log(from_date)
// series.isDirty=false
// series.isDirtyData=false
for (var i = 0; i < all_data.length; i++)
{
series.addPoint({ x: all_data[i][0],y: all_data[i][1],id: i},false,shift);
}
console.log("series object",series)
// chart.redraw();
console.log(" parameter",data)
data['from-date']=from_date
console.log("data",series.data)
// console.log(chart)
setTimeout(requestData(data), 10000);
console.log("out of success")
},
cache:false,
error:function()
{
console.log("err")
}
});
}
}
$.ajax({
url:serverUrl+'/api/fetch_all_servers/',
type:'GET',
success:function(response){
response = $.parseJSON(response)
sd = response.response.all_servers
$('input[name=select_menue]').optionTree(sd)
},
error:function(){
console.log('error')
}
});
$('.param-button').live('click',function(e){
e.stopPropagation()
})
$('param-select').live('hover',function(){
$(this).find('.type-select').show()
});
$('.final_value').live('change',function(){
select_name = 'select_menue_'
param_list = []
var param=$('select[name="'+select_name+'"] option:selected').attr('value')
while(param){
param_list.push(param)
select_name += '_'
var param=$('select[name="'+select_name+'"] option:selected').attr('value')
}
console.log(param_list,"param_list")
from_date=new Date().getTime()-300000 //5 minute data
hostname=param_list[0]
TypeOfParameter= param_list[1]
sub_type_parameter=param_list[param_list.length-1]
data = {'type':TypeOfParameter,'hostname':hostname,'param':sub_type_parameter,'from-date':from_date}
var sub_type;
if(param_list.length==4){
sub_type=param_list[2]
data['sub-type'] = sub_type
}
else
{
sub_type=sub_type_parameter
}
// console.log(hostname,TypeOfParameter,sub_type,sub_type_parameter)
data = {'type':TypeOfParameter,'hostname':hostname,'sub-type':sub_type,'param':sub_type_parameter,'from-date':from_date}
requestData(data)
$('#loadingmessage').show(); // show the loading message.
chart = $('#first').highcharts();
if(TypeOfParameter=='cpu')
{
console.log("adding axis")
chart.addAxis({ // Primary yAxis
id:'Cpu_axis'+sub_type_parameter,
labels: {
formatter: function() {
return this.value;
},
style: {
color: '#89A54E'
}
},
title: {
text: "core "+ sub_type+ " "+sub_type_parameter,
style: {
color: '#89A54E'
}
},
lineWidth: 1,
lineColor: '#08F'
});
console.log("adding series")
chart.addSeries({
id:sub_type+sub_type_parameter,
name: "core "+sub_type+" "+sub_type_parameter,
data :[],
tooltip : {
valueSuffix: ' %'
},
yAxis:'Cpu_axis'+sub_type_parameter
})
console.log("series out")
}
if(TypeOfParameter=='memory')
{
chart.addAxis ({
id:'memory'+sub_type_parameter,
labels:{
formatter: function() {
return this.value +'%';
},
style: {
color: '#89C54F'
}
},
title: {
text:sub_type+" "+sub_type_parameter
},
lineWidth: .5,
lineColor: '#08F',
opposite: true
});
chart.addSeries({
id:sub_type+sub_type_parameter,
name: sub_type+'memory usage',
data: [],
tooltip: {
valueSuffix: '%'
},
yAxis:'memory'+sub_type_parameter
});
}
if(TypeOfParameter=='disk')
{
chart = new Highcharts.Chart({
chart: {
renderTo: 'second',
defaultSeriesType: 'spline',
events: {
load: requestData
}
},
title: {
text: 'disk Usage'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
maxZoom: 20 * 1000
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: 'disk',
margin: 80
}
},
series: [{
id:sub_type+sub_type_parameter,
name: 'disk',
data: []
}]
});
}
if(TypeOfParameter=='db')
{
chart = new Highcharts.Chart({
chart: {
renderTo: 'second',
defaultSeriesType: 'spline',
events: {
load: requestData
}
},
title: {
text: 'mongo Usage'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
maxZoom: 20 * 1000
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: 'mmongo',
margin: 80
}
},
series: [{
id:sub_type+sub_type_parameter,
name: 'mongo',
data: []
}]
});
}
if(TypeOfParameter=='redis')
{
chart = new Highcharts.Chart({
chart: {
renderTo: 'second',
defaultSeriesType: 'spline',
events: {
load: requestData
}
},
title: {
text: 'redis Usage'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
maxZoom: 20 * 1000
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: 'redis',
margin: 80
}
},
series: [{
id:sub_type+sub_type_parameter,
name: 'redis',
data: []
}]
});
}
$('#loadingmessage').hide(); // hide the loading message
}
)
});
i am stuck on this problem for quite a while. and still not able to figure out the solution.
here is the full code link
someone please please help. feeling frustrated ..:-(
As you know the addPoint method is bit dangerous when dealing with quite lots points. It is recommended to disable redraw per point when dealing with many new points - more info http://api.highcharts.com/highcharts#Series.addPoint() , I notice you are doing that already in the loop statement, but why did you commented out? have you tried enabling again. Make sure chart.redraw works by adding a new redraw chart event, and set an alert or console log.
Also you may try using, below as part of ajax, instead of cache:false. I had some problems in past.
headers: { 'Cache-Control': 'no-cache' }
Cheers

Categories

Resources