New dashboard and Graphics Engine Class, that also includes the SVG Vector Graphics...
authorJoe Hunt <joe.hunt.consulting@gmail.com>
Tue, 15 Jun 2021 19:59:05 +0000 (21:59 +0200)
committerJoe Hunt <joe.hunt.consulting@gmail.com>
Tue, 15 Jun 2021 19:59:05 +0000 (21:59 +0200)
admin/dashboard.php
includes/dashboard.inc
reporting/fonts/FreeSans.ttf [new file with mode: 0644]
reporting/includes/class.graphic.inc
reporting/includes/reports_classes.inc
reporting/rep102.php
reporting/rep202.php
reporting/rep706.php
reporting/rep707.php

index 7b538159246666b3a0b3e47623c101d74d2a61c4..e44806d1955aa1d5ed517acb6ed844bde8518f31 100644 (file)
@@ -9,23 +9,30 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
 ***********************************************************************/
-
-if (isset($_GET['sel_app']))
-{
-       $page_security = 'SA_SETUPDISPLAY'; // A very low access level. The real access level is inside the routines.
        $path_to_root = "..";
 
        include_once($path_to_root . "/includes/session.inc");
        include_once($path_to_root . "/includes/ui.inc");
+       include_once($path_to_root . "/includes/data_checks.inc");
        include_once($path_to_root . "/reporting/includes/class.graphic.inc");
-       include_once($path_to_root . "/includes/dashboard.inc"); // here are all the dashboard routines.
-
+       if (file_exists("$path_to_root/themes/".user_theme()."/dashboard.inc"))
+               include_once("$path_to_root/themes/".user_theme()."/dashboard.inc"); // yse theme dashboard.inc
+       else
+               include_once("$path_to_root/includes/dashboard.inc"); // here are all the dashboard routines.
+       $page_security = 'SA_SETUPDISPLAY'; // A very low access level. The real access level is inside the routines.
+       $app = isset($_GET['sel_app']) ? $_GET['sel_app'] : (isset($_POST['sel_app']) ? $_POST['sel_app'] : "orders");
+       if (get_post('id'))
+       {
+               dashboard($app);
+               exit;
+       }
+       
        $js = "";
        if ($SysPrefs->use_popup_windows)
                $js .= get_js_open_window(800, 500);
 
        page(_($help_context = "Dashboard"), false, false, "", $js);
-       dashboard($_GET['sel_app']);
+       dashboard($app);
        end_page();
        exit;
-}
+
index 9a5a9f4b5ce57e024ebc5292ffecdcfde36c7e31..56f69a56dc1e87c276b1ca470788e65fba175fc6 100644 (file)
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
 ***********************************************************************/
+//$colors = array('#008cc9','#4db625','#ef5500','#eef100','#05c6e6', '#5ee66a'); // Current in Use      
+$colors = Chart::$palette;
+$style = "<style>
+div.square {
+       display: inline-block;
+       width: 200px;
+       height:40px;
+       padding: 3px 0 0 5px;
+       font-size:12px;
+       font-weight:normal;
+       text-align: left;
+       line-height: 1.2;
+       color:#fff;
+       border-radius:6px;
+}
 
-function dashboard($sel_app)
-{
-       $selected_app = $sel_app;
+div.square1 {
+       background:{$colors[1]};
+}
+div.square2 {
+       background:{$colors[2]};
+}
 
+.span1 {
+       width:200px;
+       padding:0;
+       margin:0;
+       font-size:16px;
+       font-weight:bold;
+       text-align: center;
+}
+</style>";
 
+function dashboard($sel_app)
+{
+       global  $style;
        if (is_object($sel_app) && !$_SESSION["wa_current_user"]->check_application_access($selected_app))
                return;
-       // first have a look through the directory, 
-       // and remove old temporary pdfs and pngs
-       $dir = company_path(). '/pdf_files';
-
-       if ($d = @opendir($dir)) {
-               while (($file = readdir($d)) !== false) {
-                       if (!is_file($dir.'/'.$file) || $file == 'index.php') continue;
-               // then check to see if this one is too old
-                       $ftime = filemtime($dir.'/'.$file);
-                // seems 3 min is enough for any report download, isn't it?
-                       if (time()-$ftime > 180){
-                               unlink($dir.'/'.$file);
+       echo $style;
+       echo "<script> 
+       function chart_update(el, id)
+       {
+               var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
+               xhr.onreadystatechange=function()
+               {
+                       if (xhr.readyState==4 && xhr.status==200)
+                       {
+                               var xxx = document.createElement('div');
+                               xxx.innerHTML = xhr.responseText;
+                               document.getElementById(id).innerHTML = xxx.querySelector('#'+id).innerHTML;
                        }
                }
-               closedir($d);
+               xhr.open('POST', location.pathname, true);
+               xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+               xhr.send('id='+id+'&'+el.id+'='+el.value+'&sel_app=$sel_app');          
        }
-
+       </script>";
        //check_for_overdue_recurrent_invoices();
-       if ($selected_app == "orders")
+       if ($sel_app == "orders")
                display_customer_topten();
-       elseif ($selected_app == "AP")
+       elseif ($sel_app == "AP")
                display_supplier_topten();
-       elseif ($selected_app == "stock")
+       elseif ($sel_app == "stock")
                display_stock_topten();
-       elseif ($selected_app == "manuf")
+       elseif ($sel_app == "manuf")
                display_stock_topten(1);
-       elseif ($selected_app == "assets")
+       elseif ($sel_app == "assets")
                display_stock_topten(2);
-       elseif ($selected_app == "proj")
+       elseif ($sel_app == "proj")
                display_dimension_topten();
-       elseif ($selected_app == "GL")
+       elseif ($sel_app == "GL")
                display_gl_info();
        else    
                display_all();
 }
 
-function display_title($title)
+function display_title($title, $id=false, $type = false, $per = '', $num = false)
 {
        br();
-       display_heading($title);
+       start_form();
+       echo "<div>";
+       echo "<span class='headingtext'>$title</span>";
+       if ($id)
+       {
+               /*
+               global $Ajax;
+               echo "<span style='margin-left:10px;text-align:right;'>";
+               $options = array('select_submit' => true ); 
+               if (!empty($per))
+               {
+                       $name = "per_$id";
+                       $sel1 = array(3 => "3", 4 => "4", 5 => "5", 6 => "6", 7 => "7", 8=> "8");
+                       echo array_selector($name, $per, $sel1, $options);
+                       echo " $per\n";
+               }
+               else
+               {
+                       $name = "select_$id";
+                       $sel = array(1 => _("Vertical bars"), 2 => _("Horizontal bars"), 3 => _("Dots"), 4 => _("Lines"), 5 => _("Pie"), 6 => _("Donut"), 7 => _("Half Donut"), 8 => _("Splines"), 9 => _("Tables"));
+                       echo array_selector($name, $type, $sel, $options);
+               }
+               if (list_updated($name))
+                       $Ajax->activate($id);
+               echo "</span>";
+               */
+               echo "<span style='margin-left:10px;text-align:right;'>";
+               if (!empty($per))
+               {
+                       $sel1 = array(3 => "3", 4 => "4", 5 => "5", 6 => "6", 7 => "7", 8=> "8");
+                       echo "<select id='per_$id' name='per_$id' style='border:1px solid #bbb;color:#555;' onchange='chart_update(this, \"$id\");'>";
+                       foreach ($sel1 as $i => $s)
+                       {
+                               echo "<option value='$i'";
+                               if ($num && $i == $num) 
+                                       echo " selected";
+                               echo ">$s</option>";
+                       }
+                       echo "</select> $per\n";
+               }
+               else
+               {
+                       $sel = array(1 => _("Vertical bars"), 2 => _("Horizontal bars"), 3 => _("Dots"), 4 => _("Lines"), 5 => _("Pie"), 6 => _("Donut"), 7 => _("Half Donut"), 8 => _("Splines"), 9 => _("Tables"));
+                       echo "<select id='select_$id' name='select_$id' style='border:1px solid #bbb;color:#555;' onchange='chart_update(this, \"$id\");'>";
+                       foreach ($sel as $i => $s)
+                       {
+                               echo "<option value='$i'";
+                               if ($type && $i == $type) 
+                                       echo " selected";
+                               echo ">$s</option>";
+                       }
+                       echo "</select>\n";
+               }
+               echo "</span>";
+       }
+       echo "</div>\n";        
+       end_form();
        br();
-       //echo "<tr><td colspan=$colspan class='headingtext' style='background-color:#fff;text-align:center;border:0;height:40px;'>$title</td></tr>\n";
 }      
 
-function table_one()
+function table($width='100%', $twidth=false)
 {
-       echo "<table width='100%'>";
-       echo "<tr valign=top><td style='width:50%'>\n"; // outer table
+       $tstyle = ($twidth != false) ? "style='width:$twidth;'" : "";
+       echo "<table width='$width'><tr valign=top><td align='center' $tstyle>";
 }
 
-function table_two()
+function td($width=false)
 {
-       echo "</td><td style='width:50%'>\n";
-}
+       $style = ($width != false) ? "style='width:$width;'" : "";
+       echo "</td><td align='center' $style>\n";
+}      
 
 function table_end()
 {
        echo "</td></tr></table>\n";
 }
 
-function display_customer_topten()
+function headers($labels)
 {
-       $pg = new graph();
+       echo "<tr>\n";
+       foreach ($labels as $label)
+               echo "<td class='tableheader'>$label</td>\n";
+       echo "</tr>\n";
+}
 
-       table_one();
-       $today = Today();
+function display_customer_topten()
+{
+       table('100%', '25%');
+       echo "<div class='square square1'>"._('Customers')."<p class='span1'>";
+       echo get_num_customers()."</p></div>";
+       td('25%');
+       echo "<div class='square square1'>"._('Branches')."<p class='span1'>";
+       echo get_num_branches()."</p></div>";
+       td('25%');
+       echo "<div class='square square1'>"._('Salesmen')."<p class='span1'>";
+       echo get_num_salesmen()."</p></div>";
+       td('25%');
+       echo "<div class='square square2'>"._('Overdue Invoices')."<p class='span1'>";
+       echo get_num_overdue_sales()."</p></div>";
+       table_end();
+       $pg = new chart('horizontalBar', 'c1');
+       if (isset($_POST['select_c1']))
+               $pg->type = $_POST['select_c1'];
+       $today = calc_today();
+       table('100%', '50%');
        $title = customer_top($today, 10, 66, $pg);
-       customer_trans($today);
-       table_two();
-       source_graphic($today, $title, _("Customer"), $pg, _("Sales"));
+       $total = customer_aging($today, 66);
+       td('50%');
+       source_graphic($today, $title[0], _("Customer"), $pg);
+       br(3);
+       echo "<div class='square square1'>"._('Sales Total')."<p class='span1'>";
+       echo number_format2($title[1])."</p></div>";
+       br(3);
+       echo "<div class='square square1'>"._('Aging Total')."<p class='span1'>";
+       echo number_format2($total)."</p></div>";
+       table_end();
+       table('100%', '100%');
        customer_recurrent_invoices($today);
+       customer_trans($today);
        table_end();
 }
 
 function display_supplier_topten()
 {
-       $pg = new graph();
-
-       $today = Today();
-       table_one();
+       table('100%', '25%');
+       echo "<div class='square square2'>"._('Suppliers')."<p class='span1'>";
+       echo get_num_suppliers()."</p></div>";
+       td('25%');
+       echo "<div class='square square2'>"._('New Orders')."<p class='span1'>";
+       echo get_new_purch_orders()."</p></div>";
+       td('25%');
+       echo "<div class='square square2'>"._('Invoices')."<p class='span1'>";
+       echo get_num_supp_invoices()."</p></div>";
+       td('25%');
+       echo "<div class='square square2'>"._('Overdue Invoices')."<p class='span1'>";
+       echo get_num_overdue_purch()."</p></div>";
+       table_end();
+       $pg = new chart('horizontalBar', 's1');
+       if (isset($_POST['select_s1']))
+               $pg->type = $_POST['select_s1'];
+       $today = calc_today();
+       table('100%', '50%');
        $title = supplier_top($today, 10, 66, $pg);
+       $total = supplier_aging($today, 66);
+       td('50%');
+       source_graphic($today, $title[0], _("Supplier"), $pg);
+       br(3);
+       echo "<div class='square square2'>"._('Purchable Total')."<p class='span1'>";
+       echo number_format2($title[1])."</p></div>";
+       br(3);
+       echo "<div class='square square2'>"._('Aging Total')."<p class='span1'>";
+       echo number_format2($total)."</p></div>";
+       table_end();
+       table('100%', '100%');
        supplier_trans($today);
-       table_two();
-       source_graphic($today, $title, _("Supplier"), $pg, _("Purchase"));
        table_end();
 }
 
 function display_stock_topten($type=0)
 {
-       $pg = new graph();
-
-       table_one();
-       $today = Today();
-       $title = stock_top($today, 10, 66, $type, $pg);
-       table_two();
+       if ($type == 0)
+       {
+               table('100%', '25%');
+               echo "<div class='square square1'>"._('Items')."<p class='span1'>";
+               echo get_num_items()."</p></div>";
+               td('25%');
+               echo "<div class='square square1'>"._('Locations')."<p class='span1'>";
+               echo get_num_locations()."</p></div>";
+               td('25%');
+               echo "<div class='square square1'>"._('Kits')."<p class='span1'>";
+               echo get_num_kits()."</p></div>";
+               td('25%');
+               echo "<div class='square square2'>"._('Below Reorder Level')."<p class='span1'>";
+               echo get_num_reorder()."</p></div>";
+               table_end();
+       }
+       elseif ($type == 1)
+       {
+               table('100%', '25%');
+               echo "<div class='square square1'>"._('Assembled Items')."<p class='span1'>";
+               echo get_num_assembled()."</p></div>";
+               td('25%');
+               echo "<div class='square square1'>"._('Manufactured Items')."<p class='span1'>";
+               echo get_num_manufactured()."</p></div>";
+               td('25%');
+               echo "<div class='square square1'>"._('Work Centres')."<p class='span1'>";
+               echo get_num_workcentres()."</p></div>";
+               td('25%');
+               echo "<div class='square square1'>"._('Open Workorders')."<p class='span1'>";
+               echo get_open_workorders()."</p></div>";
+               table_end();
+       }
+       elseif ($type == 2)
+       {
+               table('100%', '25%');
+               echo "<div class='square square1'>"._('Fixed Assets')."<p class='span1'>";
+               echo get_num_fixed_assets()."</p></div>";
+               td('25%');
+               echo "<div class='square square1'>"._('Locations')."<p class='span1'>";
+               echo get_num_fixed_locations()."</p></div>";
+               td('25%');
+               echo "<div class='square square1'>"._('Categories')."<p class='span1'>";
+               echo get_num_fixed_categories()."</p></div>";
+               td('25%');
+               echo "<div class='square square1'>"._('Fixed Asset Classes')."<p class='span1'>";
+               echo get_num_fixed_classes()."</p></div>";
+               table_end();
+       }
+       $pg = new chart('bar', 'i1');
+       if (isset($_POST['select_i1']))
+               $pg->type = $_POST['select_i1'];
+       table('100%', '50%');
+       $today = calc_today();
+       $title = stock_top($today, 5, 66, $type, $pg);
+       table('50%', '25%');
+       echo "<div class='square square1'>"._('Total Sales')."<p class='span1'>";
+       echo number_format2($title[1])."</p></div>";
+       td('25%');
+       echo "<div class='square square2'>"._('Total Costs')."<p class='span1'>";
+       echo number_format2($title[2])."</p></div>";
+       table_end();
+       td('50%');
        if ($type == 2)
                $source = _("Fixed Assets");
        elseif ($type == 1)
                $source = _("Manufacturing");
        else    
                $source = _("Items");
-       source_graphic($today, $title, $source, $pg, ($type == 0 ? _("Sales") : _("Amount")), 
-               ($type == 0 ? _("Costs") : null));
+       source_graphic($today, $title[0], $source, $pg);
+       echo "<div class='square'><span>"._('Total Results')."<br />";
+       echo number_format2($title[3])."</div>";
+       table_end();
+       table('100%', '100%');
+       stock_below_reorder($today, $type);
        table_end();
 }
 
 function display_dimension_topten()
 {
-       $pg = new graph();
-
-       table_one();
-       $today = Today();
-       $title = dimension_top($today, 10, 66, $pg);
-       table_two();
-       source_graphic($today, $title, _("Dimension"), $pg, _("Performance"), null, 5);
+       table('100%', '25%');
+       echo "<div class='square square1'>"._('Dimensions')."<p class='span1'>";
+       echo get_num_dimensions()."</p></div>";
+       td('25%');
+       echo "<div class='square square1'>"._('Type 2 Dimensions')."<p class='span1'>";
+       echo get_dim_type2()."</p></div>";
+       td('25%');
+       $res = get_dim_total();
+       $s = $res[0] < 0.0 ? 2 : 1;
+       echo "<div class='square square{$s}'>"._('Dimensions Total Balance')."<p class='span1'>";
+       echo number_format2($res[0])."</p></div>";
+       td('25%');
+       $s = $res[1] < 0.0 ? 2 : 1;
+       echo "<div class='square square{$s}'>"._('Dimensions Total Result')."<p class='span1'>";
+       echo number_format2($res[1])."</p></div>";
+       table_end();
+       $pg = new chart('bar', 'd1');
+       if (isset($_POST['select_d1']))
+               $pg->type = $_POST['select_d1'];
+       table('100%', '50%');
+       $today = calc_today();
+       $title = dimension_top($today, 5, 66, $pg);
+       td('50%');
+       source_graphic($today, $title, _("Dimension"), $pg);
        table_end();
 }      
 
 function display_gl_info()
 {
-       $pg = new graph();
-
-       table_one();
-       $today = Today();
+       $today = calc_today();
+       table('100%', '25%');
+       echo "<div class='square square1'>"._('Receivables')."<p class='span1'>";
+       echo number_format2(customer_balance($today))."</p></div>";
+       td('25%');
+       echo "<div class='square square2'>"._('Payables')."<p class='span1'>";
+       echo number_format2(-supplier_balance($today))."</p></div>";
+       td('25%');
+       echo "<div class='square square1'>"._('Todays Deposits')."<p class='span1'>";
+       echo number_format2(get_today_deposits($today))."</p></div>";
+       td('25%');
+       echo "<div class='square square2'>"._('Todays Payments')."<p class='span1'>";
+       echo number_format2(get_today_payments($today))."</p></div>";
+       table_end();
+       $pg = new chart('halfDonut', 'g1');
+       if (isset($_POST['select_g1']))
+               $pg->type = $_POST['select_g1'];
+       table('100%', '50%');
        $title = gl_top($today, 66, $pg);
+       source_graphic($today, $title, _("Class"), $pg);
+       gl_month_performance($today, 66, 5);
+       td('50%');
+       gl_week_performance($today, 66, 4);
+       cash_flow($today);
        bank_balance($today, 66);
-       table_two();
-       source_graphic($today, $title, _("Class"), $pg, _("Amount"), null, 5);
-       gl_performance($today, 66, 5);
        table_end();
 }      
 
 function display_all()
 {
-       $today = Today();
-       $pg = new graph();
+       $today = calc_today();
 
-       table_one();
+       table('100%', '25%');
+       echo "<div class='square square1'>"._('Users')."<p class='span1'>";
+       echo get_num_users()."</p></div>";
+       td('25%');
+       echo "<div class='square square1'>"._('Extensions')."<p class='span1'>";
+       echo get_num_extensions()."</p></div>";
+       td('25%');
+       echo "<div class='square square1'>"._('Languages')."<p class='span1'>";
+       echo get_num_languages()."</p></div>";
+       td('25%');
+       echo "<div class='square square1'>"._('Database Size')."<p class='span1'>";
+       echo get_database_size()."</p></div>";
+       table_end();
+       $pg = new chart('horizontalBar', 'c2');
+       if (isset($_POST['select_c2']))
+               $pg->type = $_POST['select_c2'];
+       table('100%', '50%');
        $title = customer_top($today, 3, 66, $pg);
-       source_graphic($today, $title, _("Customer"), $pg, _("Sales"));
-       $pg = new graph();
+       source_graphic($today, $title[0], _("Customer"), $pg);
+       $pg = new chart('horizontalBar', 's2');
+       if (isset($_POST['select_s2']))
+               $pg->type = $_POST['select_s2'];
        $title = supplier_top($today, 3, 66, $pg);
-       source_graphic($today, $title, _("Supplier"), $pg, _("Purchases"));
-       $pg = new graph();
+       source_graphic($today, $title[0], _("Supplier"), $pg);
+       $pg = new chart('bar', 'i2');
+       if (isset($_POST['select_i2']))
+               $pg->type = $_POST['select_i2'];
        $title = stock_top($today, 3, 66, 0, $pg);
-       source_graphic($today, $title, _("Items"), $pg, _("Sales"), _("Costs"));
-       table_two();
+       source_graphic($today, $title[0], _("Items"), $pg);
+       td('50%');
        dimension_top($today, 3, 66);
-       $pg = new graph();
+       $pg = new chart('pie', 'd2');
+       if (isset($_POST['select_d2']))
+               $pg->type = $_POST['select_d2'];
        $title = gl_top($today, 66, $pg);
-       source_graphic($today, $title, _("Class"), $pg, _("Amount"), null, 5);
+       source_graphic($today, $title, _("Class"), $pg);
        stock_top($today, 3, 66, 2);
        stock_top($today, 3, 66, 1);
        table_end();
 }
 
-function customer_top($today, $limit=10, $width="33", &$pg=null)
+function customer_top($today, $limit=10, $width='33', &$pg=null)
 {
-       $begin = begin_fiscalyear();
-       $begin1 = date2sql($begin);
-       $today1 = date2sql($today);
-       $sql = "SELECT SUM((ov_amount + ov_discount) * rate * IF(trans.type = ".ST_CUSTCREDIT.", -1, 1)) AS total,d.debtor_no, d.name FROM
-               ".TB_PREF."debtor_trans AS trans, ".TB_PREF."debtors_master AS d WHERE trans.debtor_no=d.debtor_no
+       $begin = date2sql(begin_fiscalyear());
+       $today = date2sql($today);
+       $sql = "SELECT SUM((ov_amount + ov_discount) * rate * IF(trans.type = ".ST_CUSTCREDIT.", -1, 1)) AS total,d.debtor_no, d.name FROM ".TB_PREF."debtor_trans AS trans, ".TB_PREF."debtors_master AS d WHERE trans.debtor_no=d.debtor_no
                AND (trans.type = ".ST_SALESINVOICE." OR trans.type = ".ST_CUSTCREDIT.")
-               AND tran_date >= '$begin1' AND tran_date <= '$today1' GROUP by d.debtor_no ORDER BY total DESC, d.debtor_no 
+               AND tran_date >= '$begin' AND tran_date <= '$today' GROUP by d.debtor_no ORDER BY total DESC, d.debtor_no
                LIMIT $limit";
        $result = db_query($sql);
        $title = sprintf(_("Top %s customers in fiscal year"), $limit);
        display_title($title);
        $th = array(_("Customer"), _("Amount"));
        start_table(TABLESTYLE, "width='$width%'");
-       table_header($th);
+       headers($th);
        check_page_security('SA_SALESTRANSVIEW');
        $k = 0; //row colour counter
-       $i = 0;
+       $i = 1;
+       $names = $totals = array();
+       $sales = 0;
        while ($myrow = db_fetch($result))
        {
-               alt_table_row_color($k);
-               $name = $myrow["debtor_no"]." ".htmlspecialchars_decode($myrow["name"]);
-               label_cell($name);
-               amount_cell($myrow['total']);
-               if ($pg != null)
+               $sales += round($myrow['total']);
+               if ($i++ < $limit)
                {
-                       $pg->x[$i] = $name; 
-                       $pg->y[$i] = $myrow['total'];
-               }       
-               $i++;
-               end_row();
+                       alt_table_row_color($k);
+                       $name = $myrow["debtor_no"]." ".htmlspecialchars_decode($myrow["name"]);
+                       label_cell($name);
+                       amount_cell($myrow['total']);
+                       if ($pg != null)
+                       {
+                               $names[] = $name;
+                               $totals[] = round($myrow['total']);
+                       }       
+                       end_row();
+               }
+       }
+       if ($pg != null)
+       {
+               $pg->setLabels($names);
+               $pg->addSerie(_('Sales'), $totals);
        }
        end_table(2);
-       return $title;
+       return array($title, $sales);
 }
 
-function supplier_top($today, $limit=10, $width="33", &$pg=null)
+function supplier_top($today, $limit=10, $width='33', &$pg=null)
 {
-       $begin = begin_fiscalyear();
-       $begin1 = date2sql($begin);
-       $today1 = date2sql($today);
+       $begin = date2sql(begin_fiscalyear());
+       $today = date2sql($today);
        $sql = "SELECT SUM((trans.ov_amount + trans.ov_discount) * rate) AS total, s.supplier_id, s.supp_name FROM
                ".TB_PREF."supp_trans AS trans, ".TB_PREF."suppliers AS s WHERE trans.supplier_id=s.supplier_id
                AND (trans.type = ".ST_SUPPINVOICE." OR trans.type = ".ST_SUPPCREDIT.")
-               AND tran_date >= '$begin1' AND tran_date <= '$today1' GROUP by s.supplier_id ORDER BY total DESC, s.supplier_id 
+               AND tran_date >= '$begin' AND tran_date <= '$today' GROUP by s.supplier_id ORDER BY total DESC, s.supplier_id
                LIMIT $limit";
        $result = db_query($sql);
        $title = sprintf(_("Top %s suppliers in fiscal year"), $limit);
        display_title($title);
        $th = array(_("Supplier"), _("Amount"));
        start_table(TABLESTYLE, "width='$width%'");
-       table_header($th);
+       headers($th);
        check_page_security('SA_SUPPTRANSVIEW');
        $k = 0; //row colour counter
-       $i = 0;
+       $i = 1;
+       $names = $totals = array();
+       $total = 0;
        while ($myrow = db_fetch($result))
        {
-               alt_table_row_color($k);
-               $name = $myrow["supplier_id"]." ".htmlspecialchars_decode($myrow["supp_name"]);
-               label_cell($name);
-               amount_cell($myrow['total']);
-               if ($pg != null)
+               $total += $myrow['total'];
+               if ($i++ < $limit)
                {
-                       $pg->x[$i] = $name; 
-                       $pg->y[$i] = $myrow['total'];
-               }       
-               $i++;
-               end_row();
+                       alt_table_row_color($k);
+                       $name = $myrow["supplier_id"]." ".htmlspecialchars_decode($myrow["supp_name"]);
+                       label_cell($name);
+                       amount_cell($myrow['total']);
+                       if ($pg != null)
+                       {
+                               $names[] = $name;
+                               $totals[] = round($myrow['total']);
+                       }       
+                       end_row();
+               }
+       }
+       if ($pg != null)
+       {
+               $pg->setLabels($names);
+               $pg->addSerie(_('Purchases'), $totals);
        }
        end_table(2);
-       return $title;
+       return array($title, $total);
 }
 
-function stock_top($today, $limit=10, $width="33", $type=0, &$pg=null)
+function stock_top($today, $limit=10, $width='33', $type=0, &$pg=null)
 {
        if ($type == 2)
                $sec = 'SA_ASSETSANALYTIC';
@@ -255,9 +528,8 @@ function stock_top($today, $limit=10, $width="33", $type=0, &$pg=null)
                $sec = 'SA_WORKORDERANALYTIC';
        else
                $sec = 'SA_ITEMSTRANSVIEW';
-       $begin = begin_fiscalyear();
-       $begin1 = date2sql($begin);
-       $today1 = date2sql($today);
+       $begin = date2sql(begin_fiscalyear());
+       $today = date2sql($today);
        if ($type == 0)
        {
                $sql = "SELECT SUM((trans.unit_price * trans.quantity) * d.rate) AS total, s.stock_id, s.description, 
@@ -277,9 +549,8 @@ function stock_top($today, $limit=10, $width="33", $type=0, &$pg=null)
                        $sql .= "AND s.mb_flag='F' ";
        }
        if ($type != 2)
-               $sql .= "AND tran_date >= '$begin1' ";
-       $sql .= "AND tran_date <= '$today1' GROUP by s.stock_id ORDER BY total DESC, s.stock_id 
-               LIMIT $limit";
+               $sql .= "AND tran_date >= '$begin' ";
+       $sql .= "AND tran_date <= '$today' GROUP by s.stock_id ORDER BY total DESC, s.stock_id LIMIT $limit";
        $result = db_query($sql);
        if ($type == 1)
                $title = sprintf(_("Top %s Manufactured Items in fiscal year"), $limit);
@@ -289,178 +560,442 @@ function stock_top($today, $limit=10, $width="33", $type=0, &$pg=null)
                $title = sprintf(_("Top %s Sold Items in fiscal year"), $limit);
        display_title($title);  
        if ($type == 0) 
-               $th = array(_("Item"), _("Sales"), _("Costs"), _("Quantity"));
+               $th = array(_("Item"), _("Sales"), _("Costs"), _("Results"), _("Quantity"));
        else    
                $th = array(_("Item"), _("Amount"), _("Quantity"));
        start_table(TABLESTYLE, "width='$width%'");
-       table_header($th);
+       headers($th);
        check_page_security($sec);
        $k = 0; //row colour counter
-       $i = 0;
+       $i = 1;
+       $names = $totals = $costs = $results = array();
+       $sales = $cost = $res = 0;
        while ($myrow = db_fetch($result))
        {
-               alt_table_row_color($k);
-               $name = $myrow["description"];
-               label_cell($name);
-               amount_cell($myrow['total']);
+               $sales += $myrow['total'];
                if ($type == 0)
-                       amount_cell($myrow['costs']);
-               qty_cell($myrow['qty']);
-               if ($pg != NULL)
                {
-                       $pg->x[$i] = $name; 
-                       $pg->y[$i] = $myrow['total'];
+                       $cost += $myrow['costs'];
+                       $res += ($myrow['total'] - $myrow['costs']);
+               }
+               if ($i++ < $limit)
+               {
+                       alt_table_row_color($k);
+                       $name = $myrow["description"];
+                       label_cell($name);
+                       amount_cell($myrow['total']);
                        if ($type == 0)
-                               $pg->z[$i] = $myrow['costs'];
-               }       
-               $i++;
-               end_row();
+                       {
+                               amount_cell($myrow['costs']);
+                               amount_cell($myrow['total'] - $myrow['costs']);
+                       }
+                       qty_cell($myrow['qty']);
+                       if ($pg != NULL)
+                       {
+                               $names[] = $name;
+                               $totals[] = round($myrow['total']);     
+                               if ($type == 0)
+                               {
+                                       $costs[] = round($myrow['costs']);
+                                       $results[] = round($myrow['total'] - $myrow['costs']);
+                               }
+                       }       
+                       end_row();
+               }
+       }
+       if ($pg != null)
+       {
+               $pg->setLabels($names);
+               $pg->addSerie(_('Sales'), $totals);
+               if ($type == 0)
+               {
+                       $pg->addSerie(_('Costs'), $costs);
+                       $pg->addSerie(_('Results'), $results, 8);
+               }
        }
        end_table(2);
-       return $title;
+       return array($title, $sales, $cost, $res);
 }
 
