how to COUNT explode imploding data with comma? [duplicate] - php

This question already has answers here:
Is storing a delimited list in a database column really that bad?
(10 answers)
How to count items in comma separated list MySQL
(6 answers)
Closed 1 year ago.
I want to count the number of mechanics in a chart, but some data has multiple data which I use with implode (comma). how to separate data?
I'm taking data from one of my tables, where a column has a value that is implode. the problem here, I just want to explode **nama_tmp **(EKO PAMBUDI, MURNO, ARDI PRASETYO) separately so I can count each name.
The following query I use to display the table:
var chart4;
$(document).ready(function() {
chart4 = new Highcharts.Chart({
chart: {
renderTo: 'mygraph4',
type: 'column'
},
title: {
text: 'Grafik Mekanik'
},
xAxis: {
categories: ['Mekanik']
},
yAxis: {
title: {
text: 'Total Perbaikan'
}
},
series:
[
<?php
include "system/koneksi.php";
$sql = "SELECT nama_tmp FROM tb_tmp GROUP by nama_tmp";
$query = mysqli_query($connect, $sql) or die(mysqli_error());
while($temp = mysqli_fetch_array($query))
{
$namatmp=$temp['nama_tmp'];
$sql_total = "SELECT COUNT(nama_tmp) as 'total' from tb_tmp GROUP by nama_tmp = '$namatmp'";
$query_total = mysqli_query($connect,$sql_total) or die(mysql_error());
while($data = mysqli_fetch_array( $query_total))
{
$total = $data['total'];
}
?>
{
name: '<?php echo $namatmp; ?>',
data: [<?php echo $total; ?>]
},
<?php
} ?>
]
});
});
my database:

After looking at the image again, I can understand your problem. You basically need to prepare your data, instead of printing the PDF directly.
You could use a map to calculate your output like so:
$total = array("freq" => 0, "menit" => 0, "jam" => 0);
$groups = array();
while ($data = mysqli_fetch_array($query)) {
$names = explode(",",$data['nama_tmp']);
foreach ($names as $name) {
if (!array_key_exists($name, $groups)) {
$groups[$name] = array("freq" => 0, "menit" => 0, "jam" => 0);
}
$groups[$name]["freq"] += $data["freq"];
$groups[$name]["menit"] += $data["menit"];
$groups[$name]["jam"] += $data["jam"];
$total["freq"] += $data["freq"];
$total["menit"] += $data["menit"];
$total["jam"] += $data["jam"];
}
}
Now you should have all your data in $groups and you can generate your PDF from that.
foreach ($groups as $name => $group) {
$pdf->Ln();
$pdf->Cell(90,5,$name,1,0,'L',0);
$pdf->Cell(20,5,$group['freq'],1,0,'C',0);
$pdf->Cell(25,5,$group['menit'],1,0,'C',0);
$pdf->Cell(25,5,$group['jam'],1,0,'C',0);
}
$pdf->Ln(5);
$pdf->SetFillColor(255, 235, 255);
$pdf->SetFont('times','B',8);
$pdf->Cell(90,5,'TOTAL',1,0,'C',1);
$pdf->Cell(20,5,$total["freq"],1,0,'C',1);
$pdf->Cell(25,5,$total["menit"],1,0,'C',1);
$pdf->Cell(25,5,$total["jam"],1,0,'C',1);
Note: Instead of using a variable for every column sum, I have used a $total map array instead. This makes it more readable. Also you should consider using some functions for each part of your script.
The main function could then be as simple as this:
$data = readData();
$groups= calculateSums($data);
$pdf = generatePDF($groups);

Related

Loop through multiple rows as labels and data in chart.js and PHP

