Repeating values on x-axis Morris.js line chart - date

I'm trying to display line chart with daily stats. But the dates on X- axis seem to be repeating.
Link to image
Here is the code for line chart:
new Morris.Line({
element: 'chart',
data: [ #foreach($Data as $data)
{ date: '{{$data['date']}}', value: {{$data['diff']}}},
#endforeach
],
xkey: ['date'],
xLabelFormat: function(date) {
return date.getFullYear() + '/' + (date.getMonth()+1)+ '/' + date.getDate();
},
xLabelAngle : 50,
ykeys: ['value'],
labels: ['Value'],
resize: true,
smooth: true,
lineColors: ['#9ec628'],
dateFormat: function(date) {
date = new Date(date);
return date.getFullYear()+ '/' + (date.getMonth()+1)+ '/' + date.getDate();
},
});
I also tried parseTime: false but that's not helping.

The solution is to add the option xLabels: 'day' to your config, then only 1 value in x-axis per day would be displayed. I found that option in the documentation http://morrisjs.github.io/morris.js/lines.html

Related

Enable Particular Date in datepicker

I have disabled all Mondays in datepicker but on some dates I have to enable that particular date on Monday, so how can I do that? I have pasted the code :
const datepicker2 = new Datepicker(elem2, {
daysOfWeekDisabled: dates_diable,
beforeShowDay: function(date) {
dmy = date.getDate() + "-" + (date.getMonth()+1) + "-" + date.getFullYear();
console.log(dmy+' : '+($.inArray(dmy, availableDates)));
if ($.inArray(dmy, availableDates) > '-1') {
//console.log('yes');
return true;
}
},
format: 'dd/mm/yyyy',
buttonClass: 'btn',
minDate:"Today",
maxDate:maxDate,
datesDisabled: [],
todayHighlight: false,
});

ApexCharts: Hide every nth label in chart