-function dimension_top($today, $limit=10, $width="33", &$pg=null)
+function dimension_top($today, $limit=10, $width='33', &$pg=null)
 {
+       $begin = date2sql(begin_fiscalyear());
+       $today = date2sql($today);
 
-       $begin = begin_fiscalyear();
-       $begin1 = date2sql($begin);
-       $today1 = date2sql($today);
-       $sql = "SELECT SUM(-t.amount) AS total, d.reference, d.name FROM
-               ".TB_PREF."gl_trans AS t,".TB_PREF."dimensions AS d WHERE
-               (t.dimension_id = d.id OR t.dimension2_id = d.id) AND
-               t.tran_date >= '$begin1' AND t.tran_date <= '$today1' GROUP BY d.id ORDER BY total DESC LIMIT $limit";
+       $sql = "SELECT SUM(IF(c.ctype > 3, -amount, 0)) AS result, SUM(IF(c.ctype < 4, amount, 0)) AS balance, d.reference, d.name FROM ".TB_PREF."gl_trans g 
+               LEFT JOIN ".TB_PREF."chart_master AS a ON g.account = a.account_code
+               LEFT JOIN ".TB_PREF."chart_types AS t ON t.id = a.account_type
+               LEFT JOIN ".TB_PREF."dimensions AS d ON (g.dimension_id = d.id OR g.dimension2_id = d.id)
+               LEFT JOIN ".TB_PREF."chart_class AS c ON t.class_id = c.cid
+               WHERE IF(c.ctype > 3, tran_date >= '$begin', tran_date >= '0000-00-00') 
+               AND tran_date <= '$today'  AND d.reference IS NOT NULL GROUP BY d.reference ORDER BY d.reference DESC LIMIT $limit";    
        $result = db_query($sql, "Transactions could not be calculated");
        $title = sprintf(_("Top %s Dimensions in fiscal year"), $limit);
        display_title($title);
-       $th = array(_("Dimension"), _("Amount"));
+       $th = array(_("Dimension"), _("Balance"), _("Result"));
        start_table(TABLESTYLE, "width='$width%'");
-       table_header($th);
+       headers($th);
        check_page_security('SA_DIMTRANSVIEW');
        $k = 0; //row colour counter
-       $i = 0;
+       $names = $balances = $results = array();
        while ($myrow = db_fetch($result))
        {
                alt_table_row_color($k);
                $name = $myrow['reference']." ".$myrow["name"];
                label_cell($name);
-               amount_cell($myrow['total']);
+               amount_cell($myrow['balance']);
+               amount_cell($myrow['result']);
                if ($pg != null)
                {
-                       $pg->x[$i] = $name; 
-                       $pg->y[$i] = abs($myrow['total']);
+                       $names[] = $name; 
+                       $balances[] = round(abs($myrow['balance']));
+                       $results[] = round(abs($myrow['result']));
                }       
-               $i++;
                end_row();
        }
+       if ($pg != null)
+       {
+               $pg->setLabels($names);
+               $pg->setValues(true);
+               $pg->addSerie(_('Balance'), $balances);
+               $pg->addSerie(_('Result'), $results);
+       }
        end_table(2);
        return $title;
 }
 
-function gl_top($today, $width="33", &$pg=null)
+function gl_top($today, $width='33', &$pg=null)
 {
-       $begin = begin_fiscalyear();
-       $begin1 = date2sql($begin);
-       $today1 = date2sql($today);
-       $sql = "SELECT SUM(amount) AS total, c.class_name, c.ctype FROM
+       $begin = date2sql(begin_fiscalyear());
+       $today = date2sql($today);
+       $sql = "SELECT SUM(IF(c.ctype > 3, -amount, amount)) AS total, c.class_name, c.ctype FROM
                ".TB_PREF."gl_trans,".TB_PREF."chart_master AS a, ".TB_PREF."chart_types AS t, 
                ".TB_PREF."chart_class AS c WHERE
                account = a.account_code AND a.account_type = t.id AND t.class_id = c.cid
-               AND IF(c.ctype > 3, tran_date >= '$begin1', tran_date >= '0000-00-00') 
-               AND tran_date <= '$today1' GROUP BY c.cid ORDER BY c.cid"; 
+               AND IF(c.ctype > 3, tran_date >= '$begin', tran_date >= '0000-00-00') 
+               AND tran_date <= '$today' GROUP BY c.cid ORDER BY c.cid"; 
        $result = db_query($sql, "Transactions could not be calculated");
        $title = _("Class Balances");
        display_title($title);
        start_table(TABLESTYLE2, "width='$width%'");
        check_page_security('SA_GLANALYTIC');
-       $i = 0;
        $total = 0;
+       $names = $totals = array();
        while ($myrow = db_fetch($result))
        {
                if ($myrow['ctype'] > 3)
                {
-                       $total += $myrow['total'];
-                       $myrow['total'] = -$myrow['total'];
+                       $total += round($myrow['total']);
                        if ($pg != null)
                        {
-                               $pg->x[$i] = $myrow['class_name']; 
-                               $pg->y[$i] = abs($myrow['total']);
+                               $names[] = $myrow['class_name']; 
+                               $totals[] = round(abs($myrow['total']));
                        }       
-                       $i++;
                }       
                label_row($myrow['class_name'], number_format2($myrow['total'], user_price_dec()), 
                        "class='label' style='font-weight:bold;'", "style='font-weight:bold;' align=right");
        }
        $calculated = _("Calculated Return");
        label_row("&nbsp;", "");
-       label_row($calculated, number_format2(-$total, user_price_dec()), 
+       label_row($calculated, number_format2($total, user_price_dec()), 
                "class='label' style='font-weight:bold;'", "style='font-weight:bold;' align=right");
        if ($pg != null)
        {
-               $pg->x[$i] = $calculated; 
-               $pg->y[$i] = -$total;
+               $names[] = $calculated; 
+               $totals[] = $total;
+               $pg->setLabels($names);
+               $pg->addSerie(_('Totals'), $totals);
+               $pg->setValues(true);
+               $pg->setDTitle(number_format2($total));
        }
        end_table(2);
        return $title;
 }
 
-function gl_performance($today, $width="33", $weeks=5)
+function gl_week_performance($today, $width="33", $weeks=4)
 {
        global $SysPrefs;
-       $pg = new graph();
-
-       $begin = begin_fiscalyear();
-       $begin1 = date2sql($begin);
+       
+       $pg = new chart('bar', 'g3');
+       if (isset($_POST['select_g3']))
+               $pg->type = $_POST['select_g3'];
+       if (isset($_POST['per_g3']))
+               $weeks = $_POST['per_g3'];
+       $begin = date2sql(begin_fiscalyear());
        $today1 = date2sql($today);
        $sep = $SysPrefs->dateseps[user_date_sep()];
        $sql = "SELECT week_name, sales, costs 
-               FROM(SELECT DATE_FORMAT(tran_date, '%Y{$sep}%u') AS week_name, 
+               FROM(SELECT DATE_FORMAT(tran_date, '%X{$sep}%V') AS week_name, 
                        SUM(IF(c.ctype = 4, amount * -1, 0)) AS sales, 
                        SUM(IF(c.ctype = 6, amount, 0)) AS costs FROM 
                        ".TB_PREF."gl_trans, ".TB_PREF."chart_master AS a, ".TB_PREF."chart_types AS t, 
                        ".TB_PREF."chart_class AS c WHERE(c.ctype = 4 OR c.ctype = 6) 
                        AND account = a.account_code AND a.account_type = t.id AND t.class_id = c.cid 
-                       AND tran_date >= '$begin1' AND tran_date <= '$today1' 
+                       AND tran_date >= '$begin' AND tran_date <= '$today1' 
                        GROUP BY week_name ORDER BY week_name DESC LIMIT 0, $weeks) b 
                GROUP BY week_name ORDER BY week_name ASC";
        $result = db_query($sql, "Transactions could not be calculated");
        $title = _("Last $weeks weeks Performance");
        check_page_security('SA_GLANALYTIC');
-       $i = 0;
+       $week_names = $sales = $costs = $results = array();
        while ($myrow = db_fetch($result))
        {
-               $pg->x[$i] = $myrow['week_name']; 
-               $pg->y[$i] = $myrow['sales'];
-               $pg->z[$i] = $myrow['costs'];
-               $i++;
+               $week_names[] = $myrow['week_name']; 
+               $sales[] = round($myrow['sales']);
+               $costs[] = round($myrow['costs']);
+               $results[] = round($myrow['sales'] - $myrow['costs']);
        }       
-       
-       source_graphic($today, $title, _("Week"), $pg, _("Sales"), _("Costs"), 1);
+       $pg->setLabels($week_names);
+       $pg->addSerie(_('Sales'), $sales, 'bar');
+       $pg->addSerie(_('Costs'), $costs, 'bar');
+       $pg->addSerie(_('Results'), $results, 8);
+       source_graphic($today, $title, _("Week"), $pg, _("Weeks"), $weeks);
 }
 
-function source_graphic($today, $title, $x_axis, $pg, $graphic1, $graphic2=null, $type=2)
+function gl_month_performance($today, $width="33", $months=5)
 {
-       if (count($pg->y) ==0 || (count($pg->y) == 1 && $pg->y[0] == 0))
+       global $SysPrefs;
+       $pg = new chart('bar', 'g4');
+       if (isset($_POST['select_g4']))
+               $pg->type = $_POST['select_g4'];
+       if (isset($_POST['per_g4']))
+               $months = $_POST['per_g4'];
+       $begin = date2sql(begin_fiscalyear());
+       $today1 = date2sql($today);
+       $sep = $SysPrefs->dateseps[user_date_sep()];
+       $sql = "SELECT month_name, sales, costs 
+               FROM(SELECT DATE_FORMAT(tran_date, '%Y{$sep}%m') AS month_name, 
+                       SUM(IF(c.ctype = 4, amount * -1, 0)) AS sales, 
+                       SUM(IF(c.ctype = 6, amount, 0)) AS costs FROM 
+                       ".TB_PREF."gl_trans, ".TB_PREF."chart_master AS a, ".TB_PREF."chart_types AS t, 
+                       ".TB_PREF."chart_class AS c WHERE(c.ctype = 4 OR c.ctype = 6) 
+                       AND account = a.account_code AND a.account_type = t.id AND t.class_id = c.cid 
+                       AND tran_date >= '$begin' AND tran_date <= '$today1' 
+                       GROUP BY month_name ORDER BY month_name DESC LIMIT 0, $months) b 
+               GROUP BY month_name ORDER BY month_name ASC";
+       $result = db_query($sql, "Transactions could not be calculated");
+       $title = _("Last $months Months Performance");
+       check_page_security('SA_GLANALYTIC');
+       $month_names = $sales = $costs = $results = array();
+       while ($myrow = db_fetch($result))
+       {
+               $month_names[] = $myrow['month_name']; 
+               $sales[] = round($myrow['sales']);
+               $costs[] = round($myrow['costs']);
+               $results[] = round($myrow['sales'] - $myrow['costs']);
+       }       
+       $pg->setLabels($month_names);
+       $pg->addSerie(_('Sales'), $sales, 'bar');
+       $pg->addSerie(_('Costs'), $costs, 'bar');
+       $pg->addSerie(_('Results'), $results, 8);
+       source_graphic($today, $title, _("Month"), $pg, _("Months"), $months);
+}
+
+function customer_aging($today, $width="33")
+{
+       $pg = new chart('bar', 'c3');
+       if (isset($_POST['select_c3']))
+               $pg->type = $_POST['select_c3'];
+       $today1 = date2sql($today);
+       $past1 = get_company_pref('past_due_days');
+       $past2 = 2 * $past1;
+       // removed - debtor_trans.alloc from all summations
+       $sign = "IF(`type` IN(".implode(',',  array(ST_CUSTCREDIT,ST_CUSTPAYMENT,ST_BANKDEPOSIT))."), -1, 1)";
+       $value = "IFNULL($sign*((trans.ov_amount + trans.ov_gst + trans.ov_freight + trans.ov_freight_tax + trans.ov_discount - 
+               trans.alloc)*trans.rate),0)";
+       $due = "IF (trans.type=".ST_SALESINVOICE.", trans.due_date, trans.tran_date)";
+    $sql = "SELECT Sum($value) AS Balance,
+                               Sum(IF ((TO_DAYS('$today1') - TO_DAYS($due)) > 0,$value,0)) AS Due,
+                               Sum(IF ((TO_DAYS('$today1') - TO_DAYS($due)) > $past1,$value,0)) AS Overdue1,
+                               Sum(IF ((TO_DAYS('$today1') - TO_DAYS($due)) > $past2,$value,0)) AS Overdue2
+                       FROM ".TB_PREF."debtors_master debtor
+                                LEFT JOIN ".TB_PREF."debtor_trans trans ON trans.tran_date <= '$today1' AND debtor.debtor_no = trans.debtor_no AND trans.type <> ".ST_CUSTDELIVERY.","
+                                .TB_PREF."payment_terms terms,"
+                                .TB_PREF."credit_status credit_status
+                       WHERE
+                                       debtor.payment_terms = terms.terms_indicator
+                               AND debtor.credit_status = credit_status.id";
+               $sql .= " AND ABS(trans.ov_amount + trans.ov_gst + trans.ov_freight + trans.ov_freight_tax + trans.ov_discount - trans.alloc) > ".FLOAT_COMP_DELTA;
+    $result = db_query($sql,"The customer details could not be retrieved");
+
+    $row = db_fetch($result);
+
+       $title = _("Total Customers Aged Analysis");
+       check_page_security('SA_SALESTRANSVIEW');
+       $names = array();
+       $past1a = $past1 + 1;
+       $past2a = $past2 + 1;
+       $names = array(_('Current'),"1-$past1", "$past1a-$past2", "$past2+");
+       $balances = array(round($row['Balance']-$row['Due']), round($row['Due'] - $row['Overdue1']), 
+               round($row['Overdue1'] - $row['Overdue2']), round($row['Overdue2']));
+       $total = round($row['Balance']);
+       $pg->setLabels($names);
+       $pg->addSerie(_('Balances'), $balances);
+       source_graphic($today, $title, _('Days'), $pg);
+       return $total;
+}
+
+function customer_balance($today)
+{
+       $today = date2sql($today);
+       $sign = "IF(`type` IN(".implode(',',  array(ST_CUSTCREDIT,ST_CUSTPAYMENT,ST_BANKDEPOSIT))."), -1, 1)";
+       $value = "IFNULL($sign*((trans.ov_amount + trans.ov_gst + trans.ov_freight + trans.ov_freight_tax + trans.ov_discount - 
+               trans.alloc)*trans.rate),0)";
+       $due = "IF (trans.type=".ST_SALESINVOICE.", trans.due_date, trans.tran_date)";
+    $sql = "SELECT Sum($value) AS Balance
+                       FROM ".TB_PREF."debtors_master debtor
+                                LEFT JOIN ".TB_PREF."debtor_trans trans ON trans.tran_date <= '$today' AND debtor.debtor_no = trans.debtor_no AND trans.type <> ".ST_CUSTDELIVERY."
+                       WHERE ABS(trans.ov_amount + trans.ov_gst + trans.ov_freight + trans.ov_freight_tax + trans.ov_discount - trans.alloc) > ".FLOAT_COMP_DELTA;
+    $result = db_query($sql,"The customer details could not be retrieved");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function supplier_aging($today, $width="33")
+{
+       $pg = new chart('bar', 's3');
+       if (isset($_POST['select_s3']))
+               $pg->type = $_POST['select_s3'];
+       $today1 = date2sql($today);
+       $past1 = get_company_pref('past_due_days');
+       $past2 = 2 * $past1;
+       // removed - debtor_trans.alloc from all summations
+       $value = "IF (trans.type=".ST_SUPPINVOICE." OR trans.type=".ST_BANKDEPOSIT.", 
+       (trans.ov_amount + trans.ov_gst + trans.ov_discount - trans.alloc) * trans.rate,
+       (trans.ov_amount + trans.ov_gst + trans.ov_discount + trans.alloc) * trans.rate)";
+       $due = "IF (trans.type=".ST_SUPPINVOICE." OR trans.type=".ST_SUPPCREDIT.",trans.due_date,trans.tran_date)";
+    $sql = "SELECT Sum($value) AS Balance,
+                               Sum(IF ((TO_DAYS('$today1') - TO_DAYS($due)) > 0,$value,0)) AS Due,
+                               Sum(IF ((TO_DAYS('$today1') - TO_DAYS($due)) > $past1,$value,0)) AS Overdue1,
+                               Sum(IF ((TO_DAYS('$today1') - TO_DAYS($due)) > $past2,$value,0)) AS Overdue2
+                       FROM ".TB_PREF."suppliers supplier, ".TB_PREF."supp_trans trans
+                               WHERE supplier.supplier_id = trans.supplier_id
+                       AND trans.tran_date <= '$today1'
+                       AND ABS(trans.ov_amount + trans.ov_gst + trans.ov_discount) > ".FLOAT_COMP_DELTA."
+                       AND ABS(trans.ov_amount + trans.ov_gst + trans.ov_discount) - trans.alloc > ".FLOAT_COMP_DELTA;
+    $result = db_query($sql,"The supplier details could not be retrieved");
+
+    $row = db_fetch($result);
+
+       $title = _("Total Suppliers Aged Analysis");
+       check_page_security('SA_SUPPLIERANALYTIC');
+       $names = array();
+       $past1a = $past1 + 1;
+       $past2a = $past2 + 1;
+       $names = array(_('Current'),"1-$past1", "$past1a-$past2", "$past2+");
+       $balances = array(round($row['Balance']-$row['Due']), round($row['Due'] - $row['Overdue1']), 
+               round($row['Overdue1'] - $row['Overdue2']), round($row['Overdue2']));
+       $total = round($row['Balance']);
+       $pg->setLabels($names);
+       $pg->addSerie(_('Balances'), $balances);
+       source_graphic($today, $title, _('Days'), $pg);
+       return $total;
+}
+
+function supplier_balance($today)
+{
+       $today = date2sql($today);
+       $value = "IF (trans.type=".ST_SUPPINVOICE." OR trans.type=".ST_BANKDEPOSIT.", 
+       (trans.ov_amount + trans.ov_gst + trans.ov_discount - trans.alloc) * trans.rate,
+       (trans.ov_amount + trans.ov_gst + trans.ov_discount + trans.alloc) * trans.rate)";
+    $sql = "SELECT Sum($value) AS Balance
+                       FROM ".TB_PREF."suppliers supplier, ".TB_PREF."supp_trans trans
+                               WHERE supplier.supplier_id = trans.supplier_id
+                       AND trans.tran_date <= '$today'
+                       AND ABS(trans.ov_amount + trans.ov_gst + trans.ov_discount) > ".FLOAT_COMP_DELTA."
+                       AND ABS(trans.ov_amount + trans.ov_gst + trans.ov_discount) - trans.alloc > ".FLOAT_COMP_DELTA;
+    $result = db_query($sql,"The supplier details could not be retrieved");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function cash_flow($today)
+{
+       global $date_system, $SysPrefs;
+       $months = 6;
+       $pg = new chart('spline', 'g5');
+       if (isset($_POST['select_g5']))
+               $pg->type = $_POST['select_g5'];
+       if (isset($_POST['per_g5']))
+               $months = $_POST['per_g5'];
+       if (!is_date_in_fiscalyear($today))
+               $today = end_fiscalyear();
+       $today1 = begin_month($today);
+       $today1 = add_months($today, -$months+1);
+       list($da, $mo, $yr) = explode_date_to_dmy($today1);
+       if ($date_system == 1)
+               list($yr, $mo, $da) = jalali_to_gregorian($yr, $mo, $da);
+       elseif ($date_system == 2)
+               list($yr, $mo, $da) = islamic_to_gregorian($yr, $mo, $da);
+
+       $date = array();
+
+       for ($i = 0; $i < $months; $i++)
+               $date[$i] = date('Y-m-d',mktime(0,0,0,$mo + $i,1,$yr));
+
+       $result = get_bank_accounts();
+       $total =  array_fill(0, $months, 0);
+       $balance = array_fill(0, $months, 0);
+       while ($account=db_fetch($result))
+       { 
+               $sql = "SELECT";
+               for ($i = 0; $i < $months; $i++)
+                       $sql .= " SUM(CASE WHEN trans_date < '$date[$i]' THEN amount ELSE 0 END) AS per0".($i+1).",";
+               $sql = substr($sql, 0, -1);
+               $sql .= " FROM ".TB_PREF."bank_trans
+                       WHERE bank_act=".$account['id'];
+               $res = db_query($sql, "Transactions for bank account could not be calculated");
+               $bal = db_fetch($res);
+               $is_home = is_company_currency($account['bank_curr_code']);
+               for ($i = 1; $i <= $months; $i++)
+                       $balance[$i - 1] = $bal['per0'.$i];
+               for ($i = 0; $i < $months; $i++)
+               {
+                       if (!$is_home)
+                               $balance[$i] = to_home_currency($balance[$i], $account['bank_curr_code'], sql2date($date[$i])); 
+                       $total[$i] += $balance[$i];
+               }
+       }
+       $sep = $SysPrefs->dateseps[user_date_sep()];
+       for ($i = 0; $i < $months; $i++)
+       {
+               $y = substr($date[$i], 0, 4);
+               $m = substr($date[$i], 5, 2);
+               $date[$i] = $y.$sep.$m;
+               $total[$i] = round($total[$i]);
+       }
+       $title = _("Last $months Months Cash Flow");
+       check_page_security('SA_BANKREP');
+       $pg->setLabels($date);
+       $pg->addSerie(_('Balances'), $total, false, true);
+       source_graphic($today, $title, _("Month"), $pg, _("Months"), $months);
+}
+
+function source_graphic($today, $title, $x_axis, $pg, $per = '', $num = false)
+{
+       if (!empty($per))
+               div_start($pg->id);
+       //$today = sql2date($today);
+       display_title("$title ($today)", $pg->id, $pg->type, $per, $num);       
+       if ($pg->isEmpty())
+       {
+               display_note(_("No Data available yet!"), 1);
                return;
-       display_title("$title ($today)");       
-       //$pg->title     = $title . " - " . $today;
-       $pg->axis_x    = $x_axis;
-       $pg->axis_y    = _("Amount");
-       $pg->graphic_1 = $graphic1;
-       if ($graphic2 != null)
-               $pg->graphic_2 = $graphic2;
-       $pg->type      = $type;
-       $pg->skin      = 1;
-       $pg->built_in  = false;
-       $filename = company_path(). "/pdf_files/". random_id().".png";
-       $pg->display($filename, true);
-       start_table(TABLESTYLE);
-       start_row();
-       echo "<td>";
-       echo "<img src='$filename' border='0' alt='$title'>";
-       echo "</td>";
-       end_row();
-       end_table(1);
+       }
+       if ($pg->type == 'horizontalBar')
+       {
+               $pg->setYTitle($x_axis);
+               $pg->setXTitle(_("Amount"));
+       }
+       else
+       {
+               $pg->setXTitle($x_axis);
+               $pg->setYTitle(_("Amount"));
+       }
+       if (empty($per))
+               div_start($pg->id);
+       $pg->display();
+       div_end();
 }
 
 function customer_trans($today)
