├── .gitignore ├── CRM ├── Civisualize │ ├── Dashlet.mgd.php │ ├── Page │ │ ├── Doc.php │ │ └── Main.php │ └── VisualBundle.php └── Core │ └── Smarty │ └── plugins │ ├── function.crmRetrieve.php │ ├── function.crmSQL.php │ └── function.crmTitle.php ├── LICENSE ├── README.md ├── api └── v3 │ ├── Activity │ └── Getstat.php │ ├── Contact │ └── Getstat.php │ ├── GroupContact │ └── Getstat.php │ ├── Participant │ └── Getstat.php │ └── Tag │ └── Getstat.php ├── civisualize.civix.php ├── civisualize.php ├── css └── style.css ├── examples ├── contacts.jpg ├── contribution.jpg ├── donortrends.jpg ├── event.jpg └── events.jpg ├── info.xml ├── js ├── civisualize.js ├── common.js ├── d3.min.v5.7.0.js ├── d3.v3.js ├── dc │ ├── crossfilter.min.js │ ├── dc.min.css │ └── dc.min.js ├── filesaver.js └── marked.min.js ├── queries ├── another.sql ├── contacts.sql ├── contribution_by_date.sql ├── donors.sql ├── eventdetails.json ├── eventparticipants.json ├── events.sql ├── mailing_click.json ├── mailing_event.js ├── mailing_open.json ├── mailings.json └── participants.sql ├── templates ├── CRM │ └── Civisualize │ │ └── Page │ │ ├── Doc.tpl │ │ └── Main.tpl └── dataviz │ ├── Contactcreateddate.tpl │ ├── Contactdashboard.tpl │ ├── Contacts.tpl │ ├── Contacttype.tpl │ ├── Contribute.tpl │ ├── ContributionByDate.tpl │ ├── Demo.tpl │ ├── Donortrends.tpl │ ├── Event.tpl │ ├── Events.tpl │ ├── Example.tpl │ ├── Groupbarchart.tpl │ ├── Lapseddonor.tpl │ ├── Mailing.tpl │ ├── Mailings.tpl │ ├── Tag.tpl │ └── Typebarchart.tpl ├── updateTpl └── xml └── Menu └── civisualize.xml /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | -------------------------------------------------------------------------------- /CRM/Civisualize/Dashlet.mgd.php: -------------------------------------------------------------------------------- 1 | 'dataviz_contact', 6 | 'entity'=> 'Dashboard', 7 | 'params'=> array( 8 | 'version'=>'3', 9 | 'name'=>'dataviz_contact', 10 | 'label'=> 'Dataviz of contacts', 11 | 'url' => 'civicrm/dataviz/contacts?snippet=4', 12 | ), 13 | ), 14 | 15 | array( 16 | 'name'=>'dataviz_events', 17 | 'entity'=> 'Dashboard', 18 | 'params'=> array( 19 | 'version'=>'3', 20 | 'name'=>'dataviz_event', 21 | 'label'=> 'Dataviz of events', 22 | 'url' => 'civicrm/dataviz/events?snippet=4', 23 | ), 24 | ), 25 | 26 | array( 27 | 'name'=>'dataviz_contribute', 28 | 'entity'=> 'Dashboard', 29 | 'params'=> array( 30 | 'version'=>'3', 31 | 'name'=>'dataviz_contribute', 32 | 'label'=> 'Dataviz of contributions', 33 | 'url' => 'civicrm/dataviz/contribute?snippet=4', 34 | ), 35 | ), 36 | 37 | ); 38 | -------------------------------------------------------------------------------- /CRM/Civisualize/Page/Doc.php: -------------------------------------------------------------------------------- 1 | addScriptFile('eu.tttp.civisualize', 'js/marked.min.js', 110, 'html-header', FALSE); 8 | 9 | $request = CRM_Utils_System::currentPath(); 10 | if (false !== strpos($request, '..')) { 11 | die ("SECURITY FATAL: the url can't contain '..'. Please report the issue on the forum at civicrm.org"); 12 | } 13 | 14 | $request = explode('/',$request); 15 | //print_r($request); 16 | $tplfile = NULL; 17 | $smarty= CRM_Core_Smarty::singleton( ); 18 | $smarty->assign("options",array()); 19 | $path = "doc/"; 20 | if (CRM_Utils_Array::value(2, $request)) { 21 | $tplfile = _civicrm_api_get_camel_name($request[2]); 22 | $tplfile = explode('?', $tplfile); 23 | $file = $tplfile[0].'.md'; 24 | } 25 | if (CRM_Utils_Array::value(3, $request)) { 26 | $r3 = _civicrm_api_get_camel_name($request[3]); 27 | if (!is_numeric($r3)) { 28 | $file = $r3 .'.md'; 29 | $path = $path.$tplfile[0].'/'; 30 | } 31 | $smarty->assign("id",$r3); 32 | } 33 | 34 | if (CIVISUALIZE_GITHUB_DOC) { 35 | $smarty->assign("github",CIVISUALIZE_GITHUB_DOC); 36 | } else { 37 | $smarty->assign("github","TechToThePeople/civisualize"); 38 | } 39 | 40 | // $github = civicrm_api3('setting', 'getvalue', array('group' => 'Civisualize Preferences', 'name' => 'civisualize_github_doc')); 41 | $md = file_get_contents($path.$file, FILE_USE_INCLUDE_PATH); 42 | if (!$md) { 43 | $md= "$path$file not found"; 44 | $smarty->assign("error","missing_file"); 45 | } 46 | $smarty->assign("mdfile",$file); 47 | $smarty->assign("path",$path); 48 | $smarty->assign("md",$md); 49 | 50 | if (CRM_Utils_Array::value(4, $request)) { 51 | $r3 = CRM_Utils_String::munge($request[4]); 52 | $smarty->assign("id2",$r3); 53 | } 54 | if (!$tplfile) { 55 | $tpl = "CRM/Civisualize/Page/Doc.tpl"; 56 | } 57 | 58 | parent::run(); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /CRM/Civisualize/Page/Main.php: -------------------------------------------------------------------------------- 1 | assign("options",array()); 17 | if (CRM_Utils_Array::value(2, $request)) { 18 | $tplfile = _civicrm_api_get_camel_name($request[2]); 19 | $tplfile = explode('?', $tplfile); 20 | $tpl = 'dataviz/'.$tplfile[0].'.tpl'; 21 | } 22 | if (CRM_Utils_Array::value(3, $request)) { 23 | $r3 = _civicrm_api_get_camel_name($request[3]); 24 | $smarty->assign("id",$r3); 25 | } 26 | if (CRM_Utils_Array::value(4, $request)) { 27 | $r3 = CRM_Utils_String::munge($request[4]); 28 | $smarty->assign("id2",$r3); 29 | } 30 | if (!$tplfile) { 31 | $tpl = "CRM/Civisualize/Page/Main.tpl"; 32 | } 33 | if( !$smarty->template_exists($tpl) ){ 34 | header("Status: 404 Not Found"); 35 | die ("Can't find the requested template file templates/$tpl"); 36 | } 37 | return $tpl; 38 | } 39 | 40 | function run() { 41 | $smarty= CRM_Core_Smarty::singleton( ); 42 | CRM_Civisualize_VisualBundle::register(); 43 | 44 | $dummy = NULL; 45 | if (array_key_exists('id',$_GET)) {// special treatmenent, because it's often used 46 | $smarty->assign ('id',(int)$_GET['id']);// an id is always positive 47 | } 48 | $pos = strpos (implode (array_keys ($_GET)),'<') ; 49 | 50 | if ($pos !== false) { 51 | die ("SECURITY FATAL: one of the param names contains <"); 52 | } 53 | $param = array_map( 'htmlentities' , $_GET); 54 | //TODO: sql escape the params too 55 | unset($param['q']); 56 | $smarty->assign_by_ref("request", $param); 57 | 58 | CRM_Core_Resources::singleton() 59 | ->addScriptFile('eu.tttp.civisualize', 'js/d3.min.v5.7.0.js', 110, 'html-header', FALSE) 60 | ->addScriptFile('eu.tttp.civisualize', 'js/dc/dc.min.js', 110, 'html-header', FALSE) 61 | ->addScriptFile('eu.tttp.civisualize', 'js/dc/crossfilter.min.js', 110, 'html-header', FALSE) 62 | ->addScriptFile('eu.tttp.civisualize', 'js/filesaver.js', 110, 'html-header', FALSE) 63 | ->addScriptFile('eu.tttp.civisualize', 'js/common.js', 110, 'html-header', FALSE) 64 | ->addStyleFile('eu.tttp.civisualize', 'js/dc/dc.min.css') 65 | ->addStyleFile('eu.tttp.civisualize', 'css/style.css') 66 | ->addVars('civisualize', array( 67 | 'baseUrl' => CRM_Core_Resources::singleton()->getUrl('eu.tttp.civisualize'), 68 | )); 69 | 70 | require_once 'CRM/Core/Smarty/plugins/function.crmSQL.php'; 71 | $smarty->register_function("crmSQL", "smarty_function_crmSQL"); 72 | 73 | require_once 'CRM/Core/Smarty/plugins/function.crmRetrieve.php'; 74 | $smarty->register_function("crmRetrieve", "smarty_function_crmRetrieve"); 75 | 76 | require_once 'CRM/Core/Smarty/plugins/function.crmTitle.php'; 77 | $smarty->register_function("crmTitle", "smarty_function_crmTitle"); 78 | 79 | return parent::run(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /CRM/Civisualize/VisualBundle.php: -------------------------------------------------------------------------------- 1 | addScriptUrl(Civi::service('asset_builder')->getUrl('civisualize-bundle.min.js'), CRM_Core_Resources::DEFAULT_WEIGHT -1); 28 | Civi::resources()->addStyleUrl(Civi::service('asset_builder')->getUrl('civisualize-bundle.css'), CRM_Core_Resources::DEFAULT_WEIGHT -1); 29 | } 30 | 31 | /** 32 | * Generate asset content (when accessed via AssetBuilder). 33 | * 34 | * @param \Civi\Core\Event\GenericHookEvent $event 35 | * @see CRM_Utils_hook::buildAsset() 36 | * @see \Civi\Core\AssetBuilder 37 | */ 38 | public static function buildAssetJs($event) { 39 | if ($event->asset !== 'civisualize-bundle.min.js') { 40 | return; 41 | } 42 | 43 | $file = E::path('js/civisualize.js'); 44 | $content = "// File: $file\n" . file_get_contents($file) . "\n"; 45 | $content .= "var crossfilter = this.crossfilter;\n"; 46 | 47 | $content .= "(function(){\n"; 48 | 49 | // Add crossfilter 50 | $file = E::path('js/dc/crossfilter.min.js'); 51 | $content .= "// File: $file\n" . file_get_contents($file) . "\n"; 52 | $content .= "var crossfilter = this.crossfilter;\n"; 53 | 54 | // Add d3 55 | $file = E::path('js/d3.min.v5.7.0.js'); 56 | $content .= "// File: $file\n" . file_get_contents($file) . "\n"; 57 | $content .= "var d3 = this.d3;\n"; 58 | 59 | // Add dc 60 | $file = E::path('js/dc/dc.min.js'); 61 | $content .= "// File: $file\n" . file_get_contents($file) . "\n"; 62 | $content .= "this.dc = dc;\n"; 63 | 64 | // End the anon function and call it with CRM.civisualize as its 'this' object. 65 | $content .= "}).call(CRM.civisualize);"; 66 | 67 | $event->mimeType = 'application/javascript'; 68 | $event->content = $content; 69 | } 70 | 71 | /** 72 | * Generate asset content (when accessed via AssetBuilder). 73 | * 74 | * @param \Civi\Core\Event\GenericHookEvent $event 75 | * @see CRM_Utils_hook::buildAsset() 76 | * @see \Civi\Core\AssetBuilder 77 | */ 78 | public static function buildAssetCss($event) { 79 | if ($event->asset !== 'civisualize-bundle.css') { 80 | return; 81 | } 82 | 83 | $files = [ 'dc' => 'js/dc/dc.min.css' ]; 84 | 85 | $content = []; 86 | foreach ($files as $file) { 87 | $file = E::path($file); 88 | $content[] = "// File: $file"; 89 | $content[] = file_get_contents($file); 90 | } 91 | 92 | $event->mimeType = 'text/css'; 93 | $event->content = implode("\n", $content); 94 | } 95 | 96 | } 97 | 98 | -------------------------------------------------------------------------------- /CRM/Core/Smarty/plugins/function.crmRetrieve.php: -------------------------------------------------------------------------------- 1 | trigger_error("crmRetrieve: missing car, name or type"); 6 | return; 7 | } 8 | $value = CRM_Utils_Request::retrieve($params['name'], $params['type']); 9 | if($value===null){ 10 | $smarty->trigger_error("crmRetrive: Cannot find a variable with matching name and type"); 11 | } 12 | $smarty->assign($params['var'], $value); 13 | } -------------------------------------------------------------------------------- /CRM/Core/Smarty/plugins/function.crmSQL.php: -------------------------------------------------------------------------------- 1 | trigger_error("assign: missing 'sql', 'json' OR 'file' parameter"); 11 | $error = "crmAPI: missing 'sql', 'json' or 'file' parameter"; 12 | $is_error = 1; 13 | } 14 | 15 | $parameters = array(); 16 | 17 | try{ 18 | if(array_key_exists('json', $params)){ 19 | $content=trim(str_replace(array("\t","\r\n","\r","\n")," ",file_get_contents('queries/'.$params["json"].".json", FILE_USE_INCLUDE_PATH))); 20 | $json=json_decode($content); 21 | if (!$content){ 22 | $smarty->trigger_error("assign: invalid json file"); 23 | $error = "crmSQL: empty json file"; 24 | return json_encode(array("is_error"=>1, "file"=> 'queries/'.$params["json"].".json", "error"=>$error, "values" => null), JSON_NUMERIC_CHECK); 25 | } 26 | if (!$json){ 27 | $smarty->trigger_error("assign: invalid json file"); 28 | $error = "crmSQL: empty json file"; 29 | return json_encode(array("is_error"=>1, "file"=> 'queries/'.$params["json"].".json", "error"=>$error, "content"=>$content,"values" => null), JSON_NUMERIC_CHECK); 30 | } 31 | $sql=$json->query; 32 | if (!$sql){ 33 | $smarty->trigger_error("assign: missing 'query' in the json file"); 34 | $error = "crSQL: missing 'query' in the json"; 35 | return json_encode(array("is_error"=>1, "file"=> 'queries/'.$params["json"].".json", "error"=>$error, "values" => null), JSON_NUMERIC_CHECK); 36 | } 37 | foreach ($json->params as $key => $value) { 38 | $var=intval($key); 39 | $name=$value->name; 40 | $type=$value->type; 41 | if(array_key_exists($name, $params)){ 42 | $parameters[$var] = array($params[$name],$type); 43 | } 44 | } 45 | } 46 | 47 | elseif(array_key_exists('sql', $params)){ 48 | $sql = $params["sql"]; 49 | } 50 | 51 | elseif(array_key_exists('file', $params)){ 52 | $filename = 'queries/'.$params["file"].".sql"; 53 | $sql = file_get_contents($filename, true); 54 | if (!$sql) throw new Exception ("missing filename or empty ".$filename); 55 | 56 | } 57 | 58 | $forbidden=array("delete ", "drop ","update ","grant "); 59 | foreach ($forbidden as $check) { 60 | if(strpos(strtolower($sql), $check)!==false){ 61 | $smarty->trigger_error($check."command not allowed"); 62 | $error = "crmAPI: you can not ".$check."using crmSQL"; 63 | $is_error = 1; 64 | break; 65 | } 66 | } 67 | 68 | if (array_key_exists('debug', $params)) { 69 | $smarty->trigger_error("sql:". $params["sql"]); 70 | } 71 | 72 | if($is_error==0){ 73 | $errorScope = CRM_Core_TemporaryErrorScope::useException(); 74 | CRM_Core_DAO::executeQuery("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;"); 75 | $dao = CRM_Core_DAO::executeQuery($sql,$parameters); 76 | $values = array(); 77 | $keys= null; 78 | if (array_key_exists('sequential', $params)) { 79 | while ($dao->fetch()) { 80 | if (!$keys) $keys= array_keys($dao->toArray()); 81 | $values[] = array_values($dao->toArray()); 82 | } 83 | } else { 84 | while ($dao->fetch()) { 85 | $values[] = $dao->toArray(); 86 | } 87 | $keys= array_keys($values[0]); 88 | } 89 | } 90 | } 91 | catch(Exception $e){ 92 | $is_error=1; 93 | $error = "crmAPI: ".$e->getMessage(); 94 | $values=""; 95 | } 96 | 97 | if(array_key_exists('set', $params)){ 98 | if($values!=""){ 99 | //echo "console.log('string')"; 100 | $smarty->assign($params['set'], $values); 101 | } 102 | } 103 | 104 | if (array_key_exists('debug', $params)) { 105 | return json_encode(array("is_error"=>$is_error, "keys"=> $keys, "error"=>$error, "values" => $values,"sql" => trim(preg_replace('/\s+/', ' ', $sql))), JSON_NUMERIC_CHECK); 106 | } 107 | if (!$smarty) 108 | return array("is_error"=>$is_error, "keys"=> $keys, "error"=>$error, "values" => $values); 109 | 110 | return json_encode(array("is_error"=>$is_error, "keys"=> $keys, "error"=>$error, "values" => $values), JSON_NUMERIC_CHECK); 111 | } 112 | -------------------------------------------------------------------------------- /CRM/Core/Smarty/plugins/function.crmTitle.php: -------------------------------------------------------------------------------- 1 | **Civisualize**. The currently available visualizations include: 43 | 44 | ## Contributions (/dataviz/contribute) 45 | 46 | ![alt tag](https://raw.githubusercontent.com/TechToThePeople/civisualize/master/examples/contribution.jpg) 47 | This provides an overview of contributions, type of contributors, the day of week the contribution was made, payment instrument, etc. 48 | 49 | ## Contacts (/dataviz/contacts) 50 | 51 | ![alt tag](https://raw.githubusercontent.com/TechToThePeople/civisualize/master/examples/contacts.jpg) 52 | Contacts overview is a compilation of graphs showing types, gender, age, source of contact, contacts over the time etc. 53 | 54 | ## Events (/dataviz/events) 55 | 56 | ![alt tag](https://raw.githubusercontent.com/TechToThePeople/civisualize/master/examples/events.jpg) 57 | Events shows a lot of information about all the events of an organization and their participants. It shows events over time, participants over time, money generated from events, type of events, etc. It also displays a table listing all the events. 58 | 59 | This table further links to specific event overview (/dataviz/event/) showing participants, their status, their fee etc. 60 | 61 | ![alt tag](https://raw.githubusercontent.com/TechToThePeople/civisualize/master/examples/event.jpg) 62 | 63 | ## Donor Trends (/dataviz/donortrends) 64 | 65 | ![alt tag](https://raw.githubusercontent.com/TechToThePeople/civisualize/master/examples/donortrends.jpg) 66 | Based on the idea of [CiviCRM Donor Trends Extension](https://github.com/leez/org.eff.donortrends/), the donor trends overview showcases a Bar Chart with new, lapsed, upgraded, downgraded and maintained donors over the years. This further showcases the gender and age of the donors and a list of all the donors. 67 | 68 | Need not be mentioned, you can add more graphs and details to the above mentioned visualizations. 69 | 70 | Create your own visualizations 71 | ------------------------------ 72 | If you are a developer you can customize or create your extensions with a little knowledge of mysql/crmAPI, d3.js/dc.js and crossfilter. Civisualize basically has two parts: 73 | 74 | - Extract data from CiviCRM 75 | - Display data using dc.js/d3 76 | 77 | ## Extract data 78 | 79 | For the first part, we are using the following methods: 80 | 81 | ### {crmAPI} 82 | 83 | ``{crmAPI entity="OptionValue" option_group_id="14"}`` 84 | 85 | You can add `getstat` as a new action on some entities in the api. 86 | 87 | ### {crmSQL} 88 | 89 | We have added a new crmSQL to run a mySQL query. For obvious reasons crmSQL only let you run SELECT queries. You can get your data using any of the following three methods: 90 | 91 | - ##### SQL String 92 | `{crmSQL sql="SELECT count(*) ... group by ...."}` 93 | 94 | - ##### SQL File 95 | `{crmSQL query="somethingcool"}` 96 | 97 | This will fetch the sql query from `/queries/somethingcool.sql` 98 | 99 | - ##### JSON Object 100 | `{crmSQL json="somethingcooler" cid=4 bla="hello"}` 101 | 102 | This will fetch a json object from `/queries/somethingcooler.json` 103 | The format of the json is 104 | 105 | ```json 106 | { "query":"SELECT * from ABC where id=%1 and bla=%2", 107 | "params":{ "1":{ "name":"cid", 108 | "type":"Integer"}, 109 | "2":{ "name":"bla", 110 | "type":"String"} 111 | } 112 | } 113 | ``` 114 | 115 | You can further use `{crmRetrieve var="a" name="b" type="Integer"}`. 116 | This will assign the `POST` or `GET` variable named `b` into `a` which can then be given to `{crmSQL}`. 117 | 118 | ##### Optional Arguments 119 | `{crmSQL set="varname"}` will assign the result of the sql query to a smarty variable named `varname`. 120 | 121 | ##### Return Value 122 | `{crmSQL}` returns a json of the following format: 123 | ```json 124 | {"is_error":0,"error":"error_str","values":"Array of objects"} 125 | ``` 126 | so we primarily use `{crmSQL}` values for our visualizations. 127 | 128 | - #### {crmReport} 129 | A 3rd option is to be able to fetch data from a report instance using `{crmReport...}`. Eileen has done (most of?) the work already. I think it's on 4.5. 130 | 131 | ## Display data 132 | 133 | The principle is to get the data in a template as a json, and apply dc on it until it looks awesome. You simply have to create a template into `templates/dataviz/Something.tpl`. Once you have the data from the above methods you can apply dc on it, and you can access it from `/civicrm/dataviz/something`. 134 | 135 | To get you started, you can visit `/civicrm/dataviz/contribute` or any of the above mentioned visualizations. 136 | 137 | This is using the wonderfully magic dc, that is a layer of love on the top of d3 and crossfilter. Click on the graphs to filter down. magic, I told you. No matter if you use {crmAPI} or {crmSQL}, you end up with a json and a d3 and dc loaded and ready to rock. 138 | 139 | In the template, put: 140 | 141 | ```html 142 |
143 | 12 | {/literal} 13 |
14 | 15 |
16 | {if $error} 17 | 22 | {/if} 23 |
 
