PHP Classes

File: demos/060.php

Recommend this page to a friend!
  Classes of Tom Schaefer   d3   demos/060.php   Download  
File: demos/060.php
Role: Example script
Content type: text/plain
Description: shows how to push a sql query result into a grouped bar chart
Class: d3
Output charts using D3.js JavaScript library
Author: By
Last change:
Date: 11 years ago
Size: 10,956 bytes
 

Contents

Class file image Download
<?php include_once '../d3.classes.inc.php'; class d3GroupedBarChartData { protected $username = "root"; protected $password = ""; protected $database = "northwind"; protected $host = "localhost"; protected $query = "SELECT IFNULL(country, 'other') AS country, IFNULL(jahr,'Total') as `year`, SUM(profit) as amount FROM sales GROUP BY country, year;"; public $results = array(); public function __construct($query=null, $conn=null){ if($query) $this->query = $query; if(is_array($conn)){ foreach($conn as $key => $val){ if(property_exists($this, $key)){ $this->{$key} = $val; } } } } protected function fetchData(){ $link=mysql_connect($this->host,$this->username,$this->password); @mysql_select_db($this->database) or die( "Unable to select database"); $rs = mysql_query($this->query,$link) or die('Error: '.$this->query); if(mysql_num_rows($rs)) { $value = null; $index = 0; while($value = mysql_fetch_assoc($rs)) { $this->results[$value["country"]][($value["year"]==""?"other":$value["year"])] = $value["amount"]; $this->results[$value["country"]]["country"] = $value["country"]; $index++; } } mysql_close(); } public function getBarValueName(){ return "amount"; } public function getBarTitleName(){ return "country"; } public function getResults(){ $results = array(); foreach($this->results as $row){ $results[] = $row; } return $results; } public function execute(){ $this->fetchData(); } } class d3GroupedBarChart { /** * @var d3GroupedBarChartData $data */ protected $data; protected $config = array(); protected $stack = array(); protected $register = array(); protected $barTitleName; protected $barValueName; public function __construct(d3GroupedBarChartData $data, $config = array()){ $this->data = $data; $this->prepareConfig($config); } protected function has($name){ return array_key_exists($name, $this->register); } protected function get($name){ return $this->register[$name]; } protected function set($name, $value){ $this->register[$name] = $value; return $this; } protected function add($value){ $this->stack[] = $value; return $this; } protected function prepareConfig($config){ $this->config = array( "width" => 960, "height" => 500, "margin" => array("top" => 20, "right" => 20, "bottom" => 30, "left" => 40), "color" => array("#ff0000", "#00ff00", "#0000ff", "#ffff00"), ); $this->config = array_merge_recursive($this->config, $config); } protected function prepareDataSet(){ $this->data->execute(); $this->barTitleName = $this->data->getBarTitleName(); $this->barValueName = $this->data->getBarValueName(); $this->set("dataset", d3::variable(d3::unescape( json_encode($this->data->getResults()) ),"data")); $this->add( $this->get("dataset") ); } protected function prepareDimensions(){ $this->set("margin", d3::variables(array("margin" => o3($this->config["margin"]))) ); $this->add( $this->get("margin") ); $this->set("width", d3::variable(d3::unescape( $this->config["width"]."-margin.left-margin.right"), "width") ); $this->set("height", d3::variable(d3::unescape( $this->config["height"]."-margin.top-margin.bottom"), "height") ); $this->add( $this->get("width") ); $this->add( $this->get("height") ); } protected function prepareOrdinalScale(){ $this->set("x0", d3() ->scale(d3::property) ->ordinal()->rangeRoundBands(array(0, $this->get("width")->getVar()), 0.1)->returnVar("x0") ); $this->add( $this->get("x0") ); $this->set("x1", d3() ->scale(d3::property) ->ordinal()->returnVar("x1") ); $this->add( $this->get("x1") ); $this->set("y", d3() ->scale(d3::property) ->linear()->range(array($this->get("height")->getVar(), 0))->returnVar("y") ); $this->add( $this->get("y") ); } protected function prepareColorSet(){ $this->set("color", d3() ->scale(d3::property) ->ordinal()->range($this->getColors()) ->returnVar("color") ); $this->add( $this->get("color") ); } protected function getColors(){ foreach($this->config["color"] as $index => $color){ $this->config["color"][$index] = d3::escape($color); } return $this->config["color"]; } protected function prepareAxis(){ $this->set("xAxis", d3()->svg(d3::property)->axis() ->scale($this->get("x0")->getVar())->orient("bottom")->returnVar("xAxis") ); $this->add( $this->get("xAxis") ); $this->set("yAxis", d3()->svg(d3::property)->axis() ->scale($this->get("y")->getVar()) ->orient("left")->tickFormat(d3()->format(".2s"))->returnVar("yAxis") ); $this->add( $this->get("yAxis")->linebreak() ); } protected function prepareCanvas(){ $this->set("svg", d3() ->select("body")->append("svg")->linebreak()->tab() ->attr("width", d3::unescape( $this->get("width")->getVar()."+margin.left+margin.right"))->linebreak()->tab() ->attr("height", d3::unescape( $this->get("height")->getVar()."+margin.top+margin.bottom"))->linebreak()->tab() ->append("g")->attr("transform" , d3::unescape('"translate("+margin.left+ "," + margin.top + ")"'))->returnVar("svg") ); $this->add( $this->get("svg")->linebreak() ); } protected function prepareChart(){ $this->prepareChartMethods(); $this->prepareChartBarAxes(); $this->prepareChartBarColumn(); $this->prepareChartLegend(); } protected function prepareChartMethods(){ $this->set("amountNames", d3()->keys(d3::unescape("data[1]"))->filter(function($key){return $key !== "country";})->createVar("amountNames")); $this->add( $this->get("amountNames")); $this->add( $this->get("dataset")->get()->forEach(d3::unescape("function(d) {d.amounts = amountNames.map(function(name) { return {name: name, value: parseInt((!+d[name]?0:+d[name]))}; });}")) ->colon() ); $this->add( $this->get("x0")->get()->domain($this->get("dataset")->get()->map(function($d){return $d->country;}))->colon() ); $this->add( $this->get("x1")->get()->domain($this->get("amountNames")->getVar())->rangeRoundBands(array(0, $this->get("x0")->get()->rangeBand()))->colon() ); $this->add( $this->get("y")->get()->domain( array( 0, d3::unescape("d3.max(data,function(d){return d3.max(d.amounts,function(d){return d.value;});})") ) )->colon()->linebreak() ); } protected function prepareChartBarAxes(){ $this->add( $this->get("svg")->get() ->append("g")->linebreak()->tab() ->attr("class", "x axis")->linebreak()->tab() ->attr("transform", d3::unescape('"transform(0, "+height+")"'))->linebreak()->tab() ->call($this->get("xAxis")->getVar()) ->colon() ); $this->add( $this->get("svg")->get() ->append("g")->linebreak()->tab() ->call($this->get("yAxis")->getVar())->linebreak()->tab() ->append("text")->linebreak()->tab() ->attr("transform", "rotate(-90)")->linebreak()->tab() ->attr("y", 6)->linebreak()->tab() ->attr("dy", ".71em")->linebreak()->tab() ->style("text-anchor","end")->linebreak()->tab() ->text($this->barValueName) ->colon()->linebreak() ); } protected function prepareChartBarColumn(){ $this->set($this->barTitleName, $this->get("svg")->get() ->selectAll(".".$this->barTitleName)->linebreak()->tab() ->data($this->get("dataset")->getVar())->linebreak()->tab() ->enter()->append("g")->linebreak()->tab() ->attr("class","g")->linebreak()->tab() ->attr("transform", function($d){return "translate(".$x0($d->country).",0)";}) ->createVar($this->barTitleName) ); $this->add( $this->get($this->barTitleName)); $this->add( $this->get($this->barTitleName)->get() ->selectAll("rect")->linebreak()->tab() ->data(function($d){return $d->amounts;})->linebreak()->tab() ->enter()->append("rect")->linebreak()->tab() ->attr("width", $this->get("x1")->get()->rangeBand())->linebreak()->tab() ->attr("height", function($d){return $height-$y($d->value);})->linebreak()->tab() ->attr("x", function($d){return $x1($d->name);})->linebreak()->tab() ->attr("y", function($d){return $y($d->value);})->linebreak()->tab() ->style("fill", function($d){return $color($d->name);})->linebreak() ); } protected function prepareChartLegend(){ $this->set("legend", $this->get("svg")->get() ->selectAll(".legend")->linebreak()->tab() ->data($this->get("amountNames")->get()->slice()->reverse())->linebreak()->tab() ->enter()->append("g")->linebreak()->tab() ->attr("class", "legend")->linebreak()->tab() ->attr("transform", function($d, $i){return "translate(0," . $i * 20 . ")";}) ->createVar("legend") ); $this->add( $this->get("legend")); $this->add( $this->get("legend")->get()->append("rect")->linebreak()->tab() ->attr("y", d3::unescape($this->get("height")->getVar()."/2"))->linebreak()->tab() ->attr("x", d3::unescape($this->get("width")->getVar()."-28"))->linebreak()->tab() ->attr("width", 18)->linebreak()->tab() ->attr("height", 18)->linebreak()->tab() ->attr("fill", $this->get("color")->getVar()) ->colon() ); $this->add( $this->get("legend")->get()->append("text")->linebreak()->tab() ->attr("x", d3::unescape($this->get("width")->getVar()."-30"))->linebreak()->tab() ->attr("y", d3::unescape($this->get("height")->getVar()."/2 +9"))->linebreak()->tab() ->attr("dy", ".35em")->linebreak()->tab() ->style("text-anchor", "end")->linebreak()->tab() ->text(function($d){return $d;}) ->colon() ); } protected function init(){ $this->prepareDataSet(); $this->prepareDimensions(); $this->prepareOrdinalScale(); $this->prepareColorSet(); $this->prepareAxis(); $this->prepareCanvas(); $this->prepareChart(); $this->stack[] = "\n"; $this->object = implode("\n", $this->stack); } public function render() { $this->init(); $this->stack[] = "\n"; return $this->object; } } ?><!DOCTYPE html> <meta charset="utf-8"> <style> body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .bar { fill: steelblue; } .x.axis path { display: none; } </style> <script src="http://d3js.org/d3.v3.min.js"></script> </head> <body> <div id="viz"></div> <script type="text/javascript"> <?php $script = new d3GroupedBarChart(new d3GroupedBarChartData()); echo $script->render(); ?> </script> </body> </html>