@@ -485,8 +1020,8 @@ function customer_trans($today)
        display_title($title);
        $th = array("#", _("Ref."), _("Date"), _("Due Date"), _("Customer"), _("Branch"), _("Currency"), 
                _("Total"), _("Remainder"),     _("Days"));
-       start_table(TABLESTYLE);
-       table_header($th);
+       start_table(TABLESTYLE, "width=90%");
+       headers($th);
        $k = 0; //row colour counter
        while ($myrow = db_fetch($result))
        {
@@ -524,8 +1059,8 @@ function customer_recurrent_invoices($today)
        $title = _("Overdue Recurrent Invoices");
        display_title($title);
        $th = array(_("Description"), _("Template No"),_("Customer"),_("Branch")."/"._("Group"),_("Next invoice"));
-       start_table(TABLESTYLE, "width=70%");
-       table_header($th);
+       start_table(TABLESTYLE, "width=90%");
+       headers($th);
        $k = 0;
        while ($myrow = db_fetch($result)) 
        {
@@ -570,8 +1105,8 @@ function supplier_trans($today)
        display_title($title);
        $th = array("#", _("Ref."), _("Date"), _("Due Date"), _("Supplier"), _("Currency"), _("Total"), 
                _("Remainder"), _("Days"));
-       start_table(TABLESTYLE);
-       table_header($th);
+       start_table(TABLESTYLE, "width=90%");
+       headers($th);
        $k = 0; //row colour counter
        while ($myrow = db_fetch($result))
        {
@@ -591,6 +1126,42 @@ function supplier_trans($today)
        end_table(2);
 }
 
+function stock_below_reorder($today, $type)
+{
+       $MB = ($type == 0 ? 'B' : ($type == 1 ? 'M' : 'F'));
+       $today = date2sql($today);
+
+    $sql = "SELECT st.loc_code, l.location_name, st.stock_id, sm.description, reorders.reorder_level AS r, SUM(st.qty) AS q
+               FROM ".TB_PREF."stock_moves st
+               LEFT JOIN ".TB_PREF."voided v ON st.type=v.type AND st.trans_no=v.id
+               LEFT JOIN ".TB_PREF."stock_master sm ON sm.stock_id = st.stock_id 
+               LEFT JOIN ".TB_PREF."loc_stock reorders ON reorders.loc_code=st.loc_code AND
+                       reorders.stock_id = st.stock_id
+               LEFT JOIN ".TB_PREF."locations l ON l.loc_code = st.loc_code 
+          WHERE ISNULL(v.id) AND tran_date <= '$today' AND sm.mb_flag = 'B'
+                       GROUP BY sm.stock_id HAVING q <= r";
+       $result = db_query($sql,"an item reorder could not be retreived");
+       $title = db_num_rows($result) . _(" items are below Reorder Level");
+       display_title($title);
+       $th = array("#", _("Location"), _("Stock Id"), _('Description'), _("Reorder"), _("qty")); 
+       start_table(TABLESTYLE, "width=90%");
+       headers($th);
+       $k = 0; //row colour counter
+       while ($myrow = db_fetch($result))
+       {
+               alt_table_row_color($k);
+               label_cell($myrow['loc_code']);
+               label_cell($myrow['location_name']);
+               label_cell($myrow['stock_id']);
+               label_cell($myrow['description']);
+               $dec = get_qty_dec($myrow['stock_id']);         
+               qty_cell($myrow['r'], false, $dec);
+               qty_cell($myrow['q'], false, $dec);
+               end_row();
+       }
+       end_table(2);
+}
+
 function bank_balance($today, $width)
 {
        $today = date2sql($today);
@@ -605,7 +1176,7 @@ function bank_balance($today, $width)
        display_title($title);
        $th = array(_("Account"), _("Currency"), _("Balance"));
        start_table(TABLESTYLE, "width='$width%'");
-       table_header($th);
+       headers($th);
        $k = 0; //row colour counter
        while ($myrow = db_fetch($result))
        {
@@ -616,4 +1187,314 @@ function bank_balance($today, $width)
                end_row();
        }
        end_table(1);
-}
\ No newline at end of file
+}
+
+function get_num_customers()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."debtors_master";
+       $result = db_query($sql, "Fail in count customers");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_branches()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."cust_branch";
+       $result = db_query($sql, "Fail in count branches");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_salesmen()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."salesman";
+       $result = db_query($sql, "Fail in count salesmen");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_overdue_sales()
+{
+       $today = date2sql(calc_today());
+
+       $sql = "SELECT COUNT(trans.trans_no)    
+               FROM ".TB_PREF."debtor_trans as trans
+               WHERE trans.type = ".ST_SALESINVOICE." AND (trans.ov_amount + trans.ov_gst + trans.ov_freight 
+                       + trans.ov_freight_tax + trans.ov_discount - trans.alloc) > ".FLOAT_COMP_DELTA." 
+                       AND DATEDIFF('$today', trans.due_date) > 0";
+       $result = db_query($sql);
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_suppliers()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."suppliers";
+       $result = db_query($sql, "Fail in count suppliers");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_new_purch_orders()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."purch_orders po, ".TB_PREF."purch_order_details pd WHERE po.order_no = pd.order_no AND 
+               quantity_received < quantity_ordered";
+       $result = db_query($sql, "Fail in count purch orders");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_supp_invoices()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."supp_trans WHERE (ov_amount+ov_discount+ov_gst - alloc) <> 0";
+       $result = db_query($sql, "Fail in count purch invoices");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_overdue_purch()
+{
+       $today = date2sql(calc_today());
+
+       $sql = "SELECT COUNT(*) FROM ".TB_PREF."supp_trans WHERE (ov_amount+ov_discount+ov_gst - alloc) > ".FLOAT_COMP_DELTA." AND DATEDIFF('$today', due_date) > 0";
+       $result = db_query($sql, "Fail in count purch invoices");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_items()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."stock_master";
+       $result = db_query($sql, "Fail in count stock master");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_locations()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."locations";
+       $result = db_query($sql, "Fail in count locations");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_kits()
+{
+       $sql="SELECT count(*) FROM ".TB_PREF."item_codes";
+
+       $result = db_query($sql, "Fail in count kits");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_reorder()
+{
+       $MB = 'B';
+       $today = date2sql(calc_today());
+
+    $sql = "SELECT st.stock_id, reorders.reorder_level AS r, SUM(st.qty) AS q
+               FROM ".TB_PREF."stock_moves st
+               LEFT JOIN ".TB_PREF."voided v ON st.type=v.type AND st.trans_no=v.id
+               LEFT JOIN ".TB_PREF."stock_master sm ON sm.stock_id = st.stock_id 
+               LEFT JOIN ".TB_PREF."loc_stock reorders ON reorders.loc_code=st.loc_code AND
+                       reorders.stock_id = st.stock_id
+          WHERE ISNULL(v.id) AND tran_date <= '$today' AND sm.mb_flag = 'B'
+                       GROUP BY st.stock_id HAVING q <= r";
+       $result = db_query($sql,"an item reorder could not be retreived");
+       return db_num_rows($result);
+}
+
+function get_num_assembled()
+{
+       $begin = date2sql(begin_fiscalyear());
+       $today = date2sql(calc_today());
+       $sql = "SELECT count(*) FROM ".TB_PREF."workorders WHERE closed = 1 AND type = ".WO_ASSEMBLY." AND released_date >= '$begin'
+               AND released_date <= '$today'";
+       $result = db_query($sql, "Fail in count workorders");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_manufactured()
+{
+       $begin = date2sql(begin_fiscalyear());
+       $today = date2sql(calc_today());
+       $sql = "SELECT count(*) FROM ".TB_PREF."workorders WHERE closed = 1 AND type = ".WO_ADVANCED." AND released_date >= '$begin'
+               AND released_date <= '$today'";
+       $result = db_query($sql, "Fail in count workorders");
+    $row = db_fetch($result);
+       return $row[0];
+}
+       
+function get_num_workcentres()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."workcentres";
+       $result = db_query($sql, "Fail in count work centres");
+    $row = db_fetch($result);
+       return $row[0];
+}
+       
+function get_open_workorders()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."workorders WHERE closed = 0";
+       $result = db_query($sql, "Fail in count workorders");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_fixed_assets()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."stock_master WHERE mb_flag = 'F'";
+       $result = db_query($sql, "Fail in count fixed assets");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_fixed_locations()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."stock_master s LEFT JOIN ".TB_PREF."loc_stock l ON s.stock_id = l.stock_id 
+               WHERE mb_flag = 'F'";
+       $result = db_query($sql, "Fail in count locations");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_fixed_categories()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."stock_category c LEFT JOIN ".TB_PREF."stock_master s ON c.category_id = s.category_id 
+               WHERE mb_flag = 'F'";
+       $result = db_query($sql, "Fail in count categories");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_fixed_classes()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."stock_fa_class";
+       $result = db_query($sql, "Fail in count fa classes");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_dimensions()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."dimensions";
+       $result = db_query($sql, "Fail in count dimensions");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_dim_type2()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."dimensions WHERE type_ = 2";
+       $result = db_query($sql, "Fail in count simensions 2");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_dim_closed()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."dimensions WHERE closed = 1";
+       $result = db_query($sql, "Fail in count closed dimensions");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_dim_total()
+{
+       $begin = date2sql(begin_fiscalyear());
+       $today = date2sql(calc_today());
+       
+       $sql = "SELECT SUM(IF(c.ctype > 3, -amount, 0)) AS result, SUM(IF(c.ctype < 4, amount, 0)) AS balance, d.reference, d.name FROM ".TB_PREF."gl_trans g 
+               LEFT JOIN ".TB_PREF."chart_master AS a ON g.account = a.account_code
+               LEFT JOIN ".TB_PREF."chart_types AS t ON t.id = a.account_type
+               LEFT JOIN ".TB_PREF."dimensions AS d ON (g.dimension_id = d.id OR g.dimension2_id = d.id)
+               LEFT JOIN ".TB_PREF."chart_class AS c ON t.class_id = c.cid
+               WHERE IF(c.ctype > 3, tran_date >= '$begin', tran_date >= '0000-00-00') 
+               AND tran_date <= '$today'  AND d.reference IS NOT NULL GROUP BY d.reference";   
+       $bal = $res = 0.0;
+       $result = db_query($sql, "Transactions could not be calculated");
+       while ($row = db_fetch($result))
+       {
+               $bal += $row['balance'];
+               $res += $row['result'];
+       }       
+       return array(round($bal), round($res)); 
+}
+       
+function get_today_deposits($today)
+{
+       $today= date2sql($today);
+       $sql="SELECT SUM(gl.amount) FROM ".TB_PREF."gl_trans gl, ".TB_PREF."bank_accounts ba 
+               WHERE gl.account = ba.account_code AND gl.tran_date = '$today' AND gl.amount > 0.0";
+       $result = db_query($sql, "could not retrieve today deposits");
+       if ($result == false)
+               return 0;
+       else
+       {
+               $row = db_fetch($result);
+               return $row[0];
+       }
+}
+
+function get_today_payments($today)
+{
+       $today= date2sql($today);
+       $sql="SELECT SUM(gl.amount) FROM ".TB_PREF."gl_trans gl, ".TB_PREF."bank_accounts ba 
+               WHERE gl.account = ba.account_code AND gl.tran_date = '$today' AND gl.amount < 0.0";
+       $result = db_query($sql, "could not retrieve today deposits");
+       if ($result == false)
+               return 0;
+       else
+       {
+               $row = db_fetch($result);
+               return $row[0];
+       }
+}
+
+function get_num_users()
+{
+       $sql = "SELECT count(*) FROM ".TB_PREF."users";
+       $result = db_query($sql, "could not get num users");
+    $row = db_fetch($result);
+       return $row[0];
+}
+
+function get_num_extensions()
+{
+       global $installed_extensions;
+       return count($installed_extensions);
+}
+
+function get_num_languages()
+{
+       global $installed_languages;
+       return count($installed_languages);
+}
+
+function get_database_size()
+{
+       global $db_connections;
+       $c = user_company();
+       $dbase = $db_connections[$c]['dbname'];
+       $tb_pref = $db_connections[$c]['tbpref'];
+       $sql = "SHOW TABLE STATUS FROM $dbase";
+       if (!empty($tb_pref))
+               $sql .= " LIKE '{$tb_pref}%'";
+       $result = db_query($sql, "could not get database size");
+    $size = 0;
+    while ($row = db_fetch($result)) {
+               $size += $row['Data_length'];
+               $size += $row['Index_length'];
+    }
+       return number_format2(($size / 1024 / 1024), 2).' MB';
+}
+
+function calc_today()
+{
+       $today = Today();
+       if (!is_date_in_fiscalyear($today))
+               $today = end_fiscalyear();
+       return $today;
+}
+
diff --git a/reporting/fonts/FreeSans.ttf b/reporting/fonts/FreeSans.ttf
new file mode 100644 (file)
index 0000000..4afc544
Binary files /dev/null and b/reporting/fonts/FreeSans.ttf differ
index 81e93d25e6eab66374455f2c8b040103902f1b6a..3f976f73d2f4b986d981996ef7ef7269a64e8cc8 100644 (file)
@@ -1,53 +1,18 @@
 <?php
-/**
-*
-*   graph
-*   version 1.0
-*
-*
-*
-* Author: Carlos Reche/Joe Hunt
-* E-mail: carlosreche@yahoo.com/joe.hunt.consulting@gmail.com
-* Sorocaba, SP - Brazil/Wellington, New Zealand
-*
-* Created: Sep 20, 2004
-* Last Modification: Sep 20, 2004/Apr 01, 2007
-*
-*
-*
-*  Authors' comments:
-*
-*  graph creates 6 different types of graphics with how many parameters you want. You can
-*  change the appearance of the graphics in 3 different skins, and you can still cross data from 2 
-*  graphics in only 1! It's a powerful script, and I recommend you read all the instructions 
-*  to learn how to use all of this features. Don't worry, it's very simple to use it.
-*
-*  This script is free. Please keep the credits.
-*
-*/
-
-/**
-
-   INSTRUNCTIONS OF HOW TO USE THIS SCRIPT  (Please, take a minute to read it. It's important!)
-
-
-   NOTE: make sure that your PHP is compiled to work with GD Lib.
-
-///// START OF EXAMPLE.PHP /////
-
-<?php
-
-require "class.graphics.inc";
-$pg = new graph;
-
-$pg->title = "Sex";
-$pg->type  = "5";
-$pg->x[0]  = "male";
-$pg->y[0]  = "50";
-$pg->x[1]  = "female";
-$pg->y[1]  = "55";
-$pg->display();
-?>
+/*
+
+$pg = new Chart('bar'); // Width and Height is set automatically4
+$pg->setTitle("Testing the Chart");
+$pg->setLabels(array('Jan', 'Feb', 'Mar'));
+$pg->addSerie(array(10345, 15666, 12222), 'Sales', false, true); 
+$pg->addSerie(array(20767, 10456, 2888), 'Costs', false, false);
+$pg->addSerie(array(15657, 7567, 12890), 'Result', 'spline', false);
+$pg->setXTitle("Names");
+$pg->setYTitle("Amount");
+$pg->setDValues(False);
+$pg->setDTitle(number_format("15666")); // only printed on donut or half donut
+$filename = "test.png";
+$pg->display(); // with filename to file
 
 In your html file you set it up as:
 .....
@@ -60,904 +25,1324 @@ file for later presentation.
 
 ///// END OF EXAMPLE.PHP /////
 
-
-
-   Here is a list of all parameters you may set:
-
-   title      =>  Title of the graphic
-   axis_x     =>  Name of values from Axis X
-   axis_y     =>  Name of values from Axis Y
-   graphic_1  =>  Name of Graphic_1 (only shown if you are gonna cross data from 2 different graphics)
-   graphic_2  =>  Name of Graphic_2 (same comment of above)
-
-   type  =>  Type of graphic (values 1 to 6)
-                1 => Vertical bars (default)
-                2 => Horizontal bars
-                3 => Dots
-                4 => Lines
-                5 => Pie
-                6 => Donut
-
-   skin   => Skin of the graphic (values 1 to 3)
-                1 => Office (default)
-                2 => Matrix
-                3 => Spring
-
-   credits => Only if you want to show my credits in the image. :)
-                0 => doesn't show (default)
-                1 => shows
-
-   x[0]  =>  Name of the first parameter in Axis X
-   x[1]  =>  Name of the second parameter in Axis X
-   ... (etc)
-
-   y[0]  =>  Value from "graphic_1" relative for "x[0]"
-   y[1]  =>  Value from "graphic_1" relative for "x[1]"
-   ... (etc)
-
-   z[0]  =>  Value from "graphic_2" relative for "x[0]"
-   z[1]  =>  Value from "graphic_2" relative for "x[1]"
-   ... (etc)
-
-
-   NOTE: You can't cross data between graphics if you use "pie" or "donut" graphic. Values for "z"
-   won't be considerated.
-
-   That's all! Hope you make a good use of it!
-   It would be nice to receive feedback from others users. All comments are welcome!
-
-   Regards,
-
-   Carlos Reche
-
+       Here is a list of all types you may set:
+
+       type
+       ----
+       'bar'                   1 => Vertical bars (default)
+       'horizontalBar' 2 => Horizontal bars
+       'dot'                   3 => Dots
+       'line'                  4 => Lines - Series Type Fill => Area
+       'pie'                   5 => Pie
+       'donut'                 6 => Donut
+       'halfDonut'             7 => Half Donut
+       'spline'                8 => Splines - Series Type fill => Area
+       'table'                 9 => Simple HTML table
+
+       labels[0]  =>  Name of the first parameter in Axis X
+       labels[1]  =>  Name of the second parameter in Axis X
+       ... (etc)
+
+       series[0]['data'][0]  =>  Value relative for "labels[0]"
+       series[0]['data'][1]  =>  Value relative for "labels[1]"
+       ... (etc)
+
+       series[1]['data'][0]  =>  Value relative for "labels[0]"
+       series[1]['data'][1]  =>  Value relative for "labels[1]"
+       ... (etc)
+   
+       NOTE: When using 'pie', 'donut' and 'halfDonut' only the first data set is used.
+   
+       That's all! Hope you make a good use of it!
+       It would be nice to receive feedback from others users. All comments are welcome!
+
+       Regards,
+
+       Joe Hunt
 */
 
-class graph 
+class Chart 
 {
-
-    var $x;
-    var $y;
-    var $z;
-
-    var $title;
-    var $axis_x;
-    var $axis_y;
-    var $graphic_1;
-    var $graphic_2;
-    var $type = 1;
-    var $skin = 1;
-    var $credits = 0;
-    var $latin_notation;
-
-    var $width;
-    var $height;
-    var $height_title;
-    var $alternate_x;
-
-       var $size = 2;
-       var $tsize = 5;
-
-    var $total_parameters;
-    var $sum_total;
-    var $biggest_value;
-    var $biggest_parameter;
-    var $available_types;
-    var $dec1 = 0;
-    var $dec2 = 0;
-    var $h3d = 15; // 3D height
-       var $built_in = false;
+       var $id;
+       var $labels = array();
+       var $series = array();
+       static $palette = array('#008cc9','#4db625','#ef5500','#eef100','#05c6e6', '#5ee66a'); // Currently in Use      
+       var $color = array();
+       var $num_series = 0;
+       var $title;
+       var $axis_x;
+       var $axis_y;
+       var $type = 1;
+       var $donut_title = "";
+       var $set_values = true;
+       var $angle = 0;
+       var $latin_notation;
+       var $width;
+       var $height;
+       var $title_height;
+       var $size = 12;
+       var $tsize = 18;
+       var $num_labels;
+       var $sum_total = array();
+       var $higher_value_size = 0;
+       var $max_value;
+       var $max_label;
+       var $max_legend_str;
+       var $legend_box_height;
+       var $stream = 'svg'; // stream = 'svg', 'png', 'jpg' or 'gif'
+       var $svg; // The SVG engine class.
+       var $img; // png image
+
+       var $dec1 = 0;
+       var $dec2 = 0;
        var $fontfile = "";
        var $encoding;
-       
-    function __construct()
-    {
-       global $SysPrefs;
+       var $out_dir = "";
+       var $dir = "ltr";
+       var $align;
+       var $lang;
+       var $font;
+       var $path;
+
+       function __construct($type = 1, $id = 'id', $width = 0, $height = 0)
+       {
+               global $SysPrefs;
                $this->encoding = strtoupper($_SESSION['language']->encoding);
-               $path = dirname(__FILE__).'/../fonts/';
-
-               // If you use UTF-8 encoding you have to download and install FreeSans.ttf font.
-               // It is not bundled with application due to its size.
-               // You can also use another UTF-8 font and put it in config.php with the name in $UTF8_fontfile 
-               $this->fontfile = $this->encoding == 'UTF-8' ? (isset($SysPrefs->UTF8_fontfile) && $SysPrefs->UTF8_fontfile != "" ?
-                       $path.$SysPrefs->UTF8_fontfile : $path.'FreeSans.ttf') : $path.'LiberationSans-Regular.ttf';
-        
-        $this->x = $this->y = $this->z = array();
-        $this->biggest_x        = NULL;
-        $this->biggest_y        = NULL;
-        $this->alternate_x      = false;
-        $this->graphic_2_exists = false;
-        $this->total_parameters = 0;
-        $this->sum_total        = 1;
-               $this->latin_notation   = false;
-    }
-
-
-    function display($save="", $border=false)
-    {
-        $this->legend_exists        = (preg_match("/(5|6)/", $this->type)) ? true : false;
-        $this->biggest_graphic_name = (strlen($this->graphic_1) > strlen($this->graphic_2)) ? $this->graphic_1 : $this->graphic_2;
-        $this->height_title         = (!empty($this->title)) ? ($this->string_height($this->tsize) + 15) : 0;
-        $this->space_between_bars   = ($this->type == 1) ? 40 : 30;
-        $this->space_between_dots   = 40;
-        $this->higher_value         = 0;
-        $this->higher_value_str     = 0;
-
-        $this->width               = 0;
-        $this->height              = 0;
-        $this->graphic_area_width  = 0;
-        $this->graphic_area_height = 0;
-        $this->graphic_area_x1     = 30;
-        $this->graphic_area_y1     = 20 + $this->height_title;
-        $this->graphic_area_x2     = $this->graphic_area_x1 + $this->graphic_area_width;
-        $this->graphic_area_y2     = $this->graphic_area_y1 + $this->graphic_area_height;
-
-               if (count($this->z) && (preg_match("/(1|2|3|4)/", $this->type)))
-            $this->graphic_2_exists = true;
-        $this->total_parameters    = count($this->x);
-               for ($i = 0; $i < $this->total_parameters; $i++)
+               //$this->encoding = "UTF-8"; // Use alternative if used in FA
+               $this->dir = $_SESSION['language']->dir;
+               //$this->dir = 'ltr';
+               $this->lang = $_SESSION['language']->code == 'C' ? 'en' : substr($_SESSION['language']->code, 0, 2);
+               //$this->lang = 'en';
+               $this->path = dirname(__FILE__).'/../fonts/';
+               //$this->path = dirname(__FILE__).'/';
+               // You can use another UTF-8 font and put it in config.php with the name in $UTF8_fontfile 
+               if ($this->encoding == 'UTF-8' && !empty($SysPrefs->UTF8_fontfile))
+                       $this->fontfile = $this->path.$SysPrefs->UTF8_fontfile;
+               elseif ($this->dir == 'rtl')
+                       $this->fontfile = $this->path.'zarnormal.ttf';
+               else    
+                       $this->fontfile = $this->path.'FreeSans.ttf';
+               //$this->fontfile = $this->path.'FreeSans.ttf';
+               //$this->fontfile = $this->path.'zarnormal.ttf';
+               $this->id = $id;
+               if ($type == 'bar') $type = 1;
+               elseif ($type == 'horizontalBar') $type = 2;
+               elseif ($type == 'dot') $type = 3;
+               elseif ($type == 'line') $type = 4;
+               elseif ($type == 'spline') $type = 8;
+               elseif ($type == 'pie') $type = 5;
+               elseif ($type == 'donut') $type = 6;
+               elseif ($type == 'halfDonut') $type = 7;
+               elseif ($type == 'table') $type = 9;
+               elseif ($type < 1 || $type > 9) $type = 1;
+               elseif (!is_numeric($type)) $type = 1;
+               $this->width = $width;
+               $this->height = $height;
+               $this->max_label   = NULL;
+               $this->max_value        = NULL;
+               $this->num_labels = 0;
+               $this->type = $type;
+               $this->latin_notation   = false;
+               $this->align = $this->dir == 'rtl' ? "end" : "start";
+               $this->font = "Tahoma,Arial,sans-serif";
+               if ($this->stream != 'svg')
                {
-                       if (strlen($this->x[$i]) > strlen($this->biggest_x))
-                $this->biggest_x = $this->x[$i];
-                       if ($this->y[$i] > $this->biggest_y)
-                $this->biggest_y = number_format(round($this->y[$i], 1), 1, ".", "");
-            if ($this->graphic_2_exists)    
-            {
-               if (isset($this->z[$i]) && $this->z[$i] > $this->biggest_y)
-                       $this->biggest_y = number_format(round($this->z[$i], 1), 1, ".", "");
-            }          
-        }
-
-        if (($this->graphic_2_exists == true)  &&  ((!empty($this->graphic_1)) || (!empty($this->graphic_2))))
-        {
-            $this->legend_exists = true;
-        }
-
-        $this->sum_total           = array_sum($this->y);
-        if ($this->sum_total == 0)
-               $this->sum_total = 1;
-        $this->space_between_bars += ($this->graphic_2_exists == true) ? 10 : 0;
-
-        $this->calculate_higher_value();
-        $this->calculate_width();
-        $this->calculate_height();
-
-        $this->create_graphic($save, $border);
-    }
-
-    function create_graphic($save="", $border=false)
-    {
-       $size = 3;
-        $this->img = imagecreatetruecolor($this->width, $this->height);
-
-        $this->load_color_palette();
-
-        // Fill background
-        imagefill($this->img, 0, 0, $this->color['background']);
-
-        // Draw title
-        if (!empty($this->title))
-        {
-            $center = ($this->width / 2) - ($this->string_width($this->title, $this->tsize) / 2);
-            $this->_imagestring($this->img, $this->tsize, $center, 10, $this->title, $this->color['title']);
-        }
-
-
-        // Draw axis and background lines for "vertical bars", "dots" and "lines"
-        if (preg_match("/^(1|3|4)$/", $this->type))
-        {
-            if ($this->legend_exists == true)
-            {
-                $this->draw_legend();
-            }
-
-            $higher_value_y    = $this->graphic_area_y1 + (0.1 * $this->graphic_area_height);
-            $higher_value_size = 0.9 * $this->graphic_area_height;
-
-            $less  = 7 * strlen($this->higher_value_str);
-
-            imageline($this->img, $this->graphic_area_x1, $higher_value_y, $this->graphic_area_x2, $higher_value_y, $this->color['bg_lines']);
-            $this->_imagestring($this->img, $this->size, ($this->graphic_area_x1-$less-7), ($higher_value_y-7), $this->higher_value_str, $this->color['axis_values']);
-
-            for ($i = 1; $i < 10; $i++)
-            {
-                $dec_y = $i * ($higher_value_size / 10);
-                $x1 = $this->graphic_area_x1;
-                $y1 = $this->graphic_area_y2 - $dec_y;
-                $x2 = $this->graphic_area_x2;
-                $y2 = $this->graphic_area_y2 - $dec_y;
-
-                imageline($this->img, $x1, $y1, $x2, $y2, $this->color['bg_lines']);
-                if ($i % 2 == 0) 
-                {
-                    $value = $this->number_formated($this->higher_value * $i / 10, $this->dec1);
-                    $len1 = strlen($this->higher_value_str);
-                    $len2 = strlen($value);
-                    if ($len2 < $len1)
-                       $len2 += ($len1-$len2-1);
-                    $less = 7 * $len2;
-                    $this->_imagestring($this->img, $this->size, ($x1-$less-7), ($y2-7), $value, $this->color['axis_values']);
-                }
-            }
-
-            // Axis X
-            $this->_imagestring($this->img, $this->size, $this->graphic_area_x2+40, $this->graphic_area_y2+3, $this->axis_x, $this->color['title']);
-            imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y2, $this->graphic_area_x2, $this->graphic_area_y2, $this->color['axis_line']);
-            // Axis Y
-            $this->_imagestring($this->img, $this->size, 20, $this->graphic_area_y1-20, $this->axis_y, $this->color['title']);
-            imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y1, $this->graphic_area_x1, $this->graphic_area_y2, $this->color['axis_line']);
-        }
-
-
-        // Draw axis and background lines for "horizontal bars"
-        else if ($this->type == 2)
-        {
-            if ($this->legend_exists == true)
-            {
-                $this->draw_legend();
-            }
-
-            $higher_value_x    = $this->graphic_area_x2 - (0.2 * $this->graphic_area_width);
-            $higher_value_size = 0.8 * $this->graphic_area_width;
-
-            imageline($this->img, ($this->graphic_area_x1+$higher_value_size), $this->graphic_area_y1, ($this->graphic_area_x1+$higher_value_size), $this->graphic_area_y2, $this->color['bg_lines']);
-            $this->_imagestring($this->img, $this->size, (($this->graphic_area_x1+$higher_value_size) - ($this->string_width($this->higher_value, $this->size)/2)), ($this->graphic_area_y2+2), $this->higher_value_str, $this->color['axis_values']);
-
-            for ($i = 1, $alt = 15; $i < 10; $i++)
-            {
-                $dec_x = number_format(round($i * ($higher_value_size  / 10), 1), 1, ".", "");
-
-                imageline($this->img, ($this->graphic_area_x1+$dec_x), $this->graphic_area_y1, ($this->graphic_area_x1+$dec_x), $this->graphic_area_y2, $this->color['bg_lines']);
-                if ($i % 2 == 0) 
-                {
-                    $alt   = (strlen($this->biggest_y) > 4 && $alt != 15) ? 15 : 2;
-                    $value = $this->number_formated($this->higher_value * $i / 10, $this->dec1);
-                    $this->_imagestring($this->img, $this->size, (($this->graphic_area_x1+$dec_x) - ($this->string_width($this->higher_value, $this->size)/2)), ($this->graphic_area_y2), $value, $this->color['axis_values'], $alt);
-                }
-            }
-
-            // Axis X
-            $this->_imagestring($this->img, $this->size, ($this->graphic_area_x2+10), ($this->graphic_area_y2+3), $this->axis_y, $this->color['title']);
-            imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y2, $this->graphic_area_x2, $this->graphic_area_y2, $this->color['axis_line']);
-            // Axis Y
-            $this->_imagestring($this->img, $this->size, 20, ($this->graphic_area_y1-20), $this->axis_x, $this->color['title']);
-            imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y1, $this->graphic_area_x1, $this->graphic_area_y2, $this->color['axis_line']);
-        }
-
-
-        // Draw legend box for "pie" or "donut"
-        else if (preg_match("/^(5|6)$/", $this->type))
-        {
-            $this->draw_legend();
-        }
-
-
-
-        /**
-        * Draw graphic: VERTICAL BARS
-        */
-        if ($this->type == 1)
-        {
-            $num = 1;
-            $x   = $this->graphic_area_x1 + 20;
-
-            foreach ($this->x as $i => $parameter)
-            {
-                if (isset($this->z[$i])) 
-                {
-                    $size = round($this->z[$i] * $higher_value_size / $this->higher_value);
-                    $x1   = $x + 10;
-                    $y1   = ($this->graphic_area_y2 - $size) + 1;
-                    $x2   = $x1 + 20;
-                    $y2   = $this->graphic_area_y2 - 1;
-                    imageline($this->img, ($x1+1), ($y1-1), $x2, ($y1-1), $this->color['bars_2_shadow']);
-                    imageline($this->img, ($x2+1), ($y1-1), ($x2+1), $y2, $this->color['bars_2_shadow']);
-                    imageline($this->img, ($x2+2), ($y1-1), ($x2+2), $y2, $this->color['bars_2_shadow']);
-                    imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars_2']);
-                }
-
-                $size = round($this->y[$i] * $higher_value_size / $this->higher_value);
-                $alt  = (($num % 2 == 0) && (strlen($this->biggest_x) > 5)) ? 15 : 2;
-                $x1   = $x;
-                $y1   = ($this->graphic_area_y2 - $size) + 1;
-                $x2   = $x1 + 20;
-                $y2   = $this->graphic_area_y2 - 1;
-                $x   += $this->space_between_bars;
-                $num++;
-
-                imageline($this->img, ($x1+1), ($y1-1), $x2, ($y1-1), $this->color['bars_shadow']);
-                imageline($this->img, ($x2+1), ($y1-1), ($x2+1), $y2, $this->color['bars_shadow']);
-                imageline($this->img, ($x2+2), ($y1-1), ($x2+2), $y2, $this->color['bars_shadow']);
-                imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars']);
-                $this->_imagestring($this->img, $this->size, $x1, ($y2+2), $parameter, $this->color['axis_values'], $alt);
-            }
-        }
-
-
-        /**
-        * Draw graphic: HORIZONTAL BARS
-        */
-        else if ($this->type == 2)
-        {
-            $y = 10;
-
-            foreach ($this->x as $i => $parameter)
-            {
-                if (isset($this->z[$i])) 
-                {
-                    $size = round($this->z[$i] * $higher_value_size / $this->higher_value);
-                    $x1   = $this->graphic_area_x1 + 1;
-                    $y1   = $this->graphic_area_y1 + $y + 10;
-                    $x2   = $x1 + $size;
-                    $y2   = $y1 + 15;
-                    imageline($this->img, ($x1), ($y2+1), $x2, ($y2+1), $this->color['bars_2_shadow']);
-                    imageline($this->img, ($x1), ($y2+2), $x2, ($y2+2), $this->color['bars_2_shadow']);
-                    imageline($this->img, ($x2+1), ($y1+1), ($x2+1), ($y2+2), $this->color['bars_2_shadow']);
-                    imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars_2']);
-                    $this->_imagestring($this->img, $this->size, ($x2+7), ($y1+7), $this->number_formated($this->z[$i], $this->dec2), $this->color['bars_2_shadow']);
-                }
-
-                $size = round(($this->y[$i] / $this->higher_value) * $higher_value_size);
-                $x1   = $this->graphic_area_x1 + 1;
-                $y1   = $this->graphic_area_y1 + $y;
-                $x2   = $x1 + $size;
-                $y2   = $y1 + 15;
-                $y   += $this->space_between_bars;
-
-                imageline($this->img, ($x1), ($y2+1), $x2, ($y2+1), $this->color['bars_shadow']);
-                imageline($this->img, ($x1), ($y2+2), $x2, ($y2+2), $this->color['bars_shadow']);
-                imageline($this->img, ($x2+1), ($y1+1), ($x2+1), ($y2+2), $this->color['bars_shadow']);
-                imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars']);
-                $this->_imagestring($this->img, $this->size, ($x2+7), ($y1+2), $this->number_formated($this->y[$i], $this->dec2), $this->color['bars_shadow']);
-
-                $this->_imagestring($this->img, $this->size, 30, ($y1+2), $parameter, $this->color['axis_values']);
-            }
-        }
-
-
-        /**
-        * Draw graphic: DOTS or LINE
-        */
-        else if (preg_match("/^(3|4)$/", $this->type))
-        {
-
-            $x[0] = $this->graphic_area_x1+1;
-
-            foreach ($this->x as $i => $parameter)
-            {
-                if ($this->graphic_2_exists == true) 
-                {
-                    $size  = round($this->z[$i] * $higher_value_size / $this->higher_value);
-                    $z[$i] = $this->graphic_area_y2 - $size;
-                }
-
-                $alt   = (($i % 2 == 0) && (strlen($this->biggest_x) > 5)) ? 15 : 2;
-                $size  = round($this->y[$i] * $higher_value_size / $this->higher_value);
-                $y[$i] = $this->graphic_area_y2 - $size;
-
-                if ($i != 0) 
-                {
-                    imageline($this->img, $x[$i], ($this->graphic_area_y1+10), $x[$i], ($this->graphic_area_y2-1), $this->color['bg_lines']);
-                }
-                $this->_imagestring($this->img, $this->size, $x[$i], ($this->graphic_area_y2+2), $parameter, $this->color['axis_values'], $alt);
-
-                $x[$i+1] = $x[$i] + 40;
-            }
-
-            foreach ($x as $i => $value_x)
-            {
-                if ($this->graphic_2_exists == true)
-                {
-                    if (isset($z[$i+1])) 
-                    {
-                        // Draw lines
-                        if ($this->type == 4)
-                        {
-                            imageline($this->img, $x[$i], $z[$i], $x[$i+1], $z[$i+1], $this->color['line_2']);
-                            imageline($this->img, $x[$i], ($z[$i]+1), $x[$i+1], ($z[$i+1]+1), $this->color['line_2']);
-                        }
-                        imagefilledrectangle($this->img, $x[$i]-1, $z[$i]-1, $x[$i]+2, $z[$i]+2, $this->color['line_2']);
-                    }
-                    else 
-                    { // Draw last dot
-                        imagefilledrectangle($this->img, $x[$i-1]-1, $z[$i-1]-1, $x[$i-1]+2, $z[$i-1]+2, $this->color['line_2']);
-                    }
-                }
+                       $this->tsize = 12;
+                       $this->size = 9;
+               }
+               if ($this->dir == 'rtl')
+               {
+                       $this->size += 1;
+                       $this->tsize += 1;
+               }
+       }
 
-                if (count($y) > 1)
-                {
-                    if (isset($y[$i+1])) 
-                    {
-                        // Draw lines
-                        if ($this->type == 4)
-                        {
-                            imageline($this->img, $x[$i], $y[$i], $x[$i+1], $y[$i+1], $this->color['line']);
-                            imageline($this->img, $x[$i], ($y[$i]+1), $x[$i+1], ($y[$i+1]+1), $this->color['line']);
-                        }
-                        imagefilledrectangle($this->img, $x[$i]-1, $y[$i]-1, $x[$i]+2, $y[$i]+2, $this->color['line']);
-                    }
-                    else 
-                    { // Draw last dot
-                        imagefilledrectangle($this->img, $x[$i-1]-1, $y[$i-1]-1, $x[$i-1]+2, $y[$i-1]+2, $this->color['line']);
-                    }
-                }
+       function setDirection($dir='ltr')
+       {
+               $this->dir = $dir;
+       }
+       
+       function setLanguage($lang='en')
+       {
+               $this->lang = $lang;
+       }
+       
+       function setStream($stream = 'svg')
+       {
+               $this->stream = $stream;
+               if ($this->stream == 'png')
+               {
+                       $this->tsize = 12;
+                       $this->size = 9;
+               }
+       }
 
-            }
-        }
+       function setLabels($labels)
+       {
+               $this->labels = $labels;
+       }
 
+       function addSerie($label, $data, $type = false, $fill = false)
+       {
+               if ($label == false)
+                       $label = "Serie $this->num_series";
+               $this->series[$this->num_series]['label'] = $label;
+               $this->series[$this->num_series]['data'] = $data;
+               $this->series[$this->num_series]['type'] = $type;
+               $this->series[$this->num_series]['fill'] = $fill;
+               $this->num_series++;
+       }
 
-        /**
-        * Draw graphic: PIE or DONUT
-        */
-        else if (preg_match("/^(5|6)$/", $this->type))
-        {
-            $center_x = ($this->graphic_area_x1 + $this->graphic_area_x2) / 2;
-            $center_y = ($this->graphic_area_y1 + $this->graphic_area_y2) / 2;
-            $width    = $this->graphic_area_width;
-            $height   = $this->graphic_area_height;
-            $start    = 0;
-            $sizes    = array();
+       function setXTitle($xtitle)
+       {
+               $this->axis_x = $xtitle;
+       }
 
-            foreach ($this->x as $i => $parameter)
-            {
-                $size    = $this->y[$i] * 360 / $this->sum_total;
-                               $size = round2($size, 0);
-                $sizes[] = $size;
-                $start  += $size;
-            }
-            $start = 270;
+       function setYTitle($ytitle)
+       {
+               $this->axis_y = $ytitle;
+       }
 
-            // Draw PIE
-            if ($this->type == 5)
-            {
-                // Draw shadow
-                foreach ($sizes as $i => $size)
-                {
-                    $num_color = $i + 1;
-                    while ($num_color > 7) 
-                    {
-                        $num_color -= 5;
-                    }
-                    $color = 'arc_' . $num_color . '_shadow';
+       function setTitle($title)
+       {
+               $this->title = $title;
+       }
 
-                    for ($i = $this->h3d; $i >= 0; $i--)
-                    {
-                        if ($size >= 1)
-                               imagefilledarc($this->img, $center_x, ($center_y+$i), $width, $height, $start, ($start+$size), $this->color[$color], IMG_ARC_NOFILL);
-                    }
-                    $start += $size;
-                }
+       function setDTitle($dtitle)
+       {
+               $this->donut_title = $dtitle; 
+       }
 
-                $start = 270;
+       function setValues($values = false)
+       {
+               $this->set_values = $values;
+       }
 
-                // Draw pieces
-                foreach ($sizes as $i => $size)
-                {
-                    $num_color = $i + 1;
-                    while ($num_color > 7) 
-                    {
-                        $num_color -= 5;
-                    }
-                    $color = 'arc_' . $num_color;
-                    if ($size >= 1)
-                       imagefilledarc($this->img, $center_x, $center_y, ($width+2), ($height+2), $start, ($start+$size), $this->color[$color], IMG_ARC_EDGED);
-                    $start += $size;
-                }
-            }
+       function setOutDir($dir)
+       {
+               $this->out_dir = $dir;
+       }
 
-            // Draw DONUT
-            else if ($this->type == 6)
-            {
-                foreach ($sizes as $i => $size)
-                {
-                    $num_color = $i + 1;
-                    while ($num_color > 7) 
-                    {
-                        $num_color -= 5;
-                    }
-                    $color        = 'arc_' . $num_color;
-                    $color_shadow = 'arc_' . $num_color . '_shadow';
-                    if ($size >= 1)
-                       imagefilledarc($this->img, $center_x, $center_y, $width, $height, $start, ($start+$size), $this->color[$color], IMG_ARC_PIE);
-                    $start += $size;
-                }
-                imagefilledarc($this->img, $center_x, $center_y, 100, 100, 0, 360, $this->color['background'], IMG_ARC_PIE);
-                imagearc($this->img, $center_x, $center_y, 100, 100, 0, 360, $this->color['bg_legend']);
-                imagearc($this->img, $center_x, $center_y, ($width+1), ($height+1), 0, 360, $this->color['bg_legend']);
-            }
-        }
+       function isEmpty()
+       {
+               return (!isset($this->series[0]['data']) || count($this->series[0]['data']) == 0);
+       }
 
+       function display($save="")
+       {
+               $this->encoding = strtoupper($_SESSION['language']->encoding);
+               $this->title_height                     = (!empty($this->title)) ? $this->tsize + 15 : 0;
+               $this->bar_width                        = ($this->type == 1) ? 20 : 15;
+               $this->space_between_dots       = 40;
+               $this->higher_value                     = 0;
+               $this->higher_value_str         = 0;
+               $this->graphic_area_width       = 0;
+               $this->graphic_area_height      = 0;
+               $this->graphic_area_x1          = 30;
+               $this->graphic_area_y1          = 30 + $this->title_height;
+               $this->num_labels                       = count($this->labels);
+               $this->max_legend_str           = "";
+               $this->legend_box_height  += (14 * $this->num_labels);
+               for ($i = 0; $i < $this->num_labels; $i++)
+               {
+                       if (strlen($this->labels[$i]) > strlen($this->max_label))
+                               $this->max_label = $this->labels[$i];
+               }
+               for ($j = 0; $j < $this->num_series; $j++)
+               {
+                       $this->sum_total[$j] = 0;
+                       if (strlen($this->series[$j]['label']) > strlen($this->max_legend_str))
+                               $this->max_legend_str = $this->series[$j]['label'];
+                       for ($i = 0; $i < $this->num_labels; $i++)
+                       {
+                               if ($this->series[$j]['data'][$i] > $this->max_value)
+                                       $this->max_value = $this->series[$j]['data'][$i];
+                               $this->sum_total[$j] += $this->series[$j]['data'][$i];
+                       }
+               }
+               $this->max_value = number_format(round($this->max_value, 1), 1, ".", "");
+               if ($this->num_series)
+                       $this->legend_exists = true;
+               if ($this->type == 8 && $this->num_labels < 4)
+                       $this->type = 4;
+               $this->calculate_higher_value();
+               $this->calculate_width();
+               $this->calculate_height();
+               if ($this->type == 9)
+               {
+                       $this->draw_table();
+                       return;
+               }
+               $this->create_graphic($save);
+       }
 
-        if ($this->credits == true) 
-        {
-            $this->draw_credits();
-        }
-               if ($save != "")
-                       imagepng($this->img, $save);
+       function create_graphic($save="")
+       {
+               if ($this->stream == 'svg')
+               {
+                       $this->svg = new SVG($this->width, $this->height, $this->dir, $this->lang);
+                       $this->svg->style("svg{font-family:{$this->font};background-color:inherit}.tips:hover{cursor:pointer;opacity:0.8;}");
+                       $this->load_color_palette($this->type);
+               }
                else
                {
-               header('Content-type: image/png');
-               imagepng($this->img);
-        }      
-        imagedestroy($this->img);
-    }
-
-    function calculate_width()
-    {
-        switch ($this->type)
-        {
-            // Vertical bars
-            case 1:
-                $this->legend_box_width   = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, $this->tsize) + 25) : 0;
-                $this->graphic_area_width = ($this->space_between_bars * $this->total_parameters) + 30;
-                $this->graphic_area_x1   += $this->string_width(($this->higher_value_str), $this->size);
-                $this->width += $this->graphic_area_x1 + 20;
-                $this->width += ($this->legend_exists == true) ? 50 : ((7 * strlen($this->axis_x)) + 10);
-                break;
-
-            // Horizontal bars
-            case 2:
-                $this->legend_box_width   = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, $this->size) + 25) : 0;
-                $this->graphic_area_width = ($this->string_width($this->higher_value_str, $this->size) > 50) ? (5 * ($this->string_width($this->higher_value_str, $this->size)) * 0.85) : 200;
-                $this->graphic_area_x1 += 7 * strlen($this->biggest_x);
-                $this->width += ($this->legend_exists == true) ? 60 : ((7 * strlen($this->axis_y)) + 30);
-                $this->width += $this->graphic_area_x1;
-                break;
-
-            // Dots
-            case 3:
-                $this->legend_box_width   = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, $this->size) + 25) : 0;
-                $this->graphic_area_width = ($this->space_between_dots * $this->total_parameters) - 10;
-                $this->graphic_area_x1   += $this->string_width(($this->higher_value_str), $this->size);
-                $this->width += $this->graphic_area_x1 + 20;
-                $this->width += ($this->legend_exists == true) ? 40 : ((7 * strlen($this->axis_x)) + 30);
-                break;
-
-            // Lines
-            case 4:
-                $this->legend_box_width   = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, $this->size) + 25) : 0;
-                $this->graphic_area_width = ($this->space_between_dots * $this->total_parameters) - 10;
-                $this->graphic_area_x1   += $this->string_width(($this->higher_value_str), $this->size);
-                $this->width += $this->graphic_area_x1 + 20;
-                $this->width += ($this->legend_exists == true) ? 40 : ((7 * strlen($this->axis_x)) + 30);
-                break;
-
-            // Pie
-            case 5:
-                $this->legend_box_width   = $this->string_width($this->biggest_x, $this->size) + 85;
-                $this->graphic_area_width = 200;
-                $this->width += 90;
-                break;
-
-            // Donut
-            case 6:
-                $this->legend_box_width   = $this->string_width($this->biggest_x, $this->size) + 85;
-                $this->graphic_area_width = 180;
-                $this->width += 90;
-                break;
-        }
-
-        $this->graphic_area_width = max($this->graphic_area_width, $this->string_width($this->title, $this->size));
-        $this->width += $this->graphic_area_width;
-        $this->width += $this->legend_box_width;
-
-
-        $this->graphic_area_x2 = $this->graphic_area_x1 + $this->graphic_area_width;
-        $this->legend_box_x1   = $this->graphic_area_x2 + 40;
-        $this->legend_box_x2   = $this->legend_box_x1 + $this->legend_box_width;
-    }
-
-    function calculate_height()
-    {
-        switch ($this->type)
-        {
-            // Vertical bars
-            case 1:
-                $this->legend_box_height   = ($this->graphic_2_exists == true) ? 40 : 0;
-                $this->graphic_area_height = 150;
-                $this->height += 65;
-                break;
-
-            // Horizontal bars
-            case 2:
-                $this->legend_box_height   = ($this->graphic_2_exists == true) ? 40 : 0;
-                $this->graphic_area_height = ($this->space_between_bars * $this->total_parameters) + 10;
-                $this->height += 65;
-                break;
-
-            // Dots
-            case 3:
-                $this->legend_box_height   = ($this->graphic_2_exists == true) ? 40 : 0;
-                $this->graphic_area_height = 150;
-                $this->height += 65;
-                break;
-
-            // Lines
-            case 4:
-                $this->legend_box_height   = ($this->graphic_2_exists == true) ? 40 : 0;
-                $this->graphic_area_height = 150;
-                $this->height += 65;
-                break;
-
-            // Pie
-            case 5:
-                $this->legend_box_height   = (!empty($this->axis_x)) ? 30 : 5;
-                $this->legend_box_height  += (14 * $this->total_parameters);
-                $this->graphic_area_height = 150;
-                $this->height += 50;
-                break;
-
-            // Donut
-            case 6:
-                $this->legend_box_height   = (!empty($this->axis_x)) ? 30 : 5;
-                $this->legend_box_height  += (14 * $this->total_parameters);
-                $this->graphic_area_height = 180;
-                $this->height += 50;
-                break;
-        }
-
-        $this->height += $this->height_title;
-        $this->height += ($this->legend_box_height > $this->graphic_area_height) ? ($this->legend_box_height - $this->graphic_area_height) : 0;
-        $this->height += $this->graphic_area_height;
-
-        $this->graphic_area_y2 = $this->graphic_area_y1 + $this->graphic_area_height;
-        $this->legend_box_y1   = $this->graphic_area_y1 + 10;
-        $this->legend_box_y2   = $this->legend_box_y1 + $this->legend_box_height;
-    }
-
-    function draw_legend()
-    {
-        $x1 = $this->legend_box_x1;
-        $y1 = $this->legend_box_y1;
-        $x2 = $this->legend_box_x2;
-        $y2 = $this->legend_box_y2;
-
-        imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bg_legend']);
-
-        $x = $x1 + 5;
-        $y = $y1 + 5;
-
-
-        // Draw legend values for VERTICAL BARS, HORIZONTAL BARS, DOTS and LINES
-        if (preg_match("/^(1|2|3|4)$/", $this->type))
-        {
-            $color_1 = (preg_match("/^(1|2)$/", $this->type)) ? $this->color['bars']   : $this->color['line'];
-            $color_2 = (preg_match("/^(1|2)$/", $this->type)) ? $this->color['bars_2'] : $this->color['line_2'];
-
-            imagefilledrectangle($this->img, $x, $y, ($x+10), ($y+10), $color_1);
-            imagerectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color['title']);
-            $this->_imagestring($this->img, $this->size, ($x+15), ($y-2), $this->graphic_1, $this->color['axis_values']);
-            $y += 20;
-            imagefilledrectangle($this->img, $x, $y, ($x+10), ($y+10), $color_2);
-            imagerectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color['title']);
-            $this->_imagestring($this->img, $this->size, ($x+15), ($y-2), $this->graphic_2, $this->color['axis_values']);
-        }
-
-        // Draw legend values for PIE or DONUT
-        else if (preg_match("/^(5|6)$/", $this->type))
-        {
-            if (!empty($this->axis_x))
-            {
-                $this->_imagestring($this->img, $this->size, ((($x1+$x2)/2) - (strlen($this->axis_x)*7/2)), $y, 
-                       $this->axis_x." (".$this->graphic_1.")", $this->color['title']);
-                $y += 25;
-            }
-
-            $num = 1;
-
-            foreach ($this->x as $i => $parameter)
-            {
-                while ($num > 7) 
-                {
-                    $num -= 5;
-                }
-                $color = 'arc_' . $num;
-
-                $percent = number_format(round(($this->y[$i] * 100 / $this->sum_total), 2), 2, ".", "") . ' %';
-                $less    = (strlen($percent) * 7);
-
-                if ($num != 1) 
-                {
-                    imageline($this->img, ($x1+15), ($y-2), ($x2-5), ($y-2), $this->color['bg_lines']);
-                }
-                imagefilledrectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color[$color]);
-                imagerectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color['title']);
-                $this->_imagestring($this->img, $this->size, ($x+15), ($y-2), $parameter, $this->color['axis_values']);
-                $this->_imagestring($this->img, $this->size, ($x2-$less), ($y-2), $percent, $this->color['axis_values']);
-                $y += 14;
-                $num++;
-            }
-        }
-    }
-
+                       $this->img = imagecreatetruecolor($this->width, $this->height);
+                       $this->load_color_palette($this->type);
+                       // Fill background
+                       imagefill($this->img, 0, 0, $this->color['background']);
+               }
+               // Draw title
+               if (!empty($this->title))
+               {
+                       if ($this->stream == 'svg')
+                       {
+                               $center = $this->width / 2;
+                               $this->svg->text($center, 20, $this->title, $this->tsize, $this->color['title'], false, "middle");
+                       }
+                       else
+                       {
+                               $center = ($this->width / 2) - ($this->string_width($this->title, $this->tsize) / 2);
+                               $this->_imagestring($this->img, $this->tsize, $center, 10, $this->title, $this->color['title']);
+                       }
+               }
+               // Draw axis and background lines for "vertical bars", "dots", "lines" and "splines"
+               if (preg_match("/^(1|3|4|8)$/", $this->type))
+               {
+                       if ($this->legend_exists == true)
+                       {
+                               $this->draw_legend();
+                       }
+                       $higher_value_y    = $this->graphic_area_y1 + (0.1 * $this->graphic_area_height);
+                       $this->higher_value_size = 0.9 * $this->graphic_area_height;
+                       $less  = 7 * strlen($this->higher_value_str);
+                       if ($this->stream == 'svg')
+                       {
+                               $this->svg->line($this->graphic_area_x1, $higher_value_y, $this->graphic_area_x2, $higher_value_y, $this->color['bg_lines']);
+                               $this->svg->text($this->graphic_area_x1-$less-7, $higher_value_y, $this->higher_value_str, $this->size, $this->color['axis_values'], false, $this->align);
+                       }
+                       else
+                       {
+                               imageline($this->img, $this->graphic_area_x1, $higher_value_y, $this->graphic_area_x2, $higher_value_y, $this->color['bg_lines']);
+                               $this->_imagestring($this->img, $this->size, ($this->graphic_area_x1-$less-7), ($higher_value_y-7), $this->higher_value_str, $this->color['axis_values']);
+                       }
+                       for ($i = 1; $i < 10; $i++)
+                       {
+                               $dec_y = $i * ($this->higher_value_size / 10);
+                               $x1 = $this->graphic_area_x1;
+                               $y1 = $this->graphic_area_y2 - $dec_y;
+                               $x2 = $this->graphic_area_x2;
+                               $y2 = $y1;
+                               if ($this->stream == 'svg')
+                                       $this->svg->line($x1, $y1, $x2, $y2, $this->color['bg_lines']);
+                               else
+                                       imageline($this->img, $x1, $y1, $x2, $y2, $this->color['bg_lines']);
+                               if ($i % 2 == 0) 
+                               {
+                                       $value = $this->number_formated($this->higher_value * $i / 10, $this->dec1);
+                                       $len1 = strlen($this->higher_value_str);
+                                       $len2 = strlen($value);
+                                       if ($len2 < $len1)
+                                               $len2 += ($len1-$len2-1);
+                                       $less = 7 * $len2;
+                                       if ($this->stream == 'svg')
+                                               $this->svg->text($x1-$less-7, ($y1), $value, $this->size, $this->color['axis_values'], false, $this->align);
+                                       else
+                                               $this->_imagestring($this->img, $this->size, ($x1-$less-7), ($y2-7), $value, $this->color['axis_values']);
+                               }
+                       }
+                       // Axis X
+                       if ($this->stream == 'svg')
+                       {
+                               $this->svg->text($this->graphic_area_x2+10, $this->graphic_area_y2+10, $this->axis_x, $this->size, $this->color['title'], false, $this->align);
+                               $this->svg->line($this->graphic_area_x1, $this->graphic_area_y2, $this->graphic_area_x2, $this->graphic_area_y2, $this->color['axis_line']);
+                       }
+                       else
+                       {
+                               $this->_imagestring($this->img, $this->size, $this->graphic_area_x2+20, $this->graphic_area_y2+3, $this->axis_x, $this->color['title']);
+                               imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y2, $this->graphic_area_x2, $this->graphic_area_y2, $this->color['axis_line']);
+                       }
+                       // Axis Y
+                       if ($this->stream == 'svg')
+                       {
+                               $lex = $this->dir == 'rtl' ? 35 : 25; 
+                               $this->svg->text($lex, $this->graphic_area_y1-10, $this->axis_y, $this->size, $this->color['title'], false, $this->align);
+                               $this->svg->line($this->graphic_area_x1, $this->graphic_area_y1, $this->graphic_area_x1, $this->graphic_area_y2, $this->color['axis_line']); 
+                       }
+                       else
+                       {
+                               $this->_imagestring($this->img, $this->size, 10, $this->graphic_area_y1-20, $this->axis_y, $this->color['title']);
+                               imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y1, $this->graphic_area_x1, $this->graphic_area_y2, $this->color['axis_line']);
+                       }
+               }
+               // Draw axis and background lines for "horizontal bars"
+               else if ($this->type == 2)
+               {
+                       if ($this->legend_exists == true)
+                       {
+                               $this->draw_legend();
+                       }
+                       $this->higher_value_size = 0.9 * $this->graphic_area_width;
+                       if ($this->stream == 'svg')
+                       {
+                               $this->svg->line(($this->graphic_area_x1+$this->higher_value_size), $this->graphic_area_y1, ($this->graphic_area_x1+$this->higher_value_size), $this->graphic_area_y2, $this->color['bg_lines']);
+                               $this->svg->text((($this->graphic_area_x1+$this->higher_value_size) - ($this->string_width($this->higher_value, $this->size)/2)), ($this->graphic_area_y2 + 20), $this->higher_value_str, $this->size, $this->color['axis_values'], false, $this->align);
+                       }
+                       else
+                       {
+                               imageline($this->img, ($this->graphic_area_x1+$this->higher_value_size), $this->graphic_area_y1, ($this->graphic_area_x1+$this->higher_value_size), $this->graphic_area_y2, $this->color['bg_lines']);
+                               $this->_imagestring($this->img, $this->size, (($this->graphic_area_x1+$this->higher_value_size) - ($this->string_width($this->higher_value, $this->size)/2)), ($this->graphic_area_y2+2), $this->higher_value_str, $this->color['axis_values']);
+                       }
+                       for ($i = 1, $alt = 15; $i < 10; $i++)
+                       {
+                               $dec_x = number_format(round($i * ($this->higher_value_size      / 10), 1), 1, ".", "");
+                               if ($this->stream == 'svg')
+                                       $this->svg->line(($this->graphic_area_x1+$dec_x), $this->graphic_area_y1, ($this->graphic_area_x1+$dec_x), $this->color['bg_lines']);
+                               else
+                                       imageline($this->img, ($this->graphic_area_x1+$dec_x), $this->graphic_area_y1, ($this->graphic_area_x1+$dec_x), $this->graphic_area_y2, $this->color['bg_lines']);
+                               if ($i % 2 == 0) 
+                               {
+                                       $alt   = (strlen($this->max_value) > 4 && $alt != 15) ? 15 : 2;
+                                       $value = $this->number_formated($this->higher_value * $i / 10, $this->dec1);
+                                       if ($this->stream == 'svg')
+                                               $this->svg->text((($this->graphic_area_x1+$dec_x) - ($this->string_width($this->higher_value, $this->size)/2)), ($this->graphic_area_y2+$alt+18), $value, $this->size, $this->color['axis_values'], false, $this->align);
+                                       else
+                                               $this->_imagestring($this->img, $this->size, (($this->graphic_area_x1+$dec_x) - ($this->string_width($this->higher_value, $this->size)/2)), ($this->graphic_area_y2), $value, $this->color['axis_values'], $alt);
+                               }
+                       }
+                       // Axis X
+                       if ($this->stream == 'svg')
+                       {
+                               $this->svg->text(($this->graphic_area_x2+10), ($this->graphic_area_y2+10), $this->axis_y, $this->size, $this->color['title'], false, $this->align);
+                               $this->svg->line($this->graphic_area_x1, $this->graphic_area_y2, $this->graphic_area_x2, $this->graphic_area_y2, $this->color['axis_line']);
+                       }
+                       else
+                       {
+                               $this->_imagestring($this->img, $this->size, ($this->graphic_area_x2+10), ($this->graphic_area_y2+3), $this->axis_y, $this->color['title']);
+                               imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y2, $this->graphic_area_x2, $this->graphic_area_y2, $this->color['axis_line']);
+                       }
+                       // Axis Y
+                       if ($this->stream == 'svg')
+                       {
+                               $this->svg->text(20, ($this->graphic_area_y1-10), $this->axis_x, $this->size, $this->color['title'], false, $this->align);
+                               $this->svg->line($this->graphic_area_x1, $this->graphic_area_y1, $this->graphic_area_x1, $this->graphic_area_y2, $this->color['axis_line']);
+                       }
+                       else
+                       {
+                               $this->_imagestring($this->img, $this->size, 20, ($this->graphic_area_y1-20), $this->axis_x, $this->color['title']);
+                               imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y1, $this->graphic_area_x1, $this->graphic_area_y2, $this->color['axis_line']);
+                       }
+               }
+               else if (preg_match("/^(5|6|7)$/", $this->type))
+               {
+                       // Draw legend box for "pie", "donut" or "half donut"
+                       $this->draw_legend();
+               }
+               $average_width = $this->graphic_area_width / $this->num_labels;
+               $biggest_width = $this->string_width($this->max_label, $this->size) + 10;
+               if ($biggest_width > $average_width)
+                       $this->angle = -20;
+               else
+                       $this->angle = 0;
+               /**
+               * Draw graphic: VERTICAL BARS
+               */
+               if ($this->type == 1)
+               {
+                       $this->draw_vertical_bars();
+               }
+               /**
+               * Draw graphic: HORIZONTAL BARS
+               */
+               else if ($this->type == 2)
+               {
+                       $this->draw_horizontal_bars();
+               }
+               /**
+               * Draw graphic: DOTS. LINE or SPLINE
+               */
+               else if (preg_match("/^(3|4|8)$/", $this->type))
+               {
+                       $this->draw_lines();
+                       if ($this->stream != 'svg' && $this->type == 8)
+                               $this->draw_splines();
+               }
+               /**
+               * Draw graphic: PIE, DONUT or HALF DONUT
+               */
+               else if (preg_match("/^(5|6|7)$/", $this->type))
+               {
+                       // Draw PIE, DONUT OR HALF DONUT
+                       $this->draw_pie();
+               }
+               if ($this->stream == 'svg')
+               {
+                       $this->svg->close();
+                       return $this->svg->draw();
+                       //$this->out_dir =      company_path(). '/pdf_files/';
+                       //$filename = $this->out_dir.uniqid().".svg";
+                       //$this->svg->save($filename);
+                       //echo "<img src='$filename' border='0' alt='$this->title'>";
+               }
+               else
+               {
+                       $filename = $this->out_dir.uniqid().".".$this->stream;
+                       if ($this->stream == 'png')
+                               imagepng($this->img, $save != "" ? $save : $filename);
+                       elseif ($this->stream == 'jpg')
+                               imagejpeg($this->img, $save != "" ? $save : $filename);
+                       elseif ($this->stream == 'gif') 
+                               imagegif($this->img, $save != "" ? $save : $filename);
+                       echo "<img src='$filename' border='0' alt='$this->title'>";
+                       /*
+                       header('Content-type: image/png');
+                       imagepng($this->img, NULL, 5);
+                       */
+                       imagedestroy($this->img);
+               }
+       }
 
