I would like to replicate this highcharts column graph: http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/column-drilldown/
I'm pulling my data from a table and it looks like this.
I want the Job_Num on the x-axis where brands are in the fiddle, PercentofBudgetedHrs would be the brandsData. Now when you click a job number, it drills down to departments and shows their percentage of budgeted hrs.
I have the first part working, but I'm using different code like so: http://jsfiddle.net/98Fuq/4/
Here is what I changed in that code:
$sql = "SELECT * FROM view_percentof_budgeted WHERE PercentofBudgetedHrs < 1000 && PercentofBudgetedHrs IS NOT NULL";
$result = mysqli_query($dbc3, $sql);
while($row = mysqli_fetch_assoc($result)) {
$jobNum[] = $row['Job_Num'];
$jobData[$row['Job_Num']] = $row['PercentofBudgetedHrs'];
$jobDrillData[$row['Job_Num']][] = $row;
}
The part I changed in the JS:
var colors = Highcharts.getOptions().colors,
categories = [<?php echo join($jobNum, ',') ?>],
name = '% of budgeted hours',
level = 0,
data = [
<?php echo join($jobData, ',') ?>,
];
function setChart(name, categories, data, color, level) {
chart.xAxis[0].setCategories(categories);
chart.series[0].remove();
chart.addSeries({
name: name,
data: data,
level: level,
color: color || 'red'
});
}
How do I go about doing it the way that first fiddle I posted does it? I like my method of pulling the data from a table so I don't want to use a tsv, I'm just confused on the drilldown part. I've looked at examples but can't seem to figure it out.
Instaed of using join() I advice to prepare correct strucutre of arrays in php, then use json_encode() including JSON_NUMERIC_CHECK flag. As a result you can get this json by $.getJSON and put in highcharts.
Related
im trying to populate a morris.js chart from a set of results. In my controller I create an array of the results and use json_encode to create a json array, here is the output in my view using print_r:
{"Positive":7,"Negative":26,"Pending":786,"Contact the Clinic":242,"Misc":2}
How would I pass this to my morris.js chart to populate the chart using this data as label / value pairs? everything I try I get either a blank chart or an "undefined" variable or "NaN". Here is my controller:
function execute_search()
{
// Retrieve the posted search term.
$search_term = $this->input->post('search');
// Get results count and pass it as json:
$data = $this->search_model->count_res('$p_results_data');
$pos = 0; $neg= 0; $pen = 0; $cont = 0; $misc = 0;
foreach ($data as $item) {
if ($item['result'] === 'Positive') {
$pos++;
} elseif ($item['result'] === 'Negative') {
$neg++;
} elseif ($item['result'] === 'Pending') {
$pen++;
} elseif ($item['result'] === 'Contact the Clinic') {
$cont++;
} else {
$misc++;
}
}
$res = array("Positive"=>$pos, "Negative"=>$neg, "Pending"=>$pen, "Contact the Clinic"=>$cont, "Misc"=>$misc);
$data = json_encode($res);
// Use the model to retrieve results:
$this->data['results'] = $this->search_model->get_results($search_term);
$this->data['chart'] = $data;
$this->data['totals'] = $this->search_model->total_res('$total_res');
// Pass the results to the view.
$this->data['subview'] = ('user/search_results');
$this->load->view('_layout_admin', $this->data);
}
and my morris.js:
$results = "<?php echo $chart ?>";
new Morris.Donut({
element: 'donutEg',
data: [
$results
],
});
Any help is greatly appreciated
Assuming that your morris.js is a normal javascript file, you cannot use php there by default: The server will not parse the .js file so the php source code will appear in your javascript.
You need to either:
Put the morris.js script contents in a php page in a javascript block so that the php gets parsed;
Make an ajax request from your morris.js script to get the data from the server in a separate request;
Set up your server to parse .js files as if they are / contain php.
The last one is just to illustrate what you would need, I would not recommend doing that.
In javascript, JSON.parse is your friend, assuming you have JSON that was created by PHP's json_encode function:
$results = "<?php echo $chart ?>";
new Morris.Donut({
element: 'donutEg',
data: [
JSON.parse( $results )
],
});
OR POSSIBLY
$results = "<?php echo $chart ?>";
new Morris.Donut({
element: 'donutEg',
data: JSON.parse( $results )
});
BUT THE WAY I DO IT
In the view:
<input type="hidden" id="chartData" value='<?php echo $chart; ?>' />
In the JS (using jQuery):
var chartData = $('#chartData').val();
new Morris.Donut({
element: 'donutEg',
data: JSON.parse( chartData )
});
After looking at the documentation for morris.js, I found that this is how you can do it the right way:
// Looking at the docs for morris.js:
// http://jsbin.com/ukaxod/144/embed?js,output
// This is your data, but it's all in one json object
var chartData = JSON.parse( $('#chartData').val() );
// We need to break up that object into parts of the donut
var donutParts = [];
$.each( chartData, function(k,v){
donutParts.push({
label: k,
value: v
});
});
// Now create the donut
Morris.Donut({
element: 'donutEg',
data: donutParts
});
The code I am using is below.
I want to make a simple graph based on the data from my database table.
It is working now but I want date on the bottom axis is not appearing properly.
while the value of variable is
[25-03-15, 1236], [26-03-15, 3000], [27-03-15, 3054], [30-03-15, 4000]
that is right. But I cant get this date on the x-axis. any solution there?
The way I am getting getting this value is
<?php
$usd=$this->db->query('select transaction_date, SUM(amount) as total from transactions GROUP BY transaction_date')->result_array();
$str = '';
for($i=0; $i<count($usd); $i++){
if($i!=0){
$str = $str.', ['.date('d-m-y', strtotime($usd[$i]["transaction_date"])).', '.$usd[$i]["total"].']';
}else{
$str = $str.'['.date('d-m-y', strtotime($usd[$i]["transaction_date"])).', '.$usd[$i]["total"].']';
}
}
echo $str;
?>
Then I pass this data in java script like this:
var graphData = [{
data: [ <?php echo $str; ?>]
}
];
But At the end I can not get the date on x axis.
PS:
I am working on the view of codeigniter application.
Have a look at the documentation for time series data.
You need javascript timestamps. In PHP you get them simply with
strtotime($usd[$i]["transaction_date"]) * 1000
Then your data should look like this:
[1427238000000, 1236], [1427324400000, 3000], ...
For the labels on the x axis, use the timeformat options to get back the format you want:
xaxis: {
mode: "time",
timeformat: "%d-%m-%y"
}
my DB as follows,
date income expenses maincat
2015-02-06 10000 salary
2015-02-05 500 bank charges
2015-02-05 300 rent
2015-02-01 500 bonus
and i'm using following sql query to get DB values.
$sql= mysqli_query($con,"SELECT maincat as label,income as value FROM transaction where date BETWEEN '$date1' AND '$date2' AND email='$user' GROUP BY maincat") or die ("error3");
and it goes though following php query,
$arr = array();
While($row1 = mysqli_fetch_assoc($sql)){
$arr[] = $row1;
}
$ar = array_values($arr);
and it gives out put like this,
[{"label":"income","value":"10000"},{"label":"bank charges","value":""},{"label":"rent","value":""},{"label":"bonus","value":"500"}]
and I'm passing that values to java script(Morris.js) to show it in the donut chart. but it doesn't work. when there values as,
[{"label":"income","value":"10000"},{"label":"bonus","value":"500"}]
it works fine.i cant put "" values as "0" because there is no actual income as "bank charges" or "rent" (they are expenses) is there any method to remove this empty values ({"label":"bank charges","value":""} ) from above and get out put as,
[{"label":"income","value":"10000"},{"label":"bonus","value":"500"}]
and my morris.js code as follows,
<script>
Morris.Donut({
element: 'donut',
resize : true,
data : <?php echo json_encode($ar); ?>,
backgroundColor: '#0011',
labelColor: 'black',
colors:[
'#A4A4A4','#FE2E64','#0B610B','#0B615E',
'#FF8000','#088A68','#4B8A08','#A9D0F5',
'#5F4C0B','#F3F781','#81BEF7','#04B431',
'#D7DF01','#BE85F7','#BE59F7','#BE81F7',
'#F4FA58','#0431B4','#D8D8D8','#4C0B5F',
'#086A87','#F7D358','#DF7401','#B18904',
'#045FB4',
],
});
</script>
thank you..
Why not just use a loop to filter the empty items?
$legalArray = array();
foreach($ar as $item){
if(is_numeric($item['value']))
$legalArray[] = $item;
}
Output the $legalArray.
You should check you sql code
SELECT maincat as label,income as value FROM transaction where date BETWEEN '$date1' AND '$date2' AND email='$user' AND label != '' AND value != '' GROUP BY maincat"
May have my query wrong think there is a better way of putting that,
also you can use php to do the check
While($row1 = mysqli_fetch_assoc($sql)){
if (!empty($row1['label']) && !empty($row1['value']))
$arr[] = $row1;
}
I'm trying to create a range area chart using CanvasJS and PHP to load the data from a database.
I've created the php and it returns the values from the DB.
Here is the php:
<?php
header('Content-Type: application/json');
$con = mysqli_connect("127.0.0.1","root","pwd1","db");
// Check connection
if (mysqli_connect_errno($con))
{
echo "Failed to connect to DataBase: " . mysqli_connect_error();
}else
{
$data_points = array();
$result = mysqli_query($con, "select (CalYear+1) as CalYear, concat('[',REPLACE(Year1PercWC,',','.'),',',REPLACE(Year1PercBC,',','.'),']') as ResultSet, concat('Sessies: ',calyear) as Help FROM table where cat='1' and (CalYear+1)<year(now())");
while($row = mysqli_fetch_array($result))
{
$point = array("x" => $row['CalYear'] , "y" => $row['ResultSet'],"name" => $row['Help']);
array_push($data_points, $point);
}
echo json_encode($data_points);
}
mysqli_close($con);
?>
With the results:
[{"x":"2007","y":"[35.94,35.94]","name":"Sessies: 2006"},{"x":"2008","y":"[27.67,27.67]","name":"Sessies: 2007"},...,...]
The problem are the quotes in the x and y values (=string values). CanvasJS only takes numbers to create a graph. So the output should be like:
[{"x":2007,"y":[35.94,35.94],"name":"Sessies 2006"},{"x":2008,"y":[27.67,27.67],"name":"Sessies 2007"},...,...]
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title></title>
<script type="text/javascript" src="jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="jquery.canvasjs.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$.getJSON("TestGraf.php", function (result) {
var chart = new CanvasJS.Chart("chartContainer", {
axisX: {
intervalType: "number",
title: "Year",
interval: 1,
valueFormatString: "#"
},
data: [
{
type: "rangeArea",
dataPoints: result
[{"x":2007,"y":[35.94,35.94],"name":"Sessies 2006"},{"x":2008,"y":[27.67,27.67],"name":"Sessies 2007"}] -- This is working fine
}
]
});
chart.render();
});
});
</script>
</head>
<body>
<div id="chartContainer" style="width: 800px; height: 380px;"></div>
</body>
</html>
I'm sure there must be a way to adapt my php so that x and y are passed through as numbers instead of strings, but i'm really new at php (first time ever) and can't find the solution,especially for the second part (y).
Can anyone tell me which adaptions to make to the php and/or html file?
Thx,
This should probably work for you :
json_encode($arr, JSON_NUMERIC_CHECK);
It's probably a little too late for my answer but like Alex answered, you should use echo json_encode($data_points, JSON_NUMERIC_CHECK);
The numeric check is an option. See http://php.net/manual/en/json.constants.php
However, more understanding of how a range area chart works seems to be the problem. The range area chart has an X and 2 Y values. The 2 Y values are needed to plot the range. If you simply go to the testgraf.php file in your browser, your JSON result should be:
[{x: somevalue, y:[low_value, high_value]}]
You might have to change your sql statement to get another y value. You can do what you want with that. Anyway, this is what you should do for your php code:
Change
$point = array("x" => $row['CalYear'] , "y" => $row['ResultSet'],"name" => $row['Help']);
to:
$point = array("x" => $row['CalYear'] , "y" => $row['ResultSet', 'some_value'],"name" => $row['Help']);
If your 2 Y values don't change, you may not see a graph line diplayed. Would a line graph be more appropriate?
After some trial and error I found the following solution:
$result1 = mysqli_query($con, "select (CalYear+1) as CalYear, Year1PercWC, Year1PercBC, calyear as Help FROM table_2 where cat='1' and (CalYear+1)<year(now())");
while($row = mysqli_fetch_array($result1))
{
$point = array("x" => floatval($row['CalYear']),"y" => array(floatval($row['Year1PercWC']),floatval($row['Year1PercBC'])),"name" => floatval($row['Help']));
array_push($data_points, $point);
}
echo json_encode($data_points);
The problem was I needed to create an array for my Y-values in the array for the datapoints. In this array I could store the 2 values I needed for the graph.
After this was done I needed to transform al the numeric values to float_val so that the quotes around the values disappeared.
Thx for the help everyone :)
I am using this website as a reference as how to create charts dynamically using PHP data from a database. http://www.chartjs.org/
So now I have this code after replacing some data with some php code.
<?php
$query = "SELECT * from `users` WHERE firstName = '$name' OR lastName = '$name' LIMIT 1";
$result = mysql_query($query); //<<<
$row = mysql_fetch_assoc($result);
$userid = $row['id'];
echo mysql_error();
$sql = "SELECT * FROM history WHERE userid = '$userid' ORDER BY `date` ASC";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result))
{
$pointData[] = (int)$row["points"];
$dateData[] = date("d M", $row["date"] );
}
?>
<script>
var data = {
labels : <?php echo json_encode($dateData); ?>,
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : <?php echo json_encode($pointData); ?>
}
]
}
var graphOptions =
{
bezierCurve: false,
scaleOverride: true,
scaleSteps: <?php echo max($pointData); ?>,
scaleStepWidth: 1,
scaleStartValue: 0
}
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx).Line(data, graphOptions);
</script>
As you can see everything is done through a script, but the problem is this.
The months are being repeated which makes the data look very hard to read. I made this table using data from a table that has a tuple for time whenever a point is added to a certain ID like this.
So how do I stop the months from repeating itself? Is it because the UNIX timestamp also records days? If so how do I stop that?
Based on your comment, using a monthly display instead of individual days, I would first generate a linear scale of all months and then add all your points to it (you could do the same for days, years, etc.).
Something like:
$months = array();
// using months for just one year, but you could easily adapt it for multiple years
for ($i = 1; $i <= 12; $i++)
{
$months[$i] = 0; // set the initial count to 0
}
// add the points to the appropiate months
while($row = mysql_fetch_array($result))
{
$cur_month = date('n', $row["date"]);
$months[$cur_month] += (int) $row["points"];
}
// your keys are the months and the values the total number of points
$dateData = array_keys($months);
$pointData = array_values($months);
Now you just have the month numbers on the horizontal axis, but that can easily be adapted. Also note that you can shorten this, I just used things like array_keys and array_values to show what is happening exactly and how the $months array relates to your code.