Setting starting value for Google Line Chart dynamically and redrawing chart - forms

I am using the code below to generate a line chart for a projected financial balance. Data is generated from information in a MySQL database. What I would like to be able to do is to have a form with an input field on the page that allows the user to set the starting balance dynamically once the page is loaded, such that the chart is redrawn with the correct starting balance, but I can't work out how to do this:
$rows = array();
$table = array();
$table['cols'] = array(
array('label' => 'Date', 'type' => 'string'),
array('label' => 'Amount', 'type' => 'number')
);
[code to generate data goes here - i.e. calculating a balance for each date in the chart]
$balance = $balance - $monthly - $weekly + $session_total;
$temp = array();
$temp[] = array('v' => (string) $date_display);
$temp[] = array('v' => (string) $balance);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table);
//echo $jsonTable;
?>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
function drawChart() {
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(<?=$jsonTable?>);
var formatter = new google.visualization.NumberFormat({fractionDigits:2,prefix:'\u00A3'});
formatter.format(data, 1);
var options = {
pointSize: 5,
legend: 'none',
hAxis: { showTextEvery:31 },
series: {0:{color:'2E838F',lineWidth:2}},
chartArea: {left:50,width:"95%",height:"80%"},
backgroundColor: '#F7FBFC',
height: 400
};
// Instantiate and draw our chart, passing in some options.
//do not forget to check ur div ID
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
<div id="chart_div"></div>

Hopefully there's a fairly simple way to refresh the chart when new data is available. It requires a small change to your PHP and a few JavaScript tweaks.
The nice thing about using Google Charts is that you can just re-draw them by calling drawChart() again, you just need to be able to modify the data before you do it.
The change I would make the PHP would be to store the original value, so that when you want to change the value according to the user's input you can always have something to refer back to:
// display the date
$temp[] = array('v' => (string) $date_display);
// the data used by the chart
$temp[] = array('v' => (string) $balance);
// the original value
$temp[] = array('v' => (string) $balance);
I would also make the table data global rather than drawing it directly into the function, this way you can change it and refresh the chart quite easily.
var table = <?php echo $jsonTable; ?>;
function drawChart() {
var data = new google.visualization.DataTable(table);
......
}
I tested this with a basic form that looks like this:
<form method="post" action="#" onsubmit="return false;">
<input type="text" id="balance1" />
<input type="text" id="balance2" />
<button onclick="return refreshChart()">Go</button>
</form>
Clicking on the button cancels the default action and calls a function called refreshChart(). This function takes the value and adds it to the original values on the fly before re-drawing the chart:
function refreshChart() {
var balance1 = document.getElementById('balance1').value;
var balance2 = document.getElementById('balance2').value;
if(!balance1) {
balance1 = 0;
}
if(!balance2) {
balance2 = 0;
}
for(var i = 0, length = table.rows.length; i < length; i++) {
table.rows[i].c['1'].v = parseFloat(table.rows[i].c['2'].v) + parseFloat(balance1) + parseFloat(balance2);
}
drawChart();
return false;
}
It takes the balance entered and adds it to the original value stored in table.rows[i].c['2'].v and overwrites the value in table.rows[i].c['1'].v which is used by the chart. It then calls the original drawChart() function but the new data is used.
I played around with some default data and this is the output I tested it with on JSFiddle.

Related

How do i store pictures in moodle?

I'm trying to create my own Activity in moodle where students can take pictures of their Drivers License and that pictures get stored in moodle, then later opended and shown to the teacher.
My Problem is to store the picture on the moodle side and not downloading it.(like i'm doing right now)
Hopfully someone can help me figure out a way to use the file_storage given by moodle to safe the pictures.
kind regards
J
This is my code for now (view.php) ... I know its not realy in a moodle way but im trying to get it to work first then then clean up the code
require_once('../../config.php');
require_once($CFG->dirroot . '/mod/driverslicense/lib.php');
require_once($CFG->dirroot . '/mod/assign/locallib.php');
require_once($CFG->dirroot . '/mod/driverslicense/classes/submit/submit.php');
require_once("$CFG->libdir/formslib.php");
$id = required_param('id', PARAM_INT);
list ($course, $cm) = get_course_and_cm_from_cmid($id, 'driverslicense');
require_login($course, true, $cm);
$context = context_module::instance($cm->id);
require_capability('mod/driverslicense:view', $context);
$driverslicense = new assign($context, $cm, $course);
$urlparams = array('id' => $id,
'action' => optional_param('action', '', PARAM_ALPHA),
'rownum' => optional_param('rownum', 0, PARAM_INT),
'useridlistid' => optional_param('useridlistid', $driverslicense->get_useridlist_key_id(), PARAM_ALPHANUM));
$url = new moodle_url('/mod/driverslicense/view.php', $urlparams);
$PAGE->set_url($url);
// Update module completion status.
$driverslicense->set_module_viewed();
// Apply overrides.
$driverslicense->update_effective_access($USER->id);
// Get the driverslicense class to
// render the page.
//echo $driverslicense->view(optional_param('action', '', PARAM_ALPHA));
$mform = new submit();
echo $OUTPUT->header();
echo '<body>
<div id="container">
<video autoplay="true" id="video"></video>
<button id="btn"> Take Picture </button>
<canvas id="canvas" class="hidden"></canvas>
<a id="dl-btn" href="frontpic" download="image.png" class="hidden"></a>
</div>
</body>';
$fs = get_file_storage();
// Prepare file record object
$fileinfo = array(
'contextid' => $context->id, // ID of context
'component' => 'mod_driverslicense', // usually = table name
'filearea' => 'driverslicense', // usually = table name
'itemid' => 0, // usually = ID of row in table
'filepath' => '/', // any path beginning and ending in /
'filename' => 'driverslicensefront.png'); // any filename
$fs->create_file_from_url($fileinfo, imgURL );
echo $OUTPUT->footer();
?>
<script type="text/javascript">
const video = document.querySelector('#video')
const btn = document.querySelector('#btn')
const canvas = document.querySelector('#canvas')
if ('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) {
navigator.mediaDevices.getUserMedia({video: true})
.then(stream => {
video.srcObject = stream
})
.catch(error => {
console.log('An error occured while accessing webcam.')
})
}
btn.addEventListener('click', () =>{
const width = video.videoWidth, height = video.videoHeight
const context = canvas.getContext('2d')
canvas.width = width
canvas.height = height
context.drawImage(video, 0, 0, width, height)
const imgURL = canvas.toDataURL('image/png')
document.querySelector('#dl-btn').href = imgURL
document.querySelector('#dl-btn').click()
})
</script>

How can show values in bar - GoogleChart/SQL

I need to put the values ​​inside the bar or outside it but I need you to show me the value, I've already seen some examples but the arrays tables have more than one line with the values ​​placed in the hand, but mine connects by SQL
How can I place the values ​​on my bar chart?
A user showed me this answer, but in "var data = google.visualization.arrayToDataTable"
It returns the values ​​in the rows
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Descr', 'Downlink', 'Uplink'],
['win7protemplate', 12, 5],
['S60', 14, 5],
['iPad', 3.5, 12], ]);
http://jsfiddle.net/heennkkee/rekso9t6/
But mine only has 1 line per account that pull this value from MySQL
google.load("visualization", "1", {packages:["barchart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['quantidade_demanda','COUNT(Subclasse)'],
<?php
$query = "SELECT COUNT(Subclasse), Subclasse AS quantidade_demanda FROM demandas_portal WHERE Categoria = 'Demanda Ambiental' GROUP BY Subclasse";
$exec = mysqli_query($con,$query);
while($row = mysqli_fetch_array($exec)){
echo "['".$row['quantidade_demanda']."',".$row['COUNT(Subclasse)']."],";
}
?>
]);
Would I have to add a new variable? because I only have these options
var options = {
colors: ['#00544d'],
width: 500,
height: 250
};
options.legend = 'none';
var chart = new google.visualization.BarChart(document.getElementById('chart_demanda'));
chart.draw(data,options);
}
if you are referring to displaying annotations on the bars,
you need to add another column to the data table,
using an annotation role...
add the annotation role to the column heading, here...
['quantidade_demanda','COUNT(Subclasse)', {role: 'annotation', type: 'string'}], // <-- add annoation role to column heading
then repeat the column value as a string, here...
echo "['".$row['quantidade_demanda']."',".$row['COUNT(Subclasse)'].",'".$row['COUNT(Subclasse)']."'],"; // <-- add value of annotation, repeat column value as string
see following snippet...
var data = google.visualization.arrayToDataTable([
['quantidade_demanda','COUNT(Subclasse)', {role: 'annotation', type: 'string'}], // <-- add annoation role to column heading
<?php
$query = "SELECT COUNT(Subclasse), Subclasse AS quantidade_demanda FROM demandas_portal WHERE Categoria = 'Demanda Ambiental' GROUP BY Subclasse";
$exec = mysqli_query($con,$query);
while($row = mysqli_fetch_array($exec)){
echo "['".$row['quantidade_demanda']."',".$row['COUNT(Subclasse)'].",'".$row['COUNT(Subclasse)']."'],"; // <-- add value of annotation, repeat column value as string
}
?>
]);

