I am trying to build out a google chart in an mvc app.
Here is a snippet of google Chart javascript
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Task');
data.addColumn('number', 'Hours per Day');
data.addRows([
['Work', 11],
['Eat', 2],
['Commute', 2],
['Watch TV', 2],
['Sleep', 7]
]);
}
what I would like to do is essentially replace the data.addRows line above with a for loop iterating through the items in my model. I can iterate just fine in the view outside of the tag like so of course:
"#foreach (var item in Model) {
<div>#Html.DisplayFor(modelItem => item.Customer.Name)</div>
}"
I cannot seem to find a solution to iterate through my model INSIDE a tag. Any ideas?
Assuming you have a view model:
public class MyViewModel
{
public object[][] Values { get; set; }
}
in which you store some values and pass along to the view:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Values = new[]
{
new object[] { "Work", 11 },
new object[] { "Eat", 2 },
new object[] { "Commute", 2 },
new object[] { "Watch TV", 2 },
new object[] { "Sleep", 7 },
}
};
return View(model);
}
}
in your view you could JSON encode it:
#model MyViewModel
<script type="text/javascript">
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Task');
data.addColumn('number', 'Hours per Day');
data.addRows(#Html.Raw(Json.Encode(Model.Values)));
}
</script>
which will be rendered in the final markup as:
<script type="text/javascript">
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Task');
data.addColumn('number', 'Hours per Day');
data.addRows([["Work",11],["Eat",2],["Commute",2],["Watch TV",2],["Sleep",7]]);
}
</script>
And you shouldn't be worried at all about having values that contain single or double quotes which could potentially break your javascript because you have used a JSON serializer instead of manually building it.
Related
Hi I am beginner with Ajax at the Laravel. I wanted to fetch data with Laravel Eagerload function to my blade modal.
This is my Expenses Model
protected $fillable = [
'name',
'surname',
'email',
'password',
'status',
'role',
];
protected $hidden = [
'password',
'remember_token',
];
public function Expense () {
return $this->hasMany(ExpensesModel::class);
}
This is my Expenses Model
`
{
use HasFactory;
protected $table = 'expenses';
protected $fillable = [
'id',
'emp_id',
'expense_input_date',
'expense_type',
'expense_category',
'reason',
'status'
];
public function UserExpense () {
return $this->belongsTo(User::class, 'emp_id' );
}
My controller
This is My controller function
public function edit (Request $request) {
$req_id = array('id' => $request->id);
if($request->ajax()) {
$employee = ExpensesModel::with('UserExpense')->where('id' ,$req_id)->first();
return response()->json($employee);
}
}
This is my blade script
`
function editFunc(id){
$.ajax({
type:"POST",
url: "{{ url('/expenses/advancedtable/edit') }}",
data: { id: id },
dataType: 'json',
success: function(res){
$('#EmployeeModal').html("Edit Employee");
$('#employee-modal').modal('show');
$('#id').val(res.id);
$('#emp_id').val(res.name);
$('#expense_input_date').val(res.expense_input_date);
$('#expense_type').val(res.expense_type);
$('#expense_category').val(res.expense_category);
$('#expense_slip_no').val(res.expense_slip_no);
$('#expense_amount').val(res.expense_amount);
$('#currency').val(res.currency);
$('#description').val(res.description);
}
});
}
I tried everyting but it does not work. I wanted to retrive user name from User Model by using foreign key on the Expenses model emp_id.
is there something I missed somewhere can you help me with this.
Thank you.
Here how its work.
First of all change relationship in your User and Expenses model like this.
// User Model
public function userExpense() {
return $this->hasMany(ExpensesModel::class,'emp_id','id');
}
// ExpensesModel
public function user() {
return $this->hasOne(User::class,'id','emp_id');
}
Then change your controller function.
// controller function
public function edit (Request $request) {
$req_id = $request->id;
$employeeExpense = ExpensesModel::with('user')->where('id' ,$req_id)->first();
return response()->json($employeeExpense);
}
Then change your ajax sucess function.
// ajax sucsess function
success: function(res) {
console.log(res); // to view your response from controller in webbrowser's console
$('#EmployeeModal').html("Edit Employee");
$('#employee-modal').modal('show');
$('#id').val(res.id);
$('#emp_id').val(res.user.name); // it will print user name
$('#expense_input_date').val(res.expense_input_date);
$('#expense_type').val(res.expense_type);
$('#expense_category').val(res.expense_category);
$('#expense_slip_no').val(res.expense_slip_no);
$('#expense_amount').val(res.expense_amount);
$('#currency').val(res.currency);
$('#description').val(res.description);
}
when you use 'with' eloqunt method it will add relationship function name to your query result, so you want to get user details then you should be do like res.user.userfield this is applicable for hasOne only.
For other relationship you will refer to this https://laravel.com/docs/9.x/eloquent-relationships
I've been trying to work out why google charts won't plot this JSON data in a line chart
I've scoured the internet but can't find the answer, so calling on the big guns now ...
From a .CSV file loaded into a PHP array
Array
(
[0] => Array
(
[Time] => 16:37:36
[Value] => 27.1
)
[1] => Array
(
[Time] => 16:42:05
[Value] => 27.0
)
etc
Then in JS convert to json format to give me this
var ar = [{"Time":"16:37:36","Value":27.1},{"Time":"16:42:05","Value":27} etc
var data = new google.visualization.DataTable();
data.addColumn('string', 'Time');
data.addColumn('number', 'Value');
data.addRows(ar);
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 200});
When I run the script, all I get is a basic graph without any plotted data, just an empty graticule
Any pointers would be greatly appreciated
Your array needs to be changed from:
var ar = [{"Time":"16:37:36","Value":27.1},{"Time":"16:42:05","Value":27} etc
to (drop the '{', '"Time":' and '"Value":')
["16:37:36",27.1],["16:42:05",27] ,etc
For your Google LineChart see the example below
google.charts.load('current', {packages: ['corechart', 'line']});
google.charts.setOnLoadCallback(drawCurveTypes);
function drawCurveTypes() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Time');
data.addColumn('number', 'Value');
data.addRows([
["16:37:36", 27.1], ["16:42:05", 27], ["16:44", 23], ["16:46", 17.0], ["16:51", 18], ["16:54", 9]
]);
var options = {
hAxis: {
title: 'Time'
},
vAxis: {
title: 'Hits'
},
series: {
1: {curveType: 'function'}
}
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
https://jsfiddle.net/api/post/library/pure/
I have some problem accessing to model attribute in Javascript; in particular I have this controller:
#RequestMapping(value = "/dashboard")
public ModelAndView home(HttpServletRequest request, HttpServletResponse
res, Model model) {
// Return answer's dictionary from DB to dashboard view
CompQuest dizRisp = new CompQuest();
dizRisp.setDizComp(dashDao.getRispEnd());
model.addAttribute("dizRisp", dizRisp);
return new ModelAndView("dashboard");
}
and I have this Javascript file (here: only the part with the code for my chart where I want to refer to model attribute) where I want to access to model attribute "dizRisp" from my controller:
var ctx1 = document.getElementById('myChart1').getContext('2d');
var myRadarChart = new Chart(ctx1, {
type: 'radar',
data: {
labels: ['Valori e identità del SCN', 'La cittadinanza attiva',
'Il giovane volontario nel sistema del SC', 'Lavorare',
'Prevenzione e protezione', 'Normativa sicurezza',
'Rischi sulla salute in tema di ambiente'
],
datasets: [{
label: "Civiche",
data: [4, 5, 5, 2, 4, 5, 4],
fill: true,
borderJoinStyle: "round"
}],
},
options: {
maintainAspectRatio: false,
scale: {
ticks: {
stepSize: 1,
step: 1,
beginAtZero: true,
max: 5
}
}
}
});
My classes are (here: no getters and setters):
public class CompQuest {
private HashMap <String, CompRisp> dizComp;}
public class CompRisp {
private ArrayList <Risposte> rispList = new ArrayList <Risposte> ();}
public class Risposte {
int id;
Domande domande;
int valore;
int momento; }
public class Domande {
int id;
String testo;
String descrizione;
Questionario questionario; }
My .jsp file:
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js" ></script>
<script src="resources/dashboard.js" type="text/javascript"></script>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/dashboard.css">
<title>Dashboard</title>
<style>
#import url('https://fonts.googleapis.com/css?family=Bitter|Roboto+Condensed');
#import url('https://fonts.googleapis.com/css?family=Roboto');
</style>
In particular I would want to access to my model attribute (Hashmap) in order to put in label and datasets field of my Javascript chart values from my Hashmap that contains data from my Database.
Thanks in advance to everyone that can help me!
Spring controller
#RequestMapping(value = "/dashboard")
public ModelAndView home(HttpServletRequest request,
HttpServletResponse
res, Model model) {
// Return answer's dictionary from DB to dashboard view
CompQuest dizRisp = new CompQuest();
dizRisp.setDizComp(dashDao.getRispEnd());
Gson gson = new Gson() ;
// Use Gson dependency to convert hashmap to String
String strmap = gson.toJson(dizRisp)
model.addAttribute("dizRisp", strmap);
return new ModelAndView("dashboard");
}
Javascript
<script>
$(document).ready(function(){
var element = JSON.parse('${dizRisp}');
$.each( element , function( key, value ) {
console.log(key);
console.log(value);
});
});
</script>
Hope this is what your trying to achieve.
I trying to use morris area chart, I don't know how correctly to serialize data and send date which morris area chart can understand.
This is method in HomeController which get data from DB.
public ActionResult GetData()
{
List<GraphData> GraphDataList = new List<GraphData>();
var user = db.Users.Where(p => p.Email == User.Identity.Name).Single();
var Requests = db.Transactions.Where(p => p.Package_id != null && p.User_id == user.Id);
DateTime day = new DateTime();
int CountPerDay = 0;
// count of request per day
foreach (var request in Requests)
{
if (day.Year == request.Date.Year && day.Day == request.Date.Day)
{
CountPerDay++;
}
else
{
// To 2016-12-03 format of date
string Date = day.Year + "-" + day.Month + "-" + day.Day;
GraphDataList.Add(new GraphData(Date, CountPerDay));
CountPerDay = 0;
day = request.Date;
}
}
// First elem in list is wrong
GraphDataList.RemoveAt(0);
return Json(GraphDataList, JsonRequestBehavior.AllowGet);
}
GraphData class
public class GraphData
{
public string label { get; set; }
public int value { get; set; }
public GraphData(string label, int value)
{
this.label = label;
this.value = value;
}
public GraphData()
{
}
}
Area chart in html code
<div class="col-lg-6">
<div class="panel panel-default">
<div class="panel-heading">
Request statistic
</div>
<!-- /.panel-heading -->
<div class="panel-body">
<div id="area-example"></div>
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
And func which get data from controller and send to Morris.Area
<!--Get Data for Graph-->
<script type="text/javascript">
$(document).ready(function() {
$.get('#Url.Action("GetData","Home")', function (result) {
new Morris.Area({
// ID of the element in which to draw the chart.
element: 'area-example',
// Chart data records -- each entry in this array corresponds to a point on
// the chart.
data: [result],
// The name of the data record attribute that contains x-values.
xkey: 'label',
ykeys: ['value'],
labels: ['Success requests'],
pointSize: 2,
hideHover: 'auto',
resize: true
});
});
});
</script>
So the result is the clear panel without graph
But if a init data like this
<!--Get Data for Graph-->
<script type="text/javascript">
$(document).ready(function() {
$.get('#Url.Action("GetData","Home")', function (result) {
new Morris.Area({
// ID of the element in which to draw the chart.
element: 'area-example',
// Chart data records -- each entry in this array corresponds to a point on
// the chart.
data: [
{ label: '2016-12-3', value: 150},
{ label: '2016-12-4', value: 221},
{ label: '2016-12-5', value: 43},
{ label: '2016-12-6', value: 21},
{ label: '2016-12-7', value: 312}
],
// The name of the data record attribute that contains x-values.
xkey: 'label',
ykeys: ['value'],
labels: ['Success requests'],
pointSize: 2,
hideHover: 'auto',
resize: true
});
});
});
</script>
the result is
Solution is to use this, because you have already returned a json array using ajax call. So, you do not need data:[result],all you need is data:result.
new Morris.Area({
// ID of the element in which to draw the chart.
element: 'area-example',
// Chart data records -- each entry in this array corresponds to a point on
// the chart.
data: result,
// The name of the data record attribute that contains x-values.
xkey: 'label',
ykeys: ['value'],
labels: ['Success requests'],
pointSize: 2,
hideHover: 'auto',
resize: true
});
i'm trying to make line chart in laravel using google chart and get data from database mysql.
Question:
how can i passing variable $bmi and $visits in data.addRows? so that i can showing the data using line chart.
here my code (php):
public function graphBmi($childName){
$name = DB::table('tm_child')->select('Child_Name')->distinct()
->where('Child_ID', 'LIKE', '%' . $childName . '%')->first();
$visit = DB::table('tm_Child')
->join('tr_visit', 'tm_child.Child_ID', '=', 'tr_visit.Child_ID')
->where('tr_visit.Child_ID', 'LIKE', '%' . $childName . '%')
->select('Visit_Date', 'tr_visit.Child_ID', 'Bmi_anak')
->distinct()->get();
if (!is_null($visit)) {
$visits = [];
$bmi = [];
$data[0] = array('day','counts');
foreach ($visit as $tgl) {
array_push($visits, $tgl->Visit_Date);
array_push($bmi, $tgl->Bmi_anak);
}
}
// return $visit;
echo json_encode($bmi); //number
echo json_encode($visits); //date visit
return View::make('ProfilAnak.BmiAnak.seeBmi')->with('visits',$visits)->with('bmi',$bmi);
}
here script for showing the chart
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id="chart_div"></div>
<script>
google.load('visualization', '1', {packages: ['corechart', 'line']});
google.setOnLoadCallback(drawBackgroundColor);
function drawBackgroundColor() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'Visit');
data.addColumn('number', 'X');
data.addRows([
[new Date{{$visits}},{{$bmi}}]
]);
var options = {
hAxis: {
title: 'Time'
},
vAxis: {
title: 'Popularity'
},
backgroundColor: '#f1f8e9'
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>