file: {$mdfile}
24 | -------------------------------------------------------------------------------- /templates/CRM/Civisualize/Page/Main.tpl: -------------------------------------------------------------------------------- 1 | {crmTitle string="Civisualize"} 2 | 3 | You need to choose one of the following visualizations to start with: 4 | 11 |

12 | You might like to learn how to build your own datavisualisation 13 |

14 | -------------------------------------------------------------------------------- /templates/dataviz/Contactcreateddate.tpl: -------------------------------------------------------------------------------- 1 | {if !$embedded} 2 | {php}CRM_Utils_System::setTitle('Contact Creation by Date');{/php} 3 |
4 |
5 | {/if} 6 | 7 | {crmScript ext="eu.tttp.civisualize" file="js/nvd3/nv.d3.js"} 8 | {crmScript ext="eu.tttp.civisualize" file="js/nvd3/src/tooltip.js"} 9 | {crmScript ext="eu.tttp.civisualize" file="js/nvd3/src/utils.js"} 10 | {crmScript ext="eu.tttp.civisualize" file="js/nvd3/src/interactiveLayer.js"} 11 | {crmScript ext="eu.tttp.civisualize" file="js/nvd3/src/models/legend.js"} 12 | {crmScript ext="eu.tttp.civisualize" file="js/nvd3/src/models/axis.js"} 13 | {crmScript ext="eu.tttp.civisualize" file="js/nvd3/src/models/scatter.js"} 14 | {crmScript ext="eu.tttp.civisualize" file="js/nvd3/src/models/line.js"} 15 | {crmScript ext="eu.tttp.civisualize" file="js/nvd3/src/models/lineChart.js"} 16 | 17 | {literal} 18 | 49 | 50 | 51 |
52 | 53 |
54 | 55 | 145 | {/literal} 146 | -------------------------------------------------------------------------------- /templates/dataviz/Contactdashboard.tpl: -------------------------------------------------------------------------------- 1 | {php} 2 | CRM_Utils_System::setTitle('Overview of your CiviCRM'); 3 | 4 | $this->assign("options", array('width'=>200)); 5 | 6 | {/php} 7 | 8 |
9 |
10 | {include file="dataviz/Contacttype.tpl" embedded=1 name="contactTypeGraph" options=$options} 11 | 12 | {include file="dataviz/Groupbarchart.tpl" embedded=1 name="GroupBarChart"} 13 | 14 | {literal} 15 | 18 | {/literal} 19 | 20 | -------------------------------------------------------------------------------- /templates/dataviz/Contacts.tpl: -------------------------------------------------------------------------------- 1 | {crmTitle string="Contacts Overview"} 2 | 3 |
4 |
5 |

