Sfoglia il codice sorgente

Ticket #363 - base functionality.

AntonLV 9 anni fa
parent
commit
8fdc2a4811

+ 34 - 0
chart.php

@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+require_once('./inc/header.inc.php');
+require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");
+
+bx_import('BxDolLanguages');
+
+check_logged();
+
+$sObject = isset($_REQUEST['object']) ? bx_process_input($_REQUEST['object']) : '';
+$sAction = isset($_REQUEST['action']) && preg_match ('/^[A-Za-z_-]+$/', $_REQUEST['action']) ? bx_process_input($_REQUEST['action']) : '';
+
+$oChart = BxDolChart::getObjectInstance($sObject);
+if(!$oChart || !$sAction) {
+    echoJson(array());
+    exit;
+} 
+
+$sMethod = 'action' . bx_gen_method_name($sAction);
+if(!method_exists($oChart, $sMethod)) {
+    echoJson(array());
+    exit;
+}
+
+$oChart->$sMethod();
+
+/** @} */

+ 164 - 0
inc/classes/BxDolChart.php

@@ -0,0 +1,164 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+
+class BxDolChart extends BxDolFactory implements iBxDolFactoryObject
+{
+    protected $_oDb;
+    protected $_sObject;
+    protected $_aObject;
+
+    /**
+     * Constructor
+     * @param $aObject array of chart options
+     */
+    protected function __construct($aObject)
+    {
+        parent::__construct();
+
+        $this->_oDb = new BxDolChartQuery($this->_aObject);
+
+        $this->_sObject = $aObject['object'];
+        $this->_aObject = $aObject;
+    }
+
+    /**
+     * Get editor object instance by object name
+     * @param $sObject object name
+     * @return object instance or false on error
+     */
+    static public function getObjectInstance($sObject = false, $oTemplate = false)
+    {
+        if(isset($GLOBALS['bxDolClasses']['BxDolChart!' . $sObject]))
+            return $GLOBALS['bxDolClasses']['BxDolChart!' . $sObject];
+
+        $aObject = BxDolChartQuery::getChartObject($sObject);
+        if(!$aObject || !is_array($aObject))
+            return false;
+
+        $sClass = 'BxTemplChart';
+        if(!empty($aObject['class_name'])) {
+            $sClass = $aObject['class_name'];
+            if(!empty($aObject['class_file']))
+                require_once(BX_DIRECTORY_PATH_ROOT . $aObject['class_file']);
+        }
+
+        $o = new $sClass($aObject, $oTemplate);
+        return ($GLOBALS['bxDolClasses']['BxDolChart!' . $sObject] = $o);
+    }
+
+    public function actionLoadDataByInterval()
+    {
+        $mixedResult = $this->checkAllowedView();
+        if($mixedResult !== CHECK_ACTION_RESULT_ALLOWED)
+            return array('error' => $mixedResult);
+
+        $iFrom = $this->_getTimestamp(bx_get('from'));
+        $iTo = $this->_getTimestamp(bx_get('to'), true);
+        if(!$iFrom || !$iTo)
+            return echoJson(array('error' => _t('_Error Occured')));
+
+        $aData = $this->getDataByInterval($iFrom, $iTo);
+        if(empty($aData) || !is_array($aData))
+            return echoJson(array('error' => _t('_Empty')));
+
+        return echoJson(array (
+            'title' => _t($this->_aObject['title']),
+            'data' => $aData,
+            'hide_date_range' => $this->_aObject['field_date_dt'] || $this->_aObject['field_date_ts'] ? false : true,
+            'column_date' => $this->_aObject['column_date'] >= 0 ? $this->_aObject['column_date'] : false,
+            'column_count' => $this->_aObject['column_count'] >= 0 ? $this->_aObject['column_count'] : false,
+            'type' => $this->_aObject['type'] ? $this->_aObject['type'] : 'AreaChart',
+            'options' => $this->_aObject['options'] ? unserialize($this->_aObject['options']) : false,
+        ));
+    }
+
+    public function checkAllowedView($isPerformAction = false)
+    {
+        return BxDolService::call('system', 'check_allowed_view', array($isPerformAction), 'TemplChartServices');
+    }
+
+    public function getDataByInterval($iFrom, $iTo)
+    {
+        // build query
+        $sQuery = $this->_aObject['query'] ? $this->_aObject['query'] : "SELECT {field_date_formatted} AS `period`, COUNT(*) AS {object} FROM {table} WHERE {field_date} >= :from AND {field_date} <= :to GROUP BY `period` ORDER BY {field_date} ASC";
+        $sQuery = bx_replace_markers($sQuery, array (
+            'field_date_formatted' => "DATE_FORMAT(" . ($this->_aObject['field_date_dt'] ? "`{$this->_aObject['field_date_dt']}`" : "FROM_UNIXTIME(`{$this->_aObject['field_date_ts']}`)") . ", '%Y-%m-%d')",
+            'object' => $this->_aObject['object'],
+            'table' => "`{$this->_aObject['table']}`",
+            'field_date' => "`" . ($this->_aObject['field_date_dt'] ? $this->_aObject['field_date_dt'] : $this->_aObject['field_date_ts']) . "`",
+        ));
+
+        $aBindings = array(
+            'from' => $this->_aObject['field_date_dt'] ? $this->_getDate($iFrom) . ' 00:00:00' : $iFrom,
+            'to' => $this->_aObject['field_date_dt'] ? $this->_getDate($iTo) . ' 23:59:59' : $iTo + 24*3600 - 1,
+        );
+        
+        // get data
+        if ($this->_aObject['column_date'] >= 0)
+            $aData = $this->_oDb->getAllWithKey($sQuery, $this->_aObject['column_date'], $aBindings, PDO::FETCH_NUM);
+        else
+            $aData = $this->_oDb->getAll($sQuery, array(), $aBindings, PDO::FETCH_NUM);
+
+        if (!$aData)
+            return false;
+    
+        // fill in missed days and convert values to numbers
+        if ($this->_aObject['column_date'] >= 0) {
+            $aDataSlice = array_slice($aData, 0, 1);
+            $iColumnsNum = count(array_pop($aDataSlice));
+            for ($i = $iFrom ; $i <= ($iTo + 24*3600 - 1); $i += 24*60*60) {
+                $sDate = $this->_getDate($i);
+                $aRow = array ();
+                for ($j = 0 ; $j < $iColumnsNum ; ++$j) {
+                    $v = isset($aData[$sDate]) ? (int)$aData[$sDate][$j] : 0;
+                    $aRow[$j] = ($j == $this->_aObject['column_date'] ? $sDate : $v);
+                }
+                $aData[$sDate] = $aRow;
+            }
+        } 
+        else
+            foreach ($aData as $k => $v)
+                foreach ($aData[$k] as $kk => $vv)
+                    if ($kk > 0)
+                        $aData[$k][$kk] = (int)$aData[$k][$kk];
+
+        // return values only
+        ksort($aData);
+        return array_values($aData);
+    }
+
+    public function getDataByStatus()
+    {
+        // build query
+        $sQuery = $this->_aObject['query'] ? $this->_aObject['query'] : "SELECT COUNT(*) AS {object} FROM {table} WHERE 1" . (!empty($this->_aObject['query_status']) ? $this->_aObject['query_status'] : '');
+        $sQuery = bx_replace_markers($sQuery, array (
+            'object' => $this->_aObject['object'],
+            'table' => "`{$this->_aObject['table']}`",
+        ));
+
+        return $this->_oDb->getOne($sQuery);
+    }
+
+    protected function _getTimestamp($sDate, $isNowIfError = false)
+    {
+        $aDate = explode('-', $sDate); // YYYY-MM-DD
+        if(!$aDate || empty($aDate[0]) || empty($aDate[1]) || empty($aDate[2]) || !(int)$aDate[0] || !(int)$aDate[1] || !(int)$aDate[2])
+            return $isNowIfError ? time() : false;
+
+        return mktime(0, 0, 0, $aDate[1], $aDate[2], $aDate[0]);
+    }
+
+    protected function _getDate($iDate)
+    {
+        return date('Y-m-d', $iDate);
+    }
+}
+
+/** @} */

