Morris chart not showing the last xkey value with MVC - javascript

My Morris Chart is not showing the last xkey value:
Any ideia why?
My data is:
[{"Date":"2016-07-17","Average":0.0},{"Date":"2016-07-16","Average":0.0},{"Date":"2016-07-15","Average":4.125},{"Date":"2016-07-14","Average":0.0},{"Date":"2016-07-13","Average":0.0},{"Date":"2016-07-12","Average":0.0},{"Date":"2016-07-11","Average":0.0}]
The View:
<script>
var surveyLastDaysChartData = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.SurveyLastDaysChartData));
</script>
<div class="col-lg-6">
<div class="card-box">
<h4 class="header-title m-t-0">Média dos últimos 7 dias</h4>
<div id="dsb-survey-last-days-chart" style="height: 217px;"></div>
</div>
</div><!-- end col -->
The script to build it:
var _surveyLastDaysChartId = "dsb-survey-last-days-chart";
Morris.Line({
// ID of the element in which to draw the chart.
element: _surveyLastDaysChartId,
// Chart data records -- each entry in this array corresponds to a point on the chart.
data: surveyLastDaysChartData,
// The name of the data record attribute that contains x-values.
xkey: 'Date',
// A list of names of data record attributes that contain y-values.
ykeys: ['Average'],
// Labels for the ykeys -- will be displayed when you hover over the chart.
labels: ['Média'],
resize: true,
hideHover: 'auto',
ymax: 5
});

This happened to me too.
I'm not sure how Morris calculates its elements, but sometimes, it cuts off values on the x-axis when it exceeds the width.
The way I was able to fix it (it is a hack, though) was to use their gridTextSize option and change it to a smaller font-size.
Example:
Morris.Line({
...
gridTextSize: 10,
...
});
Another option, if your app allows you to shorten your date, it to use their xLabelFormat option to parse your dates into a smaller format.
Example:
var display_date = function(d) {
var month = d.getMonth() + 1,
day = d.getDate();
var formattedDay = month + '-' + day
return formattedDay; // Return "M-DD" format for date
}
Morris.Line({
...
xLabelFormat: function(x) { return display_date(x); },
...
});

It's the default behaviour of Morris.js when the label is too long. You can use xLabelAngle, is and angle in degrees from horizontal to draw x-axis labels:
Morris.Line({
// ID of the element in which to draw the chart.
element: _surveyLastDaysChartId,
// Chart data records -- each entry in this array corresponds to a point on the chart.
data: surveyLastDaysChartData,
// The name of the data record attribute that contains x-values.
xkey: 'Date',
// A list of names of data record attributes that contain y-values.
ykeys: ['Average'],
// Labels for the ykeys -- will be displayed when you hover over the chart.
labels: ['Média'],
resize: true,
hideHover: 'auto',
xLabelAngle: 60, //<-- add this
ymax: 5
});
Demo: https://jsfiddle.net/iRbouh/hpq42x7b/

Related

Create a Stacked Column Chart with series in javascript

I am trying to create a stacked column chart with 2 categories "Kosten" & "Stromertrag". Every category has it's own column with different values. Below is the attachment of what I want to achieve.
I tried to implement 4-5 chart libraries like canvasjs, highchart, etc. But they want the array of data. But in my case I have below json from which I want to build the same.
{
substratkosten: "9,000"
kosten1: "156,600"
kosten2: "298,286"
kosten3: "64,800"
strom2: "583,200"
substrat: "108,000"
}
Where first four values is for 'Kosten' category and last 2 values is for 'Stromertrag' category. I also tried to change the chart columns color, but I didn't found any property to achieve the same.
Can anyone please help to achieve the same?
Thanks in advance.
You can parse data in the format accepted by CanvasJS and render the chart. Below is the working code.
var jsonData = {
substratkosten: "9,000",
kosten1: "156,600",
kosten2: "298,286",
kosten3: "64,800",
strom2: "583,200",
substrat: "108,000"
};
var data = [];
for (var key in jsonData) {
if(key.includes("kosten")){
data.push({type: "stackedColumn", indexLabel: "{y}", dataPoints: [{x: 1, label: "Kosten", y: parseFloat(jsonData[key].replace(/,/g, ''))}]});
}
else {
data.push({type: "stackedColumn", indexLabel: "{y}", dataPoints: [{x: 2, label: "Stromertrag", y: parseFloat(jsonData[key].replace(/,/g, ''))}]})
}
}
var chart = new CanvasJS.Chart("chartContainer", {
title:{
text: "StackedColumn Chart"
},
data: data
});
chart.render();
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>

Fix data to show with scroll bar with morris graph