-    function string_width($string, $size) 
-    {
-        $single_width = $size + 4;
-        if ($this->encoding == "UTF-8")
-               $width = mb_strlen($string, "UTF-8");
-        else   
-               $width = strlen($string);
-        return $single_width * $width;
-    }
+       function draw_vertical_bars()
+       {
+               $x       = $this->graphic_area_x1 + 10;
+               $oldx = $oldy = 0;
+               $p = array();
+               foreach ($this->labels as $i => $parameter)
+               {
+                       for ($j = 0; $j < $this->num_series; $j++)
+                       {
+                               $size = round($this->series[$j]['data'][$i] * $this->higher_value_size / $this->higher_value);
+                               $x1       = $x;
+                               $y1       = ($this->graphic_area_y2 - $size) + 1;
+                               $x2       = $this->bar_width;
+                               $y2       = $this->graphic_area_y2;
+                               if ($this->series[$j]['type'] == 8 && $this->num_labels < 4)
+                                       $this->series[$j]['type'] = 4;
+                               if ($this->stream == 'svg')
+                               {
+                                       if ($this->series[$j]['type'] == 4 || $this->series[$j]['type'] == 8) // line
+                                       {
+                                               if (!isset($this->color['line'][0]))
+                                                       $this->load_color_palette($this->series[$j]['type']);
+                                               if ($i == $this->num_labels - 1)
+                                               {
+                                                       $dx = ($this->num_series-1) * ($this->bar_width + 10);
+                                                       $xx = $this->graphic_area_x1 + $dx;
+                                                       foreach($this->series[$j]['data'] as $i => $v)
+                                                       {
+                                                               $size  = round($this->series[$j]['data'][$i] * $this->higher_value_size / $this->higher_value);
+                                                               $y = $this->graphic_area_y2 - $size;
+                                                               $p[$i][0] = $xx;
+                                                               $p[$i][1] = $y;
+                                                               $xx += $dx;
+                                                       }
+                                                       $path = "M ".$p[0][0].",".$p[0][1];
+                                                       foreach ($p as $ix => $y)
+                                                       {
+                                                               $this->svg->circle($p[$ix][0], $p[$ix][1], 2.5, $this->color['line'][$j], 2, $this->color['line'][$j], "class=\"tips\"", $this->series[$j]['label'].": ".number_format($this->series[$j]['data'][$ix], 2)); 
+                                                               if ($ix != 0)
+                                                               {
+                                                                       if ($this->series[$j]['type'] == 4) // normal line
+                                                                               $path .= " L".$p[$ix][0].",".$p[$ix][1];
+                                                                       elseif ($this->series[$j]['type'] == 8) // spline
+                                                                               $path .= $this->_splineCommand($p[$ix], $ix, $p);
+                                                               }
+                                                       }
+                                                       if ($this->series[$j]['fill'] == true)
+                                                       {
+                                                               $fpath = $path;
+                                                               $fpath .= " L ".($p[$ix][0]+1).",".($this->graphic_area_y2-2)." L ".$p[0][0].",".($this->graphic_area_y2-2)." L ".$p[0][0].",".$p[0][1];
+                                                               $this->svg->path($fpath, $this->color['line_light'][$j], 1, $this->color['line_light'][$j]);
+                                                       }
+                                                       $this->svg->path($path, $this->color['line'][$j], 3, "none");
+                                               }
+                                       }
+                                       else
+                                       {
+                                               $this->svg->rect( $x1, $y1, $x2, $y2-$y1, $this->color['bars'][$j], 1, $this->color['bars'][$j], "class=\"tips\"", $this->series[$j]['label'].": ".number_format($this->series[$j]['data'][$i], 2));
+                                               $x += $this->bar_width + 5;
+                                       }
+                               }
+                               else
+                               {
+                                       if ($this->series[$j]['type'] == 4) // line
+                                       {
+                                               if (!isset($this->color['line'][0]))
+                                                       $this->load_color_palette($this->series[$j]['type']);
+                                               if ($i > 0)
+                                               {
+                                                       $this->_imageline($this->img, $oldx, $oldy, $x1, $y1, $this->color['line'][$j], 3);
+                                                       if ($this->series[$j]['fill'] == true)
+                                                       {
+                                                               $pt = array($oldx, $oldy+3, $x1, $y1 + 3, $x1, $this->graphic_area_y2-2,        $oldx, $this->graphic_area_y2-2, $oldx, $oldy+4);
+                                                               imagefilledpolygon($this->img, $pt, 5, $this->color['line_light'][$j]);
+                                                       }
+                                               }
+                                               imagefilledrectangle($this->img, $x1-2, $y1-2, $x1+2, $y1+2, $this->color['line'][$j]);
+                                               $oldx = $x1;
+                                               $oldy = $y1;
+                                               $x += 5;
+                                       }
+                                       elseif ($this->series[$j]['type'] == 8) // spline
+                                       {
+                                               if (!isset($this->color['line'][0]))
+                                                       $this->load_color_palette($this->series[$j]['type']);
+                                               imagefilledrectangle($this->img, $x1-2, $y1-2, $x1+2, $y1+2, $this->color['line'][$j]);
+                                               $p[$x1] = $this->graphic_area_y2 - $size;
+                                               if ($i == $this->num_labels - 1)
+                                               {
+                                                       $r = $this->imageSpline($p);
+                                                       if ($r == false)
+                                                               break;
+                                                       while (list ($xx, $yy) = each($r)) 
+                                                       {
+                                                               imagefilledellipse($this->img, round($xx), round($yy)+1, 3, 3, $this->color['line'][$j]);
+                                                               if ($this->series[$j]['fill'] == true)
+                                                               {
+                                                                       $this->_imageline($this->img, round($xx), round($yy+4), round($xx), $this->graphic_area_y2-2, $this->color['line_light'][$j], 3);
+                                                               }
+                                                       }
+                                               }
+                                               $x += 5;
+                                       }
+                                       else
+                                       {
+                                               $xx2 = $x2 + $x1;
+                                               imageline($this->img, ($x1+1), ($y1-1), $xx2, ($y1-1), $this->color['bars'][$j]);
+                                               imageline($this->img, ($xx2+1), ($y1-1), ($xx2+1), $y2, $this->color['bars'][$j]);
+                                               imageline($this->img, ($xx2+2), ($y1-1), ($xx2+2), $y2, $this->color['bars'][$j]);
+                                               imagefilledrectangle($this->img, $x1, $y1, $xx2, $y2, $this->color['bars'][$j]);
+                                               $x += $this->bar_width + 5;
+                                       }
+                               }
+                               if ($j == 0)
+                               {
+                                       if ($this->stream == 'svg')
+                                       {
+                                               $lex = $this->angle == 0 ? $x1 + 40 : $x1+20;
+                                               $al = $this->dir == 'rtl' ? "start" : "end";
+                                               $this->svg->text($lex, ($y2+15), $parameter, $this->size, $this->color['axis_values'], false, $al, $this->angle);
+                                       }
+                                       else
+                                       {
+                                               $this->_imagestring($this->img, $this->size, $x1, ($y2+2), $parameter, $this->color['axis_values'], 0, $this->angle);
+                                       }
+                               }
+                       }
+                       $x += 10;
+               }
+       }
 