+ 42 - 0
inc/classes/BxDolChartQuery.php

@@ -0,0 +1,42 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+class BxDolChartQuery extends BxDolDb
+{
+    public function __construct($aObject = array())
+    {
+        parent::__construct();
+    }
+
+    static public function getChartObject($sObject)
+    {
+        $oDb = BxDolDb::getInstance();
+
+        $sQuery = $oDb->prepare("SELECT * FROM `sys_objects_chart` WHERE `object` = ?", $sObject);
+
+        $aObject = $oDb->getRow($sQuery);
+        if(!$aObject || !is_array($aObject))
+            return false;
+
+        return $aObject;
+    }
+
+    static public function getChartObjects()
+    {
+        $oDb = BxDolDb::getInstance();
+
+        $aObjects = $oDb->getAll("SELECT * FROM `sys_objects_chart` WHERE `active` = '1' ORDER BY `order` ASC");
+        if(!$aObjects || !is_array($aObjects))
+            return false;
+
+        return $aObjects;
+    }
+}
+
+/** @} */

+ 109 - 0
inc/js/classes/BxDolChartGrowth.js

@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+function BxDolChartGrowth (oOptions) {
+    this._sObjName = undefined == oOptions.sObjName ? 'oBxDolChartGrowth' : oOptions.sObjName;    // javascript object name, to run current object instance from onTimer
+    this._sActionsUrl = oOptions.sRootUrl + 'chart.php'; // actions url address
+
+    this._sAnimationEffect = 'fade';
+    this._iAnimationSpeed = 'slow';
+
+    this._sKeyObjects = 'bx_chart_growth_objects';
+    this._sKeyDateFrom = 'bx_chart_growth_date_from';
+    this._sKeyDateTo = 'bx_chart_growth_date_to';
+    this._sKeyGraph = 'bx_chart_growth_graph';
+
+    this._sDateFormat = 'yy-mm-dd';
+
+    var $this = this;
+    $(document).ready(function() {
+        google.setOnLoadCallback($this.loadData());
+    });
+}
+
+BxDolChartGrowth.prototype.loadData = function()
+{
+	var $this = this;
+	
+
+	$('#' + this._sKeyGraph).html('');
+    $('#' + this._sKeyObjects).attr('disabled', true);
+
+    bx_loading(this._sKeyGraph, true);
+
+    $.get(
+    	this._sActionsUrl,
+    	{
+    		object: $('#' + this._sKeyObjects).val(),
+    		action: 'load_data_by_interval',
+    		from: $.datepicker.formatDate($this._sDateFormat, $('#' + $this._sKeyDateFrom).datepicker('getDate')),
+            to: $.datepicker.formatDate($this._sDateFormat, $('#' + $this._sKeyDateTo).datepicker('getDate'))
+    	},
+    	function(oData) {
+    		$('#' + $this._sKeyObjects).attr('disabled', false);
+
+            bx_loading($this._sKeyGraph, false);
+
+            if(oData.error != undefined) {
+                $('#' + $this._sKeyGraph).html('<div class="bx-def-padding bx-def-font-large bx-def-font-align-center">' + oData.error + '</div>');
+                return;
+            } 
+
+            // hide date selector if chart doesn't support date range
+            if (oData.hide_date_range) {
+                $('#' + $this._sKeyDateFrom).parents('.bx-form-element-wrapper:first').fadeOut();
+                $('#' + $this._sKeyDateTo).parents('.bx-form-element-wrapper:first').fadeOut();
+            }
+            else {
+            	$('#' + $this._sKeyDateFrom).parents('.bx-form-element-wrapper:first').fadeIn();
+            	$('#' + $this._sKeyDateTo).parents('.bx-form-element-wrapper:first').fadeIn();
+            }
+
+            // convert dates
+            if(oData.column_date !== false) {
+                for (var i in oData.data) {    
+                    var sDate = oData.data[i][oData.column_date];
+                    var m = sDate.match(/(\d{4})-(\d{2})-(\d{2})/);
+                    if(!m || !m[1] || !m[2] || !m[3])
+                        continue;
+
+                    var oDate = new Date(m[1],m[2]-1,m[3]);
+                    oData.data[i][oData.column_date] = oDate;
+                }
+            } 
+
+            // add data
+            var oDataTable = new google.visualization.DataTable();                
+            for (var i = 0 ; i < oData.data[0].length ; ++i) {
+                var sType = 0 == i ? 'string' : 'number';
+                var sLabel = '';
+                if (false !== oData.column_date && i == oData.column_date)
+                    sType = 'datetime'; 
+                else if (false !== oData.column_count && i == oData.column_count)
+                    sLabel = oData.title;
+                oDataTable.addColumn(sType, sLabel);
+            }
+            oDataTable.addRows(oData.data);
+
+            // define options
+            var oOptions = {
+              title: oData.title
+            };
+
+            if (oData.options != undefined)
+                oOptions = jQuery.extend(oOptions, oData.options);
+
+            // draw chart
+            var chart = new google.visualization[oData.type]($('#' + $this._sKeyGraph)[0]);
+            chart.draw(oDataTable, oOptions);
+    	},
+    	'json'
+    );
+};
+
+/** @} */

