Realtime bandwidth monitor with PHP/flot - php

I found cool realtime bandwidth monitor here: http://www.codejungle.org/site/Realtime+bandwidth+meter+with+php+and+jquery.html
What I tried to do is to modify the code so that it could show two series: download and upload speed.
I changed only the last few lines of code in data.php:
echo '[
{
label: "download",
data: ['.implode($_SESSION['rx'], ",").']
},
{
label: "upload",
data: ['.implode($_SESSION['tx'], ",").']
}
];';
But unfortunately it doesn't work, what's wrong with this piece of code?

Loose the outer brackets (they are already in the onDataReceived function) and the semicolon at the end:
echo '
{
label: "download",
data: ['.implode($_SESSION['rx'], ",").']
},
{
label: "upload",
data: ['.implode($_SESSION['tx'], ",").']
}
';

Related

Highcharts Data Not Showing on Ajax Call

I am working on Highcharts using PHP/MYSQL. Data is showing properly in each chart but I tried to change one chart to ajax call in order to reduce page load.
I am generating multiple series data from PHP and displaying them back in the required format but data is not showing(I alerted the data it's coming).
Below is the code of ajax call:
function project_wise_lab(from_date, to_date) {
$.ajax({
type: "POST",
url: 'dashboard/project_wise_labtest',
data: {
from_dte: from_date,
to_dte: to_date
},
success: function(response) {
Highcharts.chart('subcontainer7', {
chart: {
type: 'line',
height: 230,
},
credits: {
enabled: false
},
title: {
text: null
},
xAxis: {
categories: ['Oct 2020', 'Nov 2020', 'Dec 2020', 'Jan 2021', 'Feb 2021', 'Mar 2021', 'Apr 2021', 'May 2021']
},
yAxis: {
min: 0,
title: {
// text: 'Total fruit consumption'
},
stackLabels: {
enabled: false,
style: {
fontWeight: 'bold',
color: ( // theme
Highcharts.defaultOptions.title.style &&
Highcharts.defaultOptions.title.style.color
) || 'gray'
}
}
},
legend: {
align: 'center',
verticalAlign: 'bottom',
backgroundColor: Highcharts.defaultOptions.legend.backgroundColor || 'white',
borderColor: '#CCC',
// borderWidth: 1,
shadow: false
},
tooltip: {
/* headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
*/
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
// enabled: true
}
}
},
colors: [
'#4a7fbb',
'#be4c48',
'#97b954',
'#7d6096'
],
series: response
});
console.log(response);
},
error: function(xhr, status, error) {
console.error(xhr);
}
});
}
I have alerted the response and the data is showing in the below format:
{ name : 'FKI',data : [10591,10576,9309,8422,9586,11171,9327,9384] },{ name : 'FKR',data : [4740,3105,2690,3598,3686,4930,3711,3859] },{ name : 'FHR',data : [17190,12757,10837,11944,14083,15748,12544,12494] },{ name : 'FUL',data : [1308,937,1002,1086,1452,1419,1248,1362] },{ name : 'FSW',data : [9535,9102,8689,8420,9941,10915,7273,6930] },{ name : 'FWP',data : [47437,42198,43012,44979,47377,55400,46520,41682] },{ name : 'FGR',data : [2112,1366,1619,1664,2387,2355,1633,1215] }
New Response after update:
[{"name":"FKI","data":{"01-OCT-20":"10591","01-NOV-20":"10576","01-DEC-20":"9309","01-JAN-21":"8422","01-FEB-21":"9586","01-MAR-21":"11171","01-APR-21":"9332","01-MAY-21":"9384"}},{"name":"FKR","data":{"01-OCT-20":"4740","01-NOV-20":"3105","01-DEC-20":"2690","01-JAN-21":"3598","01-FEB-21":"3686","01-MAR-21":"4930","01-APR-21":"3711","01-MAY-21":"3859"}},{"name":"FHR","data":{"01-OCT-20":"17190","01-NOV-20":"12757","01-DEC-20":"10837","01-JAN-21":"11944","01-FEB-21":"14083","01-MAR-21":"15748","01-APR-21":"12544","01-MAY-21":"12494"}},{"name":"FUL","data":{"01-OCT-20":"1308","01-NOV-20":"937","01-DEC-20":"1002","01-JAN-21":"1086","01-FEB-21":"1452","01-MAR-21":"1419","01-APR-21":"1248","01-MAY-21":"1362"}},{"name":"FSW","data":{"01-OCT-20":"9535","01-NOV-20":"9102","01-DEC-20":"8689","01-JAN-21":"8420","01-FEB-21":"9941","01-MAR-21":"10915","01-APR-21":"7273","01-MAY-21":"6930"}},{"name":"FHP","data":{"01-OCT-20":"47437","01-NOV-20":"42198","01-DEC-20":"43012","01-JAN-21":"44979","01-FEB-21":"47377","01-MAR-21":"55400","01-APR-21":"46520","01-MAY-21":"41682"}},{"name":"FGR","data":{"01-OCT-20":"2112","01-NOV-20":"1366","01-DEC-20":"1619","01-JAN-21":"1664","01-FEB-21":"2387","01-MAR-21":"2355","01-APR-21":"1633","01-MAY-21":"1215"}}]
The chart is showing empty, kindly help and let me know to get the issue resolve?
Thanks
You appear to have two problems...
jQuery is interpreting your response as plain text (a string) where Highcharts expects actual JS objects
Your response is not valid JSON so you can't interpret it as such on the client-side. Rule #1 when creating JSON responses is... never roll your own JSON.
I recommend getting PHP to generate valid JSON and respond with the correct Content-type
// Ensure jQuery (or any consumer) knows the response is JSON
header("Content-type: application/json");
// Create a data structure representing the series data
$data = [];
foreach ($project as $key => $value) {
$data[] = [
"name" => $key,
"data" => array_values($value) // you just want the values here, not the keys
];
}
// Respond with JSON
echo json_encode($data);
exit;
Then in your client-side code, you can simply use
series: response
as response will now be a valid JS array
You can also make sure jQuery treats the response as JSON by adding
dataType: "json",
to your $.ajax() options but with the right Content-type response header, jQuery should not need this.
Just an FYI, alert() is terrible for viewing data. The best option would be to use your browser's debugger. The second best option is to use console.log()