Using chart.js I want to create a graph of a given stock price.
The labels and data are fetched using the data from $select_query. Here I create a dynamic function that gets the ticker name from the URL: https://signal-invest.com/tick/?ticker=LOW
$select_query = $con->prepare("SELECT Date_buy, Name_buy, Price_buy FROM daily_buy_orders WHERE Name_buy = ?");
$select_query->bind_param('s', $ticker); // 's' specifies the variable type => 'string'
$select_query->execute();
I tried to loop through the rows using the while loop but failed.
<canvas id="myChart" style="border: 1px solid black; margin: 25px 25px" height="300"></canvas>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
//labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
labels: [<?php
$get_dates = $select_query->get_result();
while ($rows = mysqli_fetch_assoc($get_dates)) {
$dates = $rows["Date_buy"];
echo ''.$dates.'';
}
?>],
datasets: [{
label: '# of Votes',
//data: [12, 19, 3, 5, 2, 3],
data: [<?php
$get_prices = $select_query->get_result();
while ($rowss = mysqli_fetch_assoc($get_prices)) {
$prices = $rowss["Price_buy"];
echo ''.$prices.'';
}
?>],
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgb(75, 192, 192)',
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
</script>
Above code messes with my table below. When creating the tables the while loop actually works. I tried to use the same thinking when doing the while loops for the labels and data in chartjs, didn't work though.
<table style="width:50%" border="solid">
<tr>
<th>Name</th>
<th>Price</th>
<th>Date of signal</th>
</tr>
<?php
$result = $select_query->get_result();
while ($row = mysqli_fetch_assoc($result)) {
$name_buy = $row["Name_buy"];
$price_buy = $row["Price_buy"];
$date = $row["Date_buy"];
echo buy_table($name_buy, $price_buy, $date);
}
?>
</table>
Trying to dynamically build an array of JS with PHP code is never a good idea. Instead, build the array in PHP and the use json_encode to pass it to JS (or even better, use a templating engine and pass it in with data attributes, but's that a whole other topic)
Also, you are trying to loop the result multiple times, which I'm not sure is possible. It's been a long time since I used the native mysqli functions.
First, fetch the data and build the arrays you need to pass to Chart.js in PHP:
$statement = $con->prepare("SELECT Date_buy, Name_buy, Price_buy FROM daily_buy_orders WHERE Name_buy = ?");
$statement->bind_param('s', $ticker); // 's' specifies the variable type => 'string'
$statement->execute();
$result = $statement->get_result();
$dates = [];
$prices = [];
while ($row = $result->fetch_assoc()) {
$dates[] = $row['Date_buy'];
$prices[] = $row['Price_buy']
}
Now you can pass this to the chart in a much cleaner way:
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: <?php json_encode($dates); ?>,
datasets: [{
label: '# of Votes',
data: <?php json_encode($prices); ?>,
}]
}
}
I haven't tested this, but it gives you the idea
EDIT: This returns the following output:
"LOWArrayLOWArrayLOWArrayLOWArray". Where Name_buy is LOW, meaning the second print statement is bugged. How to solve this?
$arrDates = array();
$arrPrices = array();
$arrNames = array();
// $dates = [];
// $prices = [];
// $names = [];
$result = $select_query->get_result();
while ($row = mysqli_fetch_assoc($result)) {
$arrDates[] = $row['Date_buy'];
$arrPrices[] = $row['Price_buy'];
$arrNames[] = $row['Name_buy'];
print($row['Name_buy']);
print($arrNames);
}

Unable to display x-axis labels on multi-column mysql array in Highcharts

I have a mysql database containing multiple columns of power values captured over time, with time captured in the first column. I would like to plot the power values and display the time of day on the x-axis of a Highcharts chart. I am currently able to display the multiple Power values on the y-axis but I am unable to get the time of day to display on the chart. Here is the PHP code that partially works:
<?php
// Connect to database
$con = mysqli_connect("localhost","userid","passwd","power_readings");
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
// Set the variable $rows to the columns Energy_Date and Total_watts
$query = mysqli_query($con,"SELECT Energy_Date,Total_watts FROM combined_readings");
$rows = array();
$rows['name'] = 'Total_watts';
while($tmp = mysqli_fetch_array($query)) {
$rows['data'][] = $tmp['Total_watts'];
}
// Set the variable $rows1 to the columns Energy_Date and Power_watts
$query = mysqli_query($con,"SELECT Energy_Date,Power_watts FROM combined_readings");
$rows1 = array();
$rows1['name'] = 'Neurio_watts';
while($tmp = mysqli_fetch_array($query)) {
$rows1['data'][] = $tmp['Power_watts'];
}
// Set the variable $rows2 to the columns Energy_Date and Solar_watts
$query = mysqli_query($con,"SELECT Energy_Date,Solar_watts FROM combined_readings");
$rows2 = array();
$rows2['name'] = 'Solar_watts';
while($tmp = mysqli_fetch_array($query)) {
$rows2['data'][] = $tmp['Solar_watts'];
}
$result = array();
array_push($result,$rows);
array_push($result,$rows1);
array_push($result,$rows2);
print json_encode($result, JSON_NUMERIC_CHECK);
mysqli_close($con);
?>
Can someone tell me how to change the code to pass the values from the time of day column properly?
Here is what the chart currently looks like:
When I made changes to the PHP to add the 'Energy_Date' field to the array passed to Highcharts (shown below) it results in a blank chart.
The array consists of fields that look like this (a time stamp followed by a power reading, separated by period:
"2018-02-21 16:56:00.052","2018-02-21 16:59:00.052","2018-02-21 17:02:00.039","2018-02-21 17:05:00.039","2018-02-21 17:08:00.039"
<?php
// Connect to database
$con = mysqli_connect("localhost","userid","passwd","power_readings");
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
// Set the variable $rows to the columns Energy_Date and Total_watts
$query = mysqli_query($con,"SELECT Energy_Date,Total_watts FROM combined_readings");
$rows = array();
$rows['name'] = 'Total_watts';
while($tmp = mysqli_fetch_array($query)) {
$rows['data'][] = $tmp['Energy_Date'].$tmp['Total_watts'];
}
// Set the variable $rows1 to the columns Energy_Date and Power_watts
$query = mysqli_query($con,"SELECT Energy_Date,Power_watts FROM combined_readings");
$rows1 = array();
$rows1['name'] = 'Neurio_watts';
while($tmp = mysqli_fetch_array($query)) {
$rows1['data'][] = $tmp['Energy_Date'].$tmp['Power_watts'];
}
// Set the variable $rows2 to the columns Energy_Date and Solar_watts
$query = mysqli_query($con,"SELECT Energy_Date,Solar_watts FROM combined_readings");
$rows2 = array();
$rows2['name'] = 'Solar_watts';
while($tmp = mysqli_fetch_array($query)) {
$rows2['data'][] = $tmp['Energy_Date'].$tmp['Solar_watts'];
}
$result = array();
array_push($result,$rows);
array_push($result,$rows1);
array_push($result,$rows2);
print json_encode($result, JSON_NUMERIC_CHECK);
mysqli_close($con);
?>
The html receiving this array looks like this:
<!DOCTYPE html>
<html lang="en">
<title>Combined Values Graph</title>
<head>
<meta http-equiv="refresh" content="180">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
var x_values = [];
var chart;
$(document).ready(function() {
Highcharts.setOptions({
colors: ['#4083e9', '#99ccff', '#00ffff', '#e6e6e6', '#DDDF00', '#64E572', '#FF9655', '#FFF263', '#6AF9C4']
});
$.getJSON("values.php", function(json) {
chart = new Highcharts.Chart({
chart: {
renderTo: 'mygraph',
type : 'spline',
borderWidth: 1,
zoomType: 'x',
panning: true,
panKey: 'shift',
plotShadow: false,
marginTop: 100,
height: 500,
plotBackgroundImage: 'gradient.jpg'
},
plotOptions: {
series: {
fillOpacity: 1
}
},
plotOptions: {
series: {
marker: {
enabled: false
}
}
},
title: {
text: 'Combined Power Readings'
},
subtitle: {
text: 'Total = Neurio + Solar Readings in Watts'
},
xAxis : {
title : {
text : 'Time of Day'
}
},
yAxis: {
title: {
text: 'Power (watts)'
},
plotLines: [{
value: 0,
width: 2,
color: '#ff0000',
zIndex:4,
dashStyle: 'ShortDot'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
this.x +': '+ this.y;
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 120,
borderWidth: 1
},
plotOptions : {
spline : {
marker : {
radius : 0,
lineColor : '#666666',
lineWidth : 0
}
}
},
series: json
});
});
});
});
</script>
<script src="https://code.highcharts.com/highcharts.src.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
</head>
<body>
<div class="container" style="margin-top:20px">
<div class="col-md-10">
<div class="panel panel-primary">
<div class="panel-body">
<div id ="mygraph"></div>
</div>
</div>
</div>
</div>
</body>
</html>
I have added the console statement to the bottom of the js like so:
series: json
});
console.log(json);
});
Here's what is shown in the browser console for PHP version 1 (The version that displays the graphs).
Browser console 1
Here's what is shown in the browser console for PHP version 2 (The version that gives a blank chart).
Browser console 2
Thanks for your helpful suggestions. I have changed the while loops to look like this:
while($tmp = mysqli_fetch_array($query)) {
$rows['data'][] = $tmp['Energy_UTC'];
$rows['data'][] = $tmp['Total_watts'];
}
The output of the PHP now looks like this:
[{"name":"Total_watts","data":[1519315164,93,1519315344,354]},{"name":"Neurio_watts","data":[1519315164,76,1519315344,309]},{"name":"Solar_watts","data":[1519315164,17,1519315344,45]}]
The data being passed to Highcharts (from the console) now looks like this:
Browser console 3
The chart is still wrong: the x-axis is not showing the timestamps and the chart is incorrect. Can anyone suggest how to change the PHP or html to correct this?
OK, I have updated the while loops to look like this:
$query = mysqli_query($con,"SELECT Energy_UTC,Total_watts FROM combined_readings");
$rows = array();
$rows['name'] = 'Total_watts';
while($tmp = mysqli_fetch_array($query)) {
$rows['data'][] = [$tmp['Energy_UTC'],$tmp['Total_watts']];
}
The PHP output now looks like this:
[{"name":"Total_watts","data":[[1519387869,423],[1519388049,423],[1519388229,332],[1519388410,514],[1519388590,514]...
and the chart is now displaying UTC timestamps for each power value.
You are writing a large block of code with many duplicated components. I've taken the time to DRY your method. It is best practice to minimize calls to the database, so I've managed to combine your queries into one simple select.
Theoretically, you will only need to modify $colnames_labels to modify your HighChart. I have written inline comments to help you to understand what my snippet does. I have written some basic error checks to help you to debug if anything fails.
Code: (untested)
$colnames_labels=[
'Total_watts'=>'Total_watts',
'Power_watts'=>'Neurio_watts',
'Solar_watts'=>'Solar_watts'
];
$select_clause_ext=''; // declare as empty string to allow concatenation
foreach($colnames_labels as $colname=>$label){
$data[]=['name'=>$label]; // pre-populate final array with name values
// generates: [0=>['name'=>'Total_watts'],1=>['name'=>'Neurio_watts'],2=>['Solar_watts']]
$select_clause_ext.=",$colname";
// generates: ",Total_watts,Power_watts,Solar_watts"
}
$subarray_indexes=array_flip(array_keys($colnames_label)); // this will route resultset data to the correct subarray
// generates: ['Total_watts'=>0,'Power_watts'=>1,'Solar_watts'=>2]
if(!$result=mysqli_query($con,"SELECT UNIX_TIMESTAMP(Energy_Date) AS Stamp{$select_clause_ext} FROM combined_readings ORDER BY Energy_Date")){
$data=[['name'=>'Syntax Error (query error)','data'=>[0,0]]; // overwrite data with error message & maintain expected format
}elseif(!mysqli_num_rows($result)){
$data=[['name'=>'Logic Error (no rows)','data'=>[0,0]];
}else{
while($row=mysqli_fetch_assoc($result)){
foreach($subarray_indexes as $i=>$col){
$data[$i]['data'][]=[$row['Stamp'],$row[$col]]; // store [stamp,watts] data in appropriate subarrays
}
}
}
echo json_encode($data,JSON_NUMERIC_CHECK); // Convert to json (while encoding numeric strings as numbers) and print to screen

Formatting json data to work in Flot

Is there anyway to convert this json data:
[
{
"year":"1999",
"value":"3.0"
},
{
"year":"2008",
"value":"0.9"
}
]
to like this:
{
"data": [[1999, 3.0], [2008, 0.9]]
}
Check type of values ("3.0" and 3.0, string and integer).
I am having hard time to figure this out, or is it even possible.
This is how I get the json data:
I have "data" table in my database where are "year" and "value" columns, I get them from database like:
$sql = mysql_query("SELECT * FROM data");
$rows = array();
while($r = mysql_fetch_assoc($sql)) {
$rows[] = $r;
}
$encodedJson = json_encode($rows);
$encodedJson = json_encode($rows);
print $encodedJson;
I am trying to create a graph from my data, and json data must be formated properly to work in Flot.
All help is appreciated!
You could map your array of objects into an multidimensional array:
var mapped = originalData.map(function (obj) {
return [ parseInt(obj.year, 10), parseFloat(obj.value) ];
});
var newData = {
data: mapped
};
Possible solution
var a = [
{
"year":"1999",
"value":"3.0"
},
{
"year":"2008",
"value":"0.9"
}
];
var b = [];
$.each(a, function(_index, _item){
var c = [_item["year"], _item["value"]];
b.push(c);
});
console.log(b)
try this.
PHP:
$sql = mysql_query("SELECT * FROM data");
$rows = $sql->results_array();
$return_args = array();
foreach($rows as $row){
$tmp[0] = $row['year'];
$tmp[1] = $row['value'];
array_push($return_args,$tmp);
}
$encodedJson = json_encode($return_args);
print $encodedJson;

Having trouble passing data to Highcharts

I am trying to pull financial stock data of multiple companies from CSVs and display the data as separate series in a Highcharts/Highstocks line chart. I have the sources setup and I am able to pull data + convert to JSON, but I am having trouble passing the data off to Highcharts. I believe I am not using the most efficient method of preparing the data for Highcharts use, and I am hoping someone can give me direction on what I've done incorrectly. Please take a look at my code and make me aware of any inefficiencies or glaring errors you see.
PHP code:
date_default_timezone_set('America/Los_Angeles');
$stocks = array('MSFT' => 'http://ichart.finance.yahoo.com/table.csv?s=MSFT', 'AAPL' => 'http://ichart.finance.yahoo.com/table.csv?s=AAPL', 'FB' => 'http://ichart.finance.yahoo.com/table.csv?s=FB');
$stocks_data = array();
foreach ($stocks as $key=>$stock) {
$fh = fopen($stock, 'r');
$header = fgetcsv($fh);
$varname = $key . '_data';
$$varname = array();
while ($line = fgetcsv($fh)) {
${$varname}[count($$varname)] = array_combine($header, $line);
}
fclose($fh);
}
foreach($MSFT_data as $val){
$MSFT[] = strtotime($val['Date']) * 1000 . ', ' . (float)$val['Close']; //sets the date as a javascript timestamp
}
$MSFT = json_encode($MSFT);
foreach($AAPL_data as $val){
$AAPL[] = strtotime($val['Date']) * 1000 . ', ' . (float)$val['Close']; //sets the date as a javascript timestamp
}
$AAPL = json_encode($AAPL);
foreach($FB_data as $val){
$FB[] = strtotime($val['Date']) * 1000 . ', ' . (float)$val['Close']; //sets the date as a javascript timestamp
}
$FB = json_encode($FB);
JS code:
$(function () {
var seriesOptions = [],
yAxisOptions = [],
colors = Highcharts.getOptions().colors;
seriesOptions[0] = {
name: 'MSFT',
data: <? php echo $MSFT; ?>
};
seriesOptions[1] = {
name: 'AAPL',
data: <? php echo $AAPL; ?>
};
seriesOptions[2] = {
name: 'FB',
data: <? php echo $FB; ?>
};
function createChart() {
chart = new Highcharts.StockChart({
chart: {
renderTo: 'container'
},
rangeSelector: {
selected: 4
},
yAxis: {
labels: {
formatter: function () {
return (this.value > 0 ? '+' : '') + this.value + '%';
}
},
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}]
},
plotOptions: {
series: {
compare: 'percent'
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
valueDecimals: 2
},
series: seriesOptions
});
}
});
If you have any questions or need further information, please let me know with a comment.
Thanks
BTW: I have all necessary assets included for Highcharts to work; when I replace my JS + PHP with example code from the Highcharts site, it works beautifully. So the problem clearly lies in my JS + PHP code.
Alright, I believe I found the problem, it lies in the way that you are storing each individual point in the array.
Instead of this (which is passing a string x,y separated by a comma):
strtotime($val['Date']) * 1000 . ', ' . (float)$val['Close'];
You are going to want to use something like this (Highcharts accepts arrays or associative arrays):
array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
That will store the X and Y variables as an array instead of comma separated string for the javascript to pass as data.

How to get mysql data into a google chart using php loop?

I've created a Google chart and I've added data taken from the database itself. When getting data through php loops though, I have had some difficulty because I couldn't amend that data to the chart because of its syntax.
This is as far as I have gone. I need to get the mysql values in place of: 1170, 460, 45, 123, 456],
660, 1120, 145, 785, 658]
var data = google.visualization.arrayToDataTable([
['Term', <?php
while ($getchartrows = mysql_fetch_array($getchart))
{
echo " ' " . $getchartrows['std_ID'] . " ' " . ",";
}
?>],
<?php
$one = mysql_query("SELECT * FROM stusitting WHERE std_ID = '0001' AND subjectNo = '$subin' AND grade = '$gradein' AND termNo = '$tcheck' ");
$getone = mysql_fetch_array($one);
?>
['01', <?php echo $getone ['marks']; ?>, 400, 495, 565, 415],
['02', 1170, 460, 45, 123, 456],
['03', 660, 1120, 145, 785, 658]
]);
var options = {
title: 'Class Progress'
};
Try to tackle one problem after the other. First, get the data you need from the database. Then, create the data structure you need in PHP, and convert it to JavaScript using json_encode(). Finally, pass it to the visualization function in JavaScript:
<?php
// query data
$result = mysql_query(...);
// format data structure
$data = array();
$i = 0;
while($row = mysql_fetch_array($result)) {
$i += 1;
array_push($data, array($i) + $row);
}
// convert to JavaScript
?>
var raw_data = <?php echo json_encode($data) ?>;
// visualize
var data = google.visualization.arrayToDataTable(raw_data);

Categories