I am trying to plot a Time (HH:MM:SS) on y-axis against days using plotly.js. The chart plotted is not properly sorted. Can anyone please guide what I am doing wrong. I have attached my codepen link here
Codepen Link
HTML
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>
Javascript
Plotly.d3.csv("xyz.csv", function(err, rows){
var trace1 = {
type: "scatter",
mode: "lines",
x:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53],
y: ["08:15:00","08:18:00","08:25:00","08:06:00","08:31:00","08:23:00","08:35:00","08:18:00","08:25:00","08:06:00","08:26:45","08:19:20","08:06:00","08:06:00","08:20:00","08:17:22","08:18:14","08:18:00","08:09:00","08:32:00","08:16:20","08:14:29","08:14:31","08:32:00","08:39:00","08:29:00","08:27:00","08:28:00","08:24:00","08:09:00","08:32:00","08:16:20","08:14:29","08:14:31","08:32:00","08:39:00","08:29:00","08:27:00","08:28:00","08:24:00","08:25:00","08:26:45","08:19:20","08:06:00","08:06:00","08:20:00","08:17:22","08:18:00","08:25:00","08:06:00","08:25:00","08:06:00","08:31:00"],
name: 'Time In',
line: {color: '#17BECF'}
}
var data = [trace1];
var layout = {
title: 'Attendance',
};
Plotly.newPlot('myDiv', data, layout);
})
It seems you can't just use time alone, it needs a date too.
So I added a dummy date to the beginning of each time with .map(time => '2020-01-08 ' + time) and hid it from the axis ticks with yaxis: { tickformat: '%H:%M:%S' }.
Here's a working snippet:
var trace1 = {
type: "scatter",
mode: "markers",
x:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53],
y: ["08:15:00","08:18:00","08:25:00","08:06:00","08:31:00","08:23:00","08:35:00","08:18:00","08:25:00","08:06:00","08:26:45","08:19:20","08:06:00","08:06:00","08:20:00","08:17:22","08:18:14","08:18:00","08:09:00","08:32:00","08:16:20","08:14:29","08:14:31","08:32:00","08:39:00","08:29:00","08:27:00","08:28:00","08:24:00","08:09:00","08:32:00","08:16:20","08:14:29","08:14:31","08:32:00","08:39:00","08:29:00","08:27:00","08:28:00","08:24:00","08:25:00","08:26:45","08:19:20","08:06:00","08:06:00","08:20:00","08:17:22","08:18:00","08:25:00","08:06:00","08:25:00","08:06:00","08:31:00"].map(time => '2020-01-08 ' + time),
name: 'Time In',
line: {color: '#17BECF'}
}
var data = [trace1];
var layout = {
title: 'Attendance',
yaxis: {
tickformat: '%H:%M:%S'
}
};
Plotly.newPlot('myDiv', data, layout);
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>
I am currently attempting to design a Google Chart which is modelled based on values within certain div tags throughout a html document.
as it stands, there are a number of tags throughout the document such as:
<div id="abc"> 11000 </div>
<div id="def"> 12500 </div>
<div id="ghi"> 17000 </div>
I would like the Google Chart to reference these values as the Y-axis.
The Google Charts code works fine like this:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Age', 'Current', 'Proposed'],
['25', 10000],
['35', 15170],
['45', 21660],
]);
var options = {
title: 'Balance Comparison',
curveType: 'function',
legend: { position: 'bottom' }
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
chart.draw(data, options);
}
</script>
<div id="curve_chart" style="width: 900px; height: 500px"></div>
I would like to change the array in such a way that references the div values. I attempted to do this, and ended up with this:
function drawChart() {
var y1 = document.getElementByID("abc")
var y2 = document.getElementByID("def")
var y3 = document.getElementByID("ghi")
var data = google.visualization.arrayToDataTable([
['Age', 'Current'],
['25', y1],
['35', y2],
['45', y3],
]);
This does not seem to work however, and I am at a loss as to how to get it working.
it will work, first, a couple things...
javascript is case sensitive, change getElementByID to getElementById (note the last letter)
getElementById gets the element, but you want the contents of the element.
use innerHTML to get the contents.
var y1 = document.getElementById('abc').innerHTML;
finally, google charts expects a number for the y value,
innerHTML returns a string.
use parseFloat to convert the string to a number.
parseFloat(y1)
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var y1 = document.getElementById('abc').innerHTML;
var y2 = document.getElementById('def').innerHTML;
var y3 = document.getElementById('ghi').innerHTML;
var data = google.visualization.arrayToDataTable([
['Age', 'Current'],
['25', parseFloat(y1)],
['35', parseFloat(y2)],
['45', parseFloat(y3)],
]);
var options = {
title: 'Balance Comparison',
curveType: 'function',
legend: { position: 'bottom' }
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="abc"> 11000 </div>
<div id="def"> 12500 </div>
<div id="ghi"> 17000 </div>
<div id="curve_chart"></div>
I am a beginner when it comes to the following technologies:
- ASP.NET MVC
- Entity Framework
- JavaScript (in this instance, CanvasJS)
I am trying to render a chart based on a Data Model that I have created in my solution. I am following the tutorial here (adapted to my own purposes) https://canvasjs.com/docs/charts/integration/asp-net-mvc-charts/how-to/asp-net-mvc-charts-data-entity-database/ and I have completed the following.
Created a Model of my data via EF
Passed that data from my Controller to my View
Attempted to render the chart in the View CSHTML
However, the chart does not render. When I use Chrome Debugging, the Javascript shows that the 'result' is my strongly typed model, but this must be incorrect as the error is Uncaught SyntaxError: Unexpected end of input
The rendered Javascript is as follows:
<h2>StoreView - Testing this for store group P777S001</h2>
<hr />
<div class="container-fluid">
<div class="row">
<div class="col-md-6">
<div class="text-info">Here are some examples of sales data via Entity Framework</div>
</div>
<div class="col-md-6">
<div id="chartContainer"></div>
</div>
</div>
</div>
<script type="text/javascript">
var result = System.Collections.Generic.List`1[InSiteDashboard.Models.InSiteStoreSalesSummaryTable];
var datapoints = [];
for (var i = 0; i < result.length; i++) {
datapoints.push({ label: result[i].x, y: result[i].y });
}
$(function () {
var chart = new CanvasJS.Chart("chartContainer", {
theme: "light2",
zoomEnabled: true,
animationEnabled: true,
title: { text: "Line chart" },
data: [{
type: "line",
dataPoints: dataPoints,
}]
});
chart.render();
});
</script>
I am passing this to the View using the following code (it's prototyping so the code is messy apologies)
Controller:
string _servername = $"P{store}S001";
var sales = insite.InSiteStoreSalesSummaryTables.Where(s => s.ServerName == _servername && s.daily_sales_figure > 0);
//var storeEntries = db.StoreSystemInformations.Where(s => s.StoreNumber == store);
if (sales == null)
{
return HttpNotFound();
}
ViewBag.TestValue = $"Testing this for store group {_servername}";
return View(sales.ToList());
Can anyone see something I'm obviously doing wrong here?
From first glance, I assumed your problem seem occurred because of this line:
var result = System.Collections.Generic.List`1[InSiteDashboard.Models.InSiteStoreSalesSummaryTable];
I think you're passing list directly to a JS definition intended to create JS array, but Razor returns fully-qualified name of the List<InSiteDashboard.Models.InSiteStoreSalesSummaryTable> collection because Razor implicitly called ToString() in the view instead of iterating it.
Since List``1[InSiteDashboard.Models.InSiteStoreSalesSummaryTable] is not recognized as a JS identifier or property, then "Unexpected end of input" message was thrown because of invalid syntax.
You could use model serialization to pass List<T> collection as JS array, as in example below (assumed you have model directive with #model IEnumerable<InSiteStoreSalesSummaryTable> or #model List<InSiteStoreSalesSummaryTable> as implied by return View(sales.ToList())):
// standard way
var result = JSON.parse('#Html.Raw(Json.Encode(Model))');
// using Newtonsoft.Json library
var result = JSON.parse('#Html.Raw(JsonConvert.SerializeObject(Model))');
Here is an example implementation of the script:
#model IEnumerable<InSiteStoreSalesSummaryTable>
<!-- other HTML elements, skipped for brevity -->
<script>
var result = JSON.parse('#Html.Raw(Json.Encode(Model))');
var datapoints = [];
for (var i = 0; i < result.length; i++) {
datapoints.push({ label: result[i].x, y: result[i].y });
}
$(function () {
var chart = new CanvasJS.Chart("chartContainer", {
theme: "light2",
zoomEnabled: true,
animationEnabled: true,
title: { text: "Line chart" },
data: [{
type: "line",
dataPoints: dataPoints,
}]
});
chart.render();
});
</script>
I am trying to use c3.js timeseries line chart (URL : http://c3js.org/samples/timeseries.html). The only difference being that I am using the CDN link to the js files instead of downloading them. However I keep getting the following error
Chrome
Uncaught Error: x is not defined for id = "date".
Firefox
Error: x is not defined for id = "date".
throw new Error('x is not defined for id = "' + id + '".');
|
------------+
The html file is given below
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<link rel="stylesheet" type="text/css" href="http://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.css"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.js"></script>
<script>
var dates = ['20130101', '20130102', '20130103', '20130104', '20130105', '20130106'];
var sample = [30, 200, 100, 400, 150, 250];
var chart = c3.generate({
bindto: '#chart',
data: {
x:'Dates',
x_format:'%Y%m%d',
columns: [
//['Dates'].concat(dates),
//['Sample'].concat(sample)
['date', '20130101', '20130102', '20130103', '20130104', '20130105', '20130106'],
['sample', 30, 200, 100, 400, 150, 250]
]
},
axis: {
x: {
type : 'timeseries'
}
}
});
</script>
</head>
<body>
<div id="chart"></div>
</body>
</html>
I am not sure why I am getting the date related errors. I tried using actual data values in the C3 arguments as well as passing the data as variables. Any help is highly appreciated
Your dates array needs a first value with the name/id of the 'set', such as:
var dates = ['Dates', '20130101', '20130102', '20130103', '20130104', '20130105', '20130106'];
The data object's x property needs to match this. In the code above you've got differing values: Dates and date.
data: { x:'Dates',
You were closer with the concat attempt.
See this link: http://jsfiddle.net/jrdsxvys/16/
I'm very new to javascript (like 98.9%), so apologies in advance if this is a dumb question...
I currently have a list of book titles, and I am trying to put a small graph next to each bulleted item in the list. So to generate the graph, I'm using flot, and setting it up to use a stacked bar chart, horizontally.
Now my list may be 2, may be 20 items long. It all depends on the user who is logged in.
The challenge I have is that flot seems to work on the basis that a specifically identified HTML place holder must be set up for the graph, and then the javascript (external file in my case) which generates the graph, puts the resulting graphic into that specified placeholder.
If I've got more than one item, I need to dynamically create more unique in both the View, and then also in the javascript.
I could probably do it by writing my embedding my javascript in the View, and using some PHP to create the id's, but somehow that doesn't sound right - I'd rather try keep the neat seperation of unobtrusive JavaScript, View, Model, CSS etc.
Some pointers please...?
(This is PHP, CodeIgniter, JavaScript and CSS3)
[EDIT: Code example]
Below is not working code - it's "mid-experiment"
This is my JavaScript (in a separate myJS.js file)
function plotWithOptions(t,a,p) {
$(function () {
var d1 = [[t,10]];
var d2 = [[a,10]];
var d3 = [[p,10]];
$.plot($("#placeholder"), [ d1, d2, d3 ], {
series: {
stack: 0,
fill: true,
linewidth: 1,
bars: { show: true, barWidth: 10, horizontal: true}
},
xaxis: {max: 100, show:false},
yaxis: {max: 100, show:false},
grid: {show: false}
});
});
}
This is my View (CodeIgniter)
<script src="/assets/myJS.js"></script>
<script src="/assets/jquery.js"></script>
<script src="/assets/jquery.flot.js"></script>
<script src="/assets/jquery.flot.stack.js"></script>
<p>This book is rated....
<div id="placeholder1" style="width:300px;height:100px;"></div>
<script> plotWithOptions(28,14,11); </script>
<p>This book is rated....
<div id="placeholder2" style="width:300px;height:100px;"></div>
<script> plotWithOptions(28,27,1); </script>
<p>This book is rated....
<div id="placeholder3" style="width:300px;height:100px;"></div>
<script> plotWithOptions(28,27,26); </script>
<p>This book is rated....
<div id="placeholder4" style="width:300px;height:100px;"></div>
<script> plotWithOptions(28,14,11); </script>
I've managed to find a solution. I'm not sure if there is a "more correct" way of doing it, but the cost-benefit of finding a "purer/more elegant answer" is a beyond me right now.
This is the JavaScript file myGraphs.js
function plotWithOptions(n,t,a,p) {
$(function () {
var d1 = [[t,10]];
var d2 = [[a,10]];
var d3 = [[p,10]];
var divReference = "#placeholder"+n
$.plot($(divReference), [ d1, d2, d3 ], {
series: {
stack: 0,
fill: true,
linewidth: 1,
bars: { show: true, barWidth: 10, horizontal: true}
},
xaxis: {max: 100, show:false},
yaxis: {max: 100, show:false},
grid: {show: false}
});
});
}
And this is my CodeIgniter View
<script src="/assets/myGraphs.js"></script>
<script src="/assets/jquery.js"></script>
<script src="/assets/jquery.flot.js"></script>
<script src="/assets/jquery.flot.stack.js"></script>
<div id="Whatever">
<ul>
<?php
for ($i=1; $i<=5; $i++) {
echo "\n".'<li>';
echo "\n".'<div id="placeholder'.$i.'" style="width:300px;height:20px;"></div>';
echo "\n".'<script>plotWithOptions('.$i.',28,14,11); </script>';
echo "\n".'</li>';
}
?>
</ul>
</div>