PHP JSON variable in javascript - javascript

I am generating a JSON "text" using php and want to include that in a javascript in the same file.
I think I am having problem understanding how java deals with JSON as text vs as an Object.
Note: I am going to change mysql to mysqli soon, just want to get this thing working first.
Here's my script:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Knox QA tickets status</title>
</head>
<body>
<script src="am/amcharts/amcharts.js" type="text/javascript"></script>
<script src="am/amcharts/serial.js" type="text/javascript"></script>
<?php
//$subm = "8";
// This is being loaded from a selection html script
$subm = $_POST["submoduleID"];
if(!isset($_POST["submoduleID"]) )
{
// set it to the default container if it's not set.
$subm = "8";
}
// Connect to MySQL
$link = mysql_connect( 'localhost', 'root', 'secret' );
if ( !$link ) {
die( 'Could not connect: ' . mysql_error() );
}
// Select the data base
$db = mysql_select_db( 'xqa_status', $link );
if ( !$db ) {
die ( 'Error selecting database \'test\' : ' . mysql_error() );
}
// Fetch the data
$query = ("select date, tested, passed from test_status where xqa_id=" . $subm . " order by test_status_id limit 10");
$result = mysql_query( $query );
// Make a josn formatted output
$rows = array();
while ( $r = mysql_fetch_assoc($result)) {
$rows[] = $r;
}
$chartData_json = json_encode($rows);
print $chartData_json;
mysql_close($link);
?>
<!-- Custom Function
<script>
AmCharts.loadJSON = function(file) {
// create the request
if (window.XMLHttpRequest) {
// IE7+, Firefox, Chrome, Opera, Safari
var request = new XMLHttpRequest();
} else {
// code for IE6, IE5
var request = new ActiveXObject('Microsoft.XMLHTTP');
}
request.open('GET', file, false);
request.send();
// parse adn return the output
return eval(request.responseText);
};
</script> -->
<!-- chart container -->
<div id="chartdiv" style="width: 600px; height: 300px;"></div>
<!-- the chart code -->
<script>
var chart;
var chartData1 = "<?php echo $chartData_json; ?>";
var myObject = JSON.parse(chartData1, reviver);
// create chart
AmCharts.ready(function() {
// load the data
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.pathToImages = "am/amcharts/images/";
chart.dataProvider = myObject;
chart.categoryField = "date";
chart.dataDateFormat = "YYYY-MM-DD";
// GRAPHS
var graph1 = new AmCharts.AmGraph();
graph1.type = "smoothedLine";
graph1.title = "Tested";
graph1.valueField = "tested";
graph1.bullet = "round";
graph1.bulletSize = 5;
graph1.bulletBorderColor = "#FFFFFF";
graph1.bulletBorderThickness = 2;
graph1.lineThickness = 2;
graph1.lineAlpha = 0.5;
chart.addGraph(graph1);
var graph2 = new AmCharts.AmGraph();
graph2.type = "smoothedLine";
graph2.title = "Passed";
graph2.valueField = "passed";
graph2.bullet = "round";
graph2.bulletSize = 5;
graph2.bulletBorderColor = "#FFFFFF";
graph2.bulletBorderThickness = 2;
graph2.lineThickness = 2;
graph2.lineAlpha = 0.5;
chart.addGraph(graph2);
// CATEGORY AXIS
chart.categoryAxis.parseDates = true;
chart.categoryAxis.autoGridCount = false;
chart.categoryAxis.gridCout = chartData.length;
chart.categoryAxis.gridPosition = "start";
chart.categoryAxis.labelRotation = 90;
// LEGEND
var legend = new AmCharts.AmLegend();
chart.addLegend(legend);
// CURSOR
var chartCursor = new AmCharts.ChartCursor();
chartCursor.cursorAlpha = 0;
chartCursor.cursorPosition = "mouse";
chartCursor.categoryBalloonDateFormat = "YYYY-MM-DD";
chart.addChartCursor(chartCursor);
// SCROLLBAR
var chartScrollbar = new AmCharts.ChartScrollbar();
chart.addChartScrollbar(chartScrollbar);
// 3D
// chart.angle = 30;
// chart.depth3D = 15;
// WRITE
chart.write("chartdiv");
});
</script>
</body>
</html>
A sample of the json output is this:
[{"date":"2014-01-09","tested":"12","passed":"32"},{"date":"2014-01-10","tested":"12","passed":"34"},{"date":"2014-01-11","tested":"22","passed":"34"},{"date":"2014-01-12","tested":"22","passed":"34"},{"date":"2014-01-13","tested":"40","passed":"34"},{"date":"2014-01-14","tested":"40","passed":"34"},{"date":"2014-01-15","tested":"40","passed":"34"}]

