FLOT - Fluid / Dynamic Charts - PHP MYSQL - php

I am trying to Plot a Graph with FLOT but I cant get my head around how to get make it Dynamic with multiple series.
I am trying to get Race Data , Eg Laps and Time as the Graph x and y, but also trying to get the Race ID as a new series line for each Rider.
I have tried it at a Loop for each RaceID, and I have tried it as a multidimensional array, But I cant get my head around how to get it formatted to how FLOT wants it.
I can get it to work with 1 Rider:
$GetLapData = mysql_Query("SELECT LapData.*, u.RaceID
FROM `LapData`
left join User as u on LapData.TagID = u.TagID
Where LapData.EventID = '$EventID'
and LapData.RaceNameID = '$RaceNameID'
and LapData.TagID = '$RacingNumber'
ORDER BY `LapData`.`LapNumber` ASC");
while ($row = mysql_fetch_assoc($GetLapData))
{
$dataset1[] = array($row['LapNumber'],$row['LapTimeinSeconds']);
}
and then plot the single Data Set
$(function() {
var d1 = <?php echo json_encode($dataset1) ?>;
$.plot("#placeholder", [ d1 ]);
});
Any Ideas on making it all riders for the Race would be really helpful.

This is a tough question to answer without seeing your database scheme, but I'll give it a shot.
First, let's modify your SQL statement. I'm guessing that this part and LapData.TagID = '$RacingNumber' is what subset's it down to a single rider? Also, what's the purpose of the join, do you want the rider's name from there or some other identifier? I've left it but if you aren't using it, it's a waste...
$GetLapData = mysql_Query("SELECT LapData.TagID, LapData.LapNumber, LapData.LapTimeInSeconds
FROM LapData
LEFT JOIN User AS u ON LapData.TagID = u.TagID
WHERE LapData.EventID = '$EventID'
ANDLapData.RaceNameID = '$RaceNameID'
AND LapData.TagID = '$RacingNumber'
ORDER BY LapData.TagID, LapData.LapNumber ASC");
$allSeries = array(); // our "return value"
$currentSeries = null; // some temp variables
$currentRider = null;
while ($row = mysql_fetch_assoc($GetLapData))
{
$loopRider = $row['TagID']; // get rider for this database row
if ($currentRider === null || $loopRider != $currentRider) // if first loop or new rider
{
if ($currentSeries !== null)
{
$allSeries[] = $currentSeries; // we have a new rider push the last one to our return array
}
$currentSeries = array(); // this is first loop or new rider, re-init current series
$currentSeries["label"] = $loopRider;
$currentSeries["data"] = array();
}
$currentSeries["data"][] = array($row['LapNumber'],$row['LapTimeinSeconds']); //push row data into object
}
$allSeries[] = $currentSeries; // last rider's data push
In the end, allSeries is an array of associative arrays per flots documentation.
Mainly:
$allSeries = [{
"label" = "tag1",
"data" = [[0,12],[1,45],[2,454]]
},{
"label" = "tag2",
"data" = [[0,122],[1,415],[2,464]]
}]
After you Json encode this, the call is:
$.plot("#placeholder", allSeries);
My Standard PHP disclaimer, I'm not a PHP programmer, I've never used it and never ever want to use it. All the above code was peiced together from quickly reading the documentation and is untested.

Related

Mysql Data Only Pulling Last Result Into Json Array

I'm pulling multiple rows from a table and formatting them to this standard: 3 Swords, 5 Daggers, etc.
Well When I try to put that data into a json Array, It's only pulling the last result as this [{"weapons":"You Used: 3 Rusty Dagger's, "}] Which it should say: [{"weapons":"You Used: 3 Rusty Dagger's, 2 Swords"}]
Here's The Query I'm currently using, Which will show perfectly inside of the while loop:
$get_weapons = mysql_query("SELECT
O.player_id,
O.item_id,
O.name,
O.attack,
O.defense,
O.type,
O.owned,
(SELECT
sum(owned) FROM items_owned
WHERE owned <= O.owned AND player_id=$id) 'RunningTotal'
FROM items_owned O
HAVING RunningTotal <= $mob_avail
ORDER BY attack DESC");
// Get Weapon Info
while($weapon = mysql_fetch_array($get_weapons)){
$weapon_id = $weapon['item_id'];
$weapon_name = $weapon['name'];
$weapon_attack = $weapon['attack'];
$weapon_defense = $weapon['defense'];
$weapon_owned = $weapon['owned'];
// Formatting Weapons Message
$weapon_message = 'You Used: '.$weapon_owned.' '.$weapon_name.'\'s, ';
}
$data[] = array('weapons'=>$weapon_message);
echo json_encode($data);
I understand that the $data array is outside of the while loop, But I'm only needing a total of one arrays, so I'm kind of stuck on what to do to fix this issue. Any help would be awesome
You should add one static variable before append the results into the message.
Here is the reference answer:
$get_weapons = mysql_query("SELECT O.player_id, O.item_id, O.name, O.attack, O.defense, O.type, O.owned, (
SELECT sum(owned) FROM items_owned WHERE owned <= O.owned AND player_id=$id) 'RunningTotal' FROM items_owned O HAVING RunningTotal <= $mob_avail ORDER BY attack DESC");
// Initialize the message
$weapon_message = 'You Used: ';
// Get Weapon Info
while($weapon = mysql_fetch_array($get_weapons)){
$weapon_id = $weapon['item_id'];
$weapon_name = $weapon['name'];
$weapon_attack = $weapon['attack'];
$weapon_defense = $weapon['defense'];
$weapon_owned = $weapon['owned'];
// Formatting Weapons Message
$weapon_message = $weapon_message.$weapon_owned.' '.$weapon_name.'\'s, ';
}
$data[] = array('weapons'=>$weapon_message);
echo json_encode($data);

Query 2 tables and combine data in a single array

I am trying to combine the results from 2 queries into a single array but am having problems getting the correct code.
I have a table called PrimaryEvents that I query to add to an array. This query works ok:
$rows = query("SELECT * FROM PrimaryEvents WHERE unit = ? ORDER BY event", $unit);
I add the data to an array using the following:
foreach ($rows as $row)
{
// $event = lookup($row["event"]); (removed as spotted by sergio not required)
$event["event"] = $row["event"];
$event["validity"] = $row["validity"];
$event["eventsrequired"] = $row["eventsrequired"];
$event["unit"] = $row["unit"];
$event["role"] = $row["role"];
//now we have the data lets try and do something to it
if ($event["role"] == "0")
{
//then the user is active so change value to a YES
$event["role"] = "ALL";
}
//add our stock to the portfolio array
$portfolio[] = $event;
}
So far everything works well. I would like to query a separate table and add certain results to the array portfolio[];
$rowsCompleted = query("SELECT * FROM portfolio WHERE id = ? ORDER BY name", $_SESSION["id"]);
My original plan was to use the following additional code to add the data of interest to the portfolio[] but it doesn't work:
//now add individual stats to the array
foreach($rowsCompleted as $row)
{
if ($portfolio["event"] == $row["name"]
{
//then add our number and date to the array
$portfolio["datecompleted"] = $row["datecompleted"];
$portfolio["number"] = $row["number"];
}
//else do nothing
}
My final aim was to pull the datacompleted value and number value from the portfolio table and then add it to the array ONLY if the event name matches the name in portfolio array.
Hopefully I have described my problem and required behaviour well enough.
Thanks for nay help that can be offered, I am new to php/sql so learning as I go.
Andy
EDIT:
Also tried the following loop to try and loop through the array:
//now add individual stats to the array
foreach($rowsCompleted as $row)
{
foreach ($portfolio["event"] as $item)
{
if ($portfolio["event"] == $row["name"]
{
//then add our number and date to the array
$portfolio["datecompleted"] = $row["datecompleted"];
$portfolio["number"] = $row["number"];
}
}
//else do nothing
}
EDIT2: To try and make my question more clear: The Primary-events table lists all the events a specific user has to complete. The portfolio table tracks which events have been completed by the user (by means of date-completed and number).
I want to run a query that lists all the events from Primary-events, then into those results add the date-completed and number from the users portfolio. If the answer is blank from the portfolio then the user has not yet completed the event but I would still like to list it from the Primary-events table data.
I tried 2 queries to start with as it seemed to follow what I was trying to achieve.
EDIT3:
New code with help from Barmar
foreach ($rows as $row) {
$event = lookup($row["event"]);
$event["event"] = $row["event"];
$event["validity"] = $row["validity"];
// $event["datecompleted"] = $row["datecompleted"];
// $event["number"] = $row["number"];
$event["eventsrequired"] = $row["eventsrequired"];
$event["unit"] = $row["unit"];
$event["role"] = $row["role"];
//now we have the data lets try and do something to it
if ($event["role"] == "0") {
//then the user is active so change value to a YES
$event["role"] = "ALL";
}
//add our stock to the portfolio array
$portfolio[] = $event;
//now add individual stats to the array
foreach ($rowsCompleted as $row) {
foreach ($portfolio as &$item) {
if ($item["event"] == $row["name"]) {
//then add our number and date to the array
$item["datecompleted"] = $row["datecompleted"];
$item["number"] = $row["number"];
}
}
}
}
The page still isn't being displayed by chrome so guessing i've missed something.
EDIT4: Page displayed, I am now getting undefined index errors when the table is rendered on the html page.
Specifically the undefined index errors are for date-completed and number. I am taking it to mean that these values are not being added to the portfolio array? Do try and help I have added an Else statement (as below) to ensure that even if the event isn't available the index is:
//now add individual stats to the array
foreach($rowsCompleted as $row)
{
foreach ($portfolio as &$item)
{
if ($item["event"] == $row["name"])
{
//then add our number and date to the array
$item["datecompleted"] = $row["datecompleted"];
$item["number"] = $row["number"];
}
else
{
$item["datecompleted"] = "Never";
$item["number"] = "0";
}
}
}
EDIT 5: Near Success. Sorry to reopen this but I have just noticed behaviour I wasn't expecting: The nested loop only sets the date-completed and number for the first value to matches from the portfolio table. The follow on values are not set. It would seem like the nested loop isn't stepping through all of the portfolio values, and just exiting once the first "event" == "name".
EDIT 6: Sample data and clarification on desired functions:
portfolio sample data
|id|name |number|datacompleted
|21|event1 |3 |2014-07-07
|15|event1 |5 |2014-07-05
|21|event2 |5 |2014-05-08
|15|event1 |1 |2013-05-05
id is the id of the user that completed the event
number is the number of events completed
PrimaryEvents sample data
|id|event |validity|eventsrequired
|1 |event1 |7 |10
|1 |event2 |25 |1
|1 |event3 |12 |50
id is the id of the user that created the entry (used for historic purpose only)
The desired functionality is:
The query should create a an array to allow a html table to be created of everything within the Primary-events table. This table lists the events the user must complete.
The second query or current nested loop should gather the data from the portfolio table for the current user id, then match the event name to the name in the Primary-events array and update (if present) the number and date-completed value. (I.E populate the data for the events that the user has completed).
The current code merges the data from portfolio only for the first match, but then the nested loop seems to exit.
Hopefully this is a more clear description of what I am trying to achieve.
EDIT: I have changed the functionality to use the Left join statement below but am still having problems:
The table only contains some of the events from primary-events table and not all of them. The events being pulled over are only those that the user has completed, the ones the user has not yet completed are not being shown.
EDIT: This query seems to work:
$allEvents = query("SELECT * FROM PrimaryEvents LEFT JOIN portfolio ON (PrimaryEvents.event = portfolio.name) WHERE PrimaryEvents.event = ? AND (portfolio.id = ? Or portfolio.id is null) ORDER BY PrimaryEvents.event", $currentEvent, $_SESSION["id"]);
You need to notice that portfolio is not associative array but multidimensional array, so you cannot access it using $portfolio["event"]. You should use $portfolio[0]["event"], $portfolio[1]["event"] and so on.
It's hard to show you exact solution because I don't know how those arrays/database queries should be merged.
EDIT
It seems your query should look like this:
query("SELECT * FROM PrimaryEvents e LEFT JOIN portfolio p ON e.event = p.name WHERE e.unit = ? AND p.id = ? ORDER BY e.event", $unit,$_SESSION["id"]);
EDIT2
I haven't proposed nested loop (as it's now in modified question) because of performance loss.
You're getting closer with your second query, but still confused about what's in each array.
foreach($rowsCompleted as $row)
{
foreach ($portfolio as &$item) // Need to use reference so we can update it
{
if ($item["event"] == $row["name"])
{
//then add our number and date to the array
$item["datecompleted"] = $row["datecompleted"];
$item["number"] = $row["number"];
break;
}
}
}
To avoid the nested loop, it would be better for $portfolio to be an associative array. Change the code for your initial query to use:
//add our stock to the portfolio array
$portfolio[$event["name"]] = $event;
Then the second loop becomes:
foreach($rowsCompleted as $row)
{
$name = $row["name"];
if (isset($portfolio[$name]) {
$portfolio[$name]["datecompleted"] = $row["datecompleted"];
$portfolio[$name]["number"] = $row["number"];
}
}

PHP / Zend / Google Spreadsheet not getting all rows

I am trying to get all the rows from a Google spreadsheet via a PHP/Zend script. This is the script I am using:
$service = Zend_Gdata_Spreadsheets::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient('xxxxxxxxx', 'xxxxxxx', $service);
$spreadsheetService = new Zend_Gdata_Spreadsheets($client);
// Get spreadsheet key
$spreadsheetsKey = 'xxxxxxxxxxxxx';
$worksheetId = 'xxx';
// Get cell feed
$query = new Zend_Gdata_Spreadsheets_CellQuery();
$query->setSpreadsheetKey($spreadsheetsKey);
$query->setWorksheetId($worksheetId);
$cellFeed = $spreadsheetService->getCellFeed($query);
// Build an array of entries:
$ssRows = array();
$ssRow = array();
$titleRow = array();
$tableRow = 1;
foreach($cellFeed as $cellEntry) {
$row = $cellEntry->cell->getRow();
$col = $cellEntry->cell->getColumn();
$val = $cellEntry->cell->getText();
// Add each row as a new array:
if ($row != $tableRow) {
array_push($ssRows, $ssRow);
$ssRow = array();
// Move to the next row / new array
$tableRow = $row;
}
// Build the array of titles:
if ($row == 1) {
$titleRow[$col] = $val;
}
// Build the array of results with the title as the key:
else {
$key = $titleRow[$col];
$ssRow[$key] = $val;
}
}
// Pass the results array:
return array_reverse($ssRows);
This builds me an array with MOST of the details from the spreadsheet, however it always misses off the last entry - can anyone see what I am doing wrong, or is there a better way to get all the data from the spreadsheet?
The form is a 3 part form, based on different answers. On filling out one part, I want to display a URL back to the form, with some details from the first form pre-filled to make the second part of the form faster to fill out. This is all fine, it is simply the missing last entry that is the major problem!
Thanks!
Your code works like this:
if (next_row) {
data[] = current_row
current_row = array();
}
if (first_row) {
title_row logic
} else {
add cell to current_row
}
So you only add the rows to your collector once you go to the next row. This will miss the last row because you'll miss that last transition.
The easy fix is to add array_push($ssRows, $ssRow); right after the foreach loop. You will need to add a check for 0 rows, this should be skipped then.
Perhaps a more proper fix is to iterate by row, then by cell, rather than just by cell.

Populating PHP array from MySQL for use by Amcharts

I'm trying to set up some simple Amcharts graphs for a company intranet webpage. Over the last two weeks I have created HTML/JS and produced a nice graphic using Amcharts (data hard-coded in the HTML for demo purposes). I also installed XAMPP and created a MySQL database, populated with tables and some data that gets imported from csv files.
So far, everything is working fine - I can display nice graphics and I can collect the data for supplying data to the graphs. However, I have been approaching this problem from the 2 ends (getting the source data into a database AND presenting the data in a graph on a webpage). Now I need to join these 2 ends, so I can feed Amcharts with data from MySQL.
I know I need to use PHP to get the data from MySQL and put this into an array that can be used by Amcharts but my PHP knowledge is very basic and I'm struggling with the code.
What I have is PHP code which successfully connects to MySQL and extracts data to display in a browser - that works. I just don't know how to get that data into a multi-dimensional array in the format that Amcharts needs for plotting its graph.
It would be really great if you guys could give me some help here and fill in the missing pieces. I have some pseudo code for the logic of creating the array as the basis for the 'real' php code.
This is the pseudo code for populating the array:
;charset=UTF-8', '', '', array(PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$stmt = $db->query("SELECT * FROM <mytable> WHERE <mycondition>");
$prevweek = "9999";
$headrowdone = 0;
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if ($prevweek < $row['WeekNumber']) {
// New week so write out Category X Label ('Week') with the week number of the following data rows
chartData.push($DataRow);
$headrowdone = 0;
}
if (!$headrowdone) {
$DataRow = "Week: "+$row['WeekNumber'];
$headrowdone = 1;
}
// Write out the X-Axis Category value and the Y-Axis value
$DataRow = $DataRow+$row['XAxisCategory']+": "+$row['YAxisCategory'];
$prevweek = $row['WeekNumber'];
}
chartData.push($DataRow); ?>
The SQL table looks like:
CREATE TABLE ( WeekNumber varchar(4), XAxisCategory
varchar(50), YAxisValue integer );
and has data like: '1301','A',10 '1301','B',20 '1301','C',24
'1302','A',11 '1302','B',22 '1302','C',27 '1303','A',14 '1303','B',23
'1303','C',28 ...etc
The data array for amcharts needs to look like:
var chartData = [{ Week: "1301",
A: 10,
B: 20,
C: 24
}, {
Week: "1302",
A: 11,
B: 22,
C: 27
}, {
Week: "1303",
A: 14,
B: 23,
C: 28
....etc
}];
// This is spoofing your fetch via pdo
$rows [] = array('WeekNumber'=>1301, 'A'=>10);
$rows [] = array('WeekNumber'=>1301, 'B'=>20);
$rows [] = array('WeekNumber'=>1301, 'C'=>25);
$rows [] = array('WeekNumber'=>1302, 'A'=>12);
$rows [] = array('WeekNumber'=>1302, 'B'=>22);
$rows [] = array('WeekNumber'=>1302, 'C'=>27);
//var_dump($rows);
// set up some vars
$lastweek = '';
$ctr = 0;
$data = array();
// loop thru the vars, build another array
foreach( $rows as $row){
if($row['WeekNumber'] !== $lastweek){
$ctr++;
$data[$ctr] = array('Week'=>$row['WeekNumber']);
$lastweek= $row['WeekNumber'];
}
// this could be nicer, but for now will do
if( isset($row['A']) ) $data[$ctr]['A'] = $row['A'];
if( isset($row['B']) ) $data[$ctr]['B'] = $row['B'];
if( isset($row['C']) ) $data[$ctr]['C'] = $row['C'];
}
var_dump($data);
Then use json_encode() to get into the format you want.
This answer is a bit kludgy, but at least gets away from building strings to make json.

foreach php-smarty help

I have the php script as follows :
$sql = "
SELECT
*
FROM
tbl_messages
WHERE
msg_sender_id = '$this->UM_index'
";
$res = $this->db->returnArrayOfObject($sql);
$this->assign_values('sent_messages',$res);
And in the templates I retrieved :
{foreach name = feach key = indx item = k from = $sent_messages}
{$k->msg_sender_id}
{$k->msg_subject}
{/forach}
I can retriev the above two fields. But I want to retrieve the message_sender_name for the field sender_id which can be obtained from a function getDetails($id).
My question is how can I assign the sender_name fields (which is a array) to my smarty template?
So you want also want to be able to have the message_sender_name, wich is returned by the function getDetails($id)?
You will have to loop trough your results, and fetch the message_sender_name for each row. Something like this:
$arrResults = array();
while ($res = $this->db->returnArrayOfObject($sql)))
{
$res['msg_sender_name'] = getDetails($res['msg_sender_id']);
$arrResults[] = $res;
}
$this->assign_values('sent_messages',$arrResults);
If I'm right, you can now access the sender_name via {$k->msg_sender_name} in your template-file.
But I would suggest that you use a JOIN in your SQL-statement, so you don't have to make another request for the sender_name.

Categories