File diff suppressed because it is too large
+ 0 - 0
install/sql/system.sql


+ 21 - 0
modules/boonex/decorous/data/template/system/scripts/BxTemplChart.php

@@ -0,0 +1,21 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaTemplate UNA Template Classes
+ * @{
+ */
+
+/**
+ * @see BxDolChart
+ */
+class BxTemplChart extends BxBaseChart
+{
+    public function __construct ($aObject, $oTemplate = false)
+    {
+        parent::__construct ($aObject, $oTemplate);
+    }
+}
+
+/** @} */

+ 21 - 0
modules/boonex/decorous/data/template/system/scripts/BxTemplChartServices.php

@@ -0,0 +1,21 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaTemplate UNA Template Classes
+ * @{
+ */
+
+/**
+ * @see BxBaseChartServices
+ */
+class BxTemplChartServices extends BxBaseChartServices
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+}
+
+/** @} */

+ 8 - 0
modules/boonex/english/data/langs/system/en.xml

@@ -1493,10 +1493,13 @@
 	<string name="_see_more"><![CDATA[see more]]></string>
 	<string name="_show_replacement"><![CDATA[Show]]></string>
 	<string name="_sys_accept"><![CDATA[Accept]]></string>
+	<string name="_sys_accounts"><![CDATA[Accounts]]></string>
 	<string name="_sys_access_denied_to_private_content"><![CDATA[Access denied. This is private content.]]></string>
 	<string name="_sys_actions"><![CDATA[Actions]]></string>
 	<string name="_sys_active"><![CDATA[Active]]></string>
 	<string name="_sys_acl_action_account"><![CDATA[You didn't created any profiles, so you can't '{1}'.]]></string>
+	<string name="_sys_acl_action_chart_view"><![CDATA[View charts]]></string>
+	<string name="_sys_acl_action_chart_view_desc"><![CDATA[View statistical charts]]></string>
 	<string name="_sys_acl_action_comments_edit_all"><![CDATA[Comments Edit All]]></string>
 	<string name="_sys_acl_action_comments_edit_own"><![CDATA[Comments Edit Own]]></string>
 	<string name="_sys_acl_action_comments_post"><![CDATA[Comments Post]]></string>
@@ -1592,6 +1595,9 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_block_types_custom"><![CDATA[Custom]]></string>
 	<string name="_sys_block_types_skeletons"><![CDATA[Skeletons]]></string>
 	<string name="_sys_block_types_system"><![CDATA[System]]></string>
+	<string name="_sys_chart_growth_object"><![CDATA[Display]]></string>
+	<string name="_sys_chart_growth_date_from"><![CDATA[From]]></string>
+	<string name="_sys_chart_growth_date_to"><![CDATA[To]]></string>
 	<string name="_sys_close"><![CDATA[Close]]></string>
 	<string name="_sys_conn_err_connection_already_exists"><![CDATA[Connection already exists]]></string>
 	<string name="_sys_conn_err_connection_does_not_exists"><![CDATA[Connection doesn't exist]]></string>
@@ -2131,6 +2137,8 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_page_block_title_account_settings_menu"><![CDATA[Account Settings]]></string>
 	<string name="_sys_page_block_title_account_settings_pwd"><![CDATA[Change Password]]></string>
 	<string name="_sys_page_block_title_add_content"><![CDATA[Add Content]]></string>
+	<string name="_sys_page_block_title_chart_growth"><![CDATA[Growth Charts]]></string>
+	<string name="_sys_page_block_title_chart_stats"><![CDATA[Content]]></string>
 	<string name="_sys_page_block_title_confirm_email"><![CDATA[Email Confirmation]]></string>
 	<string name="_sys_page_block_title_create_account"><![CDATA[Sign up]]></string>
 	<string name="_sys_page_block_title_dashboard"><![CDATA[Dashboard]]></string>

+ 21 - 0
modules/boonex/ocean/data/template/system/scripts/BxTemplChart.php

@@ -0,0 +1,21 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaTemplate UNA Template Classes
+ * @{
+ */
+
+/**
+ * @see BxDolChart
+ */
+class BxTemplChart extends BxBaseChart
+{
+    public function __construct ($aObject, $oTemplate = false)
+    {
+        parent::__construct ($aObject, $oTemplate);
+    }
+}
+
+/** @} */

+ 21 - 0
modules/boonex/ocean/data/template/system/scripts/BxTemplChartServices.php

@@ -0,0 +1,21 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaTemplate UNA Template Classes
+ * @{
+ */
+
+/**
+ * @see BxBaseChartServices
+ */
+class BxTemplChartServices extends BxBaseChartServices
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+}
+
+/** @} */

+ 21 - 0
modules/boonex/protean/data/template/system/scripts/BxTemplChart.php

@@ -0,0 +1,21 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaTemplate UNA Template Classes
+ * @{
+ */
+
+/**
+ * @see BxDolChart
+ */
+class BxTemplChart extends BxBaseChart
+{
+    public function __construct ($aObject, $oTemplate = false)
+    {
+        parent::__construct ($aObject, $oTemplate);
+    }
+}
+
+/** @} */

+ 21 - 0
modules/boonex/protean/data/template/system/scripts/BxTemplChartServices.php

@@ -0,0 +1,21 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaTemplate UNA Template Classes
+ * @{
+ */
+
+/**
+ * @see BxBaseChartServices
+ */
+class BxTemplChartServices extends BxBaseChartServices
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+}
+
+/** @} */

+ 9 - 1
modules/boonex/russian/data/langs/system/ru.xml

@@ -1491,10 +1491,13 @@
 	<string name="_see_more"><![CDATA[смотреть ещё]]></string>
 	<string name="_show_replacement"><![CDATA[Показать]]></string>
 	<string name="_sys_accept"><![CDATA[Принять]]></string>
+	<string name="_sys_accounts"><![CDATA[Учётные записи]]></string>
 	<string name="_sys_access_denied_to_private_content"><![CDATA[Доступ запрещён. Это приватное содержимое.]]></string>
 	<string name="_sys_actions"><![CDATA[Действия]]></string>
 	<string name="_sys_active"><![CDATA[Активный]]></string>
 	<string name="_sys_acl_action_account"><![CDATA[Вы не создали ни одного профиля, поэтому Вы не можете '{1}'.]]></string>
+	<string name="_sys_acl_action_chart_view"><![CDATA[Диаграммы - Просматривать]]></string>
+    <string name="_sys_acl_action_chart_view_desc"><![CDATA[Просматривать статистические диаграммы]]></string>
 	<string name="_sys_acl_action_comments_edit_all"><![CDATA[Комментарии - Редактировать Все]]></string>
 	<string name="_sys_acl_action_comments_edit_own"><![CDATA[Комментарии - Редактировать Свои]]></string>
 	<string name="_sys_acl_action_comments_post"><![CDATA[Комментарии - Размещать]]></string>
@@ -1590,6 +1593,9 @@
 	<string name="_sys_block_types_custom"><![CDATA[Индивидуальный]]></string>
 	<string name="_sys_block_types_skeletons"><![CDATA[Скелеты]]></string>
 	<string name="_sys_block_types_system"><![CDATA[Система]]></string>
+	<string name="_sys_chart_growth_object"><![CDATA[Вывести]]></string>
+    <string name="_sys_chart_growth_date_from"><![CDATA[С]]></string>
+    <string name="_sys_chart_growth_date_to"><![CDATA[По]]></string>
 	<string name="_sys_close"><![CDATA[Закрыть]]></string>
 	<string name="_sys_conn_err_connection_already_exists"><![CDATA[Связь уже существует]]></string>
 	<string name="_sys_conn_err_connection_does_not_exists"><![CDATA[Связь не существует]]></string>
@@ -2128,7 +2134,9 @@
 	<string name="_sys_page_block_title_account_settings_info"><![CDATA[Редактировать Аккаунт]]></string>
 	<string name="_sys_page_block_title_account_settings_menu"><![CDATA[Аккаунт - Настройки]]></string>
 	<string name="_sys_page_block_title_account_settings_pwd"><![CDATA[Изменить Пароль]]></string>
-    <string name="_sys_page_block_title_add_content"><![CDATA[Добавить Содержимое]]></string>    
+    <string name="_sys_page_block_title_add_content"><![CDATA[Добавить Содержимое]]></string>
+    <string name="_sys_page_block_title_chart_growth"><![CDATA[Диаграммы развития]]></string>
+    <string name="_sys_page_block_title_chart_stats"><![CDATA[Содержимое]]></string>    
 	<string name="_sys_page_block_title_confirm_email"><![CDATA[Имейл - Подтверждение]]></string>
 	<string name="_sys_page_block_title_create_account"><![CDATA[Присоединиться]]></string>
 	<string name="_sys_page_block_title_dashboard"><![CDATA[Панель]]></string>

File diff suppressed because it is too large
+ 9 - 0
plugins_public/chart.min.js


+ 15 - 0
template/chart_growth.html

@@ -0,0 +1,15 @@
+<div class="bx-chart-growth-controls">__controls__</div>
+
+<div id="bx_chart_growth_graph" class="bx-chart-growth-graph bx-def-border bx-def-margin-top"></div>
+
+<script type="text/javascript" src="__proto__://www.google.com/jsapi"></script>
+<script type="text/javascript">
+    google.load("visualization", "1", {packages:["corechart"]});
+
+	var oBxDolChartGrowth = new BxDolChartGrowth({
+		sObjName: 'oBxDolChartGrowth',
+		sRootUrl: '<bx_url_root />',
+		sDateFrom: '__date_from__',
+		sDateTo: '__date_to__'
+	});
+</script>

+ 19 - 0
template/chart_stats.html

@@ -0,0 +1,19 @@
+<div class="bx-chart-stats">
+    <div class="bx-chart-stats-items bx-def-margin-bottom">
+        <bx_repeat:items>
+            <div class="bx-cs-item">
+                <span class="bx-def-font-h3">__value__</span> __title__
+            </div>
+        </bx_repeat:items>
+    </div>
+
+    <canvas id="bx_chart_stats_graph" class="bx-chart-stats-graph bx-def-border"></canvas>
+    <script type="text/javascript">
+    	var oHolder = $("#bx_chart_stats_graph").get(0).getContext("2d");
+    	var oChart = new Chart(oHolder).PolarArea(__chart_data__, {
+			scaleBackdropColor : "transparent",
+			segmentStrokeColor : "transparent",
+			segmentStrokeWidth : 0,
+		});
+    </script>
+</div>

+ 28 - 0
template/css/chart.css

@@ -0,0 +1,28 @@
+/*--- Chart Growth: Controls ---*/
+.bx-chart-growth-controls .bx-form-input-datepicker {
+	width: 100%;
+}
+
+/*--- Chart Growth: Graph ---*/
+.bx-chart-growth-graph {
+	height: 15rem;
+	background-color: #ffffff;
+}
+
+
+/*--- Chart Stats: Info ---*/
+.bx-chart-stats-items {
+	position: relative;
+}
+.bx-chart-stats-items .bx-cs-item {
+	display: inline-block;
+	vertical-align: top;
+	width: 30%;
+} 
+
+/*--- Chart Stats: Graph ---*/
+.bx-chart-stats-graph {
+	max-width: 100%;
+	height: 15rem;
+    background-color: #ffffff;
+}

+ 27 - 0
template/scripts/BxBaseChart.php

@@ -0,0 +1,27 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaBaseView UNA Base Representation Classes
+ * @{
+ */
+
+/**
+ * Chart representation.
+ * @see BxDolChart
+ */
+class BxBaseChart extends BxDolChart
+{
+    public function __construct ($aObject, $oTemplate)
+    {
+        parent::__construct ($aObject);
+
+        if ($oTemplate)
+            $this->_oTemplate = $oTemplate;
+        else
+            $this->_oTemplate = BxDolTemplate::getInstance();
+    }
+}
+
+/** @} */

+ 137 - 0
template/scripts/BxBaseChartServices.php

@@ -0,0 +1,137 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaBaseView UNA Base Representation Classes
+ * @{
+ */
+
+/**
+ * Services for chart objects functionality
+ * @see BxDolChart
+ */
+class BxBaseChartServices extends BxDol
+{
+    public function serviceCheckAllowedView($isPerformAction = false)
+    {
+        $iProfileId = bx_get_logged_profile_id();
+
+        $aCheck = checkActionModule($iProfileId, 'chart view', 'system', $isPerformAction);
+        if($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
+            return $aCheck[CHECK_ACTION_MESSAGE];
+
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+    
+    public function serviceGetChartGrowth()
+    {
+        $mixedResult = BxDolService::call('system', 'check_allowed_view', array(), 'TemplChartServices');
+        if($mixedResult !== CHECK_ACTION_RESULT_ALLOWED)
+            return '';
+
+        $sDateFrom = date('Y-m-d', time() - 30*24*60*60);
+        $sDateTo = date('Y-m-d', time());
+
+        $aForm = array(
+            'form_attrs' => array(
+                'id' => 'bx_chart_controls',
+                'action' => ''
+            ),
+            'inputs' => array (
+                'object' => array(
+                    'type' => 'select',
+                    'name' => 'object',
+                    'caption' => _t('_sys_chart_growth_object'),
+                    'info' => '',
+                    'value' => '',
+                    'values' => array(),
+                    'required' => '0',
+                    'attrs' => array(
+                        'id' => 'bx_chart_growth_objects',
+                        'onchange' => 'oBxDolChartGrowth.loadData()'
+                    ),
+                ),
+                'date_from' => array(
+                    'type' => 'datepicker',
+                    'name' => 'date_from',
+                    'caption' => _t('_sys_chart_growth_date_from'),
+                    'info' => '',
+                    'value' => $sDateFrom,
+                    'values' => array(),
+                    'required' => '0',
+                    'attrs' => array(
+                		'id' => 'bx_chart_growth_date_from',
+                        'onchange' => 'oBxDolChartGrowth.loadData()'
+                    ),
+                ),
+                'date_to' => array(
+                    'type' => 'datepicker',
+                    'name' => 'date_to',
+                    'caption' => _t('_sys_chart_growth_date_to'),
+                    'info' => '',
+                    'value' => $sDateTo,
+                    'values' => array(),
+                    'required' => '0',
+                    'attrs' => array(
+                		'id' => 'bx_chart_growth_date_to',
+                        'onchange' => 'oBxDolChartGrowth.loadData()'
+                    ),
+                )
+            )
+        );
+
+        $aObjects = BxDolChartQuery::getChartObjects();
+        foreach($aObjects as $aObject)
+            $aForm['inputs']['object']['values'][] = array('key' => $aObject['object'], 'value' => _t($aObject['title']));
+
+        $oForm = new BxTemplFormView($aForm);
+
+        $oTemplate = BxDolTemplate::getInstance();
+        $oTemplate->addJs(array('BxDolChartGrowth.js'));
+        $oTemplate->addCss(array('chart.css'));
+
+        return $oTemplate->parseHtmlByName('chart_growth.html', array(
+        	'proto' => bx_proto(),
+            'date_from' => $sDateFrom,
+            'date_to' => $sDateTo,
+            'controls' => $oForm->getCode()
+        ));
+    }
+
+    //TODO: Continue from here.
+    public function serviceGetChartStats()
+    {
+        $aTmplVarsItems = array();
+        $aTmplVarsData = array();
+
+        $aObjects = BxDolChartQuery::getChartObjects();
+        foreach($aObjects as $aObject) {
+            $sTitle = _t($aObject['title']);
+            $sValie = BxDolChart::getObjectInstance($aObject['object'])->getDataByStatus();
+
+            $aTmplVarsItems[] = array(
+                'title' => $sTitle,
+            	'value' => $sValie,
+            );
+
+            $aTmplVarsData[] = array(
+            	'value' => $sValie,
+	            'color' => '#' . dechex(rand(0x000000, 0xFFFFFF)),
+	            'highlight' => '',
+	            'label' => bx_js_string($sTitle, BX_ESCAPE_STR_APOS),
+            );
+        }
+
+        $oTemplate = BxDolTemplate::getInstance();
+        $oTemplate->addJs(array('chart.min.js'));
+        $oTemplate->addCss(array('chart.css'));
+
+        return $oTemplate->parseHtmlByName('chart_stats.html', array(
+        	'bx_repeat:items' => $aTmplVarsItems,
+            'chart_data' => json_encode($aTmplVarsData)
+        ));
+    }
+}
+
+/** @} */

Some files were not shown because too many files changed in this diff