I'm trying to include event lines in the Morris line chart. The event lines appear for integer values in the X axis but not for time values. It just draws an event line for '00:00:00' when event values are passed and parseTime parameter is set to true and nothing appears when parseTime is set to false. So basically, how can I draw events for time values on the X axis ?
var morrisLineData = [{y: "11:16:02", a: 17.73},
{y: "11:16:53", a: 39.43},
{y: "11:16:58", a: 5.02},
{y: "11:17:07", a: 17.73}];
var morrisLine = Morris.Line({
resize: true,
element: 'morrisLine',
data: morrisLineData,
xkey: 'y',
ykeys: 'a',
labels: ['value1'],
xLabelAngle: 45,
gridTextSize: 12,
parseTime: true,
hideHover: true,
lineColors: ['#0088cc'],
events: ['11:16:58'],
eventLineColors: 'black'
});
morrisLine.setData(morrisLineData);
Related
I have to render series data for current month/quarter/year data using morris.js charts. The series has data points on daily basis and I see a repeating days on the x-axis.
jsfiddle
I also tried turning off parseTime and using xLabelFormat as suggested on few posts on SO using the code below but output has duplicate values for days:
Morris.Line({
element: element,
data: [
{"day":"2017-10-01 11:40:09","uniqueUsers":"180","sessions":"213"},
{"day":"2017-10-01 12:40:09","uniqueUsers":"217","sessions":"213"},
{"day":"2017-10-02 11:40:09","uniqueUsers":"539","sessions":"635"},
{"day":"2017-10-03 11:40:09","uniqueUsers":"684","sessions":"826"},
{"day":"2017-10-04 07:40:09","uniqueUsers":"1095","sessions":"1229"},
{"day":"2017-10-04 10:40:09","uniqueUsers":"822","sessions":"987"},
{"day":"2017-10-04 11:40:09","uniqueUsers":"568","sessions":"836"},
{"day":"2017-10-05 11:40:09","uniqueUsers":"335","sessions":"385"}
],
xkey: 'day',
xlabels: 'day',
xLabelFormat: function (x) {
var d = new Date(x.label.slice(0, 10) + "T" + x.label.slice(11, x.label.length));
return d.getDate() + ' ' + months[d.getMonth()];
},
ykeys: ['uniqueUsers', 'sessions'],
labels: ['Unique users', 'User sessions'],
pointSize: 2,
hideHover: 'auto',
lineColors: ['rgb(156, 39, 176)', 'rgb(121, 85, 72)', 'rgb(0, 188, 212)', 'rgb(255, 152, 0)'],
xLabelAngle: 50,
//dateFormat: function (d) {
// var ds = new Date(d);
// return ds.getDate() + ' ' + months[ds.getMonth()];
//},
behaveLikeLine: true,
parseTime: false
});
How can I remove duplicate values on x-axis?
these are not redundant values, these are dates formatted automatically by Morris.js.
Therefore, you have 2 choices:
either do not parse the dates, and just display the value of "day", by setting parseTime to false
or you change date format on x-axis, by setting xLabels to hour
You can read more about these settings in the documentation.
I have the following problem. I would like to show multiple lines in a morris line chart from the following Json:
var lineChartData = [{"val":5,"sCategory":"1;#Translation Incomplete","CreatedDate":"2018-5-9"},{"val":2,"sCategory":"2;#VED incorrect/Missing","CreatedDate":"2018-5-11"},{"val":8,"sCategory":"1;#Translation Incomplete","CreatedDate":"2018-5-11"},{"val":1,"sCategory":"2;#VED incorrect/Missing","CreatedDate":"2018-5-9"},{"val":2,"sCategory":"2;#VED incorrect/Missing","CreatedDate":"2018-5-15"},{"val":1,"sCategory":"1;#Translation Incomplete","CreatedDate":"2018-5-16"},{"val":1,"sCategory":"1;#Translation Incomplete","CreatedDate":"2018-5-23"},{"val":2,"sCategory":"1;#Translation Incomplete","CreatedDate":"2018-5-18"}]
The goal will be that show the lines based on sCategory. And the x,y will be the date and the value. I am able to show one line with total figures, but cant figured out how can I split my chart into categories.
Here is my code:
Morris.Line({
element: 'morris-area-chart',
data: lineChartData ,
xkey: ['CreatedDate'],
ykeys: ['val'],
labels: ['sCategory'],
pointSize: 5,
hideHover: 'auto',
resize: true
});
Thank you!
I suppose something like:
Morris.Line({
element: 'morris-area-chart',
data: lineChartData ,
xkey: ['CreatedDate'],
ykeys: ['val', 'sCategory'],
labels: ['val', 'sCategory'],
pointSize: 5,
hideHover: 'auto',
resize: true
});
I have a Morris bar chart that show positive and negative results.
What do i want to achieve is to make 2 colors, one for negative and one for positive results like on a images below.
I looked into documentation and didn't find any solution to this.
Is this possible or not ?
Here is a current code:
var positiveColor = 'orange'; //'#32CD32';
var negativeColor = 'grey'; //'#FF6347';
Morris.Bar({
element: 'morris-bar2',
barColors: [positiveColor, negativeColor],
data: <?php echo $json_data2; ?>,
stacked: false,
resize: true,
xkey: 'y',
ykeys: ['a'],
labels: ['Total', ''],
hideHover: false,
gridTextColor: '#4F5F6F',
gridTextSize: '12'
});
Examples:
Current bar color
Need to be like
according to one of the examples on GitHub, you can use a callback for the barColors property.
So, you could do something like this:
barColors: function (row, series, type) {
if (row.y < 0)
return "grey";
return "orange";
}
Well, you can always use this code
ykeys: ['positive', 'negative'],
barColors: ['#00cccc', '#3300cc'],
and it just an example
complete example of what I have;
var bar = new Morris.Bar({
element: 'chart',
resize: true,
data:[<?php echo $chart_data; ?>],
barColors: ['#00cccc', '#3300cc'],
xkey: 'date',
ykeys: ['Positive', 'Negative'],
labels: ['Positive Value', 'Negative Value '],
hideHover: 'auto'
});
I used Morris.js to build the following chart:
http://jsbin.com/uqawig/441/embed?js,output
The xLabel have problems when I reduce the length down to 2 as:
Morris.Line({
element: 'line-example',
data: [
{ y: '2006', a: 100, b: 90 },
{ y: '2007', a: 75, b: 65 }
],
xkey: 'y',
ykeys: ['a', 'b'],
labels: ['Series A', 'Series B']
});
xLabel show as 2006-03 2006-05 2006-07 2006-09 2006-11 2007-01
I want xLabel to show only the years like 2006 2007.
I searched a lot but didn't found any solutions.
Any ideas?
Set the parseTime parameter to false in your Morris configuration:
parseTime: false
Reference: Morris Line & Area Charts
parseTime: Set to false to skip time/date parsing for X values, instead treating them as an equally-spaced series.
I used morris chart in my application project to show some details about quantity of sales.
After executing the AJAX request, the chart is only showing half part. Here's the syntax:
var chartBahan = Morris.Bar ({
element: 'morris-analytics-bahan',
xkey: '2',
ykeys: ['3'],
labels: ['Quantity Bahan'],
resize: false,
gridEnabled: true
});
//getting the morris chart over bahan and karakteristik
function getBahanPotensial(kode){
//ajax call
$.ajax({
type:"POST",
async: false,
url:"<%= request.getContextPath()%>/GenerateListBahanPotensial",
data:{
kode:kode
},
success: function(data){
chartBahan.setData($.parseJSON(data));
chartBahan.redraw();
},
error:function(msg){
alert("Data Failed to Analyze" + msg);
}
});
}
var chartKarakter = new Morris.Bar ({
element: 'morris-analytics-karakter',
xkey: '2',
ykeys: ['3'],
labels: ['Karakter Quantity'],
resize: true
});
function getKarakterPotensial(kode){
//ajax call
$.ajax({
type:"POST",
async: false,
url:"<%= request.getContextPath()%>/GenerateListKarakterPotensial",
data:{
kode:kode
},
success:function(data){
chartKarakter.setData($.parseJSON(data));
chartKarakter.redraw();
},
error:function(msg){
alert("Data Failed to Analyze" + msg);
}
});
}
I execute the above function from another function let say doProcess()
function sendRequest(thecode){
if(thecode === ""){ alert("Tolong Input Kode Produk");}
else {
var kodebarang = thecode;
}
//executing AJAX call.
$.ajax({
type:"POST",
async: false,
url:"<%= request.getContextPath()%>/GenerateAnalytics",
data:{
kodebarang:kodebarang
},
success:function(msg){
$('#result_analysis').show();
$('#navigation_button').show();
new Morris.Bar ({
element: 'morris-analytics-bar',
data: $.parseJSON(msg),
xkey: '1',
ykeys: ['2', '3'],
labels: ['Sales Area', 'Tingkat Penjualan'],
barRatio: 0.4,
xLabelAngle: 0,
hideHover: 'auto'
});
//execute the morris chart others !! PENTING
var kodeb = $('#bahan_id').val();
var kodek = $('#karakteristik_id').val();
getBahanPotensial(kodeb);
getKarakterPotensial(kodek);
},
error:function(msg){
alert("Data Failed to Analyze" + msg);
}
});
}
but the problem is, when i create Morris Chart in Success Callback
success:function(msg){
$('#result_analysis').show();
$('#navigation_button').show();
new Morris.Bar ({
element: 'morris-analytics-bar',
data: $.parseJSON(msg),
xkey: '1',
ykeys: ['2', '3'],
labels: ['Sales Area', 'Tingkat Penjualan'],
barRatio: 0.4,
xLabelAngle: 0,
hideHover: 'auto'
});
The chart is properly showing. Here's the screen shot:
But the other chart when i use template for charting (outside the success callback) the chart is BROKEN
here's the screenshot
then, i have dropdown list to regenerate the chart based on specific parameter, the chart is properly showing (all data show) BUT the chart is only half PAGE. here's the screenshot:
Is there any ideas what going on?
UPDATE
What I mean template is code like this:
var chartBahan = Morris.Bar ({
element: 'morris-analytics-bahan',
xkey: '2',
ykeys: ['3'],
labels: ['Quantity Bahan'],
resize: false,
gridEnabled: true
});
and the method to call the template is
success:function(data){
chartBahan.setData($.parseJSON(data));
chartBahan.redraw();
},
The RIGHT chart is the FIRST Screenshot. It's wider than the other two.
UPDATED 2
still getting error on charts created by Morris :(
here's the screenshot.
I solved that issue by setting the width of the svg element to 100% in css
svg{
width: 100% !important
}
Two last charts from your example threw lots of errors in the console of Google Chrome (you can open it by pressing F12).
The reason is that the data property is required when you call Morris.Bar({ data: ... }), but in you example you didn't have this property. So you should completely remove your declarations like var chartBahan = Morris.Bar (... and replace the success callback with this code:
function getBahanPotensial(kode){
$.ajax({
...
success: function(data){
if (window.chartBahan) {
chartBahan.setData($.parseJSON(data));
// chartBahan.redraw(); // useless call, it can be removed
} else {
window.chartBahan = Morris.Bar ({
element: 'morris-analytics-bahan',
data: $.parseJSON(data),
xkey: '2',
ykeys: ['3'],
labels: ['Quantity Bahan'],
resize: false,
gridEnabled: true
});
}
}
...
});
}
In my code I check whether the global variable window.chartBahan exists and if it doesn't - I create a new chart; otherwise I call setData and the chart updates itself automatically.
Also you haven't posted your HTML mark-up, it may have issues as well. I used this HTML code and it worked fine:
<body>
<div id="morris-analytics-bar" style="height: 250px;"></div>
<div id="morris-analytics-bahan" style="height: 250px;"></div>
<div id="morris-analytics-karakter" style="height: 250px;"></div>
</body>
//Java script code
Morris.Line({
element: 'hero-area',
data: getdata("<?php echo base_url('user/getYearlPremiumuser');?>") ,
xkey: 'Year',
parseTime: false,
ykeys: ['Teacher', 'Student'],
labels: ['Teacher', 'Student'],
hideHover: 'false',
lineWidth: 1,
pointSize: 5,
lineColors: ['#4a8bc2', '#ff6c60'],
fillOpacity:7,
smooth: true
});
********//php code ( code codeigniter)********
public function getYearlPremiumuser()
{
$teacherArray={ y: '2014', a: 50, b: 90},
{ y: '2015', a: 65, b: 75},
{ y: '2016', a: 50, b: 50},
{ y: '2017', a: 75, b: 60},
{ y: '2018', a: 80, b: 65},
{ y: '2019', a: 90, b: 70},
{ y: '2020', a: 100, b: 75},
{ y: '2021', a: 115, b: 75},
{ y: '2022', a: 120, b: 85},
{ y: '2023', a: 145, b: 85},
{ y: '2024', a: 160, b: 95}
for($i=0;$i<count($teacherArray);$i++)
{
$temp=array();
$temp= array_merge($teacherArray[$i],$studentarray[$i]);
$finalResultArray[]=$temp;
}
echo json_encode($finalResultArray);
}
click here to know more
I have similar issue using Morris.js and Angular2 - the problem in my case was that I use in DIV with chart the *ngIf='showChart' (or [hidden]='!showChart') - and when I set up chart, the showChar=false so the div doesn't exist. In my case I read date periodic in every 1min so at first dataLoad i see nothing, after second dataLoad i see half/part of chart). So I fix this by (typescript):
showchart = true;
setTimeout( () => { this.setUpChart() }, 1 );
And it works :)