Actually i want add dynamic charts in my laravel web-application
that reacts to changes in database..I am using lavacharts..I am able to create charts that work on data that i input through my code.
here is my controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use DB;
use App\Http\Controllers\Controller;
use Khill\Lavacharts\Laravel\LavachartsFacade as Lava;
class ratingscontroller extends Controller{
public function index(){
$stocktable = \Lava::DataTable();
$stocktable->addDateColumn('Day of Month')
->addNumberColumn('projected')
->addNumberColumn('official');
for($a = 1; $a < 30; $a++){
$stocktable->addRow([
'2015-10-' . $a, rand(800,1000), rand(800,1000)
]);
}
$chart = \Lava::AreaChart('MyStocks', $stocktable);
return view('welcome');
}}
Ok, I see thsi is a pretty old question but if there is still need for this here goes...
From what I see here you would need three things from your database; day_of_month, projected_value and official_value.
Lets say you have a table in the database that maps to an eloquent model Report.
You can now create your DataTable object as follows:
$stocktable = \Lava::DataTable();
$stocktable->addDateColumn('Day of Month')
->addNumberColumn('projected')
->addNumberColumn('official');
//$reports should be validated with number of days in month (ex. Feb has 28 days so you would have empty days and Jan has 31 so info for one day would be missing)
//for simplicities sake i won't do this here...
$reports = Report::whereBetween('day_of_month',[1,30])->get();
for($a = 1; $a < 30; $a++){
//I'm assuming here you only have one entry in your database per day of the month, if not you need to take this into account
$day = $reports->where('day_of_month')->first();
if($day){
$stocktable->addRow([
'2015-10-' . $a,
$day->projected_value,
$day->official_value
]);
}
\Lava::AreaChart('MyStocks', $stocktable);
}
With this your graph is filled with data in your database.
Hope this helps
Related
I've been working on trying to setup a blog archive for a blog site where the use clicks on a date and the corresponding posts appear. (see image) I understand I need to retrieve all my blog posts and sort by date, but the steps after that are foggy to me. Taking that data then sorting it by month/year and passing it to a template is the part I am having trouble with.
Can someone shed some light on what I am doing wrong or provide a simple working example?
What I have thus far:
public function archiveAction()
{
$em = $this->getDoctrine()->getManager();
// $query = $em->getRepository('AcmeProjectBundle:Blog')
// ->findAll();
$blogs = $em->getRepository('AcmeProjectBundle:Blog')
->getLatestBlogs();
if (!$blogs) {
throw $this->createNotFoundException('Unable to find blog posts');
}
foreach ($blogs as $post) {
$year = $post->getCreated()->format('Y');
$month = $post->getCreated()->format('F');
$blogPosts[$year][$month][] = $post;
}
// exit(\Doctrine\Common\Util\Debug::dump($month));
return $this->render('AcmeProjectBundle:Default:archive.html.twig', array(
'blogPosts' => $blogPosts,
));
}
You want to tell your archiveAction which month was actually clicked, so you need to one or more parameters to it: http://symfony.com/doc/current/book/controller.html#route-parameters-as-controller-arguments (I would do something like /archive/{year}/{month}/ for my parameters, but it's up to you.) Then when someone goes you myblog.com/archive/2014/04, they would see those posts.
Next, you want to show the posts for that month. For this you'll need to use the Doctrine Query builder. Here's one SO answer on it, but you can search around for some more that pertain to querying for dates. Select entries between dates in doctrine 2
I'm using Symfony2 and Doctrine.
I have a date field, here it is:
/**
* #ORM\Column(type="date")
*/
protected $date;
In my form I use a text field to avoid Chrome default datepicker, but I insert DateTime objects in the database:
if ($request->isMethod('POST')) {
$form->bind($request);
//Convert string date to DateTime object and send it to database as object
$dateObj = \DateTime::createfromformat('d-m-Y', $expense->getDate());
$expense->setDate($dateObj);
// ...
and then I want to find all items with a specific date:
public function findExpensesForDate($user, $date)
{
$q = $this
->createQueryBuilder('e')
->where('e.date = :date')
->andWhere('e.user = :user')
->setParameter('date', $date)
->setParameter('user', $user)
->getQuery();
return $q->getResult();
}
and call it like this:
$expenses_for_today = $this->repository->findExpensesForDate($this->user, $today);
which returns nothing when
$today = new /DateTime();
and returns the results when
$today_obj = new /DateTime();
$today = $today_obj->format('Y-m-d');
So why when I give the date as object this doesn't work? Isn't the reason to use date filed is to take advantage of quering with DateTime objects? I guess I'm missing something trivial and important, but I just can't see what, or I'm not understanding the situation quite well. My understanding is like this: the field is of type date, so I should insert DateTime objects in it and when quering I should also you DateTime objects. Can you please help me to fix this?
P.S.: I tried changing the field to datetime:
/**
* #ORM\Column(type="datetime")
*/
protected $date;
but there was no change.
And at all is it OK and good to query with string? Will I get the advantage of using objects when querying that way?
I think this is because a DateTime object is too much specific and have also hours, minutes and seconds, so it can't be equal to a registered date in database !
If you want to use DateTime objects, you need to get the date of the beginning of the day and the end date to get all results of the day ! You must compare an interval of dates to get all dates between it.
First, get the start and the end dates of the current day (to simplify, we will base the end date on the beginning of the next day, and we will exclude it in the request) :
$fromDate = new \DateTime('now'); // Have for example 2013-06-10 09:53:21
$fromDate->setTime(0, 0, 0); // Modify to 2013-06-10 00:00:00, beginning of the day
$toDate = clone $fromDate;
$toDate->modify('+1 day'); // Have 2013-06-11 00:00:00
And modify your method :
public function findExpensesForDate($user, $fromDate, $toDate)
{
$q = $this
->createQueryBuilder('e')
->where('e.date >= :fromDate')
->andWhere('e.date < :toDate')
->andWhere('e.user = :user')
->setParameter('fromDate', $fromDate)
->setParameter('toDate', $toDate)
->setParameter('user', $user)
->getQuery();
return $q->getResult();
}
That's all, it should work, here the script :
$expenses_for_today = $this->repository->findExpensesForDate($this->user, $fromDate, $toDate);
So you will get all the dates between the 2013-06-10 00:00:00 and the 2013-06-11 00:00:00 (excluded), so the results of the day !
As others have mentioned, thats due to the time in DateTime.
Yet why am I answering?
Because I want to make you aware of the $qb->expr()->between()function.
The following snippet is from my ReservationRepository where I need to find the reservations for a given date ($today). My reservations have both a dateFrom and a dateTo attribute.
if(null !== $today) {
$today0 = new \DateTime($today->format("Y-m-d"));
$today23 = new \DateTime($today->format("Y-m-d"));
$today0->setTime(0,0,0);
$today23->setTime(23,59,59);
$qb->where($qb->expr()->orX(
$qb->expr()->orX(
$qb->expr()->between('r.dateFrom', ':today0', ':today23'),
$qb->expr()->between('r.dateTo', ':today0', ':today23')
),
$qb->expr()->andX(
$qb->expr()->lte('r.dateFrom', ':today23'),
$qb->expr()->gte('r.dateTo', ':today0')
)
));
$qb->setParameter('today0', $today0);
$qb->setParameter('today23', $today23);
}
The function between() saves me two lines of code in this example, and I find it to be more readable.
I'm using insertRow to populate an empty spreadsheet, it starts off taking about 1 second to insert a row and then slows down to around 5 seconds after 150 rows or so.
Has anyone experienced this kind of behaviour?
There aren't any calculations on the data in the spreadsheet that could be getting longer with more data.
Thanks!
I'll try to be strict.
If you take a look at class "Zend_Gdata_Spreadsheets" you figure that the method insertRow() is written in a very not optimal way. See:
public function insertRow($rowData, $key, $wkshtId = 'default')
{
$newEntry = new Zend_Gdata_Spreadsheets_ListEntry();
$newCustomArr = array();
foreach ($rowData as $k => $v) {
$newCustom = new Zend_Gdata_Spreadsheets_Extension_Custom();
$newCustom->setText($v)->setColumnName($k);
$newEntry->addCustom($newCustom);
}
$query = new Zend_Gdata_Spreadsheets_ListQuery();
$query->setSpreadsheetKey($key);
$query->setWorksheetId($wkshtId);
$feed = $this->getListFeed($query);
$editLink = $feed->getLink('http://schemas.google.com/g/2005#post');
return $this->insertEntry($newEntry->saveXML(), $editLink->href, 'Zend_Gdata_Spreadsheets_ListEntry');
}
In short, it loads your whole spreadsheet just in order to learn this value $editLink->href in order to post new row into your spreadsheet.
The cure is to avoid using this method insertRow.
Instead, get your $editLink->href once in your code and then insert new rows each time by reproducing the rest of behaviour of this method. I.e, in your code instead of $service->insertRow() use following:
//get your $editLink once:
$query = new Zend_Gdata_Spreadsheets_ListQuery();
$query->setSpreadsheetKey($key);
$query->setWorksheetId($wkshtId);
$query->setMaxResults(1);
$feed = $service->getListFeed($query);
$editLink = $feed->getLink('http://schemas.google.com/g/2005#post');
....
//instead of $service->insertRow:
$newEntry = new Zend_Gdata_Spreadsheets_ListEntry();
$newCustomArr = array();
foreach ($rowData as $k => $v) {
$newCustom = new Zend_Gdata_Spreadsheets_Extension_Custom();
$newCustom->setText($v)->setColumnName($k);
$newEntry->addCustom($newCustom);
}
$service->insertEntry($newEntry->saveXML(), $editLink->href, 'Zend_Gdata_Spreadsheets_ListEntry');
Don't forget to encourage this great answer, it costed me few days to figure out. I think ZF is great however sometimes you dont want to rely on their coode too much when it comes to resources optimization.
I am trying to get weekly and monthly visitor totals with Google Analytics API for the last X years. I set:
metrics=ga:visitors
dimensions=ga:nthWeek (or nthMonth)
It returns the data I want:
0 week : 100 visitors
1 week : 200 visitors
2 week : 300 visitors
Only instead of week 0 I want it to be displayed as 01/01/2012. How do I convert Nth week (or month) to date?
I tried:
Passing ga:date as metrics (which would be a logical thing to do, similar to how it's done in SQL), but it doesn't recognize it as a valid metrics.
Passing ga:date as the second dimension prevents weekly grouping.
You don't mention what language you're using, so I don't know what sort of date-wrangling interfaces you have available to you, but ga:week,ga:year should provide you with the week of the year that you can plug in and allow you to build the date appropropriately. In PHP it might be something like the following:
<?php
// assuming use of the official PHP API for Google services, and
// that you've appropriately initialized the connection, and that
// you've chosen to "$client->setUserObjects(true)", and that you've
// initialized the necessary variables...
$results = $service->data_ga->get($analytics_id, $start_date, $end_date, 'ga:visitors',
array('dimensions' => 'ga:week,ga:nthWeek,ga:year'));
$columns = array();
foreach ($results->columnHeaders as $headidx => $col) {
$columns[$col->name] = $headidx;
}
$traffic = array();
foreach ($results->rows as $idx => $week) {
$date = new DateTime;
$date->setISODate($week[$columns['ga:year']], $week[$columns['ga:week']]);
$traffic[$week[$columns['ga:nthWeek']]] = array('date' => $date, 'visitors' => $week[$columns['ga:visitors']], 'visits' => $week[$columns['ga:visits']], 'pageviews' => $week[$columns['ga:pageviews']]);
}
ksort($traffic);
// $traffic now holds a sorted array of your week by week traffic, with the full
// date in the DateTime object that you can access and format however you please
?>
I'm trying to recreate the following in Zend Framework and am not sure how to do it:
DELETE FROM mytablename WHERE date( `time_cre` ) < curdate( ) - INTERVAL 4 DAY
I was thinking something like:
$table = $this->getTable();
$db = Zend_Registry::get('dbAdapter');
$db->delete($table, array(
'date(`time_cre`) < curdate() - interval 4'
));
Does that seem correct?
What is the best way to handle something like this?
EDIT: Ack! Sorry, I was adapting this from a SELECT I was using to test and didn't change the syntax properly when I pasted it in. I've edited the example to fix it.
Figured it out...
public function pruneOld($days) {
$table = $this->getTable();
$db = Zend_Registry::get('dbAdapter');
$where = $db->quoteInto("DATE(`time_cre`) < CURDATE() - INTERVAL ? DAY", $days);
return $table->delete($where);
}
$table gets an reference of the table I want to edit...
$db grabs an instance of the database adapter so I can use quoteInto()...
$where builds the main part of the query accepting $days to make things a bit more flexible.
Create an action to call this method... something like:
public function pruneoldAction() {
// Disable the view/layout stuff as I don't need it for this action
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
// Get the data model with a convenience method
$data = $this->_getDataModel();
// Prune the old entries, passing in the number of days I want to be older than
$data->pruneOld(2);
}
And now hitting: http://myhost/thiscontroller/pruneold/ will delete the entries. Of course, anyone hitting that url will delete the entries but I've taken steps not included in my example to deal with this. Hope this helps someone.
I usually do this to delete a row
$table = new yourDB;
$row = $table->fetchRow($table->select()->where(some where params));
$row->delete();
try:
$db->delete($table, array(
'date(time_cre) < ?' => new Zend_Db_Expr('curdate() - interval 4')
));