Why does TreeStore.sync() not write to database?

I've been assigned a task to extent and modify a Shopware plugin. The original author isn't in the company anymore. Before that I've never dealt with Shopware and ExtJs.
So I spend the last couple of days getting myself into it and I think I understood the principles and paradigm so far.
The only thing I'm having trouble with right now is the following issue:
I've got an Ext.tree.Panel which I want to save into a database using Ajax. The node is being added to the tree, I can see it appearing in the GUI. But after calling optionsTree.getStore().sync() there is nothing arriving in the database. The createProductOptionAction() in the PHP controller isn't called, but I can't figure out why. There is no error message in Browser console log, no error message in the Shopware log files. Nothing. Everything seems to work fine. But the data isn't being stored.
The original plugin had an Ext.grid.Panel to store and display data. And this works fine. But after changing to Ext.tree.Panel and modifying the code, it doesn't work anymore. From my point of view it should work tho. But it doesn't and I can't see my mistake(s).
Any help is really appreciated, I'm still a bloody beginner with ExtJs. :)
Here is what I've got so far:
app.js
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager', {
extend:'Enlight.app.SubApplication',
name:'Shopware.apps.CCBConfigurablePhotoProductsManager',
bulkLoad: true,
loadPath:'{url controller="CCBConfigurablePhotoProductsManager" action="load"}',
controllers:['ProductConfigurator'],
stores:['ProductOptionsList'],
models:['ProductOption'],
views: ['ProductOptions', 'Window' ],
launch: function() {
var me = this,
mainController = me.getController('ProductConfigurator');
return mainController.mainWindow;
}
});
controller/controller.js
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager.controller.ProductConfigurator', {
extend:'Ext.app.Controller',
refs: [
{ ref: 'productOptionsTree', selector: 'product-configurator-settings-window product-options-tree' }
],
init:function () {
var me = this;
me.mainWindow = me.createMainWindow();
me.addControls();
me.callParent(arguments);
return me.mainWindow;
},
addControls: function() {
var me = this;
me.control({
'product-configurator-settings-window product-options-tree': {
addProductOption: me.onAddProductOption
}
});
},
createMainWindow: function() {
var me = this,
window = me.getView('Window').create({
treeStore: Ext.create('Shopware.apps.CCBConfigurablePhotoProductsManager.store.ProductOptionsList').load()
}).show();
return window;
},
onAddProductOption: function() {
var me = this,
optionsTree = me.getProductOptionsTree(),
parentNode = optionsTree.getRootNode(),
nodeCount = parentNode.childNodes.length + 1,
productOption = Ext.create('Shopware.apps.CCBConfigurablePhotoProductsManager.model.ProductOption', {
parent: 0,
type: 0,
title: Ext.String.format('{s name="group/default_name"}New Group [0]{/s}', optionsTree.getRootNode().childNodes.length + 1),
active: true,
leaf: false
});
productOption.setDirty();
parentNode.appendChild(productOption);
optionsTree.getStore().sync(); // Nothing arrives at DB
optionsTree.expandAll();
},
// ...
view/window.js
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager.view.Window', {
extend:'Enlight.app.Window',
cls:Ext.baseCSSPrefix + 'product-configurator-settings-window',
alias:'widget.product-configurator-settings-window',
border:false,
autoShow:true,
maximizable:true,
minimizable:true,
layout: {
type: 'hbox',
align: 'stretch'
},
width: 700,
height: 400,
initComponent:function () {
var me = this;
me.createItems();
me.title = '{s name=window/title}Configurator Settings{/s}';
me.callParent(arguments);
},
createItems: function() {
var me = this;
me.items = [
me.createProductOptionsTree()
];
},
createProductOptionsTree: function() {
var me = this;
return Ext.create('Shopware.apps.CCBConfigurablePhotoProductsManager.view.ProductOptions', {
store: me.treeStore,
width: '20%',
flex: 1
});
}
});
store/product_options_list.js
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager.store.ProductOptionsList', {
extend: 'Ext.data.TreeStore',
pageSize: 30,
autoLoad: false,
remoteSort: true,
remoteFilter: true,
model : 'Shopware.apps.CCBConfigurablePhotoProductsManager.model.ProductOption',
proxy:{
type:'ajax',
url:'{url controller="CCBConfigurablePhotoProductsManager" action="getProductOptionsList"}',
reader:{
type:'json',
root:'data',
totalProperty:'total'
}
}
});
model/product_option.js
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager.model.ProductOption', {
extend : 'Ext.data.Model',
fields : [
{ name : 'id', type : 'int', useNull: true },
{ name : 'parent', type : 'int' },
{ name : 'title', type : 'string' },
{ name : 'active', type: 'boolean' },
{ name : 'type', type : 'int' }
],
idProperty : 'id',
proxy : {
type : 'ajax',
api: {
create: '{url controller="CCBConfigurablePhotoProductsManager" action="createProductOption"}',
update: '{url controller="CCBConfigurablePhotoProductsManager" action="updateProductOption"}',
destroy: '{url controller="CCBConfigurablePhotoProductsManager" action="deleteProductOption"}'
},
reader : {
type : 'json',
root : 'data',
totalProperty: 'total'
}
}
});
php/controller.php
<?php
use Shopware\CustomModels\CCB\ProductOption;
class Shopware_Controllers_Backend_CCBConfigurablePhotoProductsManager extends Shopware_Controllers_Backend_ExtJs
{
public function createProductOptionAction()
{
// Never being called
file_put_contents('~/test.log', "createProductOptionAction\n", FILE_APPEND);
$this->View()->assign(
$this->saveProductOption($this->Request()->getParams())
);
}
public function getProductOptionsListAction()
{
// Works fine
file_put_contents('~/test.log', "getProductOptionsListAction\n", FILE_APPEND);
// ...
}
// ...
EDIT 1
I tried adding a writer for both, the store and the model, as suggested by Saki. But unfortunately it still doesn't work. The createProductOptionAction() in the PHP controller is never being called.
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager.model.ProductOption', {
extend : 'Ext.data.Model',
fields : [
{ name : 'id', type : 'int', useNull: true },
{ name : 'parent', type : 'int' },
{ name : 'title', type : 'string' },
{ name : 'active', type: 'boolean' },
{ name : 'type', type : 'int' }
],
idProperty : 'id',
proxy : {
type: 'ajax',
api: {
create: '{url controller="CCBConfigurablePhotoProductsManager" action="createProductOption"}',
update: '{url controller="CCBConfigurablePhotoProductsManager" action="updateProductOption"}',
destroy: '{url controller="CCBConfigurablePhotoProductsManager" action="deleteProductOption"}'
},
reader: {
type : 'json',
root : 'data',
totalProperty: 'total'
},
writer: {
type: 'json'
}
}
});
What I'm wondering tho, the original plugin had no writer implemented. But when adding an entry it immediately appeared in the database.
EDIT 2
I added several listeners to the store.ProductOptionsList:
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager.store.ProductOptionsList', {
extend: 'Ext.data.TreeStore',
pageSize: 30,
autoLoad: false,
remoteSort: true,
remoteFilter: true,
model : 'Shopware.apps.CCBConfigurablePhotoProductsManager.model.ProductOption',
root: {
text: 'Product Options',
id: 'productOptions',
expanded: true
},
proxy:{
type: 'ajax',
url: '{url controller="CCBConfigurablePhotoProductsManager" action="getProductOptionsList"}',
reader: {
type:'json',
root:'data',
totalProperty:'total'
}
},
listeners: {
add: function(store, records, index, eOpts) {
console.log("**** Add fired");
console.log(records);
},
append: function(store, node, index, eOpts) {
console.log("**** Append fired");
console.log(node);
},
beforesync: function(operations) {
console.log("**** Beforesync fired");
console.log(operations);
}
}
});
All these Events are getting fired. The beforesync event shows
**** Beforesync fired
Object {create: Array[1]}
create: Array[1]
...
But still, the API requests of the model.ProductOption are not getting fired. It should work. Shouldn't it? Maybe this is a bug in ExtJS 4.1? Or something with Shopware + ExtJS?
EDIT 3
Ok, this is really getting weird.
I added a "write"-Listener to the TreeStore.
write: function(store, operation, opts){
console.log("**** Write fired");
console.log(operation);
Ext.each(operation.records, function(record){
console.log("**** ...");
if (record.dirty) {
console.log("**** Commiting dirty record");
record.commit();
}
});
}
After adding a Node and calling .getStore().sync(), the write-event IS fired, he iterates operation.records, finds one record (the one I just added)... but it isn't dirty, even though I do productOption.setDirty() before adding it to the Tree?!
Thanks alot for your time! :)
A little note on your code:
There is an error in the beforesync event: the function must return true, else sync() will not get fired.
I don't think this is the only problem. Since ExtJs is usually extensive code, I cannot tell you what is the reason of your problem. All I can give, is a simple working example with some explanations.
I'm following the recommended MVC layout, i.e. one file for each class. Here is the complete code:
Ext.define('Sandbox.Application', {
name: 'Sandbox',
extend: 'Ext.app.Application',
controllers: [
'Sandbox.controller.Trees'
]
});
Ext.define('Sandbox.controller.Trees', {
extend: 'Ext.app.Controller',
requires: ['Ext.tree.*', 'Ext.data.*', 'Ext.grid.*'],
models: ['TreeTest'],
stores: ['TreeTest'],
views: ['TreeGrid'],
init: function(){
this.control({
'treegrid toolbar button#addchild': {click: this.onAddChild},
'treegrid toolbar button#removenode': {click: this.onRemoveNode}
})
},
onAddChild: function(el){
var grid = el.up('treepanel'),
sel = grid.getSelectionModel().getSelection()[0],
store = grid.getStore();
store.suspendAutoSync()
var child = sel.appendChild({task: '', user: '', leaf: true});
sel.set('leaf', false)
sel.expand()
grid.getView().editingPlugin.startEdit(child);
store.resumeAutoSync();
},
onRemoveNode: function(el){
var grid = el.up('treepanel'),
sel = grid.getSelectionModel().getSelection()[0];
sel.remove()
}
});
Ext.define('Sandbox.model.TreeTest', {
extend: 'Ext.data.TreeModel',
fields: [
{name: 'id', type: 'int'},
{name: 'task', type: 'string'},
{name: 'user', type: 'string'},
{name: 'index', type: 'int'},
{name: 'parentId', type: 'int'},
{name: 'leaf', type: 'boolean', persist: false}
]
});
Ext.define('Sandbox.store.TreeTest', {
extend: 'Ext.data.TreeStore',
model: 'Sandbox.model.TreeTest',
proxy: {
type: 'ajax',
url: 'resources/treedata.php',
api: {
create: 'resources/treedata.php?action=create',
read: undefined,
update: 'resources/treedata.php?action=update',
destroy: 'resources/treedata.php?action=destroy'
}
},
autoSync: true,
autoLoad: false,
root: {id: 1, text: "Root Node", expanded: false}
});
Ext.define('Sandbox.view.TreeGrid', {
extend: 'Ext.tree.Panel',
alias: 'widget.treegrid',
store: 'TreeTest',
columns: [{
xtype: 'treecolumn',
text: 'Task',
flex: 2,
sortable: true,
dataIndex: 'task',
editor: {xtype: 'textfield', allowBlank: false}
},{
dataIndex: 'id',
align: 'right',
text: 'Id'
}, {
dataIndex: 'user',
flex: 1,
text: 'Utilisateur',
editor: {xtype: 'textfield', allowBlank: false}
}],
plugins: [{
ptype: 'rowediting',
clicksToMoveEditor: 1,
autoCancel: false
}],
viewConfig: {
plugins: [{
ptype: 'treeviewdragdrop',
containerScroll: true
}]
},
tbar:[
{xtype: 'button', text: 'Add Child', itemId: 'addchild'},
{xtype: 'button', text: 'Remove', itemId: 'removenode'}
]
});
I didn't elaborate the server side code. I just copied the Kitchensink example code. To get to work a create, update or delete request, it has to return the modified rows along with success: true.
Explanations:
I needed to launch sencha app build after adding the required classes in order to display everything correctly
file model/TreeTest.js : the field index is required if we want a reorder to be saved back to the server. If it is ommitted, only rows with edited fields are saved back. It was necessary to add persist: false for the leaf field, because this data is not needed on the server.
file store/TreeTest.js :
autoSync: true worked out of the box, with the restriction mentionned on reordering.
the tree autoLoads when the root node is expanded: true or if autoLoad: true. If we don't want to autoLoad, autoLoad and expanded must be both false.
root is required for a good working store. If it is missing, we must load the store manually, even if autoLoad: true.
It was necessary to add the api configuration. Without it, it was not possible to tell appart an update, create and delete request.
file view/TreeGrid.js :
a column with xtype: 'treecolumn' is required.
The removal of a row is simple and syncs the store automatically. The server side is responsible for deleting children if there are.
The creation of a new row is trickier, because the store is sync()'d as soon as appendChild() is called (suspendAutoSync() is used to avoid to write the new child before it is edited). Also, the grid gets only updated, if we control the leaf property manually (.set('leaf', false)). I expect ExtJs to correctly manage the leaf property and consider this as a bug.
The proxy used by the store must have a writer configured for sync operations to talk to the server.