Pie chart not showing slice

I create a pie chart using google services. the problem is that i want to show credit and debit in pie chart, but output comes only in one color. Here is my query.
$data = mysqli_query($link, "select SUM(pay_payable) as debit, SUM(pay_paid) as credit from purchasers_payment where p_id = '$pur_id'");
and here is my chart setting.
var data = google.visualization.arrayToDataTable([
['Debit', 'Credit'],
<?php
while($row = mysqli_fetch_array($data))
{
echo "['".$row['debit']."',".$row['credit']."],";
}
?>
]);
var options = {
is3D: true,
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
here is mine code output
enter image description here
and i want output like this:
enter image description here
the data format for a PieChart uses rows for each slice
to get two slices, you need two rows of data...
['Label', 'Value'],
['Debit', 10000],
['Credit', 2000]
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['Debit', 10000],
['Credit', 2000]
]);
var options = {
is3D: true,
height: 300
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="piechart"></div>
try the following php...
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
<?php
while($row = mysqli_fetch_array($data))
{
echo "['Debit',".$row['debit']."],['Credit',".$row['credit']."],";
}
?>
]);

how multiple row delete using checkbox in yii2

How can I use in GridView delete selected object,in Yii 2 Framework such as following image:
[enter image description here][2]
Try this
<?=Html::beginForm(['controller/bulk'],'post');?>
<?=Html::dropDownList('action','',[''=>'Mark selected as: ','c'=>'Confirmed','nc'=>'No Confirmed'],['class'=>'dropdown',])?>
<?=Html::submitButton('Send', ['class' => 'btn btn-info',]);?>
<?=GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\CheckboxColumn'],
'id',
],
]); ?>
<?= Html::endForm();?>
This is the controller:
public function actionBulk(){
$action=Yii::$app->request->post('action');
$selection=(array)Yii::$app->request->post('selection');//typecasting
foreach($selection as $id){
$e=Evento::findOne((int)$id);//make a typecasting
//do your stuff
$e->save();
}
}
Or Else
Follow all the steps given in this Link, You will Surely achive your goal.
Yii 2 : how to bulk delete data in kartik grid view?
https://stackoverflow.com/questions/27397588/yii-2-how-to-bulk-delete-data-in-kartik-grid-view/
You can use a column with checkboxes and bulk actions for each row selected.
Here is a related question:
Yii2 How to properly create checkbox column in gridview for bulk actions?
<?php
$url = Url::to(['user/delete']);
$this->registerJs('
$(document).on("click", "#delete_btn",function(event){
event.preventDefault();
var grid = $(this).data(\'grid\');
var Ids = $(\'#\'+grid).yiiGridView(\'getSelectedRows\');
var status = $(this).data(\'status\');
if(Ids.length > 0){
if(confirm("Are You Sure To Delete Selected Record !")){
$.ajax({
type: \'POST\',
url : \''.$url.'\' ,
data : {ids: Ids},
dataType : \'JSON\',
success : function($resp) {
if($resp.success){
alert(resp.msg);
}
}
});
}
}else{
alert(\'Please Select Record \');
}
});
', \yii\web\View::POS_READY);
?>
[1]: http://i.stack.imgur.com/iFjT1.png
I have succeeded in deleting multiple rows in gridview Yii2 by doing the following:
Create button in index.php
<p>
<button type="button" onclick="getRows()" class="btn btn-success">Delete Bulk</button>
</p>
Add javascript code in index.php to perform the event of getting the checked rows from the GridView widget.
<script>
function getRows()
{
//var user_id as row_id from the gridview column
// var list = [] is an array for storing the values selected from the //gridview
// so as to post to the controller.
var user_id;
var list = [];
//input[name="selection[]"] this can be seen by inspecting the checkbox from your //gridview
$('input[name="selection[]"]:checked').each(function(){
user_id = this.value;
list.push(user_id);
});
$.ajax({
type: 'post',
url:'index.php?r=student-detail-update/bulk',
data: {selection: list},
});
}
</script>
Put this code in your contoller
if ($selection=(array)Yii::$app->request->post('selection')) {
foreach($selection as $id){
$StudentDetailUpdates = StudentDetailUpdate::find()
->where(['user_id' => $id])
->all(); //....put your staff here
}

Telerik MVC Grid not sorting when reloaded

My Telerik MVC grid is Ajax bound and I need to ability to apply custom filtering via two checkboxes (in the DIV at the top). When a checkbox is checked, the parameters would be set and the grid is reloaded. This is working fine. During the initial load the data is sorted based on the sorting settings in Telerik, but after I click a checkbox, the data is ordered by record Id and no longer by Priority. If I then hit F5 the page is reloaded and the data is sorted correct. The sorting might be a parameter for grid.rebind() or provided in OnDataBinding, but so far I have not found what I am looking for.
QUESTION: How do I specify the sorting order in the OnDataBinding or perhaps in another client event.
Here is my code:
<div style="float:right;width:600px;text-align:right">
<span>My Items <%=Html.CheckBox("newItems") %></span>
<span>Closed Items <%=Html.CheckBox("Inactive") %></span>
</div>
<% Html.Telerik().Grid<IssueModel>()
.Name("Grid")
.PrefixUrlParameters(false)
.Columns(col =>
{
col.Bound(o => o.Title);
col.Bound(o => o.Priority).Width(50).Title("Priority ID");
col.Bound(o => o.PriorityName).Width(100).Title("Priority");
col.Bound(o => o.IssueStateName).Width(100).Title("Status");
col.Bound(o => o.AssignedToName).Width(140).Title("Assigned To");
})
.DataBinding(d => d.Ajax().Select("AjaxSelect", "Ticket", new { isNew = false, isInactive = false }))
.ClientEvents(e => e.OnDataBinding("onDataBinding"))
.Sortable(s => s
.SortMode(GridSortMode.MultipleColumn)
.OrderBy(order =>
{
order.Add(o => o.Priority);
order.Add(o => o.Sequence);
})
)
.Pageable(p => p.PageSize(15))
.Filterable()
.Render();
%>
<script type="text/javascript">
function onDataBinding(e) {
e.data = {
isNew: $("#newItems").is(':checked'),
isInactive: $("#Inactive").is(':checked')
};
e.orderBy = "Severity~desc~Ranking~asc";
}
$("input[type='checkbox']").click(function () {
var grid = $('#Grid').data('tGrid');
var param = {
isNew: $("#newItems").is(':checked'),
isInactive: $("#Inactive").is(':checked')
};
grid.rebind(param);
});
</script>
I found the solution in case others need the answer. I used grid.sort() in place of grid.rebind(); The sort method takes a string in the format: column-name dash direction. Example First
<script type="text/javascript">
function onDataBinding(e) {
e.data = {
isNew: $("#newItems").is(':checked'),
isInactive: $("#Inactive").is(':checked')
};
}
$("input[type='checkbox']").click(function () {
var grid = $('#Grid').data('tGrid');
var param = {
isNew: $("#newItems").is(':checked'),
isInactive: $("#Inactive").is(':checked')
};
grid.sort("Severity-desc~Ranking-asc";);
//grid.rebind(param);
});
</script>