I am using Morris Bar chart with php with data from mysql database
Now it is showing bar graph.
My question is:
There are about 100 rows in mysql database and they are increasing day by day.
My bar graph is displaying date wise data.
Can we fix number of days to display bargraph along with horizontal scroll bar to view previous data ?
Code I am using now is as follows :
<div id="graphdatewise"></div>
<script>
$(function () {
var graphdatewise = {
element: 'graphdatewise',
data: <?php echo json_encode($chartresult);?>,
xkey: 'cur_date',
ykeys: ['counter', 'counter_unique_visit'],
labels: ['PageViews', 'UniqueVisits'],
parseTime: true,
barColors: ['#F4FA58', '#00FFFF'],
xLabels: 'Date',
xLabelAngle: 70
}
bar1 = Morris.Bar(graphdatewise)
});
</script>
Now with this code, bars get resized and whole data is displayed in graph. Instead of that can we show 10 days data in graph with horizontal scroll bar to access rest data ?
It is not possbile to make a x-scroll with Morris chart. But I suppose that if you limit the width of the parent widder than the width of the chart, that should be ok. Something like:
<div id='parent' style='width: 100px;'>
<div id='graphdatewise' style='width: 50px;'></div>
</div>

Google stacked bar chart with date on x and time on y

Im trying to create a Google stacked bar chart with time on the y-axis and date on x - axis, with no success.
Ex: for 2012-05-01 i want a bar that goes from 00:00 to 24:00.
I have been able to create a simple stacked bar chart like this.
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable([
['Year', 'Austria', 'Bulgaria', 'Denmark', 'Greece'],
['2003', 1336060, 400361, 1001582, 997974],
['2004', 1538156, 366849, 1119450, 941795],
['2005', 1576579, 440514, 993360, 930593],
['2006', 1600652, 434552, 1004163, 897127],
['2007', 1968113, 393032, 979198, 1080887],
['2008', 1901067, 517206, 916965, 1056036]
]);
// Create and draw the visualization.
new google.visualization.BarChart(document.getElementById('visualization')).
draw(data,
{title:"Yearly Coffee Consumption by Country",
width:600, height:400,
vAxis: {title: "Year"},
hAxis: {title: "Cups"},
isStacked: true}
);
}
What i'm trying to accomplish is something like this
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('string', 'Name');
data.addColumn('timeofday','Starttime');
data.addColumn('timeofday','Endtime');
data.addRows{
['2015-01-01','Funtime',[13,0,0],[16,0,0],
['2015-01-01','Boringtime',[16,0,0],[19,0,0],
['2015-01-02','Sleeptime',[1,0,0],[5,0,0],
}
The result of this would be two bars. At 2015-01-01 with two events one starting from 13:00 to 16:00 (in the y-axis) and on top of that another from 16:00 to 19:00. On 2015-01-02 there would also be one event from 1:00 to 5:00.
Am I able to do this with Google Bar charts?
Appreciate any help I can get.
there are a few problems in your code, you can check the browser's console for these errors
1.
the addRows method takes an array [] of rows,
and should be called with parenthesis () not curly braces {}
within the array, there should be another array for each row
the rows from the example are not complete and are missing the final bracket ]
['2015-01-01','Funtime',[13,0,0],[16,0,0],
should be
['2015-01-01','Funtime',[13,0,0],[16,0,0]],
2.
the data format does not allow a string column, after the first column
'Funtime' will have to go...
3.
if using type 'date' for the first column, then need actual date objects in the data
if --> data.addColumn('date', 'Date');
use --> [new Date('01/01/2016'), [13,0,0], [3,0,0]],
or a 'string' column can be used for the first column as well
if --> data.addColumn('string', 'Date');
use --> ['2015-01-01', [13,0,0], [3,0,0]],
4.
notice the date format used in this example --> '01/01/2016'
using '2016-01-01' with actual dates will result in problems such as these...
Google Charts Table displaying incorrect date
How do I align date and values to gridlines in Google Chart?
5.
finally, if you want time on the y-axis and date on x - axis
use ColumnChart instead of BarChart
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('timeofday','Starttime');
data.addColumn('timeofday','Endtime');
data.addRows([
[new Date('01/01/2016'), [13,0,0], [3,0,0]],
[new Date('01/02/2016'), [16,0,0], [3,0,0]],
[new Date('01/03/2016'), [1,0,0], [4,0,0]]
]);
new google.visualization.ColumnChart(document.getElementById('visualization')).
draw(data, {
height: 600,
isStacked: true,
vAxis: {
format: 'HH:mm',
viewWindow: {
min: [0,0,0],
max: [24,0,0]
}
}
});
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="visualization"></div>

Zingchart doesn't plot correctly a CSV with more than 10 columns

Scenario:
I need to plot data in Zingchart from a CSV that will have a fixed number of columns (37). This CSV has a header that will define the legend of the graph.
Problem:
If the number of elements I define in the header is less than 10 (including the X - Axis name) then everything is good. The first nine columns get a proper legend, and the others are named using the default Series XX. Link to the gist
In the data I've tried messing around with quotes " and ' but it didn't change the behavior.
Sample graph
Times|Line_1|Line_2|Line_3|Line_4|Line_5|Line_6|Line_7|Line_8|Line_9|"Line_10" "Line_11" Line_12 Line_13 Line_14 Line_15 Line_16 Line_17 Line_18 Line_19 Line_20 Line_21 Line_22 Line_23 Line_24 Line_25 Line_26 Line_27 Line_28 Line_29 Line_30 Line_31 Line_32 Line_33 Line_34 Line_35 Line_36
1218604835|0.0756521739130562|-0.151304347825771|||||||0.122608695652389|||||||-0.130434782608745|0.0443478260868915|0.232173913043425|||||||-0.172173913043707|||||||||||
1218604836|-0.427826086956543|-0.253043478260679|||||||-0.279130434782701|||||||-0.130434782608745|-0.0573913043477887|0.232173913043425|||||||-0.27391304347816|||||||||||
1218604837|-0.229565217391325|0.0469565217390482|||||||-0.0808695652174265|||||||0.0678260869565293|0.242608695652279|-0.169565217391664|||||||0.0260869565217945|||||||||||
1218604838|0.370434782608697|0.34695652173923|||||||-0.482608695652061|||||||0.0678260869565293|-0.159130434782583|-0.169565217391664|||||||0.224347826086841|||||||||||
1218604839|-0.133043478260902|-0.156521739130767|||||||0.117391304347848|||||||0.266086956522031|0.039130434782578|0.4304347826087|||||||-0.279130434782701|||||||||||
However, as soon as I continue including elements in the header using the CSV | separator, things start to go wrong. Ideally, the file should be as this one:
Sample graph
Times|Line_1|Line_2|Line_3|Line_4|Line_5|Line_6|Line_7|Line_8|Line_9|Line_10|Line_11|Line_12|Line_13|Line_14|Line_15|Line_16|Line_17|Line_18|Line_19|Line_20|Line_21|Line_22|Line_23|Line_24|Line_25|Line_26|Line_27|Line_28|Line_29|Line_30|Line_31|Line_32|Line_33|Line_34|Line_35|Line_36
1218604835|0.0756521739130562|-0.151304347825771|||||||0.122608695652389|||||||-0.130434782608745|0.0443478260868915|0.232173913043425|||||||-0.172173913043707|||||||||||
1218604836|-0.427826086956543|-0.253043478260679|||||||-0.279130434782701|||||||-0.130434782608745|-0.0573913043477887|0.232173913043425|||||||-0.27391304347816|||||||||||
1218604837|-0.229565217391325|0.0469565217390482|||||||-0.0808695652174265|||||||0.0678260869565293|0.242608695652279|-0.169565217391664|||||||0.0260869565217945|||||||||||
1218604838|0.370434782608697|0.34695652173923|||||||-0.482608695652061|||||||0.0678260869565293|-0.159130434782583|-0.169565217391664|||||||0.224347826086841|||||||||||
1218604839|-0.133043478260902|-0.156521739130767|||||||0.117391304347848|||||||0.266086956522031|0.039130434782578|0.4304347826087|||||||-0.279130434782701|||||||||||
But then the output is completely messed up. Link to the gist
The HTML code for the graph I'm running in local with the same results:
<!DOCTYPE html>
<html>
<head>
<script src="zingchart_2.3.2/zingchart.min.js"></script>
<script>
zingchart.MODULESDIR = "zingchart_2.3.2/modules/";
</script>
<style></style>
</head>
<body>
<div id='myChart'></div>
<script>
var myConfig = {
"globals":{
"font-family":"Arial"
},
"legend":{
"layout":"4x",
"adjust-layout":true,
"align":"center",
"background-color":"none",
"shadow":0,
"border-width":0,
"vertical-align":"bottom"
},
"type": "line",
"utc":true,
"csv": {
"url": "zingchart_2.3.2/sample_5lines.dat",
"separator": "|",
"vertical-labels": true,
},
"plot":{
"line-width":2,
"active-area":true,
"shadow":0,
"exact":true,
"marker":{
"size":4
},
"hover-marker":{
"size":3
},
"preview":true,
"spline":false,
"text":"%v",
},
"plotarea":{
"adjust-layout":1,
"width":"100%",
"height":200,
"position":"0% 0%",
"margin-top":60,
"margin-right":60,
"margin-left":70,
"margin-bottom":105
},
"preview":{
"visible":true,
"height":40,
"position":"0 370",
"margin-top":10,
"margin-bottom":15
},
"scale-x":{
"format":"%v",
"zooming":true,
"label":{
"margin-top":100
},
"tick":{
"line-color":"black",
"line-width":"2px",
"size":8,
},
"transform":{
"type":"date",
"all":"%d/%M/%Y\n%H:%i:%s",
}
},
"scale-y":{
"zooming":true,
"decimals":0,
},
"tooltip":{
<!--"js-rule":"myfunc()",-->
"shadow":0,
"font-color":"#000",
"text":"%t - %k<br><br>%v<br>Hz",
"border-radius":"5px",
"sticky":true,
"timeout":500,
"decimals":6
}
};
zingchart.render({
id: 'myChart',
data: myConfig,
height: 500,
width: "100%"
});
</script>
</body>
</html>
Question:
What am I doing wrong?
There are a couple issues with the JSON that I found.
1.In the CSV object, you would need to add horizontal-labels:true to set allow ZingChart to pull the appropriate labels from your dataset. In your case, the second row contains the labels for each series.
The text "%v" is no longer necessary inside of the plot object. This essentially assigns a label to each series, but setting horizontal-labels:true fixes this.
I have increased your decimals in the scale-y object to 2 instead of 0 so the scale-y does not appear to have duplicate values. You could also use exponent notation as shown here: http://www.zingchart.com/docs/design-and-styling/formatting-numbers/?q=customizable%20number%20formats
I'm assuming the first column of values in your dat file are UNIX time stamps? These values are converted directly using the Javascript Date object, so `new Date(1218604835) would actually return a date of Wed Jan 14 1970. If they are indeed UNIX time stamps, the values would need to be multiplied by 1000 so that new Date(1218604835000) would return Tue Aug 12 2008.
Plnkr here: http://plnkr.co/edit/jQ0WuMsRBgEwV6s0fKlN?p=preview
Let me know if you need any further help! - ZingChart Member.

Show different suffix in Google Piechart

I have a piechart showing the result the total bandwidth of uplink/downlink.
Right now, they suffix is GB.
I struggling trying to display their suffix different.
Example,
Downlink in GB
Uplink in KB.
I have
<script>
google.setOnLoadCallback(drawChart);
function drawChart() {
console.log(color['downlink']);
var data = google.visualization.arrayToDataTable([
['Task', 'Bandwith'],
['Downlink', ({{$t_down_bytes}})],
['Uplink', ({{$t_up_bytes}})]
]);
var options = {
legend: 'buttom',
pieSliceText: 'value', // text | none
title: 'Total Bandwith Usage',
colors: [color['downlink'], color['uplink']],
width:'100%',
height: 400,
slices: {
1: {offset: 0.1}
},
};
var formatter = new google.visualization.NumberFormat({
fractionDigits:2,
suffix: ' GB'
});
formatter.format(data, 1);
var chart = new google.visualization.PieChart(document.getElementById('private'));
chart.draw(data, options);
}
</script>
I can someone can shed some light on this.
Any hints / suggestions on this will be much appreciated !
One way is just doing it yourself: (Correct way to convert size in bytes to KB, MB, GB in Javascript might help)
var data = google.visualization.arrayToDataTable([
['Task', 'Bandwith'],
['Downlink', {v:6.4672328, f:"6.46 GB"}],
['Uplink', {v:9.40213213, f:"9.40 KB"}]
]);
Note that v is the "real" value google uses to draw and f is the formatted value it will show
If you want to keep your google formatter, another way is to add this line after your formatter.format(data, 1);
data.setFormattedValue(1,1,data.getFormattedValue(1,1).replace("GB","KB"))
Which sets the formattedValue of row 1, column 1
Update taking into account you want to use a mix of both:
var data = google.visualization.arrayToDataTable([
['Task', 'Bandwith'],
['Downlink', $t_down_bytes],
['Uplink', $t_up_bytes],
]);
var formatter = new google.visualization.NumberFormat({
fractionDigits:2
});
formatter.format(data, 1);
data.setFormattedValue(0,1,data.getFormattedValue(0,1) + ' {{$t_down_bytes_suffix}}')
data.setFormattedValue(1,1,data.getFormattedValue(1,1) + ' {{$t_up_bytes_suffix}}')
For more info on setFormattedValue and getFormattedValue check
Google Datatable Documentation

Categories

Resources