"You're trying to decode an invalid JSON String" but it's a PHP

Good day,
I'm pretty new in extjs 5 and mvvm. I want to make an ajax request in order to display a treepanel with datas caught with a php.
Here is my store
Ext.define('MyApp.store.servicesStore', {
extend: 'Ext.data.TreeStore',
// alias: 'store.servicesStore',
storeId : 'servicesStore',
model : 'MyApp.model.servicesModel',
proxy: {
type: 'ajax',
url: 'app/store/data/GetServices.php'
},
root: {
text: 'Events',
id: 'root'
},
autoLoad: true,
folderSort: true
});
I've seen that a "success" can resolve that issue but I don't need a succes as it's only displayed in a treePanel
Ext.define('MyApp.view.tabServices.servicesTab', {
extend: 'Ext.tree.Panel',
xtype: 'servicesTab',
layout: {
type: 'border'
},
useArrows: true,
rootVisible: false,
store: {type: 'servicesStore'},
forceFit: true,
columns: [{
xtype: 'treecolumn',
dataIndex: 'text',
width: 600
}, {
dataIndex: 'mbt',
cls: 'mbtcss',
width: 80
}, {
dataIndex: 'bt',
cls: 'btcss',
width: 75
}, {
dataIndex: 'details', // port separated from rest
width: 60
}, {
dataIndex: 'code',
width: 80
}]
});
So, when I launch my app, the "You're trying to decode an invalid JSON String" appears, how can I do to make it understand that I actually use a php file?
More precisely, that code is working in extjs 3.4
To run the PHP code which did work under ExtJS 4 you must either modify your PHP to return the data in JSON format. Or otherwise you set your "enable compatibility" to version 4.
See "Enabling Compatibility" under http://docs.sencha.com/extjs/5.0/whats_new/5.0/extjs_upgrade_guide.html#Enabling_Compatibility.
compatibility: {
ext: '4.2'
}