I would like to hide some of the labels from my chart made with ApexCharts.js. I am coming from Frappé Charts, which has a feature called "continuity." It allows you to hide labels if they do not comfortably fit, because the chart is a timeseries chart.
My ApexChart looks like this:
I would like to remove many of the dates, but still have them appear in the tooltip. I was able to do this in Frappé Charts and it looked like this:
Here's my code for the Apex chart:
var options = {
chart: {
animations: { enabled: false },
toolbar: { show: false },
zoom: { enabled: false },
type: 'line',
height: 400,
fontFamily: 'PT Sans'
},
stroke: {
width: 2
},
theme: {
monochrome: {
enabled: true,
color: '#800000',
shadeTo: 'light',
shadeIntensity: 0.65
}
},
series: [{
name: 'New Daily Cases',
data: [2,0,0,0,0,0,0,1,0,1,0,7,1,1,1,8,0,11,2,9,8,21,17,28,24,20,38,39,36,21,10,49,45,44,52,74,31,29,43,28,39,58,30,47,50,31,28,79,39,54,55,33,42,39,41,52,25,30,37,26,30,35,42,64,46,25,35,45,56,45,64,34,34,32,40,65,56,64,55,37,61,51,70,81,76,64,71,61,56,52,106,108,104,33,57,82,71,67,68,63,71,32,70,65,98,52,72,87,66,85,90,47,164,123,180,119,85,66,122,65,155,191,129,144,175,224,234,240,128,99,141,131,215,228,198,152,126,201,92,137,286,139,236,238,153,170,106,61]
}],
labels: ['February 28','February 29','March 1','March 2','March 3','March 4','March 5','March 6','March 7','March 8','March 9','March 10','March 11','March 12','March 13','March 14','March 15','March 16','March 17','March 18','March 19','March 20','March 21','March 22','March 23','March 24','March 25','March 26','March 27','March 28','March 29','March 30','March 31','April 1','April 2','April 3','April 4','April 5','April 6','April 7','April 8','April 9','April 10','April 11','April 12','April 13','April 14','April 15','April 16','April 17','April 18','April 19','April 20','April 21','April 22','April 23','April 24','April 25','April 26','April 27','April 28','April 29','April 30','May 1','May 2','May 3','May 4','May 5','May 6','May 7','May 8','May 9','May 10','May 11','May 12','May 13','May 14','May 15','May 16','May 17','May 18','May 19','May 20','May 21','May 22','May 23','May 24','May 25','May 26','May 27','May 28','May 29','May 30','May 31','June 1','June 2','June 3','June 4','June 5','June 6','June 7','June 8','June 9','June 10','June 11','June 12','June 13','June 14','June 15','June 16','June 17','June 18','June 19','June 20','June 21','June 22','June 23','June 24','June 25','June 26','June 27','June 28','June 29','June 30','July 1','July 2','July 3','July 4','July 5','July 6','July 7','July 8','July 9','July 10','July 11','July 12','July 13','July 14','July 15','July 16','July 17','July 18','July 19','July 20','July 21','July 22','July 23','July 24'],
xaxis: {
tooltip: { enabled: false }
},
}
var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart"></div>
And here's my code for the Frappé Chart if it helps:
const data = {
labels: ['February 28','February 29','March 1','March 2','March 3','March 4','March 5','March 6','March 7','March 8','March 9','March 10','March 11','March 12','March 13','March 14','March 15','March 16','March 17','March 18','March 19','March 20','March 21','March 22','March 23','March 24','March 25','March 26','March 27','March 28','March 29','March 30','March 31','April 1','April 2','April 3','April 4','April 5','April 6','April 7','April 8','April 9','April 10','April 11','April 12','April 13','April 14','April 15','April 16','April 17','April 18','April 19','April 20','April 21','April 22','April 23','April 24','April 25','April 26','April 27','April 28','April 29','April 30','May 1','May 2','May 3','May 4','May 5','May 6','May 7','May 8','May 9','May 10','May 11','May 12','May 13','May 14','May 15','May 16','May 17','May 18','May 19','May 20','May 21','May 22','May 23','May 24','May 25','May 26','May 27','May 28','May 29','May 30','May 31','June 1','June 2','June 3','June 4','June 5','June 6','June 7','June 8','June 9','June 10','June 11','June 12','June 13','June 14','June 15','June 16','June 17','June 18','June 19','June 20','June 21','June 22','June 23','June 24','June 25','June 26','June 27','June 28','June 29','June 30','July 1','July 2','July 3','July 4','July 5','July 6','July 7','July 8','July 9','July 10','July 11','July 12','July 13','July 14','July 15','July 16','July 17','July 18','July 19','July 20','July 21','July 22','July 23','July 24'],
datasets: [{
name: 'Cumulative Cases',
values: [2,0,0,0,0,0,0,1,0,1,0,7,1,1,1,8,0,11,2,9,8,21,17,28,24,20,38,39,36,21,10,49,45,44,52,74,31,29,43,28,39,58,30,47,50,31,28,79,39,54,55,33,42,39,41,52,25,30,37,26,30,35,42,64,46,25,35,45,56,45,64,34,34,32,40,65,56,64,55,37,61,51,70,81,76,64,71,61,56,52,106,108,104,33,57,82,71,67,68,63,71,32,70,65,98,52,72,87,66,85,90,47,164,123,180,119,85,66,122,65,155,191,129,144,175,224,234,240,128,99,141,131,215,228,198,152,126,201,92,137,286,139,236,238,153,170,106,61],
chartType: 'line'
}]
}
const chart = new frappe.Chart('#chart', {
data: data,
type: 'line',
height: 250,
animate: false,
barOptions: {
spaceRatio: 0.25
},
colors: ['#800000'],
tooltipOptions: {
formatTooltipY: d => d.toLocaleString()
},
axisOptions: {
xAxisMode: 'tick',
xIsSeries: true
},
lineOptions: {
hideDots: true,
regionFill: true
}
})
<script src="https://cdn.jsdelivr.net/npm/frappe-charts#1.5.2/dist/frappe-charts.min.iife.min.js"></script>
<div id="chart"></div>
I've tried using the formatter callback function to return only every 10th value, but things get all out of position and the tooltips don't work. I get similar problems returning an empty string or a space for the values I wish to exclude (but still include in the tooltip).
What I do is calculate the ratio between the area's width and the number of ticks, and if that ratio is above a certain number, I add a classname to the chart or it's wrapper and there I write:
.apexcharts-xaxis-label{
display: none;
&:nth-child(5n){ display:revert; }
}
So every 5th label is shown and the rest are hidden.
You can also set up a resizeObserver to add/remove the special class.
This require the below config to be given to the chart:
xaxis: {
labels: {
rotate: 0, // no need to rotate since hiding labels gives plenty of room
hideOverlappingLabels: false // all labels must be rendered
}
}
You can try 2 things.
xaxis: {
type: 'datetime',
}
You can convert the x-axis to datetime and labels will align as shown below
Or
You can stop rotation of the x-axis labels using
xaxis: {
labels: {
rotate: 0
}
}
which produces the following result.
Vsync answer have not worked for me. It needed a little modification:
.apexcharts-xaxis-texts-g text[id^='SvgjsText'] {
display: none;
}
.apexcharts-xaxis-texts-g text[id^='SvgjsText']:nth-of-type(5n) {
display: revert;
}
labels: ['',this.props.itemNames], //"(labels: [the label , the label below])"