-    function string_height($size) 
-    {
-        if ($size <= 1) 
-        {
-            $height = 8;
-        } 
-        else if ($size <= 3) 
-        {
-            $height = 12;
-        } 
-        else if ($size >= 4) 
-        {
-            $height = 14;
-        }
-        return $height;
-    }
+       function draw_horizontal_bars()
+       {
+               $y = 10;
+               foreach ($this->labels as $i => $parameter)
+               {
+                       for ($j = 0; $j < $this->num_series; $j++)
+                       {
+                               $size = round($this->series[$j]['data'][$i] / $this->higher_value * $this->higher_value_size);
+                               $x1       = $this->graphic_area_x1 + 1;
+                               $y1       = $this->graphic_area_y1 + $y;
+                               $x2       = $x1 + $size;
+                               $y2       = $y1 + $this->bar_width;
+                               if ($this->stream == 'svg')
+                               {
+                                       $this->svg->rect($x1, $y1, $x2-$x1, $y2-$y1, $this->color['bars'][$j], 1, $this->color['bars'][$j], "class=\"tips\"", $this->series[$j]['label'].": ".number_format($this->series[$j]['data'][$i], 2));
+                                       $this->svg->text(($x2+10), ($y1+12), $this->number_formated($this->series[$j]['data'][$i], $this->dec2), $this->size, $this->color['bars'][$j], false, $this->align);
+                                       $y       += $this->bar_width + 1;
+                               }
+                               else
+                               {
+                                       $this->_imageline($this->img, ($x1), ($y2+1), $x2, ($y2+1), $this->color['bars'][$j], 3);
+                                       imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars'][$j]);
+                                       $this->_imagestring($this->img, $this->size, ($x2+7), ($y1+2), $this->number_formated($this->series[$j]['data'][$i], $this->dec2), $this->color['bars'][$j]);
+                                       $y       += $this->bar_width + 4;
+                               }
+                       }
+                       if ($this->stream == 'svg')
+                       {
+                               $this->svg->text(20, ($y2-5), $parameter, $this->size, $this->color['axis_values'], false, $this->align);
+                               $y += 8;
+                       }
+                       else
+                       {
+                               $this->_imagestring($this->img, $this->size, 20, ($y1-5), $parameter, $this->color['axis_values'], 0);
+                               $y       += 10;
+                       }
+               }
+       }
 