contacts selected from a total of records

6 |
7 |
8 |
9 | Type 10 | reset 11 |
12 |
13 |
14 | Source of Contact 15 | reset 16 |
17 |
18 |
19 |
20 | Gender 21 | reset 22 |
23 |
24 |
25 | Day - Contact Created 26 | reset 27 |
28 |
29 |
30 |
31 | Date - Contact Created 32 | reset 33 |
34 |
35 |
36 | 37 | 225 |
226 | -------------------------------------------------------------------------------- /templates/dataviz/Contacttype.tpl: -------------------------------------------------------------------------------- 1 | {if !$embedded} 2 | {php}CRM_Utils_System::setTitle('What type are your contacts?');{/php} 3 |
4 |
5 | {/if} 6 | 7 | 8 | 92 | 93 | 146 | {/literal} 147 | 148 | -------------------------------------------------------------------------------- /templates/dataviz/Contribute.tpl: -------------------------------------------------------------------------------- 1 | {crmTitle string="Contributions"} 2 |

Contributions for a total of

3 |
4 |
5 | Recurring 6 | reset 7 | 8 |
9 |
10 | 11 | 16 | 17 |
18 | Payment instrument 19 | reset 20 |
21 |
22 | 23 |
24 | Day of Week 25 | reset 26 |
27 |
28 |
29 |
30 |
31 | Amount by month 32 | 33 | reset 34 |
35 |
36 |
37 | 38 |
39 | 40 |
41 | 42 | 241 |
242 | -------------------------------------------------------------------------------- /templates/dataviz/ContributionByDate.tpl: -------------------------------------------------------------------------------- 1 | {crmScript ext="eu.tttp.civisualize" file="js/dc/dc.js"} 2 | {crmScript ext="eu.tttp.civisualize" file="js/dc/crossfilter.js"} 3 | 4 |
5 | 6 | Days by Gain or Loss 7 | 8 | 9 | 10 |
11 | 12 |
13 | Date 14 | Open 15 | Close 16 | Change 17 | Volume 18 |
19 | 20 |
21 | 22 | 23 | 24 | 322 | {/literal} 323 | 324 | -------------------------------------------------------------------------------- /templates/dataviz/Demo.tpl: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /templates/dataviz/Donortrends.tpl: -------------------------------------------------------------------------------- 1 | {crmTitle string="Donor Trends"} 2 | 3 | {literal} 4 | 12 | {/literal} 13 | 14 |
15 |
selected from a total of .
16 |
17 | Donor Trends 18 | reset 19 |
20 |
21 |
22 | Gender 23 | reset 24 |
25 |
26 |
27 | Age 28 | reset 29 |
30 |
31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
Participant NameGenderAgeTotal Amount
42 |
43 |
44 | 45 | 46 | 333 | -------------------------------------------------------------------------------- /templates/dataviz/Event.tpl: -------------------------------------------------------------------------------- 1 | {if !$id} 2 | 5 | {/if} 6 | 7 | {literal} 8 | 49 | {/literal} 50 | 51 |
52 |
53 |
54 |
55 |
56 | 57 |
58 |
59 |
60 | Participants 61 | reset 62 |
63 |
64 |
65 | Gender 66 | reset 67 |
68 |
69 |
70 | Participant Status 71 | reset 72 |
73 |
74 |
75 | Fee Paid 76 | reset 77 |
78 |
79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 |
NameGenderFee PaidStatus
89 |
90 | 91 | 304 |
305 | -------------------------------------------------------------------------------- /templates/dataviz/Events.tpl: -------------------------------------------------------------------------------- 1 | {crmTitle string="Events Overview"} 2 | 3 |
4 |
5 | , 6 | and 7 | 8 | with a total of Participants. 9 |
10 | 11 |
12 | Events 13 | 14 |
15 |
16 | 17 |
18 | Participants 19 | 20 |
21 |
22 | 23 |
24 | 25 |
26 | Type 27 | 28 |
29 |
30 | 31 |
32 | Day of Week 33 | 34 |
35 |
36 | 37 |
38 | Paid event 39 | 40 |
41 |
42 | 43 |
44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
Event NameStart DateEnd DateParticipants
54 |
55 |
56 | 57 | 371 |
372 | -------------------------------------------------------------------------------- /templates/dataviz/Example.tpl: -------------------------------------------------------------------------------- 1 | {crmTitle title="Here be dragons"} 2 | This is a demo 3 | 4 |
5 | Musician 6 | reset 7 |
8 |
9 |
10 |
11 | Gender 12 | reset 13 |
14 |
15 |
16 | 17 | 18 | 90 | 91 | 95 | {/literal} 96 | -------------------------------------------------------------------------------- /templates/dataviz/Groupbarchart.tpl: -------------------------------------------------------------------------------- 1 | {if !$embedded} 2 | {php}CRM_Utils_System::setTitle('What type are your contacts?');{/php} 3 |
4 | {/if} 5 | 6 | 106 | 107 | -------------------------------------------------------------------------------- /templates/dataviz/Lapseddonor.tpl: -------------------------------------------------------------------------------- 1 |
2 |