Editing data dynamically ( grid json Ext JS 4 )

I've such a simple question but can't find answer (documentation) on it. I've created Grid , where information is retrieved from MySQL database. Using Ext JS 4.2 .
Let's take a look of script ...
Ext.define("AppStore",{
extend: "Ext.data.Model",
fields: [
{name: "nickname" , type: "auto"},
{name: "email" , type: "auto"}
]
});
var store = Ext.create("Ext.data.Store",{
model: "AppStore",
proxy: {
type: "ajax",
api: {
read : "./read.php",
update : "./update.php"
},
reader: {
type: "json",
root: ""
},
writer: {
type: "json",
writeAllFields: true,
encode: false,
root: ""
}
},
listeners: {
read: function(operation, callback, scope){
},
update: function(operation, callback, scope){
// Do I have to do something from here ?
}
},
autoLoad: true
});
Ext.create("Ext.grid.Panel",{
store: store,
selMode: "cellmodel",
columns: [
{
text: "Nickname",
flex: 1,
dataIndex: "nickname",
editor: {
xtype: "textfield",
allowBlank: false
}
},
{
text: "Email",
flex: 1.5,
dataIndex: "email",
editor: {
xtype: "textfield",
allowBlank: false
}
}
],
plugins: [
Ext.create("Ext.grid.plugin.CellEditing",{
clicksToEdit: 2
})
]
});
Everything is working fine , just interested in how I have to send request to MySQL for updating data after changing it in Grid cell . Any example , documentation or the way how to accomplish this task will be appreciated , thanks ...
Typically, you'll want to call sync() on your grid's store in order to persist the model changes to the server. This can be configured to occur automatically on every edit (see the autoSync property of the store). However, I would suggest it's better to handle the sync() call based on some specific action (e.g., a "Save" button being clicked, etc.).