Google Charts display options

My questions (short style)
Can you customize a y-axis labeling interval ?
Can you display the extreme values of a series as an horizontal line ?
The detailed explanations
I have a combo chart made with Google Charts : the first set of data uses an area style, and the second a line style. The second one is the one that matters here :
it represents a percentage
i don't want it from 0 to 1 (or 0 to 100 in percentage), but from its min to its max (or something near)
and i want to display those min and max values
If i modify the scale so :
PHP
$min_reject_percentage = 5 * floor($min_reject_percentage / 5);
$max_reject_percentage = 5 * ceil($max_reject_percentage / 5);
JS
var options = {
...
vAxes: {
...
1: {
format:"##%",
viewWindow: {
min: <?php echo ($min_taux_rejet / 100); ?>,
max: <?php echo ($max_taux_rejet / 100); ?>,
},
},
},
series: {
0: {
targetAxisIndex: 0,
type: 'area',
},
1: {
targetAxisIndex: 1,
type: 'line',
},
}
}
The vertical axis is limited to the nearest multiple of 5 for min and max values, but :
the interval shown on the axis is from 10 to 10, which is too big. Since i have a real max of 31.5 and a real min of 17.1, axis min is 15 is 15 and axis max is 35, but the only graduation labeled are 20 and 30.
i can't see the real min and max on the graph
you can use config option ticks, which is an array of values to be used for the labels...
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['x', 'y0', 'y1'],
[0, 18, 0.171],
[1, 28, 0.315],
]);
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
var axisMin = 0.15;
var axisMax = 0.35;
var ticks = [];
for (var i = axisMin; i <= axisMax; i = i + 0.05) {
ticks.push(i);
}
var options = {
vAxes: {
1: {
format: '##%',
ticks: ticks,
viewWindow: {
min: axisMin,
max: axisMax,
},
},
},
series: {
0: {
targetAxisIndex: 0,
type: 'area',
},
1: {
targetAxisIndex: 1,
type: 'line',
},
}
};
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Highcharts custom error handler