Look, a unicorn

3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
RecoveredPrior
11 | 54 |
55 |
56 | -------------------------------------------------------------------------------- /templates/dataviz/Mailing.tpl: -------------------------------------------------------------------------------- 1 | {crmTitle string="Mailing details"} 2 | 3 | reset 4 | 5 |
6 |

Date Open

7 |
8 | 9 |
10 |
11 | 12 | 100 | 101 | 105 | {/literal} 106 | -------------------------------------------------------------------------------- /templates/dataviz/Mailings.tpl: -------------------------------------------------------------------------------- 1 | {crmTitle string=" Mailings out of "} 2 | 3 |
4 |

Campaign

5 |

Crew

6 |

% Open

7 |

% Click

8 |

Date sent

9 |
10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
DateNameCampaignCreatorRecipientsOpenClicks
24 |
25 | 26 |
27 |
28 | 29 | 237 | 238 | 249 | {/literal} 250 | -------------------------------------------------------------------------------- /templates/dataviz/Tag.tpl: -------------------------------------------------------------------------------- 1 | {*crmScript ext=eu.tttp.civisualize file=bar.js*} 2 |
3 | 121 | -------------------------------------------------------------------------------- /templates/dataviz/Typebarchart.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 166 | 167 | 219 | {/literal} 220 | 221 | -------------------------------------------------------------------------------- /updateTpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php 2 | on('renderlet', function) 118 | $html = str_replace('.renderlet(', ".on('renderlet', ", $html); 119 | 120 | if (!$html) { 121 | // Just in case. 122 | fwrite(STDERR, "Failed to convert file '$tpl'\n"); 123 | continue; 124 | } 125 | 126 | print "$tpl: "; 127 | if ($warnings) { 128 | print "WARNINGS\n"; 129 | foreach ($warnings as $_) { print "Warning: $_\n";} 130 | print "\n"; 131 | } 132 | else { 133 | print "no errors or warnings.\n"; 134 | } 135 | if (!file_put_contents($tpl, $html)) { 136 | fwrite(STDERR, "Failed to write file '$tpl'\n"); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /xml/Menu/civisualize.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | civicrm/dataviz 5 | CRM_Civisualize_Page_Main 6 | Datavisualize 7 | access CiviReport 8 | 9 | 10 | civicrm/datadoc 11 | CRM_Civisualize_Page_Doc 12 | Documentation 13 | access CiviReport 14 | 15 | 16 | --------------------------------------------------------------------------------