I have the following code:
var app = angular.module('mcmmo', ['ngGrid']);
app.controller('mcmmoCtrl', function($scope, $http) {
$scope.filterOptions = {
filterText: "",
useExternalFilter: true
};
$scope.totalServerItems = 0;
$scope.pagingOptions = {
pageSizes: [250, 500, 1000],
pageSize: 250,
currentPage: 1
};
$scope.setPagingData = function(data, page, pageSize){
var pagedData = data.slice((page - 1) * pageSize, page * pageSize);
$scope.myData = pagedData;
$scope.totalServerItems = data.length;
if (!$scope.$$phase) {
$scope.$apply();
}
};
$scope.getPagedDataAsync = function (pageSize, page, searchText) {
setTimeout(function () {
var data;
if (searchText) {
var ft = searchText.toLowerCase();
$http.get('stats.php').success(function (largeLoad) {
data = largeLoad.filter(function(item) {
return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
});
$scope.setPagingData(data,page,pageSize);
});
} else {
$http.get('stats.php').success(function (largeLoad) {
$scope.setPagingData(largeLoad,page,pageSize);
});
}
}, 100);
};
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
$scope.$watch('pagingOptions', function (newVal, oldVal) {
if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}
}, true);
$scope.$watch('filterOptions', function (newVal, oldVal) {
if (newVal !== oldVal) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}
}, true);
$scope.gridOptions = {
data: 'myData',
enablePaging: true,
showFooter: true,
totalServerItems: 'totalServerItems',
pagingOptions: $scope.pagingOptions,
filterOptions: $scope.filterOptions,
plugins: [new ngGridFlexibleHeightPlugin()]
};
});
Which pulls a very large load of JSON from a php file, that's stored in a database. Here are my json results.
[{"id":"1","user":"user1","lastlogin":"1402936307","skills":[{"taming":"4","mining":"534","woodcutting":"84","repair":"26","unarmed":"0","herbalism":"108","excavation":"219","archery":"10","swords":"75","axes":"24","acrobatics":"74","fishing":"403","alchemy":"0"}]
}
Here is the PHP that outputs this:
require_once('db.php');
error_reporting(1);
$getUsers = mysqli_query($db, 'SELECT * FROM mcmmo_users LIMIT 300');
$rows = array();
while ($r = mysqli_fetch_assoc($getUsers))
{
$skills = array();
$tempRow = $r;
$getSkills = mysqli_query($db, "SELECT * FROM mcmmo_skills WHERE user_id = '" . $r['id'] . "' LIMIT 300");
while ($r = mysqli_fetch_assoc($getSkills))
{
unset($r['user_id']);
$skills[] = $r;
}
$tempRow['skills'] = $skills;
$rows[] = $tempRow;
}
header('Content-Type: application/json');
echo json_encode($rows);
And this is what my grid currently looks like:
There is a couple of things wrong here:
I don't want the id or lastlogin columns.
I'd like to rename "users".
Instead of the "skills" column, I'd like for all of the data to be in it's own column, for example, taming and mining is it's own column with it's data in it's own row.
I'm not sure how to do that with this plugin though, any help would be appreciated!
Well, maybe changing the query string would be easy to handle it. Also by the time you navigate inside the query result, you can build your own array, just use an array with key as the name of the column.
$getUsers = mysqli_query($db, 'SELECT * FROM mcmmo_users LEFT JOIN mcmmo_skills ON mcmmo_users.id = mcmmo_skills.user_id');
$rows = array();
$cont = 0;
$userSkills = array();
while ($r = mysqli_fetch_assoc($getUsers))
{
$userSkills[$cont++] = array(
"Users" => $r['user'],
"Taming" => $r["taming"],
"Mining" => $r["mining"]
);
}
header('Content-Type: application/json');
echo json_encode($userSkills);
About Pagination
Try dirPagination at https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination
It's very simple to use it and saves a lot of time.
As one of the commenters has already suggested, you can specify different column definitions than you have received in your incoming data. When you define your grid options, you optionally specify the column definitions separately from the data displayed:
$scope.resultGridOptions = {
data: 'myData',
columnDefs: 'columndefs',
// other parameters....
Then you just need to define your columns to reference your incoming data as documented here (especially the field and displayName):
https://github.com/angular-ui/ng-grid/wiki/Defining-columns
In your case, something like
$scope.columndefs = [{field:'id', displayName:'Id'}, {field:'user', displayName:'User'}];
should only show the id and user columns with the headers Id and User. (unless I have a typo)
Just noticed the final column part of your question: I am not sure how to show so much information in the final column. ng-grid does not support variable grid height to my knowledge, so it would make it difficult unless you can figure out a way to really condense this information into a column, but I don't know enough about your domain to recommend anything that seems reasonable.
Related
I have some problem with showing data in datatable, the problem is when I using the query clause like where condition, the draw in datatable is had a null value but when I'm not using the where condition, the data will be display on my datatable, is anything wrong with my query in codeigniter?
model :
var $attendance = 'attendance';
var $employee = 'employee';
var $project = 'project';
var $column = [
null, 'attendance.no_reg', 'employee.name', 'project.project_name', 'project.project_code'
];
var $column_search = [
'attendance.no_reg', 'employee.name', 'project.project_name', 'project.project_code'
];
var $column_order = [
null, 'attendance.no_reg', 'employee.name', 'project.project_name', 'project.project_code'
];
private function _showDaily() {
$selectedValues = $this->input->post('selectedValues');
$this->db->select($this->column);
$this->db->from($this->attendance);
// $this->db->where("project_code", $selectedValues);
$this->db->join($this->employee, "attendance.no_reg = employee.no_reg");
$this->db->join($this->project, "attendance.project_id = project.id");
$this->db->group_by("attendance.no_reg");
// length table
$i = 0;
foreach ($this->column_search as $item) // initial looping for grouping insert a text search
{
error_reporting(0);
if ($_POST['search']['value']) { // if the datatable make a input search with POST method
if ($i === 0) { // initial first condition for first column
$this->db->group_start();
$this->db->like($item, $_POST['search']['value']);
} else {
$this->db->or_like($item, $_POST['search']['value']);
}
if (count($this->column_search) - 1 == $i) // condition if the text search value counting same with $i value then minus 1
$this->db->group_end();
}
$i++;
}
if (isset($_POST['order'])) {
$this->db->order_by($this->column_order[$_POST['order']['0']['column']], $_POST['order']['0']['dir']);
}
}
public function showsDaily()
{
$this->_showDaily();
$result = $this->db->get();
return $result->result();
}
If my explanation is incomprehensible, I apologize, and you can ask me again, Thank You
I have an MCU (ESP8266) with a temperature and humidity sensor.
The MCU sends the measurement data via MQTT to an MQTT broker running on my Synology NAS.
Also running on the NAS is an MQTT client (Node.js) that writes the received data to the MySQL database on the NAS.
Last but not least, a web server and PHP server are also running on the NAS.
Now I want to make a website to display the data from the db as a line chart.
Questions:
How can I populate Google line chart with data from mySQL database?
It's possible to use one single file (.php) to do this?
How can I manage a date range selection?
How can i select / deselect lines on the chart?
Here my answer to my question.
Since I have no big idea of the used programming languages, I had to search, read and test a lot of sources in the web to copy the result together :-)
I will extend it a bit in future, but for me it works perfectly.
I would like to present this solution here to help others get started.
However, there are certainly many ways to improve the code.
If someone wants to, I'd be happy about suggestions.
Complete File on Github.
https://github.com/DIYDave/MySQL-and-Google-Line-Chart
PHP. Read the data from the db and returns a JSON string to javascript
<?php
function getData(){
// Connect to MySQL (db Hostname/IP, user, password, database)
$link = new mysqli( '192.168.10.10', 'user', 'password', 'mymqttdb' );
if ( $link->connect_errno ) {
die( "Failed to connect to MySQL: (" . $link->connect_errno . ") " . $link->connect_error );
}
$start = $_GET['startDate']; // Get parameter from URL
$ende = $_GET['endDate']; // Get parameter from URL
if (!isset($endDate )){ // No end date? then actual for end
$endDate = date('Y-m-d H:i', time());
}
if (!isset($startDate )){ // No start date? then actual -1 day for start
$startDate = date('Y-m-d H:i', strtotime('-1 day', strtotime($ende)));
}
// Query in SQL ! add your own columns and database table name!
$query= "SELECT `DateTime`,`temperature`,`humidity` FROM `Chickenhouse` WHERE `DateTime` BETWEEN" . "'" . $startDate ."'" . "AND" . "'" . $endDate ."'";
$result = $link->query($query); // make db query
$rows = array();
$table = array();
$table['cols'] = array
(
array('label' => 'Date Time', 'type' => 'datetime'),
array('label' => 'Temperatur (°C)', 'type' => 'number'), // Select your label for the index
array('label' => 'Luftfeuchtigkeit (%)', 'type' => 'number') // Select your label for the index
);
while($row = mysqli_fetch_array($result)) // got to all the lines of the query result
{
$sub_array = array();
$date1 = new DateTime($row['DateTime']);
$date2 = "Date(".date_format($date1, 'Y').", ".((int) date_format($date1, 'm') - 1).", ".date_format($date1, 'd').", ".date_format($date1, 'H').", ".date_format($date1, 'i').", ".date_format($date1, 's').")";
$sub_array[] = array("v" => (string)$date2);
$sub_array[] = array("v" => $row["temperature"]);
$sub_array[] = array("v" => $row["humidity"]);
$rows[] = array("c" => $sub_array);
}
$table['rows'] = $rows;
$lineCount = count($rows); // Number of array fields (lines) to show in browser
return array(json_encode($table), $lineCount); // Make JSON from array and give it to the java script together with linecount
}
?>
CSS and HTML. More or less just for formatting and setting placeholders.
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.2.3/flatpickr.css">
<style>
*{font-family:Arial;}
.page-wrapper{ width:90%; margin:0 auto; }
input { border: 2px solid whitesmoke;border-radius: 12px; padding: 12px 10px; text-align: center; font-size: 16px; font-weight: bold; width: 250px;background: cornflowerblue; color: yellow;}
button { border: none; border-radius: 10px; text-align: center; padding: 12px 10px; cursor: pointer; font-weight: bold; background: cornflowerblue; color: white;}
</style>
</head>
<body>
<div class="page-wrapper"> </div>
<input type="text" style="float:left" id="rangeDate" placeholder="Select Timespan" data-input>
<br>
<p id="LineCount" > </p>
<div id="line_chart" style="width: 100%; height: 800px"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.2.3/flatpickr.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
Javascript. Google chart. Accepts the JSON data and displays it as a line diagram. Here are many options possible.
Details here: https://developers.google.com/chart/interactive/docs/gallery/linechart
// Setup and show Google line chart
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart(){
var data = new google.visualization.DataTable(<?php echo getData()[0]?>); // Call PHP-Function an receive JSON
document.getElementById("LineCount").innerHTML= " " + <?php echo getData()[1]?> + " Records loaded"; // Get record count
var options = {
series: {
0:{color: 'red', visibleInLegend: true, targetAxisIndex: 0},
1:{color: 'blue', visibleInLegend: true, targetAxisIndex: 1}
},
vAxes: {
// Adds labels to each axis; they don't have to match the axis names.
0: {title: 'Temp (°C)' }, // , 'minValue': 0, 'maxValue': 30
1: {title: 'Feuchte(%)'}
},
title:'Chickenhouse',
legend:{position:'top'},
chartArea:{width:'75%', height:'65%'},
//curveType: 'function',
hAxis: {
title: 'Datum', titleTextStyle: {color: '#333'},
format: 'd.M HH:mm',
slantedText:true, slantedTextAngle:80
},
explorer: {
actions: ['dragToPan', 'dragToZoom', 'rightClickToReset'], // 'dragToZoom'
axis: 'horizontal',
keepInBounds: true,
maxZoomIn: 28.0,
maxZoomOut: 1.0,
zoomDelta: 1.5
},
colors: ['#D44E41'],
};
var date_formatter = new google.visualization.DateFormat({ // Tooltip format
pattern: "dd.MM.yyyy - HH:mm"
});
date_formatter.format(data, 0);
var chart = new google.visualization.LineChart(document.getElementById('line_chart'));
chart.draw(data, options);
Javascript. Selection of displayed lines by clicking on the legend.
// Select / deselect lines by clicking on the label
var columns = [];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
if (i > 0) {
series[i - 1] = {};
}
}
google.visualization.events.addListener(chart, 'select', function () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (sel[0].row === null) {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function () {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
} else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
});
};
Javascript. Flatpickr. Cool javascript app to select date and time. It's also possible to select date ranges what I use here. https://flatpickr.js.org/
// Flatpickr to select date range
$("#rangeDate").flatpickr({
enableTime: false,
mode: 'range',
time_24hr: true,
dateFormat: "Y-m-d",
maxDate: "today",
defaulDate: "today",
onClose: function test(selectedDates, dateStr, instance){
arDateTime = dateStr.split(" to ");
dateTimeStart = arDateTime[0] + " 00:00" ;
dateTimeEnd = arDateTime[1] + " 23:59" ;
strNeu = "?startDate=" + dateTimeStart + "&endDate=" + dateTimeEnd;
window.location = strNeu;
},
});
Complete File on Github.
https://github.com/DIYDave/MySQL-and-Google-Line-Chart
Result:
Screenshot
I am using express and npm mysql (Link)
I want to do a call using
query('SELECT * FROM TABLE WHERE ?', where, cb)
where is a javascript object f.e. : {col1: 'one', col2: 'two'}
But it seems that this doesn't work. It works for SET though to update multiple columns at once.
I want a general method where I can send a different combination of columns to search. I was wondering if there is a built in method to do this.
Meanwhile, I created this script:
var andQuery = "";
var andParams = [];
var isFirst = true;
for (var filter in where) {
if (where.hasOwnProperty(filter)) {
if(!isFirst) {
andQuery += " AND ? ";
} else {
andQuery += " ? ";
isFirst = false;
}
andParams.push({[filter]: where[filter]});
}
}
db.query(
'SELECT * FROM `Table` WHERE ' + andQuery, andParams, (err, results) => {
I am trying to fetch records from mysql and render the data via amchart, but I am facing difficulty in doing so. I have written the following code which is not working. The query works fine but the problem is replacing the static (placeholder) data with the results of the query. Please suggest.
{
$selectdata="SELECT member_lhp, COUNT( * ) AS 'land_pattern' FROM hh_basic_info GROUP BY member_lhp";
$resdata=mysql_query($selectdata);
<script type="text/javascript">
var chart;
var chartData = [
<?php
$count=0;
while($rowdata = mysql_fetch_assoc($resdata))
foreach($rowdata as $rows){
$type= $rows['member_lhp'];
$lp=$rows['land_pattern'];
if($count++ > 0) echo ',';
?>
{
year: <?php echo $type;?>,
income: <?php echo $lp;?>
},
<?php } ?>
];
AmCharts.ready(function () {
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.dataProvider = chartData;
chart.categoryField = "year";
// this single line makes the chart a bar chart,
// try to set it to false - your bars will turn to columns
chart.rotate = true;
// the following two lines makes chart 3D
chart.depth3D = 20;
chart.angle = 30;
// AXES
// Category
var categoryAxis = chart.categoryAxis;
categoryAxis.gridPosition = "start";
categoryAxis.axisColor = "#DADADA";
categoryAxis.fillAlpha = 1;
categoryAxis.gridAlpha = 0;
categoryAxis.fillColor = "#FAFAFA";
// value
var valueAxis = new AmCharts.ValueAxis();
valueAxis.axisColor = "#DADADA";
valueAxis.title = "Villagers - Land holding pattern";
valueAxis.gridAlpha = 0.1;
chart.addValueAxis(valueAxis);
// GRAPH
var graph = new AmCharts.AmGraph();
graph.title = "Income";
graph.valueField = "income";
graph.type = "column";
graph.balloonText = "Land holding number in [[category]]:[[value]]";
graph.lineAlpha = 0;
graph.fillColors = "#bf1c25";
graph.fillAlphas = 1;
chart.addGraph(graph);
// WRITE
chart.write("chartdiv");
});
</script>
}
At a quick glance it looks like you may have included an extra comma after your curly bracket. You are already adding a comma via the PHP if your count is greater than 0 so this would have been introducing a second, unnecessary one between each group of data.
You had the following...
{
year: <?php echo $type;?>,
income: <?php echo $lp;?>
},
try just having this instead...
{
year: <?php echo $type;?>,
income: <?php echo $lp;?>
}
It seems you forgot to parse in json format,
Just write
var newchartData= JSON.parse(chartData);
now assign newcharData to DataProvider,it should work.
I want to display the data on a particular condition of the table after the user enters the data you want to display.
But always failed to display the data. I am confused where the fault lies.
It looks like the variable $thn = $ _POST['thn'], $bln = $ _POST['bln'], $periode = $ _POST['periode'] is empty.
please help.
I have four files.
Here the codes:
1.absen_xls.php:
<?php
include '../../inc/inc.koneksi.php';
ini_set('display_errors', 1); ini_set('error_reporting', E_ERROR);
include '../../excel/PHPExcel.php';
include '../../excel/PHPExcel/IOFactory.php';
$table = 'absen_karyawan';
$bln = $_POST['bln']; //this not work, I don't know why?
$thn = $_POST['thn']; //this not work, I don't know why?
$periode = $_POST['periode']; //this not work, I don't know why?
$where = "WHERE tahun = '$thn' AND bulan = '$bln' AND periode = '$periode'";
// Create new PHPExcel object
$objPHPExcel = new PHPExcel();
$sql = "SELECT namakaryawan,tahun,bulan,periode,absen FROM $table $where";
$query = mysql_query($sql);
// bold
$objPHPExcel->getActiveSheet()->getStyle("A2:C2")->applyFromArray(array("font" => array( "bold" => true)));
// Add some data
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A2', 'No')
->setCellValue('B2', 'Nama')
->setCellValue('C2', 'Kehadiran');
$baris = 3;
$no = 0;
while($row=mysql_fetch_array($query)){
$no = $no +1;
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue("A$baris", $no)
->setCellValue("B$baris", $row['namakaryawan'])
->setCellValue("C$baris", $row['absen']);
$baris = $baris + 1;
}
//border
$border = $baris - 1;
$styleArray = array(
'borders' => array(
'allborders' => array(
'style' => PHPExcel_Style_Border::BORDER_THIN
)
)
);
$objPHPExcel->getActiveSheet()->getStyle('A2:C'.$border)->applyFromArray($styleArray);
unset($styleArray);
//width
$objPHPExcel->getActiveSheet()->getColumnDimension("A")->setWidth(5);
$objPHPExcel->getActiveSheet()->getColumnDimension("B")->setWidth(20);
$objPHPExcel->getActiveSheet()->getColumnDimension("C")->setWidth(15);
//align center
$objPHPExcel->getActiveSheet()->getStyle('A2:C'.$border)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
// Rename sheet
$objPHPExcel->getActiveSheet()->setTitle('Absen');
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$objPHPExcel->setActiveSheetIndex(0);
// Redirect output to a client’s web browser (Excel5)
header('Content-Type: application/vnd.ms-excelformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="absen.xlsx"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
exit;
?>
2.ajax.php:
// JavaScript Document
$(document).ready(function(){
$(function(){
$('button').hover(
function() { $(this).addClass('ui-state-hover'); },
function() { $(this).removeClass('ui-state-hover'); }
);
});
$("#tampil_data").load('modul/lap-absen/tampil_data.php');
$("#print").click(function(){
var thn = $("#thn").val();
var bln = $("#bln").val();
var periode = $("#periode").val();
cetakabsen(thn,bln,periode);
});
function cetakabsen(c1,c2,c3){
var thn = c1;
var bln = c2;
var periode = c3;
$.ajax({
type : "POST",
url : "modul/lap-absen/absen_xls.php",
data : "thn="+thn+"&bln="+bln+"&periode="+periode,
success : function(data){
window.open('http://localhost/gudang/modul/lap-absen/absen_xls.php');
}
});
}
});
Change your function to this one:
function cetakabsen(c1,c2,c3){
var thn = c1;
var bln = c2;
var periode = c3;
var data = "thn="+thn+"&bln="+bln+"&periode="+periode;
window.open('http://localhost/gudang/modul/lap-absen/absen_xls.php?'+data);
}
And receive your values like this in absen_xls.php:
$bln = mysql_real_escape_string($_GET['bln']);
$thn = mysql_real_escape_string($_GET['thn']);
$periode = mysql_real_escape_string($_GET['periode']);
PS: Go for mysqli or PDO, dont use the mysql extension.