Plotting graph with FLOT using mysql and ajax

I am trying to use flot to plot some data that is pulled from a MySQL db. I am log users login visits and I have a SQL function that will retreive the number of visits per day for a given month, getStats($day). I have read some examples online how to properly do this but for some reason when I try and graph the array data in my javascript file ' it comes up empty --> 'data: '. Below is my code. I am using the CI framework so if there are some questions about my code it is most likely because of that. I have hardcoded data in and it works fine. Any help on this matter would be appreciated there is not much about using flot with databases out there currently.
Model---> metrics.php
function showUsers() {
//get the number of days in the current month and the first day
$num_days = cal_days_in_month(CAL_GREGORIAN, date(m), date(Y));
$first_day = strtotime(date('Y').'-'.date('m').'-01');
//iterate through all of the days
while( $i < $num_days ) {
//get the user visits for each day of the month
$log = $this->db->getStats($first_day);
//add +1 day to the current day
$first_day += 86400;
$flot_visits[] = '['.($first_day*1000).','.$log->fields['total'].']';
$i++;
}
//format in acceptable format for flot
$content['visits'] = '['.implode(',',$flot_visits).']';
//load the view and pass the array
$this->load->vars($content);
$this->load->view('metrics/user_metrics', $content);
}
View ---> user_metrics.php
<div id ="visits_graph" style="width:600px; height:300px"></div>
Javascript ---> user_metrics.js
function metrics() {
$.ajax({
type: "POST",
url: pathurl + "metrics/showUsers",
data: "",
success: function(data) {
graph_visits();
}
});
}
function graph_visits() {
$.plot($('#visits_graph'), [
{ label: 'Visits', data: <?php echo $visits ?> }
], {
xaxis: {
mode: "time",
timeformat: "%m/%d/%y"
},
lines: { show: true },
points: { show: true },
grid: { backgroundColor: #fffaff' }
});
}
I think your problem is within the metrics function. (also I am guessing you are using JQuery)
At the moment your metrics function requests a page at the backend but does nothing with it.
change the backend method showUsers() to be something like:
function showUsers() {
//get the number of days in the current month and the first day
$num_days = cal_days_in_month(CAL_GREGORIAN, date(m), date(Y));
$first_day = strtotime(date('Y').'-'.date('m').'-01');
//iterate through all of the days
while( $i db->getStats($first_day);
//add +1 day to the current day
$first_day += 86400;
//change this to be a nested array
$flot_visits[] = array( ($first_day*1000) , $log->fields['total'] );
$i++;
}
//output javascript array
echo json_encode( $flot_visits );
}
change user_metrics.js to be something like :
function metrics() {
$.getJSON({
pathurl + "metrics/showUsers",
function(data) {
//use the returned data
graph_visits(data);
}
});
}
function graph_visits( graphData ) {
$.plot($('#visits_graph'), [
{ label: 'Visits', data: graphData }
], {
xaxis: {
mode: "time",
timeformat: "%m/%d/%y"
},
lines: { show: true },
points: { show: true },
grid: { backgroundColor: #fffaff' }
});
}
I got it to work but not the way I would like it. I figured I would post the answer so if anyone else runs into this issue they can get it to at least work.
So for some reason and I am assuming because the javascript file and the actual view(html) file are separated due to the framework that the array is not visible to the javacscript file. The issue lies within the function
function graph_visits() {
$.plot($('#visits_graph'), [
{ label: 'Visits', data: <?php echo $visits ?> }
], {
xaxis: {
mode: "time",
timeformat: "%m/%d/%y"
},
lines: { show: true },
points: { show: true },
grid: { backgroundColor: #fffaff' }
});
}
because they are seperate
<?php echo $visits ?>
returns nothing. The way I fixed it was just go into the view and just copy and past the contents of the function between two tags at the top of the html file. It should look like this,
<script language="javascript">
$.plot($('#visits_graph'), [
{ label: 'Visits', data: <?php echo $visits ?> }
], {
xaxis: {
mode: "time",
timeformat: "%m/%d/%y"
},
lines: { show: true },
points: { show: true },
grid: { backgroundColor: #fffaff' }
});
</script>
I do not really like this solution because it is breaking away from the framework but so far it the only solution I have been able to come up with.

Categories