I've finally managed to get my php code working for my google charts column chart. When I run my php I get the following output
{"cols":[{"id":"id","label":"second","type":"number"},
{"id":"threads","label":"threads","type":"number"}],"rows":[{"c":[{"v":1},{"v":1411}]},
{"c":[{"v":2},{"v":1411}]},{"c":[{"v":3},{"v":1409}]},{"c":[{"v":4},{"v":1408}]},{"c":
[{"v":5},{"v":1407}]},{"c":[{"v":6},{"v":1408}]},{"c":[{"v":7},{"v":1408}]},{"c":[{"v":8},
{"v":1410}]},{"c":[{"v":9},{"v":1410}]},{"c":[{"v":10},{"v":1412}]},{"c":[{"v":11},
{"v":1415}]}]}
Using this other post as a guide, here, I believe that my output is correct. However I am not entirely sure since my column chart is still not being displayed, on my webapp.
This is the code I am using to show my chart
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1', {'packages':['corechart']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var json = $.ajax({
url: 'databaseQuery.php',
dataType: 'json',
async: false
}).responseText;
var data = new google.visualization.DataTable(json);
var options = {
title: 'Active Threads',
is3D: 'false',
width: 800,
height: 600
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
I have a table the displays fine, which is also getting its data from a mysql server and shows the same data the graph should just in a table.
I have been going over this code and can't seem to find the mistake. Can anyone point the mistake(s) out or suggest a better way of doing it? If the error is in my JSON, what should it look like for it to work properly?
Also the table from my database looks like this
id threads
1 1411
2 1411
3 1409
4 1408
5 1407
6 1408
7 1408
8 1410
9 1410
10 1412
11 1415
There's nothing wrong with your code as shown. I've just created a test page basically cut and paste from your markup and it worked perfectly.
I'd suggest you try replacing the ajax call with inline json initialisation and see if that works for you.
var json = {
"cols":[
{"id":"id","label":"second", "type":"number"},
{"id":"threads","label":"threads","type":"number"}
],
"rows":[
{"c":[{"v":1},{"v":1411}]},
{"c":[{"v":2},{"v":1411}]},
{"c":[{"v":3},{"v":1409}]},
{"c":[{"v":4},{"v":1408}]},
{"c":[{"v":5},{"v":1407}]},
{"c":[{"v":6},{"v":1408}]},
{"c":[{"v":7},{"v":1408}]},
{"c":[{"v":8},{"v":1410}]},
{"c":[{"v":9},{"v":1410}]},
{"c":[{"v":10},{"v":1412}]},
{"c":[{"v":11},{"v":1415}]}
]
};
var data = new google.visualization.DataTable(json);
If that works, then you'll at least have confirmed the problem is somewhere in the ajax call or the php backend.
One other thought: this may seem obvious but it's worth double checking that you do have an element on your page with the chart_div id?
<div id='chart_div'></div>
Related
I am going through all of our PHP (V7.3) pages and upgrading all charts to the latest version.
On some pages where the chart data is part of a sub page or created from an AJAX call I get this error all the time
Uncaught TypeError: Cannot read property 'axis' of undefined
at vo.parse (chart3.min.js:13)
at vo._insertElements (chart3.min.js:13)
at vo._resyncElements (chart3.min.js:13)
at vo.buildOrUpdateElements (chart3.min.js:13)
at oo.update (chart3.min.js:13)
at new oo (chart3.min.js:13)
at eval (eval at <anonymous> (jquery.min.js:2), <anonymous>:18:19)
at eval (<anonymous>)
at jquery.min.js:2
at Function.globalEval (jquery.min.js:2)
My code has changed from:
<canvas id='chart_canvas' width='620' height='300'></canvas>
<script>
var data = <?php echo json_encode($data); ?>;
var ctx = document.getElementById("chart_canvas").getContext("2d");
var myNewChart = new Chart(ctx).Line(data, {
pointHitDetectionRadius: 5
});
</script>
to this:
<canvas id='chart_canvas' width='620' height='300'></canvas>
<script>
var data = <?php echo json_encode($data); ?>;
const config = {
type: 'line',
data,
options: {
responsive: true,
}
};
var myChart = new Chart(
document.getElementById('chart_canvas'),
config
);
</script>
The data varialble is:
var data = {"labels":["2021-07-17","2021-07-18","2021-07-19","2021-07-20","2021-07-21","2021-07-22","2021-07-23","2021-07-24","2021-07-25","2021-07-26","2021-07-27","2021-07-28","2021-07-29","2021-07-30","2021-07-31","2021-08-01","2021-08-02","2021-08-03","2021-08-04","2021-08-05","2021-08-06","2021-08-07","2021-08-08","2021-08-09","2021-08-10","2021-08-11","2021-08-12","2021-08-13","2021-08-14","2021-08-15","2021-08-16","2021-08-17"],"datasets":[{"label":"Jobs Created","fillColor":"rgba(26, 188, 156,0.2)","strokeColor":"rgba(26, 188, 156,1)","pointColor":"rgba(26, 188, 156,1)","pointStrokeColor":"#fff","pointHighlightFill":"#fff","pointHighlightStroke":"rgba(26, 188, 156,1)","data":{"2021-08-17":"2"}}]};
I know the code is ok because I have tried it in https://playcode.io/
I just cannot understand the error message and there is nothing i have found on Google, appreciate any pointers.
In your data you only have 1 item. This will be very hard to see on the chart because there will be no line to draw between items.
Adding to that, the data in your datasets should be formatted like this.
It looks like you are trying to combine Primitive and Object styles when you should be using either one. Because you are already giving labels, you only need to give the data like this: [10, 20, 30]
you can also give the data like you currently are giving. You just don't need the labels.
found the culprit - prototype-1.7.js
removed it and all works perfectly
I'm using mapbox api to display maps and directions. It's easy and it works well. I want to know how to update a marker's location on the map without refreshing a page. I read this page and this page in their documentation. I understand their examples but I'm not fully grasping how to implement realtime data in my codes without causing the page to refresh. Right now I have a script that updates the user location in the database every 15 seconds and returns longitude, latitude. I have the data now what? This is where I get highly confused. If you can help I would really appreciate. I have stripped down the codes for the sake of this question.
map.html
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="https://api.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.css" rel="stylesheet" />
<script type="text/javascript" src="geolocation.js"></script>
<!--Display map-->
<div id="map"></div>
<!--mapbox script-->
<script>
mapboxgl.accessToken ='pk.xxxxxxxx';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center:[$longitude,$latitude],
zoom: 15
});
var geojson = {
type: 'FeatureCollection',
features: [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates:[$longitude,$latitude]
},
properties: {
title: '',
description: ''
}}]
};
geojson.features.forEach(function(marker) {
var el = document.createElement('div');
el.className = 'marker';
new mapboxgl.Marker(el)
.setLngLat(marker.geometry.coordinates)
.setPopup(new mapboxgl.Popup({ offset: 25 })
.setHTML('<h3>' + marker.properties.title + '</h3><p>' + marker.properties.description + '</p>'))
.addTo(map);
});
</script>
geolocation.js
setInterval(function () {
$.get("https://ipinfo.io", function (response) {
//variables
var user_id = $('.userid').val();
var geoLocation = response.loc;
//build array
var values ='geoLocation=' + encodeURIComponent(geoLocation)
+ '&userid=' + encodeURIComponent(user_id);
$.ajax({
type: 'POST',
url: 'https://mywebsite.com/mobile/geolocation.php',
data: values,
success: function (data) {
//returns new longitude
var lon = data.longitude;
//returns new latitude
var lat = data.latitude;
}
});
}, "jsonp");
}, 15000);
geolocation.php
$geoLocation= mysqli_real_escape_string($conn,$_POST['geoLocation']);//coordinates
$userid= mysqli_real_escape_string($conn,$_POST['userid']);//userid
//split coordinates into lat and longitude
$longitude = substr($geoLocation, strpos($geoLocation, ",") + 1); //put it first
$latitude =preg_replace('/^([^,]*).*$/', '$1', $geoLocation); // put it second
//insert new coordinates
$insertgeo = $conn->prepare("INSERT INTO user_geolocation (latitude,longitude,userid) VALUES(?,?,?)");
$insertgeo->bind_param("sss",$latitude,$longitude,$userid);
$insertgeo->execute();
$insertgeo->close();
//return answer to json
$result = array('message' => 'success',
'userid'=>$userid,
'longitude'=>$longitude,
'latitude'=>$latitude);
header('Content-Type: application/json');
echo json_encode($result);
The documentation resources you've linked are helpful, but I think this add live realtime data example is even better for your use case. If you zoom out of the map to see a larger region of the world, you will see a blue rocket icon marker which moves every two seconds without refreshing the page. In essence, this is exactly what you're looking to do! I'll explain how the example is working so that you can use the same logic to update your own marker locations without refreshing the page as well.
The rocket icon in this example is added to the map with a source and layer. The source specifies all the underlying data (in this case, the updating GeoJSON served by the https://wanderdrone.appspot.com URL), and the layer specifies how that data should be styled on the map. If you visit this URL, you'll see that the coordinates update each time you refresh the page.
So, the code below:
Gets the GeoJSON from the url every 2 seconds.
Gets the map's 'drone' source using Map#getSource.
Sets the data used by the source in (2) to be the GeoJSON at the url using Map#setData.
window.setInterval(function() {
map.getSource('drone').setData(url);
}, 2000);
Your current implementation is using HTML-based markers via GL JS's Marker component. So, instead of switching to this source-and-layer based approach outlined above, you could use the Marker#setLngLat method each time the user's location updates in your database. This also will not refresh the whole page.
I'm creating charts using Google Charts API. Im using PHP/MySQL as my data source using this code.
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>enter code here
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
function drawChart() {
var jsonData = $.ajax({
url: "getData.php",
dataType:"json",
async: false
}).responseText;
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(jsonData);
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, {width: 600, height: 440, is3D:true});
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="chart_div"></div>
</body>
</html>
The code is working. My Question is, Is it possible to insert events here when I'm using data from MySQL dsiplaying as JSON format in PHP? How can I change the data when the data source that I'm referring from is from another file (in this case, getData.php). In a simple explanation, if this code shows that the number of trees in 2011 is 300,000...How can I change that value if I have a value of 400,000 for 2012 in a click of a button or from a drop down selection. I hope you get what I'm asking.
thanks in advance.
Here are the codes I used:
getData.php
<?php
// This is just an example of reading server side data and sending it to the client.
// It reads a json formatted text file and outputs it.
$string = file_get_contents("sampleData.json");
echo $string;
?>
sampleData.JSON
{
"cols": [
{"id":"","label":"Topping","pattern":"","type":"string"},
{"id":"","label":"Slices","pattern":"","type":"number"}
],
"rows": [
{"c":[{"v":"Mushrooms","f":null},{"v":3,"f":null}]},
{"c":[{"v":"Onions","f":null},{"v":1,"f":null}]},
{"c":[{"v":"Olives","f":null},{"v":1,"f":null}]},
{"c":[{"v":"Zucchini","f":null},{"v":1,"f":null}]},
{"c":[{"v":"Pepperoni","f":null},{"v":2,"f":null}]}
]
}
I'm trying to read in values from a db using php (mySQL) then have them show on a graph in flot. I know the values are read in correctly and I'm not getting any errors but the graph won't show.
Little help?
Thanks in advance.
<?php
while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
$graphdata[] = array( (int)$row[0], (int)$row[1] );
}
?>
/////
<div id="placeholder" style="width:600px;height:300px"></div>
<script language="javascript" type="text/javascript">
var dataset1 = <?php echo json_encode($graphdata);?>;
var data = [
{
label: "Random Values",
data: dataset1
}
];
var plotarea = $("#placeholder");
$.plot( plotarea , data);
</script>
The contents of your pastebin show that the JSON string you're outputting is invalid JSON.
var data = [{ label: "Random Values",data: dataset1}];
will validate if it's changed to:
var data = [{"label": "Random Values","data": "dataset1"}]
That's just an example, but I suspect that Flot is looking for a slightly different format, so you'll have to verify exactly what they're looking for against their documentation. I'm going through the same exercise right now with FusionCharts, so I'm feeling your pain. jsonlint.com is your friend on this one, output your JSON and verify it frequently. I'd also recommend that to initially get it working, start with just a string of JSON (even one that you copy from their examples) that you put right in your code. Get the chart working first, then work on getting your PHP to duplicate the example JSON string separately.
Try delaying creating the graph until the DOM is loaded:
jQuery(document).ready(function ($){
var plotarea = $("#placeholder");
$.plot( plotarea , data);
});
I am trying to create a simple annotated timeline from a PostgreSQL database using a server side PHP script to access the data from the database, then a JavaScript client side script to display the graph. Basically pretty straightforward stuff there. Now as you may guess, nothing is showing up when I visit the page.
So here is where I've gotten: When I looked at my apache log files, I can see that my PHP script is parsing correctly, and when I use the hyperlink (including all the extra goodies that my JavaScript added to properly ask PHP for what it wants from the database) I can see the response in the correct Google format. At least I think. I KINDA think that the issue may be that the response from my PHP function is actually in an incorrect syntax for the Google annotated timeline object, but I cant find enough documentation to prove that is true or not.
Here is a truncated version of what my PHP function spits out:
Google.visualization.Query.setResponse({version:'0.5',reqId:'0',status:'ok',table:{cols: [{id:'date',label:"date",type:'datetime'},{id:'temp',label:"temp",type:'number'}],
rows: [{c:[{v:new Date(2011,2,22,13,47,26),f:"03\/22\/2011 01:47pm"},{v:132.8,f:"133"}]},{c:[{v:new Date(2011,2,22,13,48,57),f:"03\/22\/2011 01:48pm"},{v:136.8,f:"137"}]},
{c:[{v:new Date(2011,2,22,13,56,49),f:"03\/22\/2011 01:56pm"},{v:132.8,f:"133"}]},{c:[{v:new Date(2011,2,22,13,58,42),f:"03\/22\/2011 01:58pm"},{v:128.8,f:"129"}]},
{c:[{v:new Date(2011,2,22,14,1,26),f:"03\/22\/2011 02:01pm"},{v:124.8,f:"125"}]},{c:[{v:new Date(2011,2,22,14,4,19),f:"03\/22\/2011 02:04pm"},{v:128.8,f:"129"}]},{c:[{v:new Date(2011,2,22,14,5,51),f:"03\/22\/2011 02:05pm"},{v:132.8,f:"133"}]},
And it goes on of course, but I figured I would give you an idea of what I was seeing, not put you to sleep with a complete dump.
Now I know by putting in document.write("got here"); kinda tags into my JavaScript, I can tell that the program does finish, and doesn't throw any crazy errors due to silly oversights on my part...(Opening mouth in preparation to insert foot)... However somehow from what I have read elsewhere it this query response looks mal-formatted somehow (I did change the formatting and insert spacing for readability in this post, so if you see something wrong with the spacing, it was more than likely me). I will include both my PHP and my JavaScript code at the bottom of this post. If anyone sees anything glaring that I missed, or have any insights into what could be the problem, I would really appreciate some help with this!
Thanks in advance everyone!
JavaScript index.html
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["annotatedtimeline"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var query = new google.visualization.Query('/vis.php');
query.setQuery('SELECT date,temp FROM temp1 ORDER BY date');
query.send(function(result) {
document.write(result.getDetailedMessage());
if(result.isError()) {
alert(result.getDetailedMessage());
} else {
var data = result.getDataTable();
var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
chart.draw(data,{displayAnnotations: false});
}
});
}
</script>
</head>
<body>
<div id="chart_div"></div>
</body>
</html>
PHP vis.php
<?php
require_once 'MC/Google/Visualization.php';
$user = 'postgres';
$db = new PDO('pgsql:host=localhost;dbname=house',$user,'');
$vis = new MC_Google_Visualization($db,'postgres');
$vis->addEntity('temp1', array(
'fields' => array(
'date' => array('field' => 'date', 'type' => 'datetime'),
'temp' => array('field' => 'temp', 'type' => 'number')
)
));
$vis->setDefaultEntity('temp1');
$vis->handleRequest();
?>
----------------------------------------------------------------------------------------
EDIT: Functional Code Alert!
Ok, so here is where I'm at now, this code works, but of course doesnt pull anything from my database. As you can see, the formatting is exactly the same as I was getting from the PHP function above.
FUNCTIONAL CODE but not what I'm looking for
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["annotatedtimeline"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable(
{
cols: [{id:'date',label: 'date', type: 'datetime'},
{id:'level',label: 'level', type: 'number'}],
rows: [
{c:[{v: new Date(2011,2,24,6,52,26),f:"03\/24\/2011 06:52am"}, {v:91.4,f:"91"} ]},
{c:[{v: new Date(2011,2,25,7,35,20),f:"03\/25\/2011 07:35am"}, {v:89.4,f:"89"} ]},
{c:[{v: new Date(2011,2,26,1,2,15),f:"03\/26\/2011 01:02am"}, {v:85.4,f:"85"} ]},
{c:[{v: new Date(2011,2,27,0,27,13),f:"03\/27\/2011 12:27am"}, {v:85.4,f:"85"} ]}]
}, 0.6);
var annotatedtimeline = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
annotatedtimeline.draw(data, {'displayAnnotations': true});
}
</script>
</head>
<body>
<div id='chart_div' style="width:400; height:250"></div>
</body>
</html>
To me this indicates that there must be one parsing step I'm missing. Like I said before, from all the troubleshooting I know how to do with the google code, I got that the row and col sizes were correct in the response from the database after calling the var data = result.getDataTable() function. So there must be one further modification I have to do to the variable data before I try to use it in my annotatedtimeline.draw(data, {OPTIONS}) call.... Any ideas?
** ------------------------------------------------------------------------- **
EDIT 2: NON WORKING CODE
This is the non working code. The only real difference is the source of the data. And since I know that the database is responding, I am confused by the fact that its still showing a blank page.
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1', {packages: ['annotatedtimeline']});
function drawChart() {
//Tell Google Visualization where your script is
var query = new google.visualization.Query('/vis.php');
query.setQuery('SELECT date,level FROM tank1 ORDER BY date');
query.send(function(result) {
//if there is an error
document.write(result.getDetailedMessage());
if(result.isError()) {
alert(result.getDetailedMessage());
} else {
// otherwise plot the data
var data = result.getDataTable();
// Inserting a document.write(data.getNumberOfRows()) proves that the datatable is loading seemingly correctly here
var annotatedtimeline = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
annotatedtimeline.draw(data, { 'displayAnnotations': false });
}
});
}
google.setOnLoadCallback(drawChart);
</script>
</head>
<body>
<div id="chart_div" style="width:400px; height:250px"></div>
</body>
</html>
I have experienced this problem before, just fix this line in NON_WORKING_CODE
query.setQuery('SELECT date,level FROM tank1 ORDER BY date');
into
query.setQuery('SELECT *');
This should work. If not, try to fix the preg_quote issue https://code.google.com/p/mc-goog-visualization/issues/detail?id=16
A look at the Google docmentation page here : http://code.google.com/apis/visualization/documentation/gallery/annotatedtimeline.html
Shows the following :
Important: To use this visualization, you must specify the height and width
of the container element explicitly on your page. So, for example:
<div id="chart_div" style="width:400; height:250"></div>.
You don't appear to do this.
EDIT : I just tried the example on that page and indeed if I remove the explicit height and width I get nothing; with the height and width the timeline displays.
In your response, the keys are not enclosed in quote, it might be the reason why the chart is not rendered
{id:'date', type:'date'}
{"id":"date", "type":"date"}
I just searched for visualization.query documentation and this live example uses a response like yours but in the response, the keys are enclosed in quote:
https://spreadsheets.google.com/tq?key=pCQbetd-CptGXxxQIG7VFIQ&pub=1
I'm not familiarized with PHP and that visualization library you use in vis.php but if you could manage to add those quotes, I'm almost sure that it will work
I'm usign a tabledate with object notation as you did but in .NET and that's the only thing I see difference
Hope it helps, I know is an old post but for people like me in the future