I have a chart where I need to calculate the amount I'm earning as time goes by. In this chart, I have the amount (red line). My target is to calculate the total of every transaction that is going in. My current code is not working properly because when the time is 18:26:23 it is 1000 amount when it is 18:26:24, it is still 1000... It should be 2000. It should solve for the sum over time. I have provided my codes below and a screenshot of my current system and my target. Thank you in advance.
Views:
<div class="col-md-12">
<!-- LINE CHART -->
<div class="card card">
<div class="card-header">
<h3 class="card-title">Stats Per Day</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse" style="width:30%;">
<i class="fas fa-minus"></i>
</button>
</div>
</div>
<div class="card-body">
<div class="chart">
<div id="wholechart" style="min-height: 250px; height: 250px; max-height: 250px; max-width: 100%;"></div>
</div>
</div>
<!-- /.card-body -->
</div>
</div>
Ajax:
function sampleeesasw(){
$.ajax({
type: 'post',
url: '<?=site_url('report/datas')?>',
dataType:'json',
success: function(result) {
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(function(){drawChart(result);});
function drawChart(result) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'req');
data.addColumn('number', 'total');
data.addColumn('number', 'amount');
var dataArray =[];
$.each(result,function(i,obj){
dataArray.push([obj.req,parseInt(obj.total),parseInt(obj.amount)]);
});
data.addRows(dataArray );
var options = {
seriesType: "line",
};
var chart = new google.visualization.ComboChart(document.getElementById('wholechart')).
// Line,Bar,Area,Clomun,pie
draw(data, {curveType: "function",
vAxes: {0: {logScale: false},
1: {logScale: false, maxValue: 2}},
series:{
0:{targetAxisIndex:0},
1:{targetAxisIndex:1},
2:{targetAxisIndex:1}}}
);
}
}
});
}
setInterval(function(){
sampleeesasw()
},1000);
Controller:
public function datas(){
$data= $this->reports->wholedatachart();
foreach($data as $row){
$data['req']=$row['req'];
$data['amount']=$row['amount'];
$data['total']=$row['total'];
}
echo json_encode($data);
}
Model:
function wholedatachart(){
$query=$this->db->query("SELECT timeProcess as 'req', transID as 'total', amount as 'amount' FROM tbl_transaction");
return $query->result_array();
}
You can do calculation part inside your drawChart function. Inside that function you can simply total value of amount then , save it in some variable and pass it to your dataArray.push(..).
Demo Code :
//suppose data look like this..
var result = [{
"req": "1",
"amount": 2000,
"total": 1000
},{
"req": "2",
"amount": 1000,
"total": 1000
},{
"req": "3",
"amount": 1000,
"total": 1000
}]
function sampleeesasw() {
/*$.ajax({
type: 'post',
url: '',
dataType: 'json',
success: function(result) {*/
google.charts.load('current', {
'packages': ['corechart']
});
google.charts.setOnLoadCallback(function() {
drawChart(result);
});
function drawChart(result) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'req');
data.addColumn('number', 'total');
data.addColumn('number', 'amount');
var dataArray = [];
var total=0 //intialze..
$.each(result, function(i, obj) {
total +=parseInt(obj.amount)//add on each iteration
dataArray.push([obj.req, parseInt(obj.total), parseInt(total)]); //add value here ..
});
data.addRows(dataArray);
var options = {
seriesType: "line",
};
var chart = new google.visualization.ComboChart(document.getElementById('wholechart')).draw(data, {
curveType: "function",
vAxes: {
0: {
logScale: false
},
1: {
logScale: false,
maxValue: 2
}
},
series: {
0: {
targetAxisIndex: 0
},
1: {
targetAxisIndex: 1
},
2: {
targetAxisIndex: 1
}
}
});
}
/* }
});*/
}
setInterval(function() {
sampleeesasw()
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div class="col-md-12">
<!-- LINE CHART -->
<div class="card card">
<div class="card-header">
<h3 class="card-title">Stats Per Day</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse" style="width:30%;">
<i class="fas fa-minus"></i>
</button>
</div>
</div>
<div class="card-body">
<div class="chart">
<div id="wholechart" style="min-height: 250px; height: 250px; max-height: 250px; max-width: 100%;"></div>
</div>
</div>
<!-- /.card-body -->
</div>
</div>
I think you can try this one, you need to increment the amount of each data, you can use a temporary variable and increment all the amount.
I edited the answer sorry my bad.
change your controller to
public function datas(){
$data= $this->reports->wholedatachart();
$tempAmount = 0;
foreach($data as $row){
$tempAmount = $tempAmount + $row['amount'];
$output[]=array(
'req' => $timeline['time'],
'amount' => $tempAmount,
'amount' => $row['amount'],
);
}
echo json_encode($output);
}
if you want to add the total also you can do the same thing
Related
I wrote an AJAX Javascript code for my ESP32 datalogger which worked so far using old versions of Chart.js. The website hosted by the ESP32 is not working anylonger if I use a more recent of Chart.js.
The error message I caught is:
Uncaught ReferenceError: Chart is not defined at datalogin.html
The line in the code involved is this one
const myChart = new Chart(ctx, config);
Something in the interpretation seems to occur at a very early stage. But I could not identify what. See code below.
I already tried different Chart.js repository in order to have it working. It had absolutly no influence. I actively looked using different browser regarding this specific problematic and I could not find any way of solving this problem.
Thanks a lot for your support
<!DOCTYPE html>
<html lang="en">
<head>
<title>EFM Meter loggin interface</title>
<link rel="icon" type="image/x-icon" href="lightning.ico">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script type="module" src="https://github.com/cdnjs/cdnjs/blob/master/ajax/libs/Chart.js/4.0.1/chart.js" ></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns#2.0.1/dist/chartjs-adapter-date-fns.bundle.js"></script>
<style>
.jumbotron {
background-color: #000;
color: #fff;
}
</style>
</head>
<body>
<div class="jumbotron text-center">
<h1>Elektrofeldmeter Data Logging Page</h1>
</div>
<div class="container">
<div class="border border-2 m-2">
<div class="row">
<div class="col-sm-12 ">
<div class="container-sm">
<canvas id="myChart" style="" height="152"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="border border-2 m-2">
<div class="col-sm-12">
<h3> Parameters setup</h3>
</div>
</div>
<div class="border border-2 m-2">
<div class="row">
<div class="col-sm-12">
<label for="customRange1" class="form-label" id="labelPWM">PWM of motor: 190</label>
<input type="range" class="form-range" min="0" max="190" step="1" value="190" onchange="rangeValue(this)" id="customRange1">
</div>
<div class="col-sm-6">
<label for="customRange2" class="form-label" id="labelYmin">Y min: -5000</label>
<input type="range" class="form-range" min="-5000" max="5000" step="1" value="-5000" onchange="rangeY()" id="Ymin">
</div>
<div class="col-sm-6">
<label for="customRange2" class="form-label" id="labelYmax">Y max: +5000 0</label>
<input type="range" class="form-range" min="-5000" max="5000" step="1" value="5000" onchange="rangeY()" id="Ymax">
</div>
<div class="col-sm-12">
<button type="button" class="btn btn-primary" onclick="saveAs()">*.CSV</button>
</div>
</div>
</div>
</div>
</div>
<script>
function rangeValue(element) {
console.log(element.value);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/pwm?value="+element.value, true);
xhr.send();
document.getElementById("labelPWM").innerHTML = "PWM of motor: " + element.value;
};
function rangeY() {
myChart.options.scales.y.max = document.getElementById('Ymax').value;
myChart.options.scales.y.min = document.getElementById('Ymin').value;
myChart.update();
};
function clkOrientation(element) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/clk?value="+element.checked, true);
xhr.send();
}
const animation = { };
const config = {
type: 'line',
data: {
datasets: [{
borderColor: '#fc9905',
borderWidth: 2,
radius: 0,
data: 0
}
]
},
options: {
animation,
interaction: {
intersect: false
},
plugins: {
legend: false
},
scales: {
x: {
type: 'time',
title: {
display: true,
text: 'time',
color: '#000000',
font: {
size: 20
}
},
ticks :
{
color: '#000000',
font: {
size: 12
}
}
},
y: {
type: 'linear',
title: {
display: true,
text: 'Electrical field [V/m] # PWM=190',
color: '#000000',
font: {
size: 20
}
},
ticks :
{
color: '#000000',
font: {
size: 12
}
}
}
},
plugins: {
title: {
display: true,
text: 'Electrical field value [V/m]'
}
}
}
};
Chart.defaults.font.size = 20;
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, config);
function addData(chart, data) {
for (var i = 0 ; i < data.length; i++){
chart.data.datasets[0].data.push({"x":data[i].x,"y":(data[i].y-32.671)/0.48025});
};
chart.update();
};
function getData() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var txt = this.responseText;
var array = JSON.parse(txt); //Ref: https://www.w3schools.com/js/js_json_parse.asp
addData(myChart,array);
}
};
xhttp.open("GET", "readEFM", true); //Handle readADC server on ESP32
xhttp.send();
};
setInterval(function() {
getData();
}, 5000);
txt = '[{"x":1662921606250,"y":35.71},{"x":1662921606450,"y":35.61},{"x":1662921606650,"y":35.70},{"x":1662921606850,"y":35.74},{"x":1662921607050,"y":35.78},{"x":1662921607250,"y":35.45},{"x":1662921607450,"y":35.65},{"x":1662921607650,"y":35.66},{"x":1662921607850,"y":35.78},{"x":1662921608050,"y":35.76}]';
const myArr = JSON.parse(txt);
addData(myChart,myArr);
myChart.update();
function saveAs(){
let csvContent = "data:text/csv;charset=utf-8,";
for (var i = 0 ; i < myChart.data.datasets[0].data.length; i++){
csvContent+=myChart.data.datasets[0].data[i].x + "," + myChart.data.datasets[0].data[i].y + "\n";
}
var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "EFM_log.csv");
document.body.appendChild(link);
link.click();
};
</script>
</body>
</html>
i had implement the click event for the chart and it can filter the data in the table. But now i face the problem of the data does not return all the data in the table when click outside the chart are.How can make it return all the data when click outside the area chart? Thank you. Any help will be appreciated.
<script>
import VueApexCharts from "vue-apexcharts";
import faker from "faker";
export default {
components: {
VueApexCharts,
},
data() {
return {
Lists: [],
selectedData:{},
search1:'',
clicked:'',
clicked1:'',
isLoading1:true,
currentPage: 1,
series: [300, 200, 49, 100,290, 228, 119, 55],
chartOptions: {
colors: ['#7961F9', '#FF9F43', '#196EB0', '#2EAB56','#df87f2','#057FF2', '#14DA6E','#FF5500'],
legend: {
fontSize: "14px",
position: "top",
},
dataLabels: {
enabled: true,
minAngleToShowLabel: 0,
distributed: false,
style: {
colors: ['#111'],
},
background: {
enabled: true,
foreColor: '#fff',
borderWidth: 0,
}
},
chart: {
width: 500,
type: 'pie',
events: {
legendClick: (chartContext, seriesIndex,w, config) => {
this.clicked = w.config.labels[seriesIndex];
console.log(this.clicked);
console.log(seriesIndex);
},
dataPointSelection: (event,chartContext,config) => {
this.clicked1 = config.w.config.labels[config.dataPointIndex];
console.log(this.clicked1);
},
},
},
labels: ['Private', 'Local','Dental', 'Government','Cyber Security', 'Health', 'Foreign','Medical'],
responsive: [
{
breakpoint: 480,
options: {
legend: {
position: "bottom",
fontSize: "12px",
},
},
},
],
},
}
},
created() {
this.getData();
this.getData1();
},
computed:{
filterLists(){
let list = this.Lists;
if(this.search1 !=''){
list = list.filter((tr)=>{
return tr.agency.toUpperCase().includes(this.search1.toUpperCase())
});
}
if (this.clicked !=''&& this.clicked){
list = list.filter((tr)=>{
return tr.projectCategory.toUpperCase().includes(this.clicked.toUpperCase())
});
}
if (this.clicked1 !=''&& this.clicked1){
list = list.filter((tr)=>{
return tr.projectCategory.toUpperCase().includes(this.clicked1.toUpperCase())
});
}
return list;
},
},
methods: {
next(page) {},
getData1() {
this.isLoading1 = true;
for (let i = 0; i < this.randInt(8, 4); i++) {
let index = Math.floor(Math.random() * 2);
let projectCategory = this.rotate([
'Private', 'Local','Dental', 'Government','Cyber Security', 'Health', 'Foreign','Medical'
]);
this.Lists.push({
projectCategory:projectCategory,
project_name: faker.company.catchPhrase(),
agency: faker.company.companyName(),
logo: faker.image.abstract(),
});
}
this.maxPage = 2;
this.isLoading1 = false;
},
next1(page) {
if (page == -2) {
this.currentPage = 1;
} else if (page == -3) {
this.currentPage = this.maxPage;
} else {
if (
this.currentPage + page < 1 ||
this.currentPage + page > this.maxPage
) {
return;
}
this.currentPage += page;
}
this.showLoader("#card-list");
this.Lists = [];
this.isLoading1 = true;
setTimeout(() => {
this.closeLoader("#card-list");
this.getData1();
}, 1500);
},
},
};
</script>
<style>
#card > header{
padding: 1.5rem 2rem;
background-color: #2E3839;
}
#card{
--tw-bg-opacity: 1;
background-color: rgba(249, 250, 251, var(--tw-bg-opacity));
}
.con-img.vs-avatar--con-img img {
object-fit: cover !important;
}
.apexcharts-toolbar {
position:absolute;
margin-right:12px;
}
vs-button.btn:hover{
background-color: rgba(255,255,255,0);
cursor: pointer;
}
</style>
<template>
<div class="mb-base">
<div class="vx-row mb-base">
<div class="vx-col 2/3 w-full mb-base">
<vs-card
id="card"
class="vs-con-loading__container h-full"
>
<template slot="header">
<div class="flex">
<div>
<img
src=""
alt="Info"
class="h-12 inline-block mr-4 object-scale-down"
/>
</div>
<div class="flex flex-col justify-center w-full text-start">
<h3 class="text-white">Source of Fund</h3>
<span class="text-sm text-white">Based on Total Billed (Yearly)</span>
</div>
<div>
</div>
</div>
</template>
<div class="flex flex-wrap mt-2">
<div class="lg:w-1/3 w-full">
<vue-apex-charts
type="donut"
:options="chartOptions"
:series="series"
width="100%"
class="items-center justify-center flex mt-16 content-center"
/>
</div>
<div class="lg:w-2/3 w-full lg:pl-6 pl-0 mt-6">
<div class="flex justify-end items-end">
<vx-input-group class="mb-base lg:w-1/2 w-full">
<template slot="append">
<div class="append-text btn-addon">
<vs-button color="#A9A9A9"><i class="fas fa-search"></i></vs-button>
</div>
</template>
<vs-input
v-model="search1"
placeholder="Project Code or name"
/>
</vx-input-group>
</div>
<div id="card-list">
<vs-list v-if="!isLoading1">
<vs-list-item
v-for="(tr, index) in filtertLists"
:key="index"
class="hover:shadow cursor-pointer text-base mb-4"
>
<template slot="title">
<div
class="flex flex-col ml-2 cursor-pointer"
>
<div class="font-bold">{{ tr.project_name }}</div>
<div>{{ tr.agency }}</div>
</div>
</template>
<template slot="avatar">
<vs-avatar :src="tr.logo"></vs-avatar>
</template>
{{ tr.projectCategory }}
</vs-list-item>
<div v-if="!filterLists.length" class="flex">
<div class="items-center justify-center text-lg font-bold">No record...</div>
</div>
</vs-list>
<div v-else class="flex">
<div class="items-center justify-center">Fetching data...</div>
</div>
</div>
<div class="flex justify-end gap-4">
<div class="flex items-center justify-center text-sm">
Page {{ currentPage }} of
{{ maxPage }}
</div>
<div>
<vs-button
type="filled"
color=" rgba(243, 244, 246)"
class="w-10 mr-2 rounded-md bg-gray-400 text-black btn hover:text-black"
#click="next1(-1)"
>
<i class="fas fa-chevron-left"></i>
</vs-button>
<vs-button
type="filled"
color=" rgba(243, 244, 246)"
class="w-10 mr-2 rounded-md bg-gray-400 text-black btn"
#click="next1(1)"
>
<i class="fas fa-chevron-right"></i>
</vs-button>
</div>
</div>
</div>
</div>
</vs-card>
</div>
</div>
</div>
</template>
I am working with laravel vue pie chart. is there any way to filter the data in the table when click the element of pie chart. For example, when clicked the section pie chart, the table will be filter and display the the data in the table under that section..Any help will be appreciated
It is not possible to point directly to a solution as you have given so little detail. I will still try to explain the logic. For this process, you will get an input from the screen working with Vue.js and you will manipulate a data displayed on Vue.js.
So first; you need to know which part of your pie chart clicked on. I assume the pie chart you are using on your project have some events which triggered when you interact with charts. You will listen that event and catch the value of clicked item.
Now you have the value of clicked item and you need to filter your results by that.
To accomplish that you can use Vue.js Computed Properties and Watchers :https://v2.vuejs.org/v2/guide/computed.html
Lets say you have your data on your Vue.js application:
data () {
return {
clickedItem: null,
itemsOnTable: [ ... ]
}
}
You have all your table content in itemsOnTable and selected item's data in clickedItem
You can use computed to filter your data:
data () {
return {
clickedItem: null,
itemsOnTable: [ ... ]
}
},
computed: {
// filter itemsOnTable if clickedItem have any value
filteredItems: function () {
if(this.clickedItem==null) return this.itemsOnTable;
return this.itemsOnTable.filter(item => item.column = this.clickedItem);
}
}
Now in your Vue.js component you can directly use filteredItems for your table elements v-for
<table>
<tr v-for="items in filteredItems">
<td>{{ item.column }}</td>
<!-- other columns -->
</tr>
</table>
This examples explains basics of interactions and computed properties and aims to help you to understand basics.
I have chart bar and I am trying to show data by date wise when I filter by date but unfortunately data does not show on chart bar. I want that when I select a start date and end date record should be shown on chart bar by date wise.
Controller
public function status(Request $request)
{
$date = explode(' - ', $request->date);
$manager_hourlog = Hourlog::with('project', "user")->whereBetween('date', $date)
->get()
->groupBy('project.name');
$projects = [];
$totals = [];
foreach ($manager_hourlog as $key => $val) {
$projects[] = $key;
}
foreach ($manager_hourlog as $key2 => $val) {
$minutes = $val->sum('hour_work');
$totals[] = round($minutes / 60, 1);
}
$users = User::where("status", 1)->get();
$data = [
// manager report
'manager_projects' => $projects,
'totals' => $totals,
"manager_hourlog" => $manager_hourlog,
];
return $data;
return response()->json($data, 200);
}
html view
<form action="{{route('dashboard')}}" method="post" >
<div class="form-group">
<div class="input-group theme-input-group select-max-h-200">
<div class="input-group-prepend width-160px">
<div class="input-group-text">Date
</div>
</div>
<input parsley-trigger="change" required type="text" id="date" class="form-control" name="date" autocomplete="off">
<div class="input-group-append">
<span class="input-group-text">
<i class="md md-event-note">
</i>
</span>
</div>
</div>
<!-- input-group -->
</div>
</div>
<div class="col-lg-1">
<div class="text-right">
<button class="btn btn-light-theme waves-effect waves-light" id="search" name="search" type="submit">
<i class="fa fa-search pr-1">
</i> Search
</button>
</div>
</div>
</form>
script
<script type="text/javascript">
$(function () {
$('#search').on('click', function () {
var date = $("#date").val();
$.ajax({
type: 'GET',
url: '{{Route("dashboard.status")}}',
data: {
date: date
},
dataType: "JSon",
success: function(response){
// Employee report script
var colors = ["#1abc9c", "#2ecc71", "#3498db", "#9b59b6", "#34495e", "#16a085", "#27ae60", "#2980b9", "#8e44ad", "#2c3e50", "#f1c40f", "#e67e22", "#e74c3c", "#ecf0f1", "#95a5a6", "#f39c12", "#d35400", "#c0392b", "#bdc3c7", "#7f8c8d"];
#if ($auth->user_type != 1)
// manager report script
var managerchartbar = {
labels: {!! json_encode($manager_projects) !!},
datasets: [
#foreach($users as $user)
{
label: {!! json_encode($user->name) !!},
backgroundColor: colors[Math.floor(Math.random() * colors.length)],
data: [
#foreach($manager_hourlog as $hourlog)
{{$hourlog->where("user_id", $user->id)->sum("hour_work") / 60}},
#endforeach
]
},
#endforeach
]
};
var ctx = document.getElementById('manager').getContext('2d');
window.myBar = new Chart(ctx, {
type: 'bar',
data: managerchartbar,
options: {
title: {
display: true,
text: 'Project Report chart'
},
tooltips: {
mode: 'index',
intersect: false
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
}
});
#endif
console.log(response);
},
error: function(xhr){
console.log(xhr.responseText);
}});
});
});
</script>
I am working on a survey application with Asp.Net MVC. I have a page named Index.cshtml which has a question table and a 'Add New' button.Once button clicked, a popup is opened with jQuery. I am calling a view from controller to fill jQuery dialog named as AddOrEdit.cshtml (child page). I am adding new question and options. Question is a textfield and its options are added in editable table. Once clicked submt button Submit form event (save or update) is fired. But ajax sends twice request. One of these requests send empty object, the other sends full object. Where am I making a mistake?
According to my research, what causes this problem is that the unobtrusive validator is placed on 2 different pages. But this is not the case for me.
When I debug with chrome in f12, the initiator of one of the 2 requests 'jquery' the initiator of the other 'other' The type of one of these 2 post requests appears as 'XHR' and the type of the other is 'document'.
Index.cshtml
#{
ViewBag.Title = "Soru Listesi";
}
<h2>Soru Oluşturma</h2>
<a class="btn btn-success" style="margin-bottom: 10px"
onclick="PopupForm('#Url.Action("AddOrEdit","Question")')"><i class="fa fa-plus"></i> Yeni Soru Oluştur</a><table id="questionTable" class="table table-striped table-bordered accent-blue" style="width: 100%">
<thead>
<tr>
<th>Soru No</th>
<th>Soru Adı</th>
<th>Oluşturma Tarihi</th>
<th>Güncelleme Tarihi</th>
<th>Güncelle/Sil</th>
</tr>
</thead>
</table>
<link
href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css" rel="stylesheet" />
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
rel="stylesheet" />
#section Scripts{
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js"></script>
<script>
var Popup, dataTable;
$(document).ready(function() {
dataTable = $("#questionTable").DataTable({
"ajax": {
"url": "/Question/GetData",
"type": "GET",
"datatype": "json"
},
"columnDefs": [
{ targets: 2 }
],
"scrollX": true,
"scrollY": "auto",
"columns": [
{ "data": "QuestionId" },
{ "data": "QuestionName" },
{
"data": "CreatedDate",
"render": function(data) { return getDateString(data); }
},
{
"data": "UpdatedDate",
"render": function(data) { return getDateString(data); }
},
{
"data": "QuestionId",
"render": function(data) {
return "<a class='btn btn-primary btn-sm' onclick=PopupForm('#Url.Action("AddOrEdit", "Question")/" +
data +
"')><i class='fa fa-pencil'></i> Güncelle</a><a class='btn btn-danger btn-sm' style='margin-left:5px' onclick=Delete(" +
data +
")><i class='fa fa-trash'></i> Sil</a>";
},
"orderable": false,
"searchable": false,
"width": "150px"
}
],
"language": {
"emptyTable":
"Soru bulunamadı, lütfen <b>Yeni Soru Oluştur</b> butonuna tıklayarak yeni soru oluşturunuz. "
}
});
});
function getDateString(date) {
var dateObj = new Date(parseInt(date.substr(6)));
let year = dateObj.getFullYear();
let month = (1 + dateObj.getMonth()).toString().padStart(2, '0');
let day = dateObj.getDate().toString().padStart(2, '0');
return day + '/' + month + '/' + year;
};
function PopupForm(url) {
var formDiv = $('<div/>');
$.get(url)
.done(function(response) {
formDiv.html(response);
Popup = formDiv.dialog({
autoOpen: true,
resizable: true,
title: 'Soru Detay',
modal: true,
height: 'auto',
width: '700',
close: function() {
Popup.dialog('destroy').remove();
}
});
});
}
function SubmitForm(form) {
debugger;
if (form.checkValidity() === false) {
debugger;
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
if ($(form).valid()) {
var question = {};
question.questionId = 1111;
var options = new Array();
$("#questionForm TBODY TR").each(function() {
var row = $(this);
var option = {};
option.OptionId = row.find("TD").eq(0).html();
option.OptionName = row.find("TD").eq(1).html();
options.push(option);
});
question.options = options;
question.responses = new Array();
$.ajax({
type: "POST",
url: form.action,
data: JSON.stringify(question),
success: function(data) {
if (data.success) {
debugger;
Popup.dialog('close');
dataTable.ajax.reload();
$.notify(data.message,
{
globalPosition: "top center",
className: "success",
showAnimation: "slideDown",
gap: 1000
});
}
},
error: function(req, err) {
debugger;
alert('req : ' + req + ' err : ' + err.data);
},
complete: function(data) {
alert('complete : ' + data.status);
}
});
}
}
function ResetForm(form) {
Popup.dialog('close');
return false;
}
function Delete(id) {
if (confirm('Bu soruyu silmek istediğinizden emin misiniz?')) {
$.ajax({
type: "POST",
url: '#Url.Action("Delete", "Question")/' + id,
success: function(data) {
if (data.success) {
dataTable.ajax.reload();
$.notify(data.message,
{
className: "success",
globalPosition: "top center",
title: "BAŞARILI"
})
}
}
});
}
}
</script>
}
AddOrEdit.cshtml
#using MerinosSurvey.Models
#model Questions
#{
Layout = null;
}
#using (Html.BeginForm("AddOrEdit", "Question", FormMethod.Post, new { #class = "needs-validation",
novalidate = "true", onsubmit = "return SubmitForm(this)", onreset = "return ResetForm(this)", id =
"questionForm" }))
{
<div class="form-group row">
#Html.Label("QuestionId", "Soru No", new { #class = "col-form-label col-md-3" })
<div class="col-md-9">
#Html.TextBoxFor(model => model.QuestionId, new { #readonly = "readonly", #class = "form-control" })
</div>
</div>
<div class="form-group row">
#Html.Label("QuestionName", "Soru Adı", new { #class = "col-form-label col-md-3" })
<div class="col-md-9">
#Html.EditorFor(model => model.QuestionName, new { htmlAttributes = new { #class = "form-control", required = "true" } })
<div class="valid-feedback"><i class="fa fa-check">Süpersin</i></div>
<div class="invalid-feedback "><i class="fa fa-times"></i></div>
</div>
</div>
#*<div class="form-group row">
#Html.LabelFor(model => model.CreatedDate, new { #class = "form-control-label col-md-3"})
<div class="col-md-9">
#Html.EditorFor(model => model.CreatedDate, "{0:yyyy-MM-dd}", new { htmlAttributes = new { #class = "form-control", type = "date", #readonly = "readonly",required="false" } })
</div>
</div>*#
<div class="table-wrapper form-group table-responsive-md">
<div class="table-title">
<div class="form-group row">
<div class="col-md-9">Seçenekler</div>
<div class="col-md-3">
<a class="btn btn-success add-new" style="margin-bottom: 10px"><i class="fa fa-plus"></i>Seçenek Ekle</a>
</div>
</div>
</div>
<table class="table optionTable">
<thead>
<tr>
<th scope="col">Seçenek Id</th>
<th scope="col">Seçenek Adı</th>
<th scope="col">Güncelle/Sil</th>
</tr>
</thead>
<tbody>
#*#foreach (Options options in Model.Options)
{
<tr>
<td>#options.OptionId</td>
<td>#options.OptionName</td>
<td>
<a class="add btn btn-primary btn-sm" title="Add" data-toggle="tooltip">
<i class="fa fa-check">Onayla</i></a>
<a class="edit btn btn-secondary btn-sm" title="Edit" data-toggle="tooltip"><i class="fa fa-pencil">Güncelle</i></a>
<a class="delete btn-danger btn-sm" title="Delete" data-toggle="tooltip"><i class="fa fa-trash">Sil</i></a>
</td>
</tr>
}*#
</tbody>
</table>
</div>
<div class="form-group row">
<input type="submit" value="Submit" class="btn btn-primary" id="btnSubmit" />
<input type="reset" value="Reset" class="btn btn-secondary" />
</div>
}
<script>
$(document).ready(function () {
$('[data-toggle="tooltip"]').tooltip();
//var actions = $("table.optionTable td:last-child").html();
var actions =' <a class="add btn btn-primary btn-sm" title="Add" data-toggle="tooltip"><i
class="fa fa-check">Onayla</i></a>' + '<a class="edit btn btn-secondary btn-sm" title="Edit" data toggle="tooltip"><i class="fa fa-pencil">Güncelle</i></a>' +'<a class="delete btn-danger btn-sm" title="Delete" data-toggle="tooltip"><i class="fa fa-trash">Sil</i></a>';
// Append table with add row form on add new button click
$(".add-new").click(function () {
$(this).attr("disabled", "disabled");
var index = $("table.optionTable tbody tr:last-child").index();
var row = '<tr>' +
'<td><input type="text" class="form-control" name="optionId" id="optionId"></td>' +
'<td><input type="text" class="form-control" name="optionId" id="optionName"></td>' +
'<td>' + actions + '</td>' +
'</tr>';
$("table.optionTable").append(row);
$("table.optionTable tbody tr").eq(index + 1).find(".add, .edit").toggle();
$('[data-toggle="tooltip"]').tooltip();
});
// Add row on add button click
$(document).on("click", ".add", function () {
var empty = false;
var input = $(this).parents("tr").find('input[type="text"]');
input.each(function () {
if (!$(this).val()) {
$(this).addClass("error");
empty = true;
} else {
$(this).removeClass("error");
}
});
$(this).parents("tr").find(".error").first().focus();
if (!empty) {
input.each(function () {
$(this).parent("td").html($(this).val());
});
$(this).parents("tr").find(".add, .edit").toggle();
$(".add-new").removeAttr("disabled");
}
});
// Edit row on edit button click
$(document).on("click", ".edit", function () {
$(this).parents("tr").find("td:not(:last-child)").each(function () {
$(this).html('<input type="text" class="form-control" value="' + $(this).text() + '">');
});
$(this).parents("tr").find(".add, .edit").toggle();
$(".add-new").attr("disabled", "disabled");
});
// Delete row on delete button click
$(document).on("click", ".delete", function () {
debugger;
$(this).parents("tr").remove();
$(".add-new").removeAttr("disabled");
});
});
event.preventDefault(); move this line and place it immediately after function SubmitForm (form){
Like below:
function SubmitForm(form) {
debugger;
event.preventDefault();
if (form.checkValidity() === false) {
debugger;
event.stopPropagation();
}
form.classList.add('was-validated');
if ($(form).valid()) {
var question = {};
question.questionId = 1111;
var options = new Array();
$("#questionForm TBODY TR").each(function() {
var row = $(this);
var option = {};
option.OptionId = row.find("TD").eq(0).html();
option.OptionName = row.find("TD").eq(1).html();
options.push(option);
});
question.options = options;
question.responses = new Array();
$.ajax({
type: "POST",
url: form.action,
data: JSON.stringify(question),
success: function(data) {
if (data.success) {
debugger;
Popup.dialog('close');
dataTable.ajax.reload();
$.notify(data.message,
{
globalPosition: "top center",
className: "success",
showAnimation: "slideDown",
gap: 1000
});
}
},
error: function(req, err) {
debugger;
alert('req : ' + req + ' err : ' + err.data);
},
complete: function(data) {
alert('complete : ' + data.status);
}
});
}
}
I am a newbie to Chart JS library. Iam facing issues in displaying my charts automatically. The charts do no display until I click on one of them or trigger the load by using chrome developer tools. Can you help me in displaying the charts automatically without having to click ?
Thanks for your help.
The code of my page is as follows:
<!-- Layout of the different charts -->
<div class="container-fluid">
<div class="row">
<div class="col-sm-6 col-md-4">
<div class="chart-wrapper">
<div class="chart-title">
Distance totale (en mètres) par Tag
</div>
<div class="chart-stage">
<div id="grid-1-1">
<div id="chart-01"></div>
<canvas id="chart01" ></canvas>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4">
<div class="chart-wrapper">
<div class="chart-title">
Durée totale (en secondes) par Tag
</div>
<div class="chart-stage">
<div id="chart-02"></div>
<canvas id="chart02"></canvas>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4">
<div class="chart-wrapper">
<div class="chart-title">
Nombre de Trajets par Zone
</div>
<div class="chart-stage">
<div id="chart-03"></div>
<canvas id="chart03"></canvas>
</div>
</div>
</div>
</div>
<div class="row" >
<div class="col-sm-6 col-md-4">
<div class="chart-wrapper">
<div class="chart-title">
Durée totale (en secondes) par Zone
</div>
<div class="chart-stage">
<div id="chart-04"></div>
<canvas id="chart04"></canvas>
</div>
</div>
</div>
</div>
<hr/>
</div>
<!-- The scripts to inject data in the graphs -->
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script>
var userSite = '';
var ctx1 = document.getElementById("chart01");
var ctx2 = document.getElementById("chart02");
var ctx3 = document.getElementById("chart03");
var ctx4 = document.getElementById("chart04");
var tags = [];
var tagsColor = [];
var tagsBorderColor = [];
var distances = [];
var durations = [];
var areas = [];
var nbpaths = [];
var chart01 = {};
var chart02 = {};
var chart03 = {};
var chart04 = {};
<!-- Uitlity to create colors adapted to the graphs -->
function getRandColor(){
var color = [{c:'rgba(255, 99, 132, 0.2)',b:'rgba(255,99,132,1)'},
{c:'rgba(54, 162, 235, 0.2)',b:'rgba(54, 162, 235, 1)'},
{c:'rgba(255, 206, 86, 0.2)', b:'rgba(255, 206, 86, 1)'},
{c:'rgba(75, 192, 192, 0.2)', b:'rgba(75, 192, 192, 1)'},
{c:'rgba(153, 102, 255, 0.2)',b:'rgba(153, 102, 255, 1)'},
{c:'rgba(255, 159, 64, 0.2)]',b:'rgba(255, 159, 64, 1)'}];
return color[Math.floor(Math.random()*(color.length-1))];
}
<!-- Get the specific site to feed data -->
window.onload = function() {
$.ajax({
type: 'GET',
url: 'rest/maps/sites',
dataType: 'json',
async: false,
success: function(data) {
userSite = data[0];
}
});
<!-- Calling webservices to get data -->
$.ajax({
url: 'rest/tags/' + userSite + '/chartinfos',
dataType: 'json',
success: function(response, status){
for ( i=0; i<response.length; i++){
var color = getRandColor();
tags.push(response[i].idTag);
durations.push(response[i].duration);
tagsColor.push(color.c);
tagsBorderColor.push(color.b);
distances.push(response[i].distance);
}
}
});
chart01 = new Chart(ctx1, {
type: 'bar',
data: {
labels: tags,
datasets: [{
label: 'Distance/Tag',
data: distances,
backgroundColor: tagsColor,
borderColor: tagsBorderColor,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
chart02 = new Chart(ctx2, {
type: 'bar',
data: {
labels: tags,
datasets: [{
label: 'Durée/Tag',
data: durations,
backgroundColor: tagsColor,
borderColor: tagsBorderColor,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
$.ajax({
url: 'rest/areas/' + userSite + '/chartinfos2',
dataType: 'json',
success: function(response, status){
for ( i=0; i<response.areas.length; i++){
var color = getRandColor();
areas.push(response.areas[i].idAreas);
nbpaths.push(response.areas[i].nbPaths);
tagsColor.push(color.c);
tagsBorderColor.push(color.b);
}
}
});
chart03 = new Chart(ctx3, {
type: 'bar',
data: {
labels: areas,
datasets: [{
label: 'Trajets/Zone',
data: nbpaths,
backgroundColor: tagsColor,
borderColor: tagsBorderColor,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
chart04 = new Chart(ctx4, {
type: 'bar',
data: {
labels: areas,
datasets: [{
label: 'Durée/Zone',
data: durations,
backgroundColor: tagsColor,
borderColor: tagsBorderColor,
hidden: false,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
};
</script>
</body>
</html>