Preface:
My overall goal is to create a pie chart showing the data below. The pie chart would have slices depicted as 1-8, with matching percentages based on the numerical value to the right of the colon.
I have the following data that is sent automatically in an email:
1:64.00
2:63.07
3:62.78
4:61.87
5:47.47
6:43.97
7:36.99
8:19.85
Sent from: [email redacted]
Parameters:3000,0
Time Server:2018.11.05 08:21:53
Time Local: 2018.11.04 22:21:53
There always this many lines sent in the email.
What I am trying to do is splice out the lines for data 1-8, which I have successfully done with this portion of the code:
if (strpos($row['subject'], 'Currency Relative Strength') !== false) {
$a1 = preg_split('/\r\n|\r|\n/', $row['body']);
$a = array("label" => $b[0], "p1" => $a1[1], "p2" => $a1[2], "p3" => $a1[3], "p4" => $a1[4], "p5" => $a1[5], "p6" => $a1[6], "p7" => $a1[7]);
$array[] = $a;
}
It looks like this:
[{"p0":"1:64.00","p1":"2:63.07","p2":"3:62.78","p3":"4:61.87","p4":"5:47.47","p5":"6:43.97","p6":"7:36.99","p7":"8:19.85"}]
The issue I am running into is that I am trying to follow the documentation here:
https://canvasjs.com/docs/charts/integration/jquery/chart-types/jquery-pie-chart/
Which for the datapoints portion requires an array that is completely different from the one I managed to put together.
This either leaves me needing to completely restructure the array, OR use a different pie chart system, which I am not against if anybody has any suggestions. I also understand that if I choose to go the route of canvasjs then to get an automatically updating pie chart with data that updates every minute, I have to implement something more like this:
CanvasJS: Making a chart dynamic with data.php, json encode and ajax(bandwidth meters)
To anybody willing to provide either assistance with the current code to better fit canvas js, OR suggest a whole different pie chart system that might work better with the array I have managed to build, I appreciate you very much! Btw I am not married to the idea of a jquery pie chart, I just figured it might be a better way to go...
Given that
$message = '
...
';
and the format for plotting JQuery pie chart
dataPoints: [
{ label: "Samsung", y: 30.3, legendText: "Samsung"},
...
]
The data points can be extracted as follow.
$lines = explode("\n", trim($message));
$firstEightLines = array_slice($lines, 0, 8);
$dataPoints = array_map(function($line) {
list($index, $point) = explode(":", $line);
return [
'label' => "p{$index}",
'legendText' => "p{$index}",
'y' =>(float)$point,
];
}, $firstEightLines);
var_dump($dataPoints);
/*
array(8) {
[0]=>
array(3) {
["label"]=>
string(2) "p1"
["legendText"]=>
string(2) "p1"
["y"]=>
float(64)
}
...*/
Related
I have a text file with following json data-
{"sender":"175","time":15,"message":"office app","response":{"recipient":{"id":"17"},"message":{"text":"Sorry, this message is not understandable to me."}}}
{"sender":"175","time":15,"message":"office app","response":{"recipient":{"id":"17"},"message":{"text":"But I will learn this in next few days."}}}
{"sender":"175","time":15,"message":"update next","response":{"recipient":{"id":"17"},"message":{"text":"this will be updated next."}}}
{"sender":"175","time":15,"message":"office app","response":{"recipient":{"id":"17"},"message":{"text":"Anything else you want to ask me?"}}}
I want to update 3rd record based on two criteria:
"id":"17"
"message":"update next"
Output of 3rd record I want -
{"sender":"175","time":15,"message":"office app","response":{"recipient":{"id":"17"},"message":{"text":"Meanwhile, please wait for our representative to get back to you."}}}
please help me to update the record with php.
First of all, you need to make a valid JSON
then you have to convert the JSON to an array
then you have to iterate through the array and find which item matches the criteria
and last you change the values.
JSON file content (filename: items.json):
[
{"sender":"175","time":15,"message":"office app","response":{"recipient":{"id":"17"},"message":{"text":"Sorry, this message is not understandable to me."}}},
{"sender":"175","time":15,"message":"office app","response":{"recipient":{"id":"17"},"message":{"text":"But I will learn this in next few days."}}},
{"sender":"175","time":15,"message":"update next","response":{"recipient":{"id":"17"},"message":{"text":"this will be updated next."}}},
{"sender":"175","time":15,"message":"office app","response":{"recipient":{"id":"17"},"message":{"text":"Anything else you want to ask me?"}}}
]
an example code is provided below:
<?php
$json = file_get_contents('items.json');
$json_as_array = json_decode($json, true);
$found = null;
foreach ($json_as_array as $key => $item)
{
if(strtolower($item['message']) == "update next" && $item['response']['recipient']['id'] == 17)
{
$found = $key;
}
}
$json_as_array[$found] = ["sender" => 175, "time" => 15, "message" => "office app", "response" => [ "recipient" => ["id" => 17], "message" => ["text" => "Meanwhile, please wait for our representative to get back to you."]]];
$json_output = json_encode($json_as_array);
file_put_contents('items.json', $json_output);
echo "Done!";
?>
i will not write all of the code but the proper way of storing the json , the way i do is
file_put_contents('appendData.txt', json_encode($inRadiusPostalCodes) , FILE_APPEND | LOCK_EX);
next when you read the file just read the file with
file_get_contents();
store it in a variable and then json_decode the string and then loop through your array to update record on desired index like
if($index == $someindex){......}
I am trying to figure out how to echo the genre value from an object created with this programme wrapper that requests json data from 'The Movie Database'. I'm so stuck and grappling to understand Object-oriented PHP so any help would be great.
I think the fact it is 'nested' (if that's the correct terminology) might be the issue.
<?php
include("tmdb/tmdb-api.php");
$apikey = "myapi_key";
$tmdb = new TMDB($apikey, 'en', true);
$idMovie = 206647;
$movie = $tmdb->getMovie($idMovie);
// returns a Movie Object
echo $movie->getTitle().'<br>';
echo $movie->getVoteAverage().'<br>';
echo '<img src="'. $tmdb->getImageURL('w185') . $movie->getPoster() .'"/></li><br>';
echo $movie->genres->id[28]->name;
?>
All of the other values are echoed just fine but I can't seem to get at genres. The json data looks like this ( some of it).
{
"adult":false,
"backdrop_path":"\/fa9qPNpmLtk7yC5KZj9kIxlDJvG.jpg",
"belongs_to_collection":{
"id":645,
"name":"James Bond Collection",
"poster_path":"\/HORpg5CSkmeQlAolx3bKMrKgfi.jpg",
"backdrop_path":"\/6VcVl48kNKvdXOZfJPdarlUGOsk.jpg" },
"budget": 0,
"genres":[
{ "id": 28, "name": "Action" },
{ "id": 12, "name": "Adventure" },
{ "id": 80, "name": "Crime" }
],
"homepage":"http:\/\/www.sonypictures.com\/movies\/spectre\/",
"id":206647,
"imdb_id":"tt2379713",
"original_language":"en",
"original_title":"SPECTRE",
"overview":"A cryptic message from Bond\u2019s past sends him on a trail to uncover a sinister organization. While M battles political forces to keep the secret service alive, Bond peels back the layers of deceit to reveal the terrible truth behind SPECTRE."
}
$movie->genres->id[28]->name
This assumes that id is an array and you want the item with index number 28 from it. What you want is the item containing an id with the value 28 without knowing its index number.
There's no easy way to get to it. You'd have to loop over the array $movie->genres and output the right one.
Maybe like this:
$n = 28;
// loop over genres-array
foreach($movie->genres as $i=>$g){
// check if id of item has right value and if so print it
if($g->id == $n){
echo $g->name;
// skip rest of loop if you only want one
break;
}
}
I am using a PHP script (this one) to generate a JSON file for a Google Map.
this is the PHP code (note: I am using Laravel):
<?php
$query = "SELECT id, info, lat, lng FROM places";
$results = DB::select($query);
$myLocations = array();
$i = 0;
$testLoc = array('loc95' => array( 'lat' => 15, 'lng' => 144.9634 ));
foreach ($results as $result)
{
$myLocation = array(
'loc'.++$i => array(
'lat' => round((float)$result->lat, 4),
'lng' => round((float)$result->lng, 4)
));
$myLocations += $myLocation;
}
$myLocations += $testLoc;
echo json_encode($myLocations);
?>
and this is the output:
{"loc1":{"lat":45.4833,"lng":9.1854},"loc2":{"lat":45.4867,"lng":9.1648},"loc3":{"lat":45.4239,"lng":9.1652},"loc95":{"lat":15,"lng":144.9634}}
ok. the script I use to put the JSON data in a Google Map, unfortunately, keeps ignoring any data coming from the MySQL database, and shows only the test data place(s). I have tried to swap data, to put in test data the same info found in database... nothing, I keep seeing only the test data.
but, really: I cannot figure out why. What am I missing... ?
You wrote that you're using another script and that the other script only shows the testlocations on google maps.
My guess is that you didn't update the other script to your needs, specifically my crystal ball is telling me that you still have this line in there:
setMarkers(locs);//Create markers from the initial dataset served with the document.
In your question you only showed the part which worked and I agree, but you only mentioned that "something else" isn't working. If you want an answer for that part, try reprashing your question and include the parts which cause you problems.
I was curious ab your opinions whats the most efficient transfer format between SpatiaLite and OpenLayers. Currently Im developing an application based on SpatiaLite (extension of SQLite) and OpenLayers and as a transfer format I use GeoJSON.
My procedure:
1) quering DB by php script, using SpatiaLite's function AsGeoJSON, thus obtaining geojson formatted data
2) using php's print() to transfer retrieved data from php variable to JS variable:
$result = $db->query($query);
$r = '{"type": "FeatureCollection","features": [';
while($row = $result->fetchArray(SQLITE3_ASSOC))
{
$r .= '{"type":"Feature","properties":{}, "geometry":' . $row['geometry'] . '},';
}
$r .= ']}';
print'<script> CadastreBorder = ' . $r . '; </script>';
3) creating the features for Vector Layer in OpenLayers by reading
var vectorLayer = new OpenLayers.Layer.Vector(name, {style: style, rendererOptions:
{zIndexing: true}});
var formatGeoJSON = new OpenLayers.Format.GeoJSON({});
vectorLayer.addFeatures(formatGeoJSON.read(CadastreBorder));
map.addLayer(vectorLayer);
Is there any way how to achieve the same goal more efficiently and more nicely?
Thanks!
Not sure about speed, but if you're using recent version of PHP (5.2 >=) you'd might consider using json_encode on php's arrays. Instead of creating string you'd create an array looking somewhere like this:
$geoJSON_array = Array(
"type" => "FeatureCollection",
"features" => Array()
);
And for each row of geometry, add new table to "features":
Array(
"type" => "Feature",
"properties" => Array(),
"geometry" => Array(... your geometry),
)
After creating such array, run json_encode over it and you're home. For safety I'd check it validates (e.g. using http://geojsonlint.com/). This may help you later on, when e.g. there would be need to support new information, or to add new kinds of elements to the map.
Question: Why are you not using fixed strategy for loading points? If you're creating this geoJSON to file/as script, you may also tell openlayers to download it automatically, likes this:
var vectorLayer = new OpenLayers.Layer.Vector(name, {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "json/my_geojson.json",
format: new OpenLayers.Format.GeoJSON()
}),
style: style,
rendererOptions: {zIndexing: true}
});
I'm using a Mongo MapReduce to perform a word-count operation on a bunch of documents. The documents are very simple (just an ID and a hash of words):
{ "_id" : 6714078, "words" : { "my" : 1, "cat" : 1, "john" : 1, "likes" : 1, "cakes" : 1 } }
{ "_id" : 6715298, "words" : { "jeremy" : 1, "kicked" : 1, "the" : 1, "ball" : 1 } }
{ "_id" : 6717695, "words" : { "dogs" : 1, "can't" : 1, "look" : 1, "up" : 1 } }
The database is called "words" in my environment, the collections in question are named "wordsX" where X is a category number (I know, don't ask). The field in the document hash where the words are stored is also named "words". Gah.
The problem I'm having is that under certain conditions in my PHP app, the MapReduce doesn't return any data. Annoyingly, running the same commands from the Mongo shell gives perfect results. I'm trying to pin down where this bug is occurring but I'm really stumped, so hoping someone might be able to shed some light on this. The lead-up to this question does go on a bit, because the environment is a bit complicated, but please bear with me.
The commands I've tried running from the Mongo shell to replicate the PHP-based operations are as follows:
m = function () {
if (this.words) {
for (index in this.words) {
emit(index, this.words[index]);
}
}
}
r = function (key, values) {
var total = 0;
for (var i in values) {
total += values[i];
}
return total;
}
res = db.words.mapReduce(m, r, { query : { _id : { $in : [6714078,6715298,6717695] } } });
This results in a temporary collection being created containing the word count data. All OK so far.
However if I run the same commands from PHP (using the standard Mongo library), I end up with no data under certain conditions. It's a bit tricky to describe because I don't want to bore you with the details of the application/environment beyond Mongo, but basically I'm using Sphinx to filter some records, then supplying a list of content IDs to Mongo on which the MapReduce is performed. If I filter back into the data set by 2 or 3 days, I get results back from Mongo; if I don't filter, I get an empty dataset back. The PHP code to run the same operation is as follows. I've not included the Sphinx-based parts as I don't think they're relevant (just know that we get a list of IDs back) because I've tried supplying exactly the same list to Mongo on the command line and got the right results, whereas I don't from within PHP. Hope that makes sense.
The PHP code I'm using looks like this:
$objMongo = new Mongo();
$objDB = $objMongo->words;
$arrWordList = array();
$strMap = '
function() {
if (this.words) {
for (index in this.words) {
emit(index, this.words[index]);
}
}
}
';
$strReduce = '
function(key, values) {
var total = 0;
for (var i in values) {
total += values[i];
}
return total;
}
';
$objMapFunc = new MongoCode($strMap);
$objReduceFunc = new MongoCode($strReduce);
$arrQuery = array(
'_id' => array('$in' => $arrIDs) // <--- list of IDs from Sphinx
);
$arrCommand = array(
'mapreduce' => 'wordsX',
'map' => $objMapFunc,
'reduce' => $objReduceFunc,
'query' => $arrQuery
);
MongoCursor::$timeout = -1;
$arrStatsInfo = $objDB->command($arrCommand);
var_dump($arrStatsInfo);
The contents of the result-info array ($arrStatsInfo) under working and non-working conditions (the filtering as specified above) are as follows.
Working results:
array(4) {
["result"]=>
string(31) "tmp.mr.mapreduce_1279637336_227"
["timeMillis"]=>
int(171)
["counts"]=>
array(3) {
["input"]=>
int(54)
["emit"]=>
int(2517)
["output"]=>
int(1526)
}
["ok"]=>
float(1)
}
Empty results:
array(4) {
["result"]=>
string(31) "tmp.mr.mapreduce_1279637381_228"
["timeMillis"]=>
int(21)
["counts"]=>
array(3) {
["input"]=>
int(0)
["emit"]=>
int(0)
["output"]=>
int(0)
}
["ok"]=>
float(1)
}
So it looks like under the broken condition, no records even make it into the MapReduce. I've spent ages trying to work out what on earth is going on here but I've had no insights thus far. As I've said, running the same commands (as above) directly in the Mongo command line using exactly the same set of IDs returns the right results.
After all that, I guess my question is: is there anything obviously wrong with the PHP-Mongo interaction I'm doing above? Are there other steps I can take to try to debug this?
Please let me know if supplying any further information would be helpful. I appreciate this is a somewhat expansive and ill-defined question but I've tried my best to communicate the issue! Really hope someone can suggest a way out of this.
Many thanks for reading!
For future readers, this issue turned out to be the result of inconsistent handling of ints/numeric strings elsewhere in the app. Sorry about the red herring!