-    function calculate_higher_value() 
-    {
-        $digits   = strlen(round($this->biggest_y));
-        $interval = pow(10, ($digits-1));
-        $this->higher_value     = round(($this->biggest_y - ($this->biggest_y % $interval) + $interval), 1);
-        $this->higher_value_str = $this->number_formated($this->higher_value, $this->dec1);
-    }
+       function draw_lines()
+       {
+               for ($j = 0; $j < $this->num_series; $j++)
+               {
+                       $x = $this->graphic_area_x1+1;
+                       $oldx = $oldy = 0;
+                       if ($this->type == 8 && $this->num_labels < 4)
+                               $this->type = 4;
+                       if ($this->stream == 'svg')
+                       {
+                               $p = array();
+                               foreach ($this->labels as $i => $parameter)
+                               {
+                                       $size  = round($this->series[$j]['data'][$i] * $this->higher_value_size / $this->higher_value);
+                                       $y = $this->graphic_area_y2 - $size;
+                                       $p[$i][0] = $x;
+                                       $p[$i][1] = $y;
+                                       if ($j == 0)
+                                       {
+                                               $lex = $this->angle == 0 ? $x + 30 : $x+10;
+                                               $al = $this->dir == 'rtl' ? "start" : "end";
+                                               $this->svg->text($lex, ($this->graphic_area_y2+15), $parameter, $this->size, $this->color['axis_values'], false, $al, $this->angle);
+                                       }
+                                       $x += $this->space_between_dots;
+                               }
+                               $path = "M ".$p[0][0].",".$p[0][1];
+                               foreach ($p as $i => $y)
+                               {
+                                       $this->svg->circle($p[$i][0], $p[$i][1], 2.5, $this->color['line'][$j], 3, $this->color['line'][$j], "class=\"tips\"", $this->series[$j]['label'].": ".number_format($this->series[$j]['data'][$i], 2)); 
+                                       if ($i != 0)
+                                       {
+                                               if ($this->type == 4) // normal line
+                                                       $path .= " L".$p[$i][0].",".$p[$i][1];
+                                               elseif ($this->type == 8) // spline
+                                                       $path .= $this->_splineCommand($p[$i], $i, $p);
+                                       }
+                               }
+                               if ($this->series[$j]['fill'] == true)
+                               {
+                                       $fpath = $path;
+                                       $fpath .= " L ".($p[$i][0]+1).",".($this->graphic_area_y2-1)." L ".$p[0][0].",".($this->graphic_area_y2-1)." L ".$p[0][0].",".$p[0][1];
+                                       $this->svg->path($fpath, $this->color['line_light'][$j], 1, $this->color['line_light'][$j]);
+                               }
+                               $this->svg->path($path, $this->color['line'][$j], 3, "none");
+                               $x += $this->space_between_dots;
+                       }
+                       else
+                       {
+                               foreach ($this->labels as $i => $parameter)
+                               {
+                                       $size  = round($this->series[$j]['data'][$i] * $this->higher_value_size / $this->higher_value);
+                                       $y = $this->graphic_area_y2 - $size;
+                                       
+                                       if ($this->type == 4 && $i > 0) // lINES
+                                       {
+                                               $this->_imageline($this->img, $oldx, $oldy, $x, $y, $this->color['line'][$j], 3);
+                                               if ($this->series[$j]['fill'] == true)
+                                               {
+                                                       $pt = array($oldx, $oldy+3, $x, $y + 3, $x, $this->graphic_area_y2-2,   $oldx, $this->graphic_area_y2-2, $oldx, $oldy+4);
+                                                       imagefilledpolygon($this->img, $pt, 5, $this->color['line_light'][$j]);
+                                               }
+                                       }
+                                       imagefilledrectangle($this->img, $x-2, $y-2, $x+2, $y+2, $this->color['line'][$j]);
+                                       $oldx = $x;
+                                       $oldy = $y;
+                                       if ($j == 0)
+                                               $this->_imagestring($this->img, $this->size, $oldx, ($this->graphic_area_y2+2), $parameter, $this->color['axis_values'], 0, $this->angle);
+                                       $x += $this->space_between_dots;
+                               }
+                       }
+               }
+       }
 
-    function number_formated($number, $dec_size = 1)
-    {
-        if ($this->latin_notation == true) 
-            return number_format(round($number, $dec_size), $dec_size, ",", ".");
-               return number_format(round($number, $dec_size), $dec_size, ".", ",");
-    }
+       function draw_splines()
+       {
+               for ($j = 0; $j < $this->num_series; $j++)
+               {
+                       $n = $this->graphic_area_x1+1;
+                       foreach ($this->labels as $i => $parameter)
+                       {
+                               $size  = round($this->series[$j]['data'][$i] * $this->higher_value_size / $this->higher_value);
+                               $y = $this->graphic_area_y2 - $size;
+                               $p[$n] = $y;
+                               $n += $this->space_between_dots;
+                       }
+                       $r = $this->imageSpline($p);
+                       reset($r);
+                       $oldx = key($r);
+                       $oldy = current($r);
+                       foreach ($r as $x => $y) 
+                       {
+                               imagefilledellipse($this->img, round($x), round($y)+1, 3, 3, $this->color['line'][$j]);
 
-    function number_float($number)
-    {
-        if ($this->latin_notation == true) 
-            $number = str_replace(".", "", $number);
-               return (float)str_replace(",", "", $number);
-    }
+                               if ($this->series[$j]['fill'] == true)
+                               {
+                                       $this->_imageline($this->img, round($x), round($y+4), round($x), $this->graphic_area_y2-2, $this->color['line_light'][$j], 1);
+                               }
+                       }
+               }
+       }
 
+       function imageSpline($p, $step = 1, $minx = -1, $maxx = -1)
+       {
+               $splines = array();
+               if (count($p) < 4)
+                       return false;
+               $cx = $cy = $p1 = array();
+               ksort($p);
+               foreach ($p as $x => $y)
+               {
+                       $cx[] = $x;
+                       $cy[] = $y;
+               }
+               if ($minx == -1)
+                       $minx = min($cx);
+               if ($maxx == -1)
+                       $maxx = max($cx);
+               $n = count($cx);
+               for ($i = 0; $i < $n; ++$i) 
+               {
+                       $splines[$i]['x'] = $cx[$i];
+                       $splines[$i]['a'] = $cy[$i];
+               }
+               $splines[0]['c'] = $splines[$n - 1]['c'] = 0;
+               $alpha[0] = $beta[0] = 0;
+               for ($i = 1; $i < $n - 1; ++$i) 
+               {
+                       $h_i = $cx[$i] - $cx[$i - 1];
+                       $h_i1 = $cx[$i + 1] - $cx[$i];
+                       $A = $h_i;
+                       $C = 2.0 * ($h_i + $h_i1);
+                       $B = $h_i1;
+                       $F = 6.0 * (($cy[$i + 1] - $cy[$i]) / $h_i1 - ($cy[$i] - $cy[$i - 1]) / $h_i);
+                       $z = ($A * $alpha[$i - 1] + $C);
+                       $alpha[$i] = - $B / $z;
+                       $beta[$i] = ($F - $A * $beta[$i - 1]) / $z;
+               }
+               for ($i = $n - 2; $i > 0; --$i) 
+                       $splines[$i]['c'] = $alpha[$i] * $splines[$i + 1]['c'] + $beta[$i];
+               for ($i = $n - 1; $i > 0; --$i) 
+               {
+                       $h_i = $cx[$i] - $cx[$i - 1];
+                       $splines[$i]['d'] = ($splines[$i]['c'] - $splines[$i - 1]['c']) / $h_i;
+                       $splines[$i]['b'] = $h_i * (2.0 * $splines[$i]['c'] + $splines[$i - 1]['c']) / 6.0 + ($cy[$i] - $cy[$i - 1]) / $h_i;
+               }
+               for ($x = $minx; $x <= $maxx; $x += $step) 
+               {
+                       $n = count($splines);
+                       if ($x <= $splines[0]['x'])      {
+                               $s = $splines[1];
+                       } else {
+                               if ($x >= $splines[$n - 1]['x']) {
+                                       $s = $splines[$n - 1];
+                               } else {
+                                       $i = 0;
+                                       $j = $n - 1;
+                                       while ($i + 1 < $j) {
+                                               $k = $i + ($j - $i) / 2;
+                                               if ($x <= $splines[$k]['x']) {
+                                                       $j = $k;
+                                               } else {
+                                                       $i = $k;
+                                               }
+                                       }
+                                       $s = $splines[$j];
+                               }
+                       }
+                       $dx = ($x - $s['x']);
+                       $p1[$x] = $s['a'] + ($s['b'] + ($s['c'] / 2.0 + $s['d'] * $dx / 6.0) * $dx) * $dx;
+               }
+               return $p1;
+       }
 
-    function draw_credits() 
-    {
-        $this->_imagestring($this->img, $this->size - 2, ($this->width-120), ($this->height-10), "Powered by Carlos Reche", $this->color['title']);
-    }
+       function draw_pie()
+       {
+               $n = count(self::$palette);
+               if ($this->stream == 'svg')
+               {
+                       $cx = ($this->graphic_area_x1 + $this->graphic_area_x2) / 2;
+                       $cy = ($this->graphic_area_y1 + $this->graphic_area_y2) / 2;
+                       $width    = $this->graphic_area_width;
+                       $height   = $this->graphic_area_height;
+                       if ($this->sum_total[0] == 0)
+                               $this->sum_total[0] = 1;
+                       $r = $cx * 0.7;
+                       $rc = $this->type == 5 ? 0.01 : $r - 25;
+                       $d = $this->type == 7 ? 180 : 360; // half donut or all
+                       $area = $d / $this->sum_total[0]; 
+                       $start = $this->type == 7 ? 180 : 90;
+                       $rad = pi() / 180.;
+                       $out='';
+                       $gap=0.01;
+                       $ang1=0;          // start angle
+                       foreach ($this->labels as $i => $num)
+                       {
+                               $pct[$i] = round($this->series[0]['data'][$i] / $this->sum_total[0] * 100, 1);
+                               $dang = $this->series[0]['data'][$i] * $area;           // delta angle
+                               $laf  = $dang > 180 ? 1 : 0; // Large Arc Flag
+                               $ang2 = $ang1 + $dang;          // second angle
+                               $a = ($ang1 - $start) * $rad + asin($gap / $rc); 
+                               $p1 = sprintf('%0.2f,%0.2f', $cx + $rc * cos($a), $cy + $rc * sin($a));
+                               $a = ($ang1 - $start) * $rad + asin($gap / $r); 
+                               $p2 = sprintf('%0.2f,%0.2f', $cx + $r * cos($a), $cy + $r * sin($a));
+                               $a = ($ang2 - $start) * $rad - asin($gap / $r); 
+                               $p3 = sprintf('%0.2f,%0.2f', $cx + $r * cos($a), $cy + $r * sin($a));
+                               $a = ($ang2 - $start) * $rad - asin($gap / $rc); 
+                               $p4 = sprintf('%0.2f,%0.2f', $cx + $rc * cos($a), $cy + $rc * sin($a));
+                               $a = ($ang1 - $start) * $rad + asin($gap / $rc); 
+                               $p5 = sprintf('%0.2f,%0.2f', $cx + $rc * cos($a), $cy + $rc * sin($a));
+                               $this->svg->path("M$p1 L$p2 A$r,$r 0 $laf,1 $p3 L$p4 A$rc,$rc 0 $laf,0 $p5", $this->color[$i], 0, $this->color[$i], "class=\"tips\"", "$num: ".number_format($pct[$i], 1)."&#x25;");
+                               $ang1=$ang2;
+                       }
+                       if (!empty($this->donut_title) && $this->type != 5)
+                       {
+                               // Display center text
+                               if ($this->type == 6)
+                                       $cy += 5;
+                               $this->svg->text($cx, $cy, $this->donut_title, $this->size, $this->color[0], "style=\"font-size:18px;font-weight:bold;\"", "middle");
+                       }
+               }
+               else
+               {
+                       $start    = 0;
+                       $sizes    = array();
+                       $degrees = $this->type == 7 ? 180 : 360; // half donut or all
+                       foreach ($this->labels as $i => $parameter)
+                       {
+                               if ($this->sum_total[0] == 0)
+                                       $this->sum_total[0] = 1;
+                               if ($this->series[0]['data'][$i] < 0)
+                                       $this->series[0]['data'][$i] = 0;
+                               $size    = $this->series[0]['data'][$i] * $degrees / $this->sum_total[0];
+                               $size = round($size, 0);
+                               $sizes[] = $size;
+                               $start  += $size;
+                       }
+                       $center_x = ($this->graphic_area_x1 + $this->graphic_area_x2) / 2;
+                       $center_y = ($this->graphic_area_y1 + $this->graphic_area_y2) / 2;
+                       $width    = $this->graphic_area_width;
+                       $height   = $this->graphic_area_height;
+                       $start = $this->type == 7 ? 180 : 270;
+                       // Draw pieces
+                       foreach ($sizes as $i => $size)
+                       {
+                               $j = $i % $n;
+                               $color = 'arc_' . $j;
+                               if ($size >= 1)
+                                       imagefilledarc($this->img, $center_x, $center_y, $width, $height, $start, ($start+$size), $this->color[$color], IMG_ARC_PIE);
+                               $start += $size;
+                       }
+                       if ($this->type != 5) // DONUTS
+                       {
+                               // 85 pixels width hole
+                               $start = $this->type == 7 ? 180 : 0; 
+                               imagefilledarc($this->img, $center_x, $center_y, 85, 85, $start, 360, $this->color['background'], IMG_ARC_PIE);
+                               imagearc($this->img, $center_x, $center_y, 85, 85, $start, 360, $this->color['bg_legend']);
+                               imagearc($this->img, $center_x, $center_y, ($width+1), ($height+1), $start, 360, $this->color['bg_legend']);
+                               if (!empty($this->donut_title))
+                               {
+                                       $plen = $this->string_width($this->donut_title, $this->size);
+                                       $x1 = $center_x - $plen / 2 - 6;
+                                       $co = $this->type == 7 ? 20 : 10; // HALF or ALL
+                                       $this->_imagestring($this->img, $this->size + 4, $x1, $center_y - $co, $this->donut_title, $this->color['arc_0'], 2, 0);        
+                                       $this->_imagestring($this->img, $this->size + 4, $x1+1, $center_y - $co, $this->donut_title, $this->color['arc_0'], 2, 0);      
+                               }
+                       }
+               }
+       }
 
+       function draw_table()
+       {
+               $cs = $this->num_labels + 1;
+               $html = "<table cellspacing='0' style='width:{$this->width}px;font-family:{$this->font};font-size:12px;background:inherit;text-align:center;'>\n";
+               if (!empty($this->title))
+                       $html .= "<tr><th colspan=$cs style='text-align:center;'><h3>$this->title</th><tr>\n";
+               $html .= "<tr><th style='text-align:left;border-bottom:1px solid #444'>#</th>"; 
+               for ($i = 0; $i < $this->num_labels; $i++)
+                       $html .= "<th style='text-align:right;border-bottom:1px solid #444'>{$this->labels[$i]}</th>";
+               $html .= "</tr>\n";
+               for ($j = 0; $j < $this->num_series; $j++)
+               {
+                       $html .= "<tr><td style='text-align:left;'>{$this->series[$j]['label']}</td>";
+                       for ($i = 0; $i < $this->num_labels; $i++)
+                               $html .= "<td style='text-align:right;'>".number_format($this->series[$j]['data'][$i], 0)."</td>";
+                       $html .= "</tr>\n";
+               }
+               $html .= "</table>\n";
+               echo $html;
+       }
 