You need to assign the output of your PHP into a Javascript variable:
<script>
var json_data=<?php
...
?>;
// Do stuff with json_data
</script>
Then json_data will be an array or objects in Javascript (it's not JSON anymore since the JSON will be parsed as an array literal, not a string). That is most likely what you want, since then you can work with the array, like json_data[0].data.

Related

How to get MySQL data from PHP to Javascript via XMLHttpRequest and output the data chronologically?

I've managed to get the MySQL data that I needed in order for me to display it onto the notification's container. Now I have a problem at manipulating the data I needed. Instead of printing the objects one by one, it prints the same object at multiple times. Here is the source code.
PHP MySQL data getter
<?php
$host = 'localhost';
$username = 'root';
$password = '';
$dbname= 'notifications';
$dsn = "mysql:host=$host;dbname=$dbname";
$connection = new PDO($dsn, $username, $password);
$sql = 'SELECT * from notifications ORDER by date';
$query = $connection->prepare($sql);
$query->execute(PDO::FETCH_OBJ);
$array_list = [];
while($row = $query->fetch()){
array_push($array_list, $row);
}
echo json_encode($array_list);
?>
Javascript that gets the value of MySQL data from PHP file. Don't mind the long string, it's just an element that will be added up to the notification container when scrolled down.
var notificationContainer = document.getElementById('notifications-container');
notificationContainer.addEventListener("scroll", myPageScroll);
var index = -1;
function myPageScroll(){
var theScrollTop = notificationContainer.scrollTop;
var theScrollHeight = notificationContainer.scrollHeight;
var height = notificationContainer.clientHeight;
//THIS IS WHERE I HAVE A PROBLEM. IT PRINTS THE SAME OBJECT 5 TIMES.
if(theScrollTop + height >= theScrollHeight){
for(i = 0; i < 5; i++){
testing();
index = index + 1;
}
}
}
function testing(){
var xhr = new XMLHttpRequest();
xhr.open("POST", "data_getter.php");
xhr.onload = function(){
var jsvar = this.response;
jsvar = JSON.parse(xhr.responseText);
console.log(jsvar[index]);
notificationContainer.insertAdjacentHTML('beforeend', jsvar[index].notification_content);
};
xhr.send();
}
Html file
<div class="drop-down-container" id="notifications-container"></div>
<script src="header.js"></script>
Though when I printed the objects into the console, it has the organized data.
This is because when you get any fetch response the for loop has done iterating so index (inside the testing function) always has the same value. You need to pass index has parameter of testing function.
var notificationContainer = document.getElementById('notifications-container');
notificationContainer.addEventListener("scroll", myPageScroll);
var index = -1;
function myPageScroll(){
var theScrollTop = notificationContainer.scrollTop;
var theScrollHeight = notificationContainer.scrollHeight;
var height = notificationContainer.clientHeight;
//THIS IS WHERE I HAVE A PROBLEM. IT PRINTS THE SAME OBJECT 5 TIMES.
if(theScrollTop + height >= theScrollHeight){
for(i = 0; i < 5; i++){
testing(index); // pass index as parameter
index = index + 1;
}
}
}
function testing(index){ // index has been added as parameter
var xhr = new XMLHttpRequest();
xhr.open("POST", "data_getter.php");
xhr.onload = function(){
var jsvar = this.response;
jsvar = JSON.parse(xhr.responseText);
console.log(jsvar[index]);
notificationContainer.insertAdjacentHTML('beforeend', jsvar[index].notification_content);
};
xhr.send();
}

Add another field for legend in amcharts to show percentage

I am using amcharts to create a piechart for some details in codeigniter and I use pie chart with legend(http://www.amcharts.com/demos/pie-chart-with-legend/) and I made view the legend with title and value just like in the demo. Now I want to add another field for the legend that display relevant percentage in line for each. Are there any keyword or method to do that? I am new to programming.
Here's my code..
$data['chartOne'] = $this->prepareJson($totalQuotations, "q");
$data['chartTwo'] = $this->prepareJson($totalContribution, "c");
<script type = "text/javascript">
var chart1 = AmCharts.makeChart( "salesReportPerformanceChartdiv",' . $data["chartOne"] . ');
var chart2 = AmCharts.makeChart( "salesReportContributionChartdiv",' . $data["chartTwo"] . ');
</script>';
public function prepareJson($data, $type) {
$chatData = [];
foreach ($data as $status) {
$stustotal = new \stdClass();
$stustotal->y = $status->count;
if ($type == "q") {
$stustotal->x = $status->status_name;
} else if ($type == "c") {
$stustotal->x = $status->user_name;
}
array_push($chatData, $stustotal);
}
$listeners = new \stdClass();
$listeners->method = addLegendLabel;
$listeners->event = "drawn";
$export = new \stdClass();
$export->enabled = true;
$legend = new \stdClass();
$legend->position = "right";
$legend->markerType = "circle";
$legend->autoMargins = true;
$feOffset = new \stdClass();
$feOffset->result = "offOut";
$feOffset->in = "SourceAlpha";
$feOffset->dx = 0;
$feOffset->dy = 0;
$feGaussianBlur = new \stdClass();
$feGaussianBlur->result = "blurOut";
$feGaussianBlur->in = "offOut";
$feGaussianBlur->stdDeviation = 5;
$feBlend = new \stdClass();
$feBlend->in = "SourceGraphic";
$feBlend->in2 = "blurOut";
$feBlend->mode = "normal";
$filter = new \stdClass();
$filter->id = "shadow";
$filter->width = "200%";
$filter->height = "200%";
$filter->feOffset = $feOffset;
$filter->feGaussianBlur = $feGaussianBlur;
$filter->feBlend = $feBlend;
$defs = new \stdClass();
$defs->filter = $filter;
$chart = new \stdClass();
$chart->type = "pie";
$chart->startDuration = 0;
$chart->theme = "light";
$chart->addClassNames = true;
$chart->legend = $legend;
$chart->innerRadius = "85%";
$chart->defs = $defs;
$chart->dataProvider = (array)$chatData;
$chart->valueField = "y";
$chart->titleField = "x";
$chart->labelRadius = 5;
$chart->radius = "42%";
$chart->labelText = "";
$chart->listeners = $listeners;
$chart->export = $export;
$chartJSON = json_encode($chart);
return $chartJSON;
}
You can customize the legend's valueText to include the percents by adding the [[percents]] shortcode to the string. By default, it is set to "[[value]]". In your case, it looks like you have to set it through your $legend variable. You might also want to set the valueWidth to accommodate for the longer value string like so:
$legend->valueText = "[[value]] [[percents]]%"; //customize as needed
$legend->valueWidth = 100; //adjust as needed so it doesn't overlap
Fiddle

Display date in x Axis value using amCharts

I've a AmSerialChart with three AmGraph on whcih I've formatted the balloonText like this:
grp.balloonText = "<small><b>Date: [[category]]</b></small><br>[[value]]";
The problem with the category (x value) is that is also displayed in the balloonText with the following format: "MMM DD, YYYY". How can I display this date in another way?
I've checked dateFormats in the categoryaxis and dataDateFormat but that only changes the bottom value.
Here's the full code so far:
<script src="amcharts/amcharts.js" type="text/javascript"></script>
<script src="amcharts/serial.js" type="text/javascript"></script>
<script type="text/javascript">
var chart;
var chartData = <% properties.get("jsonData") %>;
var chartTitles = <% properties.get("jsonTitles") %>;
AmCharts.ready(function () {
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.pathToImages = "amcharts/images/";
chart.dataProvider = chartData;
chart.categoryField = "date";
chart.dataDateFormat = [{period:'fff',format:'JJ:NN:SS'},{period:'ss',format:'JJ:NN:SS'},{period:'mm',format:'JJ:NN:SS'},{period:'hh',format:'JJ:NN:SS'},{period:'DD',format:'JJ:NN:SS'},{period:'WW',format:'JJ:NN:SS'},{period:'MM',format:'JJ:NN:SS'},{period:'YYYY',format:'JJ:NN:SS'}];
// listen for "dataUpdated" event (fired when chart is inited) and call zoomChart method when it happens
// chart.addListener("dataUpdated", zoomChart);
// AXES
// category
var categoryAxis = chart.categoryAxis;
categoryAxis.parseDates = true; // as our data is date-based, we set parseDates to true
categoryAxis.minPeriod = "ss";
categoryAxis.minorGridEnabled = true;
categoryAxis.axisColor = "#DADADA";
// categoryAxis.dateFormats = [{period:'fff',format:'JJ:NN:SS'},{period:'ss',format:'JJ:NN:SS'},{period:'mm',format:'JJ:NN:SS'},{period:'hh',format:'JJ:NN:SS'},{period:'DD',format:'JJ:NN:SS'},{period:'WW',format:'JJ:NN:SS'},{period:'MM',format:'JJ:NN:SS'},{period:'YYYY',format:'JJ:NN:SS'}];
var vAxis = new AmCharts.ValueAxis();
chart.addValueAxis(vAxis);
for (var i = 0; i < chartTitles.length; i++) {
var grp = new AmCharts.AmGraph();
grp.valueField = "d"+i;
grp.title = chartTitles[i];
grp.type = "line";
grp.valueAxis = vAxis; // indicate which axis should be used
grp.lineThickness = 1;
grp.bullet = "round";
grp.labelPosition = "right";
grp.balloonText = "<small><b>Date: [[category]]</b></small><br>[[value]]";
grp.balloonText = "[[value]], [[description]], [[percents]], [[open]], [[total]], [[category]]";
grp.showBalloon = true;
grp.bulletSize = 1;
grp.bulletBorderThickness = 6;
grp.dashLengthField = "dashLength";
chart.addGraph(grp);
}
// SCROLLBAR
var chartScrollbar = new AmCharts.ChartScrollbar();
chart.addChartScrollbar(chartScrollbar);
// LEGEND
var legend = new AmCharts.AmLegend();
legend.marginLeft = 180;
legend.useGraphSettings = true;
chart.addLegend(legend);
// WRITE
chart.write("chartdiv");
});
</script>
<div id="chartdiv" style="width: 100%; height: 360px;"></div>
Good questions, which helped me to find out that I have a missing property in the docs. In case you don't use ChartCursor, you should use chart.balloonDateFormat property to format the date.

How to make a page resize without resizing?

How do I make a page resize without resizing it?
I have a Javascript which runs to get data from a text file followed by plotting a graph on Amcharts. The problem is that some axis components of the chart are missing when it is first plotted and still missing when I attempt to refresh (F5).
The missing components all come out when I resize the browser, so I am wondering what is it that the resizing does and how do I mimic a resize after the chart has been drawn without actually resizing?
The full html version of the source is right here.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>amCharts Example</title>
<link rel="stylesheet" href="style.css" type="text/css">
<script src="javascript/amcharts.js" type="text/javascript"></script>
<script type="text/javascript">
var chart;
var chartData = [];
// declaring variables
var dataProvider;
// this method called after all page contents are loaded
var srcFrame;
window.onload = function() {
//generateChartData();
//createChart();
loadOuter('data.txt');
//loadOuter('Test.txt');
//loadCSV('data.txt');
}
//External content into a layer
function loadOuter(doc) {
srcFrame = document.getElementById("hiddenContent");
srcFrame.src = doc;
// workaround for missing onLoad event in IFRAME for NN6
if (!srcFrame.onload) {
if (srcFrame.contentDocument){
srcContent=srcFrame.contentDocument.getElementsByTagName("BODY")[0].innerHTML;
}
else if (srcFrame.contentWindow){
srcContent=srcFrame.contentWindow.document.body.innerHTML;
}
srcContent = srcContent.substring(5,srcContent.length-6)
parseCSV(srcContent);
//setTimeout("transferHTML()", 1000)
}
}
function parseCSV(data){
//replace UNIX new lines
data = data.replace (/\r\n/g, "\n");
//replace MAC new lines
data = data.replace (/\r/g, "\n");
//split into rows
var rows = data.split("\n");
// create array which will hold our data:
dataProvider = [];
// loop through all rows
for (var i = 0; i < rows.length; i++){
// this line helps to skip empty rows
if (rows[i]) {
// our columns are separated by comma
var column = rows[i].split(",");
// column is array now
// first item is date
var date = column[0];
var myDate= new Date();
var dateparse = date.split("-");
myDate.setFullYear(dateparse[0],dateparse[1],dateparse[2]);
//alert(myDate);
// second item is value of the second column
var value1 = column[1];
// third item is value of the fird column
var value2 = column[2];
// create object which contains all these items:
chartData.push({
date: myDate,
visits: value1,
hits: value2,
});
//var dataObject = {date:date, value1:value1, value2:value2};
// add object to dataProvider array
//dataProvider.push(dataObject);
}
}
// set data provider to the chart
chart.dataProvider = chartData;
// this will force chart to rebuild using new data
chart.validateData();
}
// generate some random data, quite different range
function generateChartData() {
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 50);
//alert(firstDate);
//alert(firstDate.getDate());
for (var i = 0; i < 50; i++) {
var newDate = new Date(firstDate);
newDate.setDate(newDate.getDate() + i);
//alert(newDate);
var visits = Math.round(Math.random() * 40) + 100;
var hits = Math.round(Math.random() * 80) + 500;
chartData.push({
date: newDate,
visits: visits,
hits: hits,
});
}
}
//function createChart(){
AmCharts.ready(function () {
//loadOuter('data.txt');
// generate some random data first
//generateChartData();
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.pathToImages = "amcharts/images/";
chart.zoomOutButton = {
backgroundColor: '#000000',
backgroundAlpha: 0.15
};
chart.dataProvider = chartData;
chart.categoryField = "date";
// listen for "dataUpdated" event (fired when chart is inited) and call zoomChart method when it happens
chart.addListener("dataUpdated", zoomChart);
// AXES
// category
var categoryAxis = chart.categoryAxis;
categoryAxis.parseDates = true; // as our data is date-based, we set parseDates to true
categoryAxis.minPeriod = "DD"; // our data is daily, so we set minPeriod to DD
categoryAxis.dashLength = 2;
categoryAxis.gridAlpha = 0.15;
categoryAxis.axisColor = "#DADADA";
// first value axis (on the left)
var valueAxis1 = new AmCharts.ValueAxis();
valueAxis1.axisColor = "#FF6600";
valueAxis1.axisThickness = 2;
valueAxis1.gridAlpha = 0;
chart.addValueAxis(valueAxis1);
// second value axis (on the right)
var valueAxis2 = new AmCharts.ValueAxis();
valueAxis2.position = "right"; // this line makes the axis to appear on the right
valueAxis2.axisColor = "#FCD202";
valueAxis2.gridAlpha = 0;
valueAxis2.axisThickness = 2;
chart.addValueAxis(valueAxis2);
// GRAPHS
// first graph
var graph1 = new AmCharts.AmGraph();
graph1.valueAxis = valueAxis1; // we have to indicate which value axis should be used
graph1.title = "red line";
graph1.valueField = "visits";
graph1.bullet = "round";
graph1.hideBulletsCount = 30;
chart.addGraph(graph1);
// second graph
var graph2 = new AmCharts.AmGraph();
graph2.valueAxis = valueAxis2; // we have to indicate which value axis should be used
graph2.title = "yellow line";
graph2.valueField = "hits";
graph2.bullet = "square";
graph2.hideBulletsCount = 30;
chart.addGraph(graph2);
// CURSOR
var chartCursor = new AmCharts.ChartCursor();
chartCursor.cursorPosition = "mouse";
chart.addChartCursor(chartCursor);
// SCROLLBAR
var chartScrollbar = new AmCharts.ChartScrollbar();
chart.addChartScrollbar(chartScrollbar);
// LEGEND
var legend = new AmCharts.AmLegend();
legend.marginLeft = 110;
chart.addLegend(legend);
// WRITE
chart.write("chartdiv");
});
// this method is called when chart is first inited as we listen for "dataUpdated" event
function zoomChart() {
// different zoom methods can be used - zoomToIndexes, zoomToDates, zoomToCategoryValues
chart.zoomToIndexes(10, 20);
//chart.validateData();
//createChart();
}
</script>
<div id="outerDisplay"></div>
<iframe id="hiddenContent" width="200" height="200" style="position:absolute;visibility:hidden;" ></iframe>
<div id="chartdiv" style="width:600px; height:400px; background-color:#FFFFFF"></div>
</body>
</html>
Anyone has any idea on how to troubleshoot it to make it display on the first load instead of having to resize it?
Did you try calling chart.validateNow()? See Amcharts reference.
Chart will be redrawn, useful when a property changes.

JavaScript Array Formatting problem

Can someone assist me with formatting this JavaScript array correctly? I am obviously missing something fundamental:
Javascript:
<script type="text/javascript">
var widths = new Array("225","320","480", "--");
var sidewalls = new Array();
sidewalls["225"] = new Array("65","55","45","40", "--");
var rims["225"] = new Array();
rims["225"]["65"] = new Array("R17", "--");
rims["225"]["55"] = new Array("R17","R18", "--");
rims["225"]["45"] = new Array("R17", "--");
rims["225"]["40"] = new Array("R18", "--");
sidewalls["320"] = new Array("70", "--");
var rims["320"] = new Array();
rims["320"]["70"] = new Array("R20","R24", "--");
sidewalls["480"] = new Array("65", "--");
var rims["480"] = new Array();
rims["480"]["65"] = new Array("R28", "--");
</script>
PHP used to generate the above JavaScript:
<?php while($row = mysql_fetch_array($result)) {
list($width, $sidewall, $rim) = explode("/",$row['meta_value']); $menu[$width][$sidewall][$rim] = 1; }
$widths = implode('","', array_keys($menu));
print "var widths = new Array(\"$widths\", \"--\");\n";
print "\nvar sidewalls = new Array();\n";
foreach($menu as $width => $sidewall_array) {
$sidewalls = implode('","', array_keys($sidewall_array));
print "sidewalls[\"$width\"] = new Array(\"$sidewalls\", \"--\");";
print "\nvar rims[\"$width\"] = new Array();\n";
foreach($sidewall_array as $sidewall => $rim_array) {
$rims = implode('","', array_keys($rim_array));
print "rims[\"$width\"][\"$sidewall\"] = new Array(\"$rims\", \"--\");";
}
} ?>
Thank you in advance for your help
Stu
You shouldn't be putting var in front of array assignments, just the initial definitions.
So var widths = ... is fine, but var rims["225"] = ... is incorrect and should just be rims["225"] = ....
Change your php; in the line of code that outputs that text remove the "var". Change this:
print "\nvar rims[\"$width\"] = new Array();\n";
To this:
print "\nrims[\"$width\"] = new Array();\n";
That will solve your problem. But really, this overall solution is not the best. You ought to consider looking into the json-encode php method.
You can take a fully-structured php data structure and with this one command convert to something that can be read by javascript. Try replacing your php with the below and see what happens (note that this is untested, but this is the basic idea):
<?php
while($row = mysql_fetch_array($result)) { list($width, $sidewall, $rim) = explode("/",$row['meta_value']); $menu[$width][$sidewall][$rim] = 1; }
print "var widths = " . json_encode(array_keys($menu)) . ";\n";
print "var sidewalls = " . json_encode($menu) . ";\n";
?>

Categories

Resources