We are using highcharts to plot multiple charts on a single HTML page.
However one/some of the chart throw highchart error and we like to capture those error and show different error to user.
For this highcharts do provide custom error handler. But this custom error handler does not provide information about specific chart throwing that error.
Here that JS Fiddle provided by highcharts, which works fine for a chart :
Highcharts.error = function (code, true) {
// See
https://github.com/highcharts/highcharts/blob/master/errors/errors.xml
// for error id's
Highcharts.charts[0].renderer
.text('Chart error ' + code)
.attr({
fill: 'red',
zIndex: 20
})
.add()
.align({
align: 'center',
verticalAlign: 'middle'
}, null, 'plotBox');
};
http://jsfiddle.net/gh/get/library/pure/highslide-software/highcharts.com/tree/master/samples/highcharts/chart/highcharts-error/
Any idea how can I use this custom error handler per chart?
I'm using new Highcharts.Charts(options) to create new chart, but don't see way to specify error handler per chart.
Additional info: Charts are refreshed/appended using data through APIs. User that configures chart also configures refresh interval and query to use for chart.
Error handling in HighCharts does not make much sense. It would make more sense to pass the chart instance to Highcharts.error (like Kamil Kulig wrote) or to have an error event in chart.events. Anyways
here is a solution I came up with:
Create an array of errors:
var chartErrors = [];
Create an error handler which will push errors into the chartErrors. Error objects I'm making look like this: {"chartIndex": <chart index>, "errorCode": <error code>}. All charts are added to the Highcharts.charts array when they are created so we can use Highcharts.charts.length - 1 for the chartIndex.
Highcharts.error = function (code) {
// See https://github.com/highcharts/highcharts/blob/master/errors/errors.xml
// for error id's
chartErrors.push({"chartIndex": Highcharts.charts.length - 1, "errorCode":code});
};
After initiating all charts we will have an array of errors. We can call forEach on this array and handle errors the way we want.
chartErrors.forEach(function(c) {
Highcharts.charts[c.chartIndex].renderer
.text('Chart error ' + c.errorCode)
.attr({
fill: 'red',
zIndex: 20
})
.add()
.align({
align: 'center',
verticalAlign: 'middle'
}, null, 'plotBox');
});
Working example:
Note: I've wrapped the code in a self invoking function to prevent leaking variables to global scope.
(function() {
var chartErrors = [];
Highcharts.error = function (code) {
// See https://github.com/highcharts/highcharts/blob/master/errors/errors.xml
// for error id's
chartErrors.push({"chartIndex": Highcharts.charts.length - 1, "errorCode":code});
};
Highcharts.chart('container1', {
title: {
text: 'Demo of Highcharts error handling'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May']
},
yAxis: {
type: 'logarithmic',
min: 0
},
series: [{
data: [1, 3, 2],
type: 'column'
}]
});
Highcharts.chart('container2', {
title: {
text: 'Solar Employment Growth by Sector, 2010-2016'
},
subtitle: {
text: 'Source: thesolarfoundation.com'
},
yAxis: {
title: {
text: 'Number of Employees'
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
plotOptions: {
series: {
label: {
connectorAllowed: false
},
pointStart: 2010
}
},
series: [{
name: 'Installation',
data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
}, {
name: 'Manufacturing',
data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434]
}, {
name: 'Sales & Distribution',
data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387]
}, {
name: 'Project Development',
data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227]
}, {
name: 'Other',
data: [12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111]
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
});
Highcharts.chart('container3', {
title: {
text: 'Demo of Highcharts error handling'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May']
},
yAxis: {
type: 'logarithmic',
min: 0
},
series: [{
data: [1, 3, 2],
type: 'column'
}]
});
chartErrors.forEach(function(e) {
Highcharts.charts[e.chartIndex].renderer
.text('Chart error ' + e.errorCode)
.attr({
fill: 'red',
zIndex: 20
})
.add()
.align({
align: 'center',
verticalAlign: 'middle'
}, null, 'plotBox');
});
})();
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container1" style="height: 400px"></div>
<div id="container2" style="height: 400px"></div>
<div id="container3" style="height: 400px"></div>
Highcharts error function is not adjusted to have a chart context as an argument, because it can be executed in different contexts too.
For example: error number 16 occurs when Highcharts/Highstock is loaded second time in the same page. It has nothing to do with the chart, because it depends on script importing only.
The workaround I found requires some searching and and a little bit of coding.
Refer to this live demo: http://jsfiddle.net/kkulig/a8nun9aL/
I found the place in the code responsible for throwing the error 10 (the one you used in your example). I overwrote this function (see this doc page for more information about overwriting in Highcharts: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts) and added a chart variable (from Highcharts.Axis.prototype.setTickInterval scope) as the third argument:
if (
axis.positiveValuesOnly &&
!secondPass &&
Math.min(axis.min, pick(axis.dataMin, axis.min)) <= 0
) { // #978
H.error(10, 1, chart); // Can't plot negative values on log axis // MODIFIED LINE
}
It should be done for all errors you want to custom handle.
Now it can be used in custom Highcharts.error function:
Highcharts.error = function(code, stop, chart) {
// See https://github.com/highcharts/highcharts/blob/master/errors/errors.xml
// for error id's
Highcharts.charts[0].renderer
.text('Chart error ' + code + " on chart titled: " + chart.title.textStr)
(...)
You can add your own property in chart constructor options and find it in chart.options object.

Datatable Date format is not working correctly

My date is showing in datatable in this format : "2013-09-02 12:00:00 AM".
I want it in this format: "2013/09/02".
I've googled and found a way to do so. But the code is not working. Output is showing "NaN/NaN/NaN".
My script for datatable is here:
$(document).ready(function () {
$('#RequisitionTbl').dataTable({
"aoColumnDefs": [
{
"aTargets": [0],
"sType": 'date',
"fnRender": function (oObj) { // trying to format(like "2013/09/02") the date here
var javascriptDate = new Date(oObj.aData[0]);
javascriptDate = javascriptDate.getDate() + "/" + javascriptDate.getMonth() + "/" + javascriptDate.getFullYear();
return "<div class= date>" + javascriptDate + "<div>";
}
},
{ "sWidth": "350px", "aTargets": [0] },
{ "sWidth": "180px", "aTargets": [1] },
{ "sWidth": "200px", "aTargets": [2] },
{ "bSortable": false, "aTargets": [4] },
{ "bSearchable": false, "aTargets": [4] }
],
"sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>",
"sPaginationType": "bootstrap",
"oLanguage": {
"sLengthMenu": "Display _MENU_ records"
}
}).columnFilter({
sPlaceHolder: "head:before",
aoColumns: [
{ type: 'date-range' }, ,{},]
});
});
Need help to fin out the problem.
Remember that Month is zero-based index:
var currentDate = new Date();
var day = currentDate.getDate();
var month = currentDate.getMonth() + 1;
var year = currentDate.getFullYear();
var javascriptDate = year + '/' + month + '/' + day // Modify as you need
Hope this helps!