-    function load_color_palette()
-    {
-        switch ($this->skin)
-        {
-            // Office
-            case 1:
-                $this->color['title']       = imagecolorallocate($this->img,  40,  70,  130);
-                $this->color['background']  = imagecolorallocate($this->img, 255, 255, 255);
-                $this->color['axis_values'] = imagecolorallocate($this->img,  50,  50,  50);
-                $this->color['axis_line']   = imagecolorallocate($this->img, 100, 100, 100);
-                $this->color['bg_lines']    = imagecolorallocate($this->img, 220, 220, 220);
-                $this->color['bg_legend']   = imagecolorallocate($this->img, 255, 255, 255);
+       function calculate_width()
+       {
+               $this->legend_box_width = ($this->legend_exists == true) ? ($this->string_width($this->max_legend_str, $this->size) + 70) : 0;
+               switch ($this->type)
+               {
+                       // Vertical bars or Table
+                       case 1:
+                       case 9:
+                               $this->graphic_area_x1   += $this->string_width($this->higher_value_str, $this->size);
+                               if (!empty($this->width)) 
+                                       $this->graphic_area_width = $this->width - $this->graphic_area_x1 - 30 - $this->legend_box_width;
+                               else
+                               {
+                                       $gap_series = 10;
+                                       $gap_labels = 5;
+                                       $serie_width = 0;
+                                       for ($j = 0; $j < $this->num_series; $j++)
+                                       {
+                                               if ($this->series[$j]['type'] != 4 && $this->series[$j]['type'] != 8)
+                                                       $serie_width += $this->bar_width;
+                                               $serie_width += $gap_labels;
+                                       }
+                                       $serie_width += $gap_series;
+                                       $this->graphic_area_width = $serie_width * $this->num_labels;
+                                       $this->width += $this->graphic_area_width;
+                                       $this->width += $this->graphic_area_x1;
+                                       $this->width += $this->legend_box_width;
+                               }
+                               break;
+                       // Horizontal bars
+                       case 2:
+                               $this->graphic_area_x1 += $this->string_width($this->max_label, $this->size);
+                               if (!empty($this->width))
+                                       $this->graphic_area_width = $this->width - $this->graphic_area_x1 - 30 - $this->legend_box_width;
+                               else
+                               {
+                                       $this->graphic_area_width = ($this->string_width($this->higher_value_str, $this->size) > 50) ? (5 * ($this->string_width($this->higher_value_str, $this->size)) * 0.85) : 200;
+                                       $this->width += $this->graphic_area_x1;
+                                       $this->width += $this->graphic_area_width;
+                                       $this->width += $this->legend_box_width;
+                               }
+                               break;
+                       // Dots
+                       case 3:
+                       // Lines
+                       case 4:
+                       // Splines
+                       case 8:
+                               $this->graphic_area_x1   += $this->string_width(($this->higher_value_str), $this->size);
+                               if (!empty($this->width))
+                                       $this->graphic_area_width = $this->width - $this->graphic_area_x1 - 30 - $this->legend_box_width;
+                               else
+                               {
+                                       $this->graphic_area_width = $this->space_between_dots * ($this->num_labels - 1) + 5;
+                                       $this->width += $this->graphic_area_width;
+                                       $this->width += $this->graphic_area_x1 + 30;
+                                       $this->width += $this->legend_box_width;
+                               }
+                               break;
+                       // Pie
+                       case 5:
+                       // Donut
+                       case 6:
+                       // Half Donut
+                       case 7:
+                               $this->legend_box_width   += 60;
+                               if (!empty($this->width))
+                                       $this->graphic_area_width = $this->width - $this->graphic_area_x1 - 30 - $this->legend_box_width;
+                               else
+                               {
+                                       $this->graphic_area_width = 150;
+                                       $this->width += $this->graphic_area_x1 +20;
+                                       $this->width += $this->legend_box_width;
+                                       $this->width += $this->graphic_area_width;
+                                       $this->width += 90;
+                               }
+                               break;
+               }
+               $this->graphic_area_width = max($this->graphic_area_width, $this->string_width($this->title, $this->size));
+               $this->graphic_area_x2 = $this->graphic_area_x1 + $this->graphic_area_width;
+               $this->legend_box_x1   = $this->graphic_area_x2 + 20;
+               $this->legend_box_x2   = $this->legend_box_x1 + $this->legend_box_width;
+       }
 
-                if (preg_match("/^(1|2)$/", $this->type))
-                {
-                    $this->color['bars']          = imagecolorallocate($this->img, 100, 150, 200);
-                    $this->color['bars_shadow']   = imagecolorallocate($this->img,  50, 100, 150);
-                    $this->color['bars_2']        = imagecolorallocate($this->img, 200, 250, 150);
-                    $this->color['bars_2_shadow'] = imagecolorallocate($this->img, 120, 170,  70);
-                }
-                else if (preg_match("/^(3|4)$/", $this->type))
-                {
-                    $this->color['line']   = imagecolorallocate($this->img, 100, 150, 200);
-                    $this->color['line_2'] = imagecolorallocate($this->img, 230, 100, 100);
-                }
-                else if (preg_match("/^(5|6)$/", $this->type))
-                {
-                    $this->color['arc_1']        = imagecolorallocate($this->img, 255, 150,   0);
-                    $this->color['arc_2']        = imagecolorallocate($this->img, 150,   0, 255);
-                    $this->color['arc_3']        = imagecolorallocate($this->img,   0, 255, 255);
-                    $this->color['arc_4']        = imagecolorallocate($this->img, 255,   0,   0);
-                    $this->color['arc_5']        = imagecolorallocate($this->img,   0, 255,   0);
-                    $this->color['arc_6']        = imagecolorallocate($this->img,   0,   0, 255);
-                    $this->color['arc_7']        = imagecolorallocate($this->img, 255, 255,   0);
-                    $this->color['arc_1_shadow'] = imagecolorallocate($this->img, 127,  75,   0);
-                    $this->color['arc_2_shadow'] = imagecolorallocate($this->img,  75,   0, 127);
-                    $this->color['arc_3_shadow'] = imagecolorallocate($this->img,   0, 127, 127);
-                    $this->color['arc_4_shadow'] = imagecolorallocate($this->img, 127,   0,   0);
-                    $this->color['arc_5_shadow'] = imagecolorallocate($this->img,   0, 127,   0);
-                    $this->color['arc_6_shadow'] = imagecolorallocate($this->img,   0,   0, 127);
-                    $this->color['arc_7_shadow'] = imagecolorallocate($this->img, 127, 127,   0);
-                }
-                break;
+       function calculate_height()
+       {
+               switch ($this->type)
+               {
+                       // Vertical bars
+                       case 1:
+                               if (!empty($this->height))
+                                       $this->graphic_area_height = $this->height - $this->title_height;
+                               else
+                               {
+                                       $this->graphic_area_height = 150;
+                                       $this->height += 65;
+                               }
+                               break;
+                  // Horizontal bars
+                       case 2:
+                               if (!empty($this->height))
+                                       $this->graphic_area_height = $this->height - $this->title_height;
+                               else
+                               {
+                                       $gap_labels = 12;
+                                       if ($this->stream != 'svg')
+                                               $gap_labels += 6;
+                                       $this->graphic_area_height = $this->num_series * $this->bar_width * $this->num_labels + $this->num_labels * $gap_labels;
+                                       $this->height += 65;
+                               }
+                               break;
+                       // Dots
+                       case 3:
+                       // Lines
+                       case 4:
+                       // Spines
+                       case 8:
+                               if (!empty($this->height))
+                                       $this->graphic_area_height = $this->height - $this->title_height;
+                               else
+                               {
+                                       $this->graphic_area_height = 150;
+                                       $this->height += 65;
+                               }
+                               break;
+                       // Pie
+                       case 5:
+                       // Donut
+                       case 6:
+                       // Half Donut
+                       case 7:
+                               if (!empty($this->height))
+                                       $this->graphic_area_height = $this->height - $this->title_height;
+                               else
+                               {
+                                       $this->graphic_area_height = 150;
+                                       $this->height += 65;
+                               }
+                               break;
+               }
+               //if ($this->type == 7) // Half Donut;
+               $this->graphic_area_y1 -= 10;
+               $this->legend_box_y1   = $this->graphic_area_y1;
+               $this->height += $this->graphic_area_height + 40;
+               $this->graphic_area_y2 = $this->graphic_area_y1 + $this->graphic_area_height;
+               $this->legend_box_y2   = $this->legend_box_y1 + $this->legend_box_height;
+       }
 
-            // Matrix
-            case 2:
-                $this->color['title']       = imagecolorallocate($this->img, 255, 255, 255);
-                $this->color['background']  = imagecolorallocate($this->img,   0,   0,   0);
-                $this->color['axis_values'] = imagecolorallocate($this->img,   0, 230,   0);
-                $this->color['axis_line']   = imagecolorallocate($this->img,   0, 200,   0);
-                $this->color['bg_lines']    = imagecolorallocate($this->img, 100, 100, 100);
-                $this->color['bg_legend']   = imagecolorallocate($this->img,  70,  70,  70);
+       function draw_legend()
+       {
+               $x1 = $this->legend_box_x1;
+               $y1 = $this->legend_box_y1;
+               $x2 = $this->legend_box_x2;
+               $y2 = $this->legend_box_y2;
+               if ($this->stream == 'svg')
+                       $this->svg->rect($x1, $y1, $x2, $y2, $this->color['bg_legend']);
+               else
+                       imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bg_legend']);
+               $x = $x1 + 10;
+               $y = $y1;
+               // Draw legend values for VERTICAL BARS, HORIZONTAL BARS, DOTS, LINES AND SPLINES
+               if (preg_match("/^(1|2|3|4|8)$/", $this->type))
+               {
+                       for ($j = 0; $j < $this->num_series; $j++)
+                       {
+                               $color = (preg_match("/^(1|2)$/", $this->type)) ? $this->color['bars'][$j]       : $this->color['line'][$j];
+                               if ($this->stream == 'svg')
+                               {
+                                       $lex = $this->dir == 'rtl' ? $x1+$this->string_width($this->max_legend_str, $this->size)-20 : $x1-5;
+                                       $this->svg->circle($lex, $y-5, 6, "#fff", 1, $color);
+                                       //$this->svg->rect($lex, $y-10, 10, 10, "#fff", 1, $color);
+                                       $lex = $this->dir == 'rtl' ? $x-20 : $x-5; 
+                                       $this->svg->text($lex, ($y-2), $this->series[$j]['label'], $this->size, $this->color['axis_values'], false, $this->align);
+                               }
+                               else
+                               {
+                                       $lex = $this->dir == 'rtl' ? $x2-60 : $x-10;
+                                       imagefilledrectangle($this->img, $lex, $y, ($lex+10), ($y+10), $color);
+                                       imagerectangle($this->img, $lex, $y, ($lex+10), ($y+10), $this->color['title']);
+                                       $lex = $this->dir == 'rtl' ? $x-10 : $x+10;
+                                       $this->_imagestring($this->img, $this->size, $lex, ($y-2), $this->series[$j]['label'], $this->color['axis_values']);
+                               }
+                               $y += 20;
+                       }
+               }
+               // Draw legend values for PIE, DONUT or HALF DONUT
+               else if (preg_match("/^(5|6|7)$/", $this->type))
+               {
+                       $n = count(self::$palette);
+                       if ($this->sum_total[0] == 0)
+                               return;
+                       if (!empty($this->axis_x)) // Only first serie [0]
+                       {
+                               if ($this->stream == 'svg')
+                                       $this->svg->text(((($x1+$x2)/2) - (strlen($this->axis_x)*7/2)), $y, $this->axis_x." (".$this->series[0]['label'].")", $this->size, $this->color['title'], false, $this->align);
+                               else
+                                       $this->_imagestring($this->img, $this->size, (($x1+$x2)/2 - strlen($this->axis_x)*7/2)+30, $y, 
+                                       $this->axis_x."-".$this->series[0]['label'], $this->color['title']);
+                               $y += 25;
+                       }
+                       foreach ($this->labels as $i => $parameter)
+                       {
+                               if ($this->set_values)
+                                       $text = number_format($this->series[0]['data'][$i]);
+                               else
+                                       $text = number_format($this->series[0]['data'][$i] * 100 / $this->sum_total[0], 2) . ' %';
+                               if ($this->stream == 'svg')
+                               {
+                                       $j = $i % $n;
+                                       $lex = $this->dir == 'rtl' ? $x2+60 : $x+5;
+                                       $this->svg->circle($lex, $y-5, 6, "#fff", 1, $this->color[$j]);
+                                       //$this->svg->rect($cx, $cy-10, 10, 10, "#fff", 1, $this->color[$j]);
+                                       // Display label text
+                                       $lex = $this->dir == 'rtl' ? $x2-100 : $x+15;
+                                       $this->svg->text($lex, ($y-2), $parameter, $this->size, $this->color['axis_values'], false, $this->align);
+                                       $lex = $this->dir == 'rtl' ? $x1+25 : $x2;
+                                       $al = $this->dir == 'rtl' ? "start" : "end";
+                                       $this->svg->text($lex, ($y-2), $text, $this->size, $this->color['axis_values'], false, $al);
+                                       $lex = $this->dir == 'rtl' ? $x1-10 : $x1+10;
+                                       $lex2 = $this->dir == 'rtl' ? $x2+50 : $x2;
+                                       $this->svg->line($lex, $y+1, $lex2, $y+1, $this->color['bg_lines']);
+                               }
+                               else
+                               {
+                                       $j = $i % $n;
+                                       $color = 'arc_' . $j;
+                                       $width = $this->string_width($text, $this->size);
+                                       imageline($this->img, $x1+15, ($y-2), $x2+20, ($y-2), $this->color['bg_lines']);
+                                       $lex = $this->dir == 'rtl' ? $x2+20 : $x;
+                                       imagefilledrectangle($this->img, $lex, $y, ($lex+10), ($y+10), $this->color[$color]);
+                                       imagerectangle($this->img, $lex, $y, ($lex+10), ($y+10), $this->color['title']);
+                                       $lex = $this->dir == 'rtl' ? $x2+10 : $x+15;
+                                       $this->_imagestring($this->img, $this->size, $lex, ($y-2), $parameter, $this->color['axis_values'], 0, 0, $this->align);
+                                       $lex = $this->dir == 'rtl' ? $x+10 : $x2-$width;
+                                       $this->_imagestring($this->img, $this->size, $lex, ($y-2), $text, $this->color['axis_values'], 0, 0, $this->align);
+                               }
+                               $y += 18;
+                       }
+               }
+       }
 
-                if (preg_match("/^(1|2)$/", $this->type))
-                {
-                    $this->color['bars']          = imagecolorallocate($this->img,  50, 200,  50);
-                    $this->color['bars_shadow']   = imagecolorallocate($this->img,   0, 150,   0);
-                    $this->color['bars_2']        = imagecolorallocate($this->img, 255, 255, 255);
-                    $this->color['bars_2_shadow'] = imagecolorallocate($this->img, 220, 220, 220);
-                }
-                else if (preg_match("/^(3|4)$/", $this->type))
-                {
-                    $this->color['line']   = imagecolorallocate($this->img, 220, 220, 220);
-                    $this->color['line_2'] = imagecolorallocate($this->img,   0, 180,   0);
-                }
-                else if (preg_match("/^(5|6)$/", $this->type))
-                {
-                    $this->color['arc_1']        = imagecolorallocate($this->img, 255, 255, 255);
-                    $this->color['arc_2']        = imagecolorallocate($this->img, 200, 220, 200);
-                    $this->color['arc_3']        = imagecolorallocate($this->img, 160, 200, 160);
-                    $this->color['arc_4']        = imagecolorallocate($this->img, 135, 180, 135);
-                    $this->color['arc_5']        = imagecolorallocate($this->img, 115, 160, 115);
-                    $this->color['arc_6']        = imagecolorallocate($this->img, 100, 140, 100);
-                    $this->color['arc_7']        = imagecolorallocate($this->img,  90, 120,  90);
-                    $this->color['arc_1_shadow'] = imagecolorallocate($this->img, 127, 127, 127);
-                    $this->color['arc_2_shadow'] = imagecolorallocate($this->img, 100, 110, 100);
-                    $this->color['arc_3_shadow'] = imagecolorallocate($this->img,  80, 100,  80);
-                    $this->color['arc_4_shadow'] = imagecolorallocate($this->img,  67,  90,  67);
-                    $this->color['arc_5_shadow'] = imagecolorallocate($this->img,  57,  80,  57);
-                    $this->color['arc_6_shadow'] = imagecolorallocate($this->img,  50,  70,  50);
-                    $this->color['arc_7_shadow'] = imagecolorallocate($this->img,  45,  60,  45);
-                }
-                break;
+       function string_width($string, $size) 
+       {
+               $p = imagettfbbox($size, 0, $this->fontfile, $string);
+               return $p[4] - $p[0];
+       }
 
+       function calculate_higher_value() 
+       {
+               $digits   = strlen(round($this->max_value));
+               $interval = pow(10, ($digits-1));
+               $this->higher_value = round(($this->max_value - ($this->max_value % $interval) + $interval), 1);
+               $this->higher_value_str = $this->number_formated($this->higher_value, $this->dec1);
+       }
 
-            // Spring
-            case 3:
-                $this->color['title']       = imagecolorallocate($this->img, 250,  50,  50);
-                $this->color['background']  = imagecolorallocate($this->img, 255, 255, 255);
-                $this->color['axis_values'] = imagecolorallocate($this->img,  50, 150,  50);
-                $this->color['axis_line']   = imagecolorallocate($this->img,  50, 100,  50);
-                $this->color['bg_lines']    = imagecolorallocate($this->img, 200, 224, 180);
-                //$this->color['bg_legend']   = imagecolorallocate($this->img, 230, 230, 200);
-                $this->color['bg_legend']   = imagecolorallocate($this->img, 255, 255, 255);
+       function number_formated($number, $dec_size = 1)
+       {
+               if ($this->latin_notation == true) 
+                       return number_format(round($number, $dec_size), $dec_size, ",", ".");
+               return number_format(round($number, $dec_size), $dec_size, ".", ",");
+       }
 
-                if (preg_match("/^(1|2)$/", $this->type))
-                {
-                    $this->color['bars']          = imagecolorallocate($this->img, 255, 170,  80);
-                    $this->color['bars_shadow']   = imagecolorallocate($this->img, 200, 120,  30);
-                    $this->color['bars_2']        = imagecolorallocate($this->img, 250, 230,  80);
-                    $this->color['bars_2_shadow'] = imagecolorallocate($this->img, 180, 150,   0);
-                }
-                else if (preg_match("/^(3|4)$/", $this->type))
-                {
-                    $this->color['line']   = imagecolorallocate($this->img, 230, 100,   0);
-                    $this->color['line_2'] = imagecolorallocate($this->img, 220, 200,  50);
-                }
-                else if (preg_match("/^(5|6)$/", $this->type))
-                {
-                    $this->color['arc_1']        = imagecolorallocate($this->img, 100, 150, 200);
-                    $this->color['arc_2']        = imagecolorallocate($this->img, 200, 250, 150);
-                    $this->color['arc_3']        = imagecolorallocate($this->img, 250, 200, 150);
-                    $this->color['arc_4']        = imagecolorallocate($this->img, 250, 150, 150);
-                    $this->color['arc_5']        = imagecolorallocate($this->img, 250, 250, 150);
-                    $this->color['arc_6']        = imagecolorallocate($this->img, 230, 180, 250);
-                    $this->color['arc_7']        = imagecolorallocate($this->img, 200, 200, 150);
-                    $this->color['arc_1_shadow'] = imagecolorallocate($this->img,  50,  75, 100);
-                    $this->color['arc_2_shadow'] = imagecolorallocate($this->img, 100, 125,  75);
-                    $this->color['arc_3_shadow'] = imagecolorallocate($this->img, 125, 100,  75);
-                    $this->color['arc_4_shadow'] = imagecolorallocate($this->img, 125,  75,  75);
-                    $this->color['arc_5_shadow'] = imagecolorallocate($this->img, 125, 125,  75);
-                    $this->color['arc_6_shadow'] = imagecolorallocate($this->img, 115,  90, 125);
-                    $this->color['arc_7_shadow'] = imagecolorallocate($this->img, 100, 100,  75);
-                }
-                break;
+       function load_color_palette($type)
+       {
+               // The usual color palette. Change if you like. Must be 6 colors.
+               $color = self::$palette;
+               if ($this->stream == 'svg')
+               {
+                       $this->color['title']           = sprintf("#%02x%02x%02x",      40,      70, 130);
+                       $this->color['background']      = sprintf("#%02x%02x%02x", 255, 255, 255);
+                       $this->color['axis_values'] = sprintf("#%02x%02x%02x",  50,      50,  50);
+                       $this->color['axis_line']       = sprintf("#%02x%02x%02x", 100, 100, 100);
+                       $this->color['bg_lines']        = sprintf("#%02x%02x%02x", 220, 220, 220);
+                       $this->color['bg_legend']       = sprintf("#%02x%02x%02x", 255, 255, 255);
+                       $this->color['shadow']          = sprintf("#%02x%02x%02x", 255, 255, 255);
+
+                       if (preg_match("/^(1|2)$/", $type)) // Vertical Bar or Horizontal bar
+                       {
+                               for ($j = 0; $j < $this->num_series; $j++)
+                               {
+                                       $this->color['bars'][$j] = $color[$j];
+                               }
+                       }
+                       elseif (preg_match("/^(3|4|8)$/", $type)) // Dots, Lines or Splines
+                       {
+                               for ($j = 0; $j < $this->num_series; $j++)
+                               {
+                                       $this->color['line'][$j] = $color[$j];
+                                       $this->color['line_light'][$j] = $this->colorLuminate($color[$j], 0.8);
+                               }
+                       }
+                       elseif (preg_match("/^(5|6|7)$/", $type)) // Pie, Donut or Half Donut
+                       {
+                               $n = count($color);
+                               for ($j = 0; $j < $n; $j++) 
+                                       $this->color[$j] = $color[$j];
+                       }
+               }
+               else
+               {
+                       $this->color['title']           = imagecolorallocate($this->img,  40,  70,      130);
+                       $this->color['background']      = imagecolorallocate($this->img, 255, 255, 255);
+                       $this->color['axis_values'] = imagecolorallocate($this->img,  50,  50,  50);
+                       $this->color['axis_line']       = imagecolorallocate($this->img, 100, 100, 100);
+                       $this->color['bg_lines']        = imagecolorallocate($this->img, 220, 220, 220);
+                       $this->color['bg_legend']       = imagecolorallocate($this->img, 255, 255, 255);
+                       $this->color['shadow']          = imagecolorallocate($this->img, 255, 255, 255);
+
+                       if (preg_match("/^(1|2)$/", $type)) // Vertical Bar or Horizontal bar
+                       {
+                               for ($j = 0; $j < $this->num_series; $j++)
+                               {
+                                       $c = $this->hex2rgb($color[$j]);
+                                       $this->color['bars'][$j] = imagecolorallocate($this->img, $c[0], $c[1], $c[2]);
+                               }
+                       }
+                       else if (preg_match("/^(3|4|8)$/", $type)) // Dots, Lines or Splines
+                       {
+                               for ($j = 0; $j < $this->num_series; $j++)
+                               {
+                                       $c = $this->hex2rgb($color[$j]);
+                                       $this->color['line'][$j] = imagecolorallocate($this->img, $c[0], $c[1], $c[2]);
+                                       $c = $this->hex2rgb($this->colorLuminate($color[$j], 0.8)); // lighten for Areas
+                                       $this->color['line_light'][$j] = imagecolorallocate($this->img, $c[0], $c[1], $c[2]);
+                               }
+                       }
+                       else if (preg_match("/^(5|6|7)$/", $type)) // Pie, Donut or Half Donut
+                       {
+                               $n = count($color); 
+                               for ($j = 0; $j < $n; $j++) 
+                               {
+                                       $c = $this->hex2rgb($color[$j]);
+                                       $this->color["arc_{$j}"] = imagecolorallocate($this->img, $c[0], $c[1], $c[2]);
+                               }
+                       }
+               }
+       }
 
-        }
-    }
+       function colorLuminate($hex, $percent) // Color lightner, minus is darker
+       {
+               $hex = ltrim($hex, '#');
+               if (strlen($hex) == 3) {
+                       $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
+               }
+               $hex = array_map('hexdec', str_split($hex, 2));
+               foreach ($hex as &$color) {
+                       $limit = $percent < 0 ? $color : 255 - $color;
+                       $value = ceil($limit * $percent);
+                       $color = str_pad(dechex($color + $value), 2, '0', STR_PAD_LEFT);
+               }
+               return '#' . implode($hex);
+       }
+       
+       function _imageline($image, $x1, $y1, $x2, $y2, $color, $thick = 1)
+       {
+               if ($thick == 1) 
+                       return imageline($image, $x1, $y1, $x2, $y2, $color);
+               $t = $thick / 2 - 0.5;
+               if ($x1 == $x2 || $y1 == $y2)
+                       return imagefilledrectangle($image, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), $color);
+               $k = ($y2 - $y1) / ($x2 - $x1); //y = kx + q
+               $a = $t / sqrt(1 + pow($k, 2));
+               $points = array(
+                       round($x1 - (1+$k)*$a), round($y1 + (1-$k)*$a),
+                       round($x1 - (1-$k)*$a), round($y1 - (1+$k)*$a),
+                       round($x2 + (1+$k)*$a), round($y2 - (1-$k)*$a),
+                       round($x2 + (1-$k)*$a), round($y2 + (1+$k)*$a),
+               );
+               imagefilledpolygon($image, $points, 4, $color);
+               return imagepolygon($image, $points, 4, $color);
+       }
 
-    function _imagestring($img, $size, $x, $y, $string, $col, $alt=0)
-    {
-               if ($this->encoding != 'UTF-8') {
+       function _imagestring($img, $size, $x, $y, $string, $col, $alt=0, $angle=0, $align=false)
+       {
+               if ($align == 'end')
+               {
+                       $p = imagettfbbox($size, $angle, $this->fontfile, $string); 
+                       $x -= $p[2];
+               }
+                       
+               if ($this->encoding != 'UTF-8') 
+               {
                        if (function_exists('iconv'))
                                $string = iconv($this->encoding, 'UTF-8', $string);
                        else
@@ -967,49 +1352,235 @@ class graph
                // Handling ev. RTL languages
                if ($alt)
                {
-                       if ($this->encoding == 'UTF-8' && is_arabic($string))
+                       if ($this->encoding == 'UTF-8' && $this->dir == 'rtl')
                                $alt_len = 18;
                        else
                                $alt_len = 12;
                        if (strlen($string) > $alt_len)
-                               $string = substr($string, 0, $alt_len);
-               }               
+                               $string = substr($string, 0, $alt_len);
+               }               
                if ($this->encoding == 'UTF-8')
                {
                        if (is_arabic($string))
-                               $string = arabic($string, "we");
+                               $string = arabic($string);
                        elseif (is_hebrew($string))
                                $string = hebrew($string);
                }
+               $y += $size + 3;        
+               if ($this->encoding == 'UTF-8' && is_arabic($string))
+               {
+                       $size += 2;
+                       $string = str_replace(" ", "  ", $string);
+               }       
+               imagettftext($img, $size, $angle, $x, $y  + $alt, $col, $this->fontfile, $string);
+       }
 
-       if ($this->built_in)
-       {
-               imagestring($img, $size, $x, $y + $alt, $string, $col);
-       }       
-       else    
-       {
-               if ($size == 1)
-                       $size = 7;
-               elseif ($size == 2)
-                       $size = 8;
-               elseif ($size == 3)
-                       $size = 9;
-               elseif ($size == 4)
-                       $size = 11;
-               else
-                       $size = 12;
-               $y += $size + 3;        
-                       $angle = 0;
+       function hex2rgb($hex)
+       {
+               list($r, $g, $b) = sscanf($hex, "#%02x%02x%02x");
+               return array($r, $g, $b);
+       }
 
-                       if ($this->encoding == 'UTF-8' && is_arabic($string))
-                       {
-                               $size += 2;
-                               $string = str_replace(" ", "  ", $string);
-                       }       
-                       
-                       imagettftext($img, $size, $angle, $x, $y + $alt, $col, $this->fontfile, $string);
-       }
-    }  
+       function _controlPoint($curr, $prev, $next, $reverse = false)
+       {
+               $p = $prev ? $prev : $curr;
+               $n = $next ? $next : $curr;
+               $smooth = 0.2;
+               $lenx = $n[0] - $p[0];
+               $leny = $n[1] - $p[1];
+               $len = sqrt(pow($lenx, 2) + pow($leny, 2));
+               $angle = atan2($leny, $lenx);
+               $len *= $smooth;
+               $angle += ($reverse ? pi() : 0);
+               $x = $curr[0] + cos($angle) * $len;
+               $y = $curr[1] + sin($angle) * $len;
+               return array($x, $y);
+       }
+
+       function _splineCommand($p, $i, $a)
+       {
+               $c = isset($a[$i - 1]) ? $a[$i - 1] : false;
+               $d = isset($a[$i - 2]) ? $a[$i - 2] : false;
+               $e = isset($a[$i + 1]) ? $a[$i + 1] : false;
+               $cps = $this->_controlPoint($c, $d, $p);
+               $cpe = $this->_controlPoint($p, $c, $e, true);
+               return " C".round($cps[0],1).",".round($cps[1],1)." ".round($cpe[0],1).",".round($cpe[1], 1)." $p[0],$p[1]";
+       }
+
+       function clean_out_dir()
+       {
+               $dir = $this->out_dir;
+               if ($d = @opendir($dir)) {
+                       while (($file = readdir($d)) !== false) {
+                               if (!is_file($dir.'/'.$file) || $file == 'index.php') continue;
+                               // then check to see if this one is too old
+                               $ftime = filemtime($dir.'/'.$file);
+                               // seems 3 min is enough for any report download, isn't it?
+                               if (time()-$ftime > 180){
+                                       unlink($dir.'/'.$file);
+                               }
+                       }
+                       closedir($d);
+               }
+       }
+}
+
+class SVG
+{
+       var $svg;
+
+       function __construct($width=0, $height=0, $dir='ltr', $lang='en')
+       {
+               $this->svg = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" direction=\"$dir\" xml:lang=\"$lang\" width=\"$width\" height=\"$height\" viewPort=\"0 0 $width $height\"";
+               $this->svg .= ">\n";
+       }
+       function circle($x, $y, $r, $bcolor=false, $line_width=1, $color=false, $style=false, $tooltip=false)
+       {
+               $this->svg .= "<circle cx=\"$x\" cy=\"$y\" r=\"$r\"";
+               if (!empty($line_width))
+                       $this->svg .= " stroke-width=\"$line_width\"";
+               if (!empty($bcolor))
+                       $this->svg .= " stroke=\"$bcolor\"";
+               if (empty($color))
+                       $color = "none";
+               $this->svg .= " fill=\"$color\"";
+               if (!empty($style))
+                       $this->svg .= " $style";
+               if (!empty($tooltip))
+                       $this->svg .= "><title>$tooltip</title></circle>\n";
+               else
+                       $this->svg .= " />\n";
+       }
+       function rect($x1, $y1, $x2, $y2, $bcolor=false, $line_width=1, $color=false, $style=false, $tooltip=false)
+       {
+               $this->svg .= "<rect x=\"$x1\" y=\"$y1\" width=\"$x2\" height=\"$y2\"";
+               if (!empty($line_width))
+                       $this->svg .= " stroke-width=\"$line_width\"";
+               if (!empty($bcolor))
+                       $this->svg .= " stroke=\"$bcolor\"";
+               if (empty($color))
+                       $color = "none";
+               $this->svg .= " fill=\"$color\"";
+               if (!empty($style))
+                       $this->svg .= " $style";
+               if (!empty($tooltip))
+                       $this->svg .= "><title>$tooltip</title></rect>\n";
+               else
+                       $this->svg .= " />\n";
+       }
+       function line($x1, $y1, $x2, $y2, $bcolor=false, $line_width=1, $color=false, $style=false, $tooltip=false)
+       {
+               $this->svg .= "<line x1=\"$x1\" y1=\"$y1\" x2=\"$x2\" y2=\"$y2\"";
+               if (!empty($line_width))
+                       $this->svg .= " stroke-width=\"$line_width\"";
+               if (!empty($bcolor))
+                       $this->svg .= " stroke=\"$bcolor\"";
+               if (empty($color))
+                       $color = "none";
+               $this->svg .= " fill=\"$color\"";
+               if (!empty($style))
+                       $this->svg .= " $style";
+               if (!empty($tooltip))
+                       $this->svg .= "><title>$tooltip</title></line>\n";
+               else
+                       $this->svg .= " />\n";
+       }
+       function polygon($p, $bcolor=false, $line_width=1, $color=false, $style=false, $tooltip=false)
+       {
+               $this->svg .= "<polygon points=\"$p\"";
+               if (!empty($line_width))
+                       $this->svg .= " stroke-width=\"$line_width\"";
+               if (!empty($bcolor))
+                       $this->svg .= " stroke=\"$bcolor\"";
+               if (empty($color))
+                       $color = "none";
+               $this->svg .= " fill=\"$color\"";
+               if (!empty($style))
+                       $this->svg .= " $style";
+               if (!empty($tooltip))
+                       $this->svg .= "><title>$tooltip</title></polygon>\n";
+               else
+                       $this->svg .= " />\n";
+       }
+       function polyline($p, $bcolor=false, $line_width=1, $color=false, $style=false, $tooltip=false)
+       {
+               $this->svg .= "<polyline points=\"$p\"";
+               if (!empty($line_width))
+                       $this->svg .= " stroke-width=\"$line_width\"";
+               if (!empty($bcolor))
+                       $this->svg .= " stroke=\"$bcolor\"";
+               if (empty($color))
+                       $color = "none";
+               $this->svg .= " fill=\"$color\"";
+               if (!empty($style))
+                       $this->svg .= " $style";
+               if (!empty($tooltip))
+                       $this->svg .= "><title>$tooltip</title></polyline>\n";
+               else
+                       $this->svg .= " />\n";
+       }
+       function path($d, $bcolor=false, $line_width=1, $color=false, $style=false, $tooltip=false)
+       {
+               $this->svg .= "<path d=\"$d\"";
+               if (!empty($line_width))
+                       $this->svg .= " stroke-width=\"$line_width\"";
+               if (!empty($bcolor))
+                       $this->svg .= " stroke=\"$bcolor\"";
+               if (empty($color))
+                       $color = "none";
+               $this->svg .= " fill=\"$color\"";
+               if (!empty($style))
+                       $this->svg .= " $style";
+               if (!empty($tooltip))
+                       $this->svg .= "><title>$tooltip</title></path>\n";
+               else
+                       $this->svg .= " />\n";
+       }
+       function text($x, $y, $text, $size=false, $color=false, $style=false, $align=false, $angle=false) // align start, middle, end. 
+       {
+               $this->svg .= "<text x=\"$x\" y=\"$y\"";
+               if (!empty($color))
+                       $this->svg .= " fill=\"$color\"";
+               if (!empty($size))
+                       $this->svg .= " font-size=\"$size\"";
+               if (!empty($style))
+                       $this->svg .= " $style";
+               if (!empty($align))
+                       $this->svg .= " text-anchor=\"$align\"";
+               if (!empty($angle))
+                       $this->svg .= " transform=\"rotate($angle $x $y)\"";
+               $this->svg .= ">$text</text>\n";
+       }
+       function other($s)
+       {
+               $this->svg .= $s;
+       }
+       function style($s='')
+       {
+               $this->svg .= "<defs><style type=\"text/css\"><![CDATA[ $s ]]></style></defs>\n";
+       }
+       function open_group($p = '')
+       {
+               $this->svg .= "<g $p>\n";
+       }
+       function close_group()
+       {
+               $this->svg .= "</g>\n";
+       }
+       function close()
+       {
+               $this->svg .= "</svg>\n";
+       }
+       function draw()
+       {
+               //header('Content-Type: image/svg+xml');
+               echo $this->svg;
+               return true;
+       }
+       function save($fileName)
+       {
+               file_put_contents($fileName, $this->svg);
+       }
 }
 
 // The following is for handling RTL texts. GD does not handle RTL at all.
@@ -1035,11 +1606,11 @@ function utf8_strlen($str)
 function utf8_chr($uni) 
 {
        $r = "";
-    # ASCII range (including control chars)
-    if ( ($uni >= 0) && ($uni <= 0x007f) ) 
-            $r .= chr($uni);
+       # ASCII range (including control chars)
+       if ( ($uni >= 0) && ($uni <= 0x007f) ) 
+                       $r .= chr($uni);
        elseif ($uni <= 0x07ff) // 2 byte sequence
-       {
+       {
                $r .= chr(0xc0 | ($uni >> 6));
                $r .= chr(0x80 | ($uni & 0x003f));
        } 
@@ -1069,53 +1640,53 @@ function utf8_chr($uni)
 function arabic($str,$z="",$method='normal')
 {
 $p_chars = array (
-    utf8_chr(0x0622) => array (utf8_chr(0xfe82), utf8_chr(0xfe82), utf8_chr(0x0622)),
-    utf8_chr(0x0627) => array (utf8_chr(0xfe8e), utf8_chr(0xfe8e), utf8_chr(0x0627)),
-    utf8_chr(0x0628) => array (utf8_chr(0xfe90), utf8_chr(0xfe92), utf8_chr(0xfe91)),
-    utf8_chr(0x067e) => array (utf8_chr(0xfb57), utf8_chr(0xfb59), utf8_chr(0xfb58)),
-    utf8_chr(0x062a) => array (utf8_chr(0xfe96), utf8_chr(0xfe98), utf8_chr(0xfe97)),
-    utf8_chr(0x062b) => array (utf8_chr(0xfe9a), utf8_chr(0xfe9c), utf8_chr(0xfe9b)),
-    utf8_chr(0x062c) => array (utf8_chr(0xfe9e), utf8_chr(0xfea0), utf8_chr(0xfe9f)),
-    utf8_chr(0x0686) => array (utf8_chr(0xfb7b), utf8_chr(0xfb7d), utf8_chr(0xfb7c)),
-    utf8_chr(0x062d) => array (utf8_chr(0xfea2), utf8_chr(0xfea4), utf8_chr(0xfea3)),
-    utf8_chr(0x062e) => array (utf8_chr(0xfea6), utf8_chr(0xfea8), utf8_chr(0xfea7)),
-    utf8_chr(0x062f) => array (utf8_chr(0xfeaa), utf8_chr(0xfeaa), utf8_chr(0xfea9)),
-    utf8_chr(0x0630) => array (utf8_chr(0xfeac), utf8_chr(0xfeac), utf8_chr(0xfeab)),
-    utf8_chr(0x0631) => array (utf8_chr(0xfeae), utf8_chr(0xfeae), utf8_chr(0xfead)),
-    utf8_chr(0x0632) => array (utf8_chr(0xfeb0), utf8_chr(0xfeb0), utf8_chr(0xfeaf)),
-    utf8_chr(0x0698) => array (utf8_chr(0xfb8b), utf8_chr(0xfb8b), utf8_chr(0xfb8a)),
-    utf8_chr(0x0633) => array (utf8_chr(0xfeb2), utf8_chr(0xfeb4), utf8_chr(0xfeb3)),
-    utf8_chr(0x0634) => array (utf8_chr(0xfeb6), utf8_chr(0xfeb8), utf8_chr(0xfeb7)),
-    utf8_chr(0x0635) => array (utf8_chr(0xfeba), utf8_chr(0xfebc), utf8_chr(0xfebb)),
-    utf8_chr(0x0636) => array (utf8_chr(0xfebe), utf8_chr(0xfec0), utf8_chr(0xfebf)),
-    utf8_chr(0x0637) => array (utf8_chr(0xfec2), utf8_chr(0xfec4), utf8_chr(0xfec3)),
-    utf8_chr(0x0638) => array (utf8_chr(0xfec6), utf8_chr(0xfec8), utf8_chr(0xfec7)),
-    utf8_chr(0x0639) => array (utf8_chr(0xfeca), utf8_chr(0xfecc), utf8_chr(0xfecb)),
-    utf8_chr(0x063a) => array (utf8_chr(0xfece), utf8_chr(0xfed0), utf8_chr(0xfecf)),
-    utf8_chr(0x0641) => array (utf8_chr(0xfed2), utf8_chr(0xfed4), utf8_chr(0xfed3)),
-    utf8_chr(0x0642) => array (utf8_chr(0xfed6), utf8_chr(0xfed8), utf8_chr(0xfed7)),
-    utf8_chr(0x06a9) => array (utf8_chr(0xfeda), utf8_chr(0xfedc), utf8_chr(0xfedb)),
-    utf8_chr(0x06af) => array (utf8_chr(0xfb93), utf8_chr(0xfb95), utf8_chr(0xfb94)),
-    utf8_chr(0x0644) => array (utf8_chr(0xfede), utf8_chr(0xfee0), utf8_chr(0xfedf)),
-    utf8_chr(0x0645) => array (utf8_chr(0xfee2), utf8_chr(0xfee4), utf8_chr(0xfee3)),
-    utf8_chr(0x0646) => array (utf8_chr(0xfee6), utf8_chr(0xfee8), utf8_chr(0xfee7)),
-    utf8_chr(0x0648) => array (utf8_chr(0xfeee), utf8_chr(0xfeee), utf8_chr(0xfeed)),
-    utf8_chr(0x06cc) => array (utf8_chr(0xfbfd), utf8_chr(0xfbff), utf8_chr(0xfbfe)),
-    utf8_chr(0x0643) => array (utf8_chr(0xfeda), utf8_chr(0xfedc), utf8_chr(0xfedb)),
-    utf8_chr(0x064a) => array (utf8_chr(0xfef2), utf8_chr(0xfef4), utf8_chr(0xfef3)),
-    utf8_chr(0x0623) => array (utf8_chr(0xfe84), utf8_chr(0xfe84), utf8_chr(0xfe83)),
-    utf8_chr(0x0624) => array (utf8_chr(0xfe86), utf8_chr(0xfe86), utf8_chr(0xfe85)),
-    utf8_chr(0x0625) => array (utf8_chr(0xfe88), utf8_chr(0xfe88), utf8_chr(0xfe87)),
-    utf8_chr(0x0626) => array (utf8_chr(0xfe8a), utf8_chr(0xfe8c), utf8_chr(0xfe8b)),
-    utf8_chr(0x0629) => array (utf8_chr(0xfe94), utf8_chr(0xfe98), utf8_chr(0xfe97))
+       utf8_chr(0x0622) => array (utf8_chr(0xfe82), utf8_chr(0xfe82), utf8_chr(0x0622)),
+       utf8_chr(0x0627) => array (utf8_chr(0xfe8e), utf8_chr(0xfe8e), utf8_chr(0x0627)),
+       utf8_chr(0x0628) => array (utf8_chr(0xfe90), utf8_chr(0xfe92), utf8_chr(0xfe91)),
+       utf8_chr(0x067e) => array (utf8_chr(0xfb57), utf8_chr(0xfb59), utf8_chr(0xfb58)),
+       utf8_chr(0x062a) => array (utf8_chr(0xfe96), utf8_chr(0xfe98), utf8_chr(0xfe97)),
+       utf8_chr(0x062b) => array (utf8_chr(0xfe9a), utf8_chr(0xfe9c), utf8_chr(0xfe9b)),
+       utf8_chr(0x062c) => array (utf8_chr(0xfe9e), utf8_chr(0xfea0), utf8_chr(0xfe9f)),
+       utf8_chr(0x0686) => array (utf8_chr(0xfb7b), utf8_chr(0xfb7d), utf8_chr(0xfb7c)),
+       utf8_chr(0x062d) => array (utf8_chr(0xfea2), utf8_chr(0xfea4), utf8_chr(0xfea3)),
+       utf8_chr(0x062e) => array (utf8_chr(0xfea6), utf8_chr(0xfea8), utf8_chr(0xfea7)),
+       utf8_chr(0x062f) => array (utf8_chr(0xfeaa), utf8_chr(0xfeaa), utf8_chr(0xfea9)),
+       utf8_chr(0x0630) => array (utf8_chr(0xfeac), utf8_chr(0xfeac), utf8_chr(0xfeab)),
+       utf8_chr(0x0631) => array (utf8_chr(0xfeae), utf8_chr(0xfeae), utf8_chr(0xfead)),
+       utf8_chr(0x0632) => array (utf8_chr(0xfeb0), utf8_chr(0xfeb0), utf8_chr(0xfeaf)),
+       utf8_chr(0x0698) => array (utf8_chr(0xfb8b), utf8_chr(0xfb8b), utf8_chr(0xfb8a)),
+       utf8_chr(0x0633) => array (utf8_chr(0xfeb2), utf8_chr(0xfeb4), utf8_chr(0xfeb3)),
+       utf8_chr(0x0634) => array (utf8_chr(0xfeb6), utf8_chr(0xfeb8), utf8_chr(0xfeb7)),
+       utf8_chr(0x0635) => array (utf8_chr(0xfeba), utf8_chr(0xfebc), utf8_chr(0xfebb)),
+       utf8_chr(0x0636) => array (utf8_chr(0xfebe), utf8_chr(0xfec0), utf8_chr(0xfebf)),
+       utf8_chr(0x0637) => array (utf8_chr(0xfec2), utf8_chr(0xfec4), utf8_chr(0xfec3)),
+       utf8_chr(0x0638) => array (utf8_chr(0xfec6), utf8_chr(0xfec8), utf8_chr(0xfec7)),
+       utf8_chr(0x0639) => array (utf8_chr(0xfeca), utf8_chr(0xfecc), utf8_chr(0xfecb)),
+       utf8_chr(0x063a) => array (utf8_chr(0xfece), utf8_chr(0xfed0), utf8_chr(0xfecf)),
+       utf8_chr(0x0641) => array (utf8_chr(0xfed2), utf8_chr(0xfed4), utf8_chr(0xfed3)),
+       utf8_chr(0x0642) => array (utf8_chr(0xfed6), utf8_chr(0xfed8), utf8_chr(0xfed7)),
+       utf8_chr(0x06a9) => array (utf8_chr(0xfeda), utf8_chr(0xfedc), utf8_chr(0xfedb)),
+       utf8_chr(0x06af) => array (utf8_chr(0xfb93), utf8_chr(0xfb95), utf8_chr(0xfb94)),
+       utf8_chr(0x0644) => array (utf8_chr(0xfede), utf8_chr(0xfee0), utf8_chr(0xfedf)),
+       utf8_chr(0x0645) => array (utf8_chr(0xfee2), utf8_chr(0xfee4), utf8_chr(0xfee3)),
+       utf8_chr(0x0646) => array (utf8_chr(0xfee6), utf8_chr(0xfee8), utf8_chr(0xfee7)),
+       utf8_chr(0x0648) => array (utf8_chr(0xfeee), utf8_chr(0xfeee), utf8_chr(0xfeed)),
+       utf8_chr(0x06cc) => array (utf8_chr(0xfbfd), utf8_chr(0xfbff), utf8_chr(0xfbfe)),
+       utf8_chr(0x0643) => array (utf8_chr(0xfeda), utf8_chr(0xfedc), utf8_chr(0xfedb)),
+       utf8_chr(0x064a) => array (utf8_chr(0xfef2), utf8_chr(0xfef4), utf8_chr(0xfef3)),
+       utf8_chr(0x0623) => array (utf8_chr(0xfe84), utf8_chr(0xfe84), utf8_chr(0xfe83)),
+       utf8_chr(0x0624) => array (utf8_chr(0xfe86), utf8_chr(0xfe86), utf8_chr(0xfe85)),
+       utf8_chr(0x0625) => array (utf8_chr(0xfe88), utf8_chr(0xfe88), utf8_chr(0xfe87)),
+       utf8_chr(0x0626) => array (utf8_chr(0xfe8a), utf8_chr(0xfe8c), utf8_chr(0xfe8b)),
+       utf8_chr(0x0629) => array (utf8_chr(0xfe94), utf8_chr(0xfe98), utf8_chr(0xfe97))
 );
 
 $nastaligh = array (
-    utf8_chr(0x0647) => array (utf8_chr(0xfbab), utf8_chr(0xfbad), utf8_chr(0xfbac))
+       utf8_chr(0x0647) => array (utf8_chr(0xfbab), utf8_chr(0xfbad), utf8_chr(0xfbac))
 );
 
 $normal = array (
-    utf8_chr(0x0647) => array (utf8_chr(0xfeea), utf8_chr(0xfeec), utf8_chr(0xfeeb))
+       utf8_chr(0x0647) => array (utf8_chr(0xfeea), utf8_chr(0xfeec), utf8_chr(0xfeeb))
 );
 
 $mp_chars = array (utf8_chr(0x0622), utf8_chr(0x0627), utf8_chr(0x062f), utf8_chr(0x0630), utf8_chr(0x0631), utf8_chr(0x0632), 
@@ -1287,6 +1858,19 @@ $ignorelist = array (utf8_chr(0x0000), utf8_chr(0x064c), utf8_chr(0x064d), utf8_
                $str_next = null;
                $str_back = null;
        }
-       return  $output;
+       return  $output;
 }
 
+// For debugging
+if (!function_exists('dump'))
+{
+       function dump($str)
+       {
+               $req_dump = print_r($str, true);
+               $fp = fopen('dump.log', 'a');
+               date_default_timezone_set("Europe/Amsterdam");
+               $msg = "[" . date('Y-m-d / H:i:s') . "] - $req_dump\n";
+               fwrite($fp, $msg);
+               fclose($fp);
+       }
+}
index c96378f7337b99dc93d1b87651c47ec29e056f8d..c4a476ed66cec4cba15da90253a87fc8dc91b875 100644 (file)
@@ -253,7 +253,7 @@ class BoxReports
 
                                case 'GRAPHIC':
                                        $sel = array(_("No Graphics"), _("Vertical bars"), _("Horizontal bars"), 
-                                                               _("Dots"), _("Lines"), _("Pie"), _("Donut"));
+                                                               _("Dots"), _("Lines"), _("Pie"), _("Donut"), _("Half donut"), _("Spline"));
                                        return array_selector($name, null, $sel);
 
                                case 'SYS_TYPES':
index 22c2d8a96edf7859ca6283e4a92e3d7469ee56fe..92b56466b7cbd7f7dfdf0f6c734032d5f8b27749 100644 (file)
@@ -85,7 +85,7 @@ function print_aged_customer_analysis()
        if ($graphics)
        {
                include_once($path_to_root . "/reporting/includes/class.graphic.inc");
-               $pg = new graph();
+               $pg = new chart($graphics);
        }
 
        if ($fromcust == ALL_TEXT)
@@ -225,28 +225,30 @@ function print_aged_customer_analysis()
        $rep->fontSize += 2;
        $rep->TextCol(0, 3, _('Grand Total'));
        $rep->fontSize -= 2;
+       $serie = array();
        for ($i = 0; $i < count($total); $i++)
        {
                $rep->AmountCol($i + 3, $i + 4, $total[$i], $dec);
                if ($graphics && $i < count($total) - 1)
                {
-                       $pg->y[$i] = abs($total[$i]);
+                       $serie[] = abs($total[$i]);
                }
        }
        $rep->Line($rep->row - 8);
        if ($graphics)
        {
-               $pg->x = array(_('Current'), $nowdue, $pastdue1, $pastdue2);
-               $pg->title     = $rep->title;
-               $pg->axis_x    = _("Days");
-               $pg->axis_y    = _("Amount");
-               $pg->graphic_1 = $to;
-               $pg->type      = $graphics;
-               $pg->skin      = $SysPrefs->graph_skin;
-               $pg->built_in  = false;
+               $pg->setStream('png');
+               $pg->addSerie(_('Balances'), $serie);
+               $pg->setLabels(array(_('Current'), $nowdue, $pastdue1, $pastdue2));
+               $pg->setTitle($rep->title);
+               $pg->setXTitle(_("Days"));
+               $pg->setYTitle(_("Amount"));
+               $pg->setDTitle(number_format2($total[4]));
+               $pg->setValues(true);
                $pg->latin_notation = ($SysPrefs->decseps[user_dec_sep()] != ".");
                $filename = company_path(). "/pdf_files/". random_id().".png";
-               $pg->display($filename, true);
+               $pg->display($filename);
+               //sleep(5);
                $w = $pg->width / 1.5;
                $h = $pg->height / 1.5;
                $x = ($rep->pageWidth - $w) / 2;
index 04d1afa1d5365b735759ebde3e44376685740745..0e122ab4f25a4f5c6bc9587a896dc14e030a3d06 100644 (file)
@@ -91,7 +91,8 @@ function print_aged_supplier_analysis()
        if ($graphics)
        {
                include_once($path_to_root . "/reporting/includes/class.graphic.inc");
-               $pg = new graph();
+               $pg = new chart($graphics);
+               $serie = array();
        }
 
        if ($fromsupp == ALL_TEXT)
@@ -237,21 +238,21 @@ function print_aged_supplier_analysis()
                $rep->AmountCol($i + 3, $i + 4, $total[$i], $dec);
                if ($graphics && $i < count($total) - 1)
                {
-                       $pg->y[$i] = abs($total[$i]);
+                       $serie[$i] = abs($total[$i]);
                }
        }
        $rep->Line($rep->row  - 8);
        $rep->NewLine();
        if ($graphics)
        {
-               $pg->x = array(_('Current'), $nowdue, $pastdue1, $pastdue2);
-               $pg->title     = $rep->title;
-               $pg->axis_x    = _("Days");
-               $pg->axis_y    = _("Amount");
-               $pg->graphic_1 = $to;
-               $pg->type      = $graphics;
-               $pg->skin      = $SysPrefs->graph_skin;
-               $pg->built_in  = false;
+               $pg->setStream('png');
+               $pg->setLabels(array(_('Current'), $nowdue, $pastdue1, $pastdue2));
+               $pg->addSerie(_("Balances"), $serie);
+               $pg->setTitle($rep->title);
+               $pg->setXTitle(_("Days"));
+               $pg->setYTitle(_("Amount"));
+               $pg->setDTitle(number_format2($total[4]));
+               $pg->setValues(true);
                $pg->latin_notation = ($SysPrefs->decseps[user_dec_sep()] != ".");
                $filename = company_path(). "/pdf_files/". random_id().".png";
                $pg->display($filename, true);
index 30e2520bfded355d83efc04caaa9395d3a1cea64..cc41fd395a4ac5de79085a58bf24d4e272f2c4f5 100644 (file)
@@ -26,7 +26,7 @@ include_once($path_to_root . "/admin/db/tags_db.inc");
 
 //----------------------------------------------------------------------------------------------------
 
-function display_type ($type, $typename, $from, $to, $convert, &$dec, &$rep, $dimension, $dimension2, $tags, &$pg, $graphics)
+function display_type ($type, $typename, $from, $to, $convert, &$dec, &$rep, $dimension, $dimension2, $tags, &$pg, $graphics, &$labels, &$serie1, &$serie2)
 {
        $code_open_balance = 0;
        $code_period_balance = 0;
@@ -109,9 +109,9 @@ function display_type ($type, $typename, $from, $to, $convert, &$dec, &$rep, $di
                $rep->AmountCol(4, 5, ($code_open_balance + $open_balance_total + $code_period_balance + $period_balance_total) * $convert, $dec);              
                if ($graphics)
                {
-                       $pg->x[] = $typename;
-                       $pg->y[] = abs($code_open_balance + $open_balance_total);
-                       $pg->z[] = abs($code_period_balance + $period_balance_total);
+                       $labels[] = $typename;
+                       $serie1[] = abs(($code_period_balance + $period_balance_total) * $convert);
+                       $serie2[] = abs(($code_open_balance + $open_balance_total + $code_period_balance + $period_balance_total) * $convert);
                }
                $rep->NewLine();
        }
@@ -172,7 +172,10 @@ function print_balance_sheet()
        if ($graphics)
        {
                include_once($path_to_root . "/reporting/includes/class.graphic.inc");
-               $pg = new graph();
+               $pg = new Chart($graphics);
+               $labels = array();
+               $serie1 = array();
+               $serie2 = array();
        }
        if (!$decimals)
                $dec = 0;
@@ -241,8 +244,7 @@ function print_balance_sheet()
                $typeresult = get_account_types(false, $class['cid'], -1);
                while ($accounttype=db_fetch($typeresult))
                {
-                       $classtotal = display_type($accounttype["id"], $accounttype["name"], $from, $to, $convert, $dec, 
-                               $rep, $dimension, $dimension2, $tags, $pg, $graphics);
+                       $classtotal = display_type($accounttype["id"], $accounttype["name"], $from, $to, $convert, $dec, $rep, $dimension, $dimension2, $tags, $pg, $graphics, $labels, $serie1, $serie2);
                        $class_open_total += $classtotal[0];
                        $class_period_total += $classtotal[1];                  
                }
@@ -300,17 +302,18 @@ function print_balance_sheet()
        $rep->Line($rep->row);
        if ($graphics)
        {
-               $pg->x[] = _('Calculated Return');
-               $pg->y[] = abs($calc_open);
-               $pg->z[] = abs($calc_period);
-               $pg->title     = $rep->title;
-               $pg->axis_x    = _("Group");
-               $pg->axis_y    = _("Amount");
-               $pg->graphic_1 = $headers[2];
-               $pg->graphic_2 = $headers[3];
-               $pg->type      = $graphics;
-               $pg->skin      = $SysPrefs->graph_skin;
-               $pg->built_in  = false;
+               $labels[] = _('Calculated Return');
+               $serie1[] = abs($calc_period);
+               $serie2[] = abs($calc_open + $calc_period);
+               $pg->setStream('png');
+               $pg->setLabels($labels);
+               $pg->addSerie($headers[3], $serie1);
+               $pg->addSerie($headers[4], $serie2);
+               $pg->setTitle($rep->title);
+               $pg->setXTitle(_("Group"));
+               $pg->setYTitle(_("Amount"));
+               $pg->setDTitle(number_format2(abs($calc_open + $calc_period)));
+               $pg->setValues(true);
                $pg->latin_notation = ($SysPrefs->decseps[user_dec_sep()] != ".");
                $filename = company_path(). "/pdf_files/". random_id().".png";
                $pg->display($filename, true);
index 19a01cabbfe64952f350729c9a8839aa75d77319..cf2590054015697fc70e19062403016e5acc36f5 100644 (file)
@@ -26,8 +26,7 @@ include_once($path_to_root . "/admin/db/tags_db.inc");
 
 //----------------------------------------------------------------------------------------------------
 
-function display_type ($type, $typename, $from, $to, $begin, $end, $compare, $convert, &$dec, &$pdec, &$rep, $dimension, $dimension2, 
-       $tags, &$pg, $graphics)
+function display_type ($type, $typename, $from, $to, $begin, $end, $compare, $convert, &$dec, &$pdec, &$rep, $dimension, $dimension2, $tags, &$pg, $graphics, &$labels, &$serie1, &$serie2)
 {
        $code_per_balance = 0;
        $code_acc_balance = 0;
@@ -118,9 +117,9 @@ function display_type ($type, $typename, $from, $to, $begin, $end, $compare, $co
                $rep->AmountCol(4, 5, Achieve(($code_per_balance + $per_balance_total), ($code_acc_balance + $acc_balance_total)), $pdec);              
                if ($graphics)
                {
-                       $pg->x[] = $typename;
-                       $pg->y[] = abs($code_per_balance + $per_balance_total);
-                       $pg->z[] = abs($code_acc_balance + $acc_balance_total);
+                       $labels[] = $typename;
+                       $serie1[] = abs($code_per_balance + $per_balance_total);
+                       $serie2[] = abs($code_acc_balance + $acc_balance_total);
                }
                $rep->NewLine();
        }
@@ -196,7 +195,10 @@ function print_profit_and_loss_statement()
        if ($graphics)
        {
                include_once($path_to_root . "/reporting/includes/class.graphic.inc");
-               $pg = new graph();
+               $pg = new Chart($graphics);
+               $labels = array();
+               $serie1 = array();
+               $serie2 = array();
        }
        if (!$decimals)
                $dec = 0;
@@ -285,8 +287,7 @@ function print_profit_and_loss_statement()
                $typeresult = get_account_types(false, $class['cid'], -1);
                while ($accounttype=db_fetch($typeresult))
                {
-                       $classtotal = display_type($accounttype["id"], $accounttype["name"], $from, $to, $begin, $end, $compare, $convert, $dec, 
-                               $pdec, $rep, $dimension, $dimension2, $tags, $pg, $graphics);
+                       $classtotal = display_type($accounttype["id"], $accounttype["name"], $from, $to, $begin, $end, $compare, $convert, $dec, $pdec, $rep, $dimension, $dimension2, $tags, $pg, $graphics, $labels, $serie1, $serie2);
                        $class_per_total += $classtotal[0];
                        $class_acc_total += $classtotal[1];                     
                }
@@ -312,25 +313,23 @@ function print_profit_and_loss_statement()
        $rep->AmountCol(2, 3, $salesper *-1, $dec); // always convert
        $rep->AmountCol(3, 4, $salesacc * -1, $dec);
        $rep->AmountCol(4, 5, Achieve($salesper, $salesacc), $pdec);
-       if ($graphics)
-       {
-               $pg->x[] = _('Calculated Return');
-               $pg->y[] = abs($salesper);
-               $pg->z[] = abs($salesacc);
-       }
        $rep->Font();
        $rep->NewLine();
        $rep->Line($rep->row);
        if ($graphics)
        {
-               $pg->title     = $rep->title;
-               $pg->axis_x    = _("Group");
-               $pg->axis_y    = _("Amount");
-               $pg->graphic_1 = $headers[2];
-               $pg->graphic_2 = $headers[3];
-               $pg->type      = $graphics;
-               $pg->skin      = $SysPrefs->graph_skin;
-               $pg->built_in  = false;
+               $labels[] = _('Calculated Return');
+               $serie1[] = abs($salesper);
+               $serie2[] = abs($salesacc);
+               $pg->setStream('png');
+               $pg->setLabels($labels);
+               $pg->addSerie($headers[2], $serie1);
+               $pg->addSerie($headers[3], $serie2);
+               $pg->setTitle($rep->title);
+               $pg->setXTitle(_("Group"));
+               $pg->setYTitle(_("Amount"));
+               $pg->setDTitle(number_format2(abs($salesper)));
+               $pg->setValues(true);
                $pg->latin_notation = ($SysPrefs->decseps[user_dec_sep()] != ".");
                $filename = company_path(). "/pdf_files/". random_id().".png";
                $pg->display($filename, true);