├── pentaho-plugin
└── saiku-chart-plus
│ ├── images
│ └── chart.png
│ ├── js
│ └── google.js
│ ├── version.xml
│ ├── plugin.xml
│ ├── LICENSES.txt
│ ├── css
│ └── plugin.css
│ └── saiku
│ └── plugins
│ └── saiku-chart-plus.js
├── saiku-server
└── saiku-chart-plus
│ ├── images
│ └── chart.png
│ ├── js
│ └── google.js
│ ├── LICENSES.txt
│ ├── css
│ └── plugin.css
│ └── plugin.js
└── README.md
/pentaho-plugin/saiku-chart-plus/images/chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/it4biz/SaikuChartPlus/HEAD/pentaho-plugin/saiku-chart-plus/images/chart.png
--------------------------------------------------------------------------------
/saiku-server/saiku-chart-plus/images/chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/it4biz/SaikuChartPlus/HEAD/saiku-server/saiku-chart-plus/images/chart.png
--------------------------------------------------------------------------------
/saiku-server/saiku-chart-plus/js/google.js:
--------------------------------------------------------------------------------
1 | setTimeout(function(){google.load('visualization', '1', {'callback':'', 'packages':['geochart','geomap']})}, 2000);
--------------------------------------------------------------------------------
/pentaho-plugin/saiku-chart-plus/js/google.js:
--------------------------------------------------------------------------------
1 | setTimeout(function(){google.load('visualization', '1', {'callback':'', 'packages':['geochart','geomap']})}, 2000);
--------------------------------------------------------------------------------
/pentaho-plugin/saiku-chart-plus/version.xml:
--------------------------------------------------------------------------------
1 |
2 | ChartPlusStable
3 |
--------------------------------------------------------------------------------
/pentaho-plugin/saiku-chart-plus/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/pentaho-plugin/saiku-chart-plus/LICENSES.txt:
--------------------------------------------------------------------------------
1 | Licenses
2 | Before you put this project in your production environment,
3 | please visit http://www.highcharts.com/ to learn more about
4 | the Highchart project, and https://developers.google.com/maps/terms
5 | to learn more about the Google GeoChart project.
6 |
7 | Saiku Chart Plus is a free and open source software. The UI, contained
8 | in this repository, is available under the terms of the Apache License
9 | Version 2. A copy is attached for your convenience.
--------------------------------------------------------------------------------
/saiku-server/saiku-chart-plus/LICENSES.txt:
--------------------------------------------------------------------------------
1 | Licenses
2 | Before you put this project in your production environment,
3 | please visit http://www.highcharts.com/ to learn more about
4 | the Highchart project, and https://developers.google.com/maps/terms
5 | to learn more about the Google GeoChart project.
6 |
7 | Saiku Chart Plus is a free and open source software. The UI, contained
8 | in this repository, is available under the terms of the Apache License
9 | Version 2. A copy is attached for your convenience.
--------------------------------------------------------------------------------
/saiku-server/saiku-chart-plus/css/plugin.css:
--------------------------------------------------------------------------------
1 | #nav, #nav ul{
2 | overflow: visible;
3 | z-index:100;
4 | margin:0;
5 | padding:0;
6 | list-style-type:none;
7 | list-style-position:outside;
8 | position:relative;
9 | line-height:1.5em;
10 | background: #fff;
11 | border-radius: 6px;
12 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
13 | }
14 |
15 | #nav a{
16 | display:relative;
17 | padding:0px 5px;
18 | color:#555555;
19 | text-decoration:none;
20 | }
21 |
22 | .menu{
23 | border: 1px solid #D5D5D5;
24 | margin: 2px 2px;
25 | }
26 |
27 | .menu:hover{
28 | background:#155FB0;
29 | color: #FFFFFF;
30 | text-decoration: none;
31 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0);
32 | }
33 |
34 | .menu ul li:hover{
35 | background:#155FB0;
36 | text-decoration: none;
37 | border-radius: 6px;
38 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
39 | }
40 |
41 | .menu a:hover{
42 | color:#FFFFFF !important;
43 | }
44 |
45 | #nav li{
46 | float:left;
47 | position:relative;
48 | }
49 |
50 | #nav ul {
51 | position:absolute;
52 | display:none;
53 | width:13em;
54 | top:1.5em;
55 | }
56 |
57 | #nav li ul a{
58 | width:12em;
59 | height:auto;
60 | float:left;
61 | }
62 |
63 | #nav ul ul{
64 | top:auto;
65 | }
66 |
67 | #nav li ul ul {
68 | left:12em;
69 | margin:0px 0 0 10px;
70 | }
71 |
72 | #nav li:hover ul ul, #nav li:hover ul ul ul, #nav li:hover ul ul ul ul{
73 | display:none;
74 | }
75 | #nav li:hover ul, #nav li li:hover ul, #nav li li li:hover ul, #nav li li li li:hover ul{
76 | display:block;
77 | }
78 |
79 | #nav .submenu:after {
80 | content: ">";
81 | color: #666;
82 | position: absolute;
83 | top: 0;
84 | right: 3px;
85 | z-index: 1;
86 | }
87 |
--------------------------------------------------------------------------------
/pentaho-plugin/saiku-chart-plus/css/plugin.css:
--------------------------------------------------------------------------------
1 | #nav, #nav ul{
2 | overflow: visible;
3 | z-index:100;
4 | margin:0;
5 | padding:0;
6 | list-style-type:none;
7 | list-style-position:outside;
8 | position:relative;
9 | line-height:1.5em;
10 | background: #fff;
11 | border-radius: 6px;
12 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
13 | }
14 |
15 | #nav a{
16 | display:relative;
17 | padding:0px 5px;
18 | color:#555555;
19 | text-decoration:none;
20 | }
21 |
22 | .menu{
23 | border: 1px solid #D5D5D5;
24 | margin: 2px 2px;
25 | }
26 |
27 | .menu:hover{
28 | background:#155FB0;
29 | color: #FFFFFF;
30 | text-decoration: none;
31 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0);
32 | }
33 |
34 | .menu ul li:hover{
35 | background:#155FB0;
36 | text-decoration: none;
37 | border-radius: 6px;
38 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
39 | }
40 |
41 | .menu a:hover{
42 | color:#FFFFFF !important;
43 | }
44 |
45 | #nav li{
46 | float:left;
47 | position:relative;
48 | }
49 |
50 | #nav ul {
51 | position:absolute;
52 | display:none;
53 | width:13em;
54 | top:1.5em;
55 | }
56 |
57 | #nav li ul a{
58 | width:12em;
59 | height:auto;
60 | float:left;
61 | }
62 |
63 | #nav ul ul{
64 | top:auto;
65 | }
66 |
67 | #nav li ul ul {
68 | left:12em;
69 | margin:0px 0 0 10px;
70 | }
71 |
72 | #nav li:hover ul ul, #nav li:hover ul ul ul, #nav li:hover ul ul ul ul{
73 | display:none;
74 | }
75 | #nav li:hover ul, #nav li li:hover ul, #nav li li li:hover ul, #nav li li li li:hover ul{
76 | display:block;
77 | }
78 |
79 | #nav .submenu:after {
80 | content: ">";
81 | color: #666;
82 | position: absolute;
83 | top: 0;
84 | right: 3px;
85 | z-index: 1;
86 | }
87 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Saiku Chart Plus
2 |
3 | Welcome to Saiku Chart Plus Project.
4 |
5 | What is Saiku Chart Plus?
6 |
7 | It is an open source project that helps Pentaho BI users to create other types of charts and maps based on Saiku Project, Highcharts and Google Maps.
8 |
9 | Saiku Chart Plus is used by more than 120 countries around the World.
10 |
11 | ### Read More
12 |
13 | To learn more visit our page http://it4biz.github.com/SaikuChartPlus/
14 |
15 |
16 | ### Installation
17 |
18 | * For Pentaho BA Users, please use Pentaho Marketplace
19 | * For Saiku Server Users, please follow the tutorial at section "advanced instalation" in http://it4biz.github.io/SaikuChartPlus/
20 |
21 | ### Support
22 | * If you need support please feel free to create a issue here https://github.com/it4biz/SaikuChartPlus/issues we will do our best to help you.
23 |
24 | ### Licenses
25 |
26 | Before you put this project in your production environment, please visit http://www.highcharts.com/ to learn more about the Highchart project, and https://developers.google.com/maps/terms to learn more about the Google GeoChart project.
27 |
28 | Saiku Chart Plus is a free and open source software. The UI, contained in this repository, is available under the terms of the Apache License Version 2. A copy is attached for your convenience.
29 |
30 |
31 | ###Changelog
32 |
33 | 3.1RC1 (on development...)
34 | * Add Interactive Heatmaps with Google Maps API v3 (https://github.com/it4biz/SaikuChartPlus/issues/35);
35 | * Work in open issues;
36 |
37 | 3.0 Stable version:
38 | * Ready to work with Saiku 3
39 |
40 | 2.4 Stable version:
41 | * Position legend - https://github.com/it4biz/SaikuChartPlus/issues/4
42 | * Error label description - https://github.com/it4biz/SaikuChartPlus/issues/11
43 | * Add support for multiple measures at geoChart/Map
44 | * Ass support to GeoChart with resolution provinces
45 |
46 | 2.5 RC4 version:
47 | * Removed dependency of bootstrap
48 |
49 | * Removed Highcharts Exporting file because insconsistence with IE
50 |
51 | * Changed Button Plus, add togle for table render button
52 |
53 | ###People talking about us
54 | http://www.osbi.fr/saiku-chart-plus/
55 | http://www.redopenbi.com/group/saiku/forum/topics/tutorial-01-saiku-chart-plus-geomap-y-geochart
56 | http://www.dataprix.com/blog-it/business-intelligence/saiku-chart-plus-geomap-geochart
57 |
58 | If your link is not listed, please contact us by email info@it4biz.com.br
59 |
--------------------------------------------------------------------------------
/pentaho-plugin/saiku-chart-plus/saiku/plugins/saiku-chart-plus.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 IT4biz IT Solutions Ltda
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | * changed by it4biz.com.br
16 | */
17 |
18 | /**
19 | * Renders a chart for each workspace
20 | */
21 | var ChartPlus = Backbone.View.extend({
22 |
23 | initialize: function(args) {
24 | this.workspace = args.workspace;
25 |
26 | // Create a unique ID for use as the CSS selector
27 | this.id = _.uniqueId("chartPlus_");
28 | $(this.el).attr({ id: this.id });
29 |
30 | // Bind table rendering to query result event
31 | _.bindAll(this, "render", "receive_data", "process_data", "show",
32 | "setOptions");
33 |
34 | this.workspace.bind('query:result', this.receive_data);
35 |
36 | // Add chart button
37 | this.add_button();
38 | this.workspace.toolbar.chartPlus = this.show;
39 |
40 | // Listen to adjust event and rerender chart
41 | this.workspace.bind('workspace:adjust', this.render);
42 |
43 | // Create navigation
44 | this.nav = $("
"+
45 | "
"+
46 | ""+
54 | ""+
59 | ""+
64 | ""+
345 | ""+
626 | "
"+
627 | "
");
628 |
629 |
630 |
631 |
632 |
633 | this.nav.find('a').click(this.setOptions);
634 |
635 | //function for menu
636 | $("#nav ul ").css({display: "none"}); // Opera Fix
637 | $("#nav li").hover(function(){
638 | $(this).find('ul:first').css({visibility: "visible",display: "none"}).show(400);
639 | },function(){
640 | $(this).find('ul:first').css({visibility: "hidden"});
641 | });
642 |
643 | // Append chart to workspace
644 | $(this.workspace.el).find('.workspace_results')
645 | .prepend($(this.el).hide())
646 | .prepend(this.nav.hide());
647 |
648 |
649 |
650 | },
651 |
652 | add_button: function() {
653 | var $chart_button =
654 | $('')
655 | .css({ 'background-image': "url('../saiku-chart-plus/images/chart.png')",
656 | 'background-repeat':'no-repeat',
657 | 'background-position':'20% 50%'
658 | });
659 |
660 | var $chart_li = $('').append($chart_button);
661 | $(this.workspace.toolbar.el).find("ul").append($chart_li);
662 | },
663 |
664 | show: function(event, ui) {
665 | $(this.workspace.table.el).toggle();
666 | $(this.el).toggle();
667 | $(this.nav).toggle();
668 | $(event.target).toggleClass('on');
669 |
670 | if ($(event.target).hasClass('on')) {
671 | this.render();
672 | } else {
673 | this.workspace.table.render({ data: this.workspace.query.result.lastresult() });
674 | }
675 | },
676 |
677 | setOptions: function(event) {
678 | var type = $(event.target).attr('href').replace('#', '');
679 | var chartOptions=[];
680 | chartOptions.type=type;
681 |
682 | try {
683 | if(type=='geoChart' || type=='geoMap'){
684 | var region=$(event.target).attr('id');
685 | chartOptions.region=region;
686 | this.render(chartOptions);
687 | }else
688 | this.render(chartOptions);
689 | } catch (e) { }
690 |
691 | return false;
692 | },
693 |
694 | render: function(chartOptions) {
695 |
696 | if (! $(this.workspace.toolbar.el).find('.chartPlus').hasClass('on')) {
697 | return;
698 | }
699 |
700 | //configurações default
701 | var options = _.extend({
702 | canvas: this.id,
703 | width: $(this.workspace.el).find('.workspace_results').width() - 40,
704 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
705 | yAxisSize: 70,
706 | orientation: 'vertical',
707 | stacked: false,
708 | animate: false,
709 | showValues: false,
710 | legend: true,
711 | legendPosition:"top",
712 | legendAlign: "right",
713 | colors: ["#B40010", "#CCC8B4", "#DDB965", "#72839D", "#1D2D40"],
714 | serializeType: "highCharts",
715 | type: 'bar'
716 | }, chartOptions);
717 |
718 | //start serialization of data
719 | if(options.type!='pie' && options.type!='geoMap' && options.type!='geoChart'){
720 | var metadata=new Array();
721 | //numero de colunas
722 | var colNumberY=this.data.metadata.length-1;//-1 devido a coluna 0 armazena o valor de X
723 | var x=new Array();
724 | var y=new Array();
725 | for(var i=0; i < colNumberY; i++){
726 | y[i]=new Array();
727 | }
728 |
729 |
730 | if (this.data.resultset.length > 0 ) {
731 | $.each(this.data.resultset, function(key, value) {
732 | x[key]=value[0];
733 | for(var i=0; i < colNumberY; i++){
734 | y[i][key]=value[i+1];// +1 devido ao valor de x armazenado na coluna 0
735 | }
736 |
737 | });
738 | }
739 |
740 | var seriesData=[];
741 | for(var i=0; i < colNumberY; i++){
742 | seriesData[i]={
743 | name: this.data.metadata[i+1].colName,
744 | data: y[i]
745 | };
746 | }
747 | }else if(options.type=='pie' && options.type!='geoMap' && options.type!='geoChart'){
748 | if(this.data.metadata.length>0){
749 | var metadata=new Array();
750 | //numero de colunas
751 | var colNumber=this.data.metadata.length;
752 | var seriesData=new Array();
753 | var series=new Array();
754 | if (this.data.resultset.length > 0 ) {
755 | $.each(this.data.resultset, function(key, value) {
756 | series[key]=[value[0], value[1]];
757 | });
758 | }
759 |
760 | seriesData=[{
761 | type: 'pie',
762 | name: this.data.metadata[0].colName,
763 | data: series
764 | }];
765 | }else{
766 | return false;
767 | }
768 | }else if(options.type=='geoMap'){
769 | if(this.data.metadata.length>0){
770 | var series=[];
771 | //nome das colunas
772 | var column=[];
773 |
774 | column[0]=this.data.metadata[0].colName;
775 | column[1]=this.data.metadata[1].colName;
776 | series[0]=column;
777 |
778 |
779 | if (this.data.resultset.length > 0 ) {
780 | var data= this.data;
781 | $.each(this.data.resultset, function(key, value) {
782 | var array=[];
783 | array[0]=value[0];
784 | array[1]=value[1];
785 | array[2]=value[1];
786 | for(var i=2; i < data.metadata.length; i++){
787 | columnName=data.metadata[i].colName;
788 | value=value[i];
789 | array[2]+=', '+columnName+': '+value;
790 | }
791 | series[key+1]=array; // +1 devido ao nome das colunas
792 | });
793 | }
794 |
795 | }else{
796 | return false;
797 | }
798 |
799 | }else{//options.type=='geoChart'
800 | var series=[];
801 | //nome das colunas
802 | var column=[];
803 | for(var i=0; i < this.data.metadata.length; i++)
804 | column[i]=this.data.metadata[i].colName;
805 | series[0]=column;
806 |
807 | if (this.data.resultset.length > 0 ) {
808 | $.each(this.data.resultset, function(key, value) {
809 | series[key+1]=value; // +1 devido ao nome das colunas
810 | });
811 | }
812 | }
813 | //end serialization of data
814 |
815 | //start draw graphics
816 | if(options.type=='bar'){
817 | chart = new Highcharts.Chart({
818 | chart: {
819 | renderTo: this.id,
820 | type: 'bar',
821 | zoomType: 'x,y',
822 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
823 | width: $(this.workspace.el).find('.workspace_results').width() - 40
824 | },
825 | title: {
826 | text: '',
827 | x: -20 //center
828 | },
829 | credits: {
830 | text: 'Saiku Chart Plus Plugin by IT4biz',
831 | href: 'http://it4biz.github.com/SaikuChartPlus'
832 | },
833 | subtitle: {
834 | text: '',
835 | x: -20
836 | },
837 | xAxis: {
838 | categories: x
839 | },
840 | yAxis: {
841 | title: {
842 | text: ''
843 | },
844 | plotLines: [{
845 | value: 0,
846 | width: 1,
847 | color: '#808080'
848 | }]
849 | },
850 | tooltip: {
851 | formatter: function() {
852 | return ''+ this.series.name +'
'+
853 | this.x +': '+ this.y +'';
854 | }
855 | },
856 | legend: {
857 | layout: 'vertical',
858 | align: 'right',
859 | verticalAlign: 'top',
860 | x: -10,
861 | y: 100,
862 | borderWidth: 0
863 | },
864 | series: seriesData
865 | });
866 | }
867 | else if(options.type=='stackedBar')
868 | {
869 | chart = new Highcharts.Chart({
870 | chart: {
871 | renderTo: this.id,
872 | type: 'bar',
873 | zoomType: 'x,y',
874 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
875 | width: $(this.workspace.el).find('.workspace_results').width() - 40
876 | },
877 | title: {
878 | text: '',
879 | x: -20 //center
880 | },
881 | credits: {
882 | text: 'Saiku Chart Plus Plugin by IT4biz',
883 | href: 'http://it4biz.github.com/SaikuChartPlus'
884 | },
885 | subtitle: {
886 | text: '',
887 | x: -20
888 | },
889 | xAxis: {
890 | categories: x
891 | },
892 | yAxis: {
893 | title: {
894 | text: ''
895 | },
896 | plotLines: [{
897 | value: 0,
898 | width: 1,
899 | color: '#808080'
900 | }]
901 | },
902 | plotOptions: {
903 | series: {
904 | stacking: 'normal'
905 | }
906 | },
907 | tooltip: {
908 | formatter: function() {
909 | return ''+ this.series.name +'
'+
910 | this.x +': '+ this.y +'';
911 | }
912 | },
913 | legend: {
914 | layout: 'vertical',
915 | align: 'right',
916 | verticalAlign: 'top',
917 | x: -10,
918 | y: 100,
919 | borderWidth: 0
920 | },
921 | series: seriesData
922 | });
923 | }
924 | else if(options.type=='column')
925 | {
926 | chart = new Highcharts.Chart({
927 | chart: {
928 | renderTo: this.id,
929 | type: 'column',
930 | zoomType: 'x,y',
931 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
932 | width: $(this.workspace.el).find('.workspace_results').width() - 40
933 | },
934 | credits: {
935 | text: 'Saiku Chart Plus Plugin by IT4biz',
936 | href: 'http://it4biz.github.com/SaikuChartPlus'
937 | },
938 | title: {
939 | text: '',
940 | x: -20 //center
941 | },
942 | subtitle: {
943 | text: '',
944 | x: -20
945 | },
946 | xAxis: {
947 | categories: x,
948 | labels: {
949 | rotation: -90,
950 | align: 'right'
951 | }
952 | },
953 | yAxis: {
954 | title: {
955 | text: ''
956 | },
957 | plotLines: [{
958 | value: 0,
959 | width: 1,
960 | color: '#808080'
961 | }]
962 | },
963 | tooltip: {
964 | formatter: function() {
965 | return ''+ this.series.name +'
'+
966 | this.x +': '+ this.y +'';
967 | }
968 | },
969 | legend: {
970 | layout: 'vertical',
971 | align: 'right',
972 | verticalAlign: 'top',
973 | x: -10,
974 | y: 100,
975 | borderWidth: 0
976 | },
977 | series: seriesData
978 | });
979 | }
980 | else if(options.type=='stackedColumn')
981 | {
982 | chart = new Highcharts.Chart({
983 | chart: {
984 | renderTo: this.id,
985 | type: 'column',
986 | zoomType: 'x,y',
987 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
988 | width: $(this.workspace.el).find('.workspace_results').width() - 40
989 | },
990 | credits: {
991 | text: 'Saiku Chart Plus Plugin by IT4biz',
992 | href: 'http://it4biz.github.com/SaikuChartPlus'
993 | },
994 | title: {
995 | text: '',
996 | x: -20 //center
997 | },
998 | subtitle: {
999 | text: '',
1000 | x: -20
1001 | },
1002 | xAxis: {
1003 | categories: x,
1004 | labels: {
1005 | rotation: -90,
1006 | align: 'right'
1007 | }
1008 | },
1009 | yAxis: {
1010 | title: {
1011 | text: ''
1012 | },
1013 | plotLines: [{
1014 | value: 0,
1015 | width: 1,
1016 | color: '#808080'
1017 | }]
1018 | },
1019 | plotOptions: {
1020 | series: {
1021 | stacking: 'normal'
1022 | }
1023 | },
1024 | tooltip: {
1025 | formatter: function() {
1026 | return ''+ this.series.name +'
'+
1027 | this.x +': '+ this.y +'';
1028 | }
1029 | },
1030 | legend: {
1031 | layout: 'vertical',
1032 | align: 'right',
1033 | verticalAlign: 'top',
1034 | x: -10,
1035 | y: 100,
1036 | borderWidth: 0
1037 | },
1038 | series: seriesData
1039 | });
1040 | }
1041 | else if(options.type=='line')
1042 | {
1043 | chart = new Highcharts.Chart({
1044 | chart: {
1045 | renderTo: this.id,
1046 | type: 'line',
1047 | zoomType: 'x,y',
1048 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
1049 | width: $(this.workspace.el).find('.workspace_results').width() - 40
1050 | },
1051 | credits: {
1052 | text: 'Saiku Chart Plus Plugin by IT4biz',
1053 | href: 'http://it4biz.github.com/SaikuChartPlus'
1054 | },
1055 | title: {
1056 | text: '',
1057 | x: -20 //center
1058 | },
1059 | subtitle: {
1060 | text: '',
1061 | x: -20
1062 | },
1063 | xAxis: {
1064 | categories: x,
1065 | labels: {
1066 | rotation: -90,
1067 | align: 'right'
1068 | }
1069 | },
1070 | yAxis: {
1071 | title: {
1072 | text: ''
1073 | },
1074 | plotLines: [{
1075 | value: 0,
1076 | width: 1,
1077 | color: '#808080'
1078 | }]
1079 | },
1080 | tooltip: {
1081 | formatter: function() {
1082 | return ''+ this.series.name +'
'+
1083 | this.x +': '+ this.y +'';
1084 | }
1085 | },
1086 | legend: {
1087 | layout: 'vertical',
1088 | align: 'right',
1089 | verticalAlign: 'top',
1090 | x: -10,
1091 | y: 100,
1092 | borderWidth: 0
1093 | },
1094 | series: seriesData
1095 | });
1096 | }
1097 | else if(options.type=='pie')
1098 | {
1099 | chart = new Highcharts.Chart({
1100 | chart: {
1101 | renderTo: this.id,
1102 | plotBackgroundColor: null,
1103 | plotBorderWidth: null,
1104 | plotShadow: false,
1105 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
1106 | width: $(this.workspace.el).find('.workspace_results').width() - 40
1107 | },
1108 | credits: {
1109 | text: 'Saiku Chart Plus Plugin by IT4biz',
1110 | href: 'http://it4biz.github.com/SaikuChartPlus'
1111 | },
1112 | title: {
1113 | text: ''
1114 | },
1115 | tooltip: {
1116 | pointFormat: '{series.name}: {point.percentage}%',
1117 | percentageDecimals: 1
1118 | },
1119 | plotOptions: {
1120 | pie: {
1121 | allowPointSelect: true,
1122 | cursor: 'pointer',
1123 | dataLabels: {
1124 | enabled: true,
1125 | color: '#000000',
1126 | connectorColor: '#000000',
1127 | formatter: function() {
1128 | return ''+ this.point.name +': '+ this.percentage.toFixed(1) +' %';
1129 | }
1130 | }
1131 | }
1132 | },
1133 | series: seriesData
1134 | });
1135 | }
1136 | else if(options.type=='geoChart')
1137 | {
1138 | var data = google.visualization.arrayToDataTable(series);
1139 | var optionsMap;
1140 |
1141 | if(options.region=='world'){
1142 | optionsMap = {
1143 | width: $(this.workspace.el).find('.workspace_results').width() - 40,
1144 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
1145 | datalessRegionColor: 'F5F5F5',
1146 | region: options.region,
1147 | displayMode: 'markers'
1148 | };
1149 | }else{
1150 | optionsMap = {
1151 | width: $(this.workspace.el).find('.workspace_results').width() - 40,
1152 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
1153 | datalessRegionColor: 'F5F5F5',
1154 | region: options.region,
1155 | resolution: 'provinces',
1156 | displayMode: 'regions'
1157 | };
1158 | }
1159 |
1160 | var geoChart = new google.visualization.GeoChart(document.getElementById(this.id));
1161 | geoChart.draw(data, optionsMap);
1162 |
1163 | }
1164 | else if(options.type=='geoMap')
1165 | {
1166 | var data =new google.visualization.DataTable();
1167 | data.addRows(series.length);
1168 | data.addColumn('string', series[0][0]);
1169 | data.addColumn('number', series[0][1]);
1170 |
1171 | for (var i=1; i < series.length; i++) {
1172 | data.setCell(i, 0, series[i][0]);
1173 | data.setCell(i, 1, series[i][1], series[i][2]);
1174 | };
1175 |
1176 | var options = {
1177 | width: $(this.workspace.el).find('.workspace_results').width() - 40,
1178 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
1179 | colors: [0xE0FFD4, 0xA5EF63, 0x50AA00, 0x267114],
1180 | region: options.region,
1181 | dataMode: 'regions'
1182 | };
1183 |
1184 | var geoMap = new google.visualization.GeoMap(document.getElementById(this.id));
1185 | google.visualization.events.addListener(geoMap, "error", function errorHandler(e) {
1186 | google.visualization.errors.removeError(e.id);
1187 | });
1188 |
1189 | geoMap.draw(data, options);
1190 |
1191 | }
1192 | /*********End charts draw**************/
1193 | },
1194 |
1195 | receive_data: function(args) {
1196 | return _.delay(this.process_data, 0, args);
1197 | },
1198 |
1199 | process_data: function(args) {
1200 | this.data = {};
1201 | this.data.resultset = [];
1202 | this.data.metadata = [];
1203 | this.data.height = 0;
1204 | this.data.width = 0;
1205 |
1206 | if (args.data.cellset && args.data.cellset.length > 0) {
1207 |
1208 | var lowest_level = 0;
1209 |
1210 | for (var row = 0; row < args.data.cellset.length; row++) {
1211 | if (args.data.cellset[row][0].type == "ROW_HEADER_HEADER") {
1212 | this.data.metadata = [];
1213 | for (var field = 0; field < args.data.cellset[row].length; field++) {
1214 | if (args.data.cellset[row][field].type == "ROW_HEADER_HEADER") {
1215 | this.data.metadata.shift();
1216 | lowest_level = field;
1217 | }
1218 |
1219 | this.data.metadata.push({
1220 | colIndex: field,
1221 | colType: typeof(args.data.cellset[row + 1][field].value) !== "number" &&
1222 | isNaN(args.data.cellset[row + 1][field].value
1223 | .replace(/[^a-zA-Z 0-9.]+/g,'')) ? "String" : "Numeric",
1224 | colName: args.data.cellset[row][field].value
1225 | });
1226 | }
1227 | } else if (args.data.cellset[row][0].value !== "null" && args.data.cellset[row][0].value !== "") {
1228 | var record = [];
1229 | this.data.width = args.data.cellset[row].length;
1230 | for (var col = lowest_level; col < args.data.cellset[row].length; col++) {
1231 | var value = args.data.cellset[row][col].value;
1232 | // check if the resultset contains the raw value, if not try to parse the given value
1233 | if (args.data.cellset[row][col].properties.raw && args.data.cellset[row][col].properties.raw !== "null" && col>0)
1234 | {
1235 | value = parseFloat(args.data.cellset[row][col].properties.raw);
1236 | } else if (typeof(args.data.cellset[row][col].value) !== "number" &&
1237 | parseFloat(args.data.cellset[row][col].value.replace(/[^a-zA-Z 0-9.]+/g,'')) && col>0)
1238 | {
1239 | value = parseFloat(args.data.cellset[row][col].value.replace(/[^a-zA-Z 0-9.]+/g,''));
1240 | }
1241 | record.push(value);
1242 | }
1243 | this.data.resultset.push(record);
1244 | }
1245 | }
1246 | this.data.height = this.data.resultset.length;
1247 | this.render();
1248 | } else {
1249 | $(this.el).text("No results");
1250 | }
1251 | }
1252 | });
1253 |
1254 | function loadCSS(file){
1255 |
1256 | var headID = document.getElementsByTagName("head")[0];
1257 | var cssNode = document.createElement('link');
1258 | cssNode.type = 'text/css';
1259 | cssNode.rel = 'stylesheet';
1260 | cssNode.href = file;
1261 | cssNode.media = 'screen';
1262 | headID.appendChild(cssNode);
1263 | }
1264 |
1265 | function loadJS(file){
1266 |
1267 | var headID = document.getElementsByTagName("head")[0];
1268 | var newScript = document.createElement('script');
1269 | newScript.type = 'text/javascript';
1270 | newScript.src = file;
1271 | headID.appendChild(newScript);
1272 | }
1273 |
1274 | /**
1275 | * Start Plugin
1276 | */
1277 | Saiku.events.bind('session:new', function(session) {
1278 |
1279 | loadCSS('../saiku-chart-plus/css/plugin.css');
1280 |
1281 | loadJS('//www.google.com/jsapi');
1282 | loadJS("../saiku-chart-plus/js/google.js");
1283 |
1284 | loadJS('../saiku-chart-plus/js/highcharts.js');
1285 | loadJS('//code.highcharts.com/modules/exporting.js');
1286 |
1287 |
1288 | function new_workspace(args) {
1289 | // Add stats element
1290 | if (typeof args.workspace.chartPlus == "undefined") {
1291 | args.workspace.chartPlus = new ChartPlus({ workspace: args.workspace });
1292 | }
1293 | }
1294 |
1295 | function clear_workspace(args) {
1296 | if (typeof args.workspace.chartPlus != "undefined") {
1297 | $(args.workspace.chartPlus.nav).hide();
1298 | $(args.workspace.chartPlus.el).parents().find('.workspace_results table').show();
1299 | $(args.workspace.chartPlus.el).hide();
1300 | }
1301 | }
1302 |
1303 |
1304 | // Attach stats to existing tabs
1305 | for(var i = 0; i < Saiku.tabs._tabs.length; i++) {
1306 | var tab = Saiku.tabs._tabs[i];
1307 | new_workspace({
1308 | workspace: tab.content
1309 | });
1310 | };
1311 |
1312 | // Attach stats to future tabs
1313 | Saiku.session.bind("workspace:new", new_workspace);
1314 | Saiku.session.bind("workspace:clear", clear_workspace);
1315 | });
1316 |
--------------------------------------------------------------------------------
/saiku-server/saiku-chart-plus/plugin.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 IT4biz IT Solutions Ltda
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | * changed by it4biz.com.br
16 | */
17 |
18 | /**
19 | * Renders a chart for each workspace
20 | */
21 | var ChartPlus = Backbone.View.extend({
22 |
23 | initialize: function(args) {
24 | this.workspace = args.workspace;
25 |
26 | // Create a unique ID for use as the CSS selector
27 | this.id = _.uniqueId("chartPlus_");
28 | $(this.el).attr({ id: this.id });
29 |
30 | // Bind table rendering to query result event
31 | _.bindAll(this, "render", "receive_data", "process_data", "show",
32 | "setOptions");
33 |
34 | this.workspace.bind('query:result', this.receive_data);
35 |
36 | // Add chart button
37 | this.add_button();
38 | this.workspace.toolbar.chartPlus = this.show;
39 |
40 | // Listen to adjust event and rerender chart
41 | this.workspace.bind('workspace:adjust', this.render);
42 |
43 | // Create navigation
44 | this.nav = $(""+
45 | "
"+
46 | ""+
54 | ""+
59 | ""+
64 | ""+
345 | ""+
626 | "
"+
627 | "
");
628 |
629 |
630 |
631 |
632 |
633 | this.nav.find('a').click(this.setOptions);
634 |
635 | //function for menu
636 | $("#nav ul ").css({display: "none"}); // Opera Fix
637 | $("#nav li").hover(function(){
638 | $(this).find('ul:first').css({visibility: "visible",display: "none"}).show(400);
639 | },function(){
640 | $(this).find('ul:first').css({visibility: "hidden"});
641 | });
642 |
643 | // Append chart to workspace
644 | $(this.workspace.el).find('.workspace_results')
645 | .prepend($(this.el).hide())
646 | .prepend(this.nav.hide());
647 |
648 |
649 |
650 | },
651 |
652 | add_button: function() {
653 | var $chart_button =
654 | $('')
655 | .css({ 'background-image': "url('js/saiku/plugins/saiku-chart-plus/images/chart.png')",
656 | 'background-repeat':'no-repeat',
657 | 'background-position':'20% 50%'
658 | });
659 |
660 | var $chart_li = $('').append($chart_button);
661 | $(this.workspace.toolbar.el).find("ul").append($chart_li);
662 | },
663 |
664 | show: function(event, ui) {
665 | $(this.workspace.table.el).toggle();
666 | $(this.el).toggle();
667 | $(this.nav).toggle();
668 | $(event.target).toggleClass('on');
669 |
670 | if ($(event.target).hasClass('on')) {
671 | this.render();
672 | } else {
673 | this.workspace.table.render({ data: this.workspace.query.result.lastresult() });
674 | }
675 | },
676 |
677 | setOptions: function(event) {
678 | var type = $(event.target).attr('href').replace('#', '');
679 | var chartOptions=[];
680 | chartOptions.type=type;
681 |
682 | try {
683 | if(type=='geoChart' || type=='geoMap'){
684 | var region=$(event.target).attr('id');
685 | chartOptions.region=region;
686 | this.render(chartOptions);
687 | }else
688 | this.render(chartOptions);
689 | } catch (e) { }
690 |
691 | return false;
692 | },
693 |
694 | render: function(chartOptions) {
695 |
696 | if (! $(this.workspace.toolbar.el).find('.chartPlus').hasClass('on')) {
697 | return;
698 | }
699 |
700 | //configurações default
701 | var options = _.extend({
702 | canvas: this.id,
703 | width: $(this.workspace.el).find('.workspace_results').width() - 40,
704 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
705 | yAxisSize: 70,
706 | orientation: 'vertical',
707 | stacked: false,
708 | animate: false,
709 | showValues: false,
710 | legend: true,
711 | legendPosition:"top",
712 | legendAlign: "right",
713 | colors: ["#B40010", "#CCC8B4", "#DDB965", "#72839D", "#1D2D40"],
714 | serializeType: "highCharts",
715 | type: 'bar'
716 | }, chartOptions);
717 |
718 | //start serialization of data
719 | if(options.type!='pie' && options.type!='geoMap' && options.type!='geoChart'){
720 | var metadata=new Array();
721 | //numero de colunas
722 | var colNumberY=this.data.metadata.length-1;//-1 devido a coluna 0 armazena o valor de X
723 | var x=new Array();
724 | var y=new Array();
725 | for(var i=0; i < colNumberY; i++){
726 | y[i]=new Array();
727 | }
728 |
729 |
730 | if (this.data.resultset.length > 0 ) {
731 | $.each(this.data.resultset, function(key, value) {
732 | x[key]=value[0];
733 | for(var i=0; i < colNumberY; i++){
734 | y[i][key]=value[i+1];// +1 devido ao valor de x armazenado na coluna 0
735 | }
736 |
737 | });
738 | }
739 |
740 | var seriesData=[];
741 | for(var i=0; i < colNumberY; i++){
742 | seriesData[i]={
743 | name: this.data.metadata[i+1].colName,
744 | data: y[i]
745 | };
746 | }
747 | }else if(options.type=='pie' && options.type!='geoMap' && options.type!='geoChart'){
748 | if(this.data.metadata.length>0){
749 | var metadata=new Array();
750 | //numero de colunas
751 | var colNumber=this.data.metadata.length;
752 | var seriesData=new Array();
753 | var series=new Array();
754 | if (this.data.resultset.length > 0 ) {
755 | $.each(this.data.resultset, function(key, value) {
756 | series[key]=[value[0], value[1]];
757 | });
758 | }
759 |
760 | seriesData=[{
761 | type: 'pie',
762 | name: this.data.metadata[0].colName,
763 | data: series
764 | }];
765 | }else{
766 | return false;
767 | }
768 | }else if(options.type=='geoMap'){
769 | if(this.data.metadata.length>0){
770 | var series=[];
771 | //nome das colunas
772 | var column=[];
773 |
774 | column[0]=this.data.metadata[0].colName;
775 | column[1]=this.data.metadata[1].colName;
776 | series[0]=column;
777 |
778 |
779 | if (this.data.resultset.length > 0 ) {
780 | var data= this.data;
781 | $.each(this.data.resultset, function(key, value) {
782 | var array=[];
783 | array[0]=value[0];
784 | array[1]=value[1];
785 | array[2]=value[1];
786 | for(var i=2; i < data.metadata.length; i++){
787 | columnName=data.metadata[i].colName;
788 | value=value[i];
789 | array[2]+=', '+columnName+': '+value;
790 | }
791 | series[key+1]=array; // +1 devido ao nome das colunas
792 | });
793 | }
794 |
795 | }else{
796 | return false;
797 | }
798 |
799 | }else{//options.type=='geoChart'
800 | var series=[];
801 | //nome das colunas
802 | var column=[];
803 | for(var i=0; i < this.data.metadata.length; i++)
804 | column[i]=this.data.metadata[i].colName;
805 | series[0]=column;
806 |
807 | if (this.data.resultset.length > 0 ) {
808 | $.each(this.data.resultset, function(key, value) {
809 | series[key+1]=value; // +1 devido ao nome das colunas
810 | });
811 | }
812 | }
813 | //end serialization of data
814 |
815 | //start draw graphics
816 | if(options.type=='bar'){
817 | chart = new Highcharts.Chart({
818 | chart: {
819 | renderTo: this.id,
820 | type: 'bar',
821 | zoomType: 'x,y',
822 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
823 | width: $(this.workspace.el).find('.workspace_results').width() - 40
824 | },
825 | title: {
826 | text: '',
827 | x: -20 //center
828 | },
829 | credits: {
830 | text: 'Saiku Chart Plus Plugin by IT4biz',
831 | href: 'http://it4biz.github.com/SaikuChartPlus'
832 | },
833 | subtitle: {
834 | text: '',
835 | x: -20
836 | },
837 | xAxis: {
838 | categories: x
839 | },
840 | yAxis: {
841 | title: {
842 | text: ''
843 | },
844 | plotLines: [{
845 | value: 0,
846 | width: 1,
847 | color: '#808080'
848 | }]
849 | },
850 | tooltip: {
851 | formatter: function() {
852 | return ''+ this.series.name +'
'+
853 | this.x +': '+ this.y +'';
854 | }
855 | },
856 | legend: {
857 | layout: 'vertical',
858 | align: 'right',
859 | verticalAlign: 'top',
860 | x: -10,
861 | y: 100,
862 | borderWidth: 0
863 | },
864 | series: seriesData
865 | });
866 | }
867 | else if(options.type=='stackedBar')
868 | {
869 | chart = new Highcharts.Chart({
870 | chart: {
871 | renderTo: this.id,
872 | type: 'bar',
873 | zoomType: 'x,y',
874 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
875 | width: $(this.workspace.el).find('.workspace_results').width() - 40
876 | },
877 | title: {
878 | text: '',
879 | x: -20 //center
880 | },
881 | credits: {
882 | text: 'Saiku Chart Plus Plugin by IT4biz',
883 | href: 'http://it4biz.github.com/SaikuChartPlus'
884 | },
885 | subtitle: {
886 | text: '',
887 | x: -20
888 | },
889 | xAxis: {
890 | categories: x
891 | },
892 | yAxis: {
893 | title: {
894 | text: ''
895 | },
896 | plotLines: [{
897 | value: 0,
898 | width: 1,
899 | color: '#808080'
900 | }]
901 | },
902 | plotOptions: {
903 | series: {
904 | stacking: 'normal'
905 | }
906 | },
907 | tooltip: {
908 | formatter: function() {
909 | return ''+ this.series.name +'
'+
910 | this.x +': '+ this.y +'';
911 | }
912 | },
913 | legend: {
914 | layout: 'vertical',
915 | align: 'right',
916 | verticalAlign: 'top',
917 | x: -10,
918 | y: 100,
919 | borderWidth: 0
920 | },
921 | series: seriesData
922 | });
923 | }
924 | else if(options.type=='column')
925 | {
926 | chart = new Highcharts.Chart({
927 | chart: {
928 | renderTo: this.id,
929 | type: 'column',
930 | zoomType: 'x,y',
931 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
932 | width: $(this.workspace.el).find('.workspace_results').width() - 40
933 | },
934 | credits: {
935 | text: 'Saiku Chart Plus Plugin by IT4biz',
936 | href: 'http://it4biz.github.com/SaikuChartPlus'
937 | },
938 | title: {
939 | text: '',
940 | x: -20 //center
941 | },
942 | subtitle: {
943 | text: '',
944 | x: -20
945 | },
946 | xAxis: {
947 | categories: x,
948 | labels: {
949 | rotation: -90,
950 | align: 'right'
951 | }
952 | },
953 | yAxis: {
954 | title: {
955 | text: ''
956 | },
957 | plotLines: [{
958 | value: 0,
959 | width: 1,
960 | color: '#808080'
961 | }]
962 | },
963 | tooltip: {
964 | formatter: function() {
965 | return ''+ this.series.name +'
'+
966 | this.x +': '+ this.y +'';
967 | }
968 | },
969 | legend: {
970 | layout: 'vertical',
971 | align: 'right',
972 | verticalAlign: 'top',
973 | x: -10,
974 | y: 100,
975 | borderWidth: 0
976 | },
977 | series: seriesData
978 | });
979 | }
980 | else if(options.type=='stackedColumn')
981 | {
982 | chart = new Highcharts.Chart({
983 | chart: {
984 | renderTo: this.id,
985 | type: 'column',
986 | zoomType: 'x,y',
987 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
988 | width: $(this.workspace.el).find('.workspace_results').width() - 40
989 | },
990 | credits: {
991 | text: 'Saiku Chart Plus Plugin by IT4biz',
992 | href: 'http://it4biz.github.com/SaikuChartPlus'
993 | },
994 | title: {
995 | text: '',
996 | x: -20 //center
997 | },
998 | subtitle: {
999 | text: '',
1000 | x: -20
1001 | },
1002 | xAxis: {
1003 | categories: x,
1004 | labels: {
1005 | rotation: -90,
1006 | align: 'right'
1007 | }
1008 | },
1009 | yAxis: {
1010 | title: {
1011 | text: ''
1012 | },
1013 | plotLines: [{
1014 | value: 0,
1015 | width: 1,
1016 | color: '#808080'
1017 | }]
1018 | },
1019 | plotOptions: {
1020 | series: {
1021 | stacking: 'normal'
1022 | }
1023 | },
1024 | tooltip: {
1025 | formatter: function() {
1026 | return ''+ this.series.name +'
'+
1027 | this.x +': '+ this.y +'';
1028 | }
1029 | },
1030 | legend: {
1031 | layout: 'vertical',
1032 | align: 'right',
1033 | verticalAlign: 'top',
1034 | x: -10,
1035 | y: 100,
1036 | borderWidth: 0
1037 | },
1038 | series: seriesData
1039 | });
1040 | }
1041 | else if(options.type=='line')
1042 | {
1043 | chart = new Highcharts.Chart({
1044 | chart: {
1045 | renderTo: this.id,
1046 | type: 'line',
1047 | zoomType: 'x,y',
1048 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
1049 | width: $(this.workspace.el).find('.workspace_results').width() - 40
1050 | },
1051 | credits: {
1052 | text: 'Saiku Chart Plus Plugin by IT4biz',
1053 | href: 'http://it4biz.github.com/SaikuChartPlus'
1054 | },
1055 | title: {
1056 | text: '',
1057 | x: -20 //center
1058 | },
1059 | subtitle: {
1060 | text: '',
1061 | x: -20
1062 | },
1063 | xAxis: {
1064 | categories: x,
1065 | labels: {
1066 | rotation: -90,
1067 | align: 'right'
1068 | }
1069 | },
1070 | yAxis: {
1071 | title: {
1072 | text: ''
1073 | },
1074 | plotLines: [{
1075 | value: 0,
1076 | width: 1,
1077 | color: '#808080'
1078 | }]
1079 | },
1080 | tooltip: {
1081 | formatter: function() {
1082 | return ''+ this.series.name +'
'+
1083 | this.x +': '+ this.y +'';
1084 | }
1085 | },
1086 | legend: {
1087 | layout: 'vertical',
1088 | align: 'right',
1089 | verticalAlign: 'top',
1090 | x: -10,
1091 | y: 100,
1092 | borderWidth: 0
1093 | },
1094 | series: seriesData
1095 | });
1096 | }
1097 | else if(options.type=='pie')
1098 | {
1099 | chart = new Highcharts.Chart({
1100 | chart: {
1101 | renderTo: this.id,
1102 | plotBackgroundColor: null,
1103 | plotBorderWidth: null,
1104 | plotShadow: false,
1105 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
1106 | width: $(this.workspace.el).find('.workspace_results').width() - 40
1107 | },
1108 | credits: {
1109 | text: 'Saiku Chart Plus Plugin by IT4biz',
1110 | href: 'http://it4biz.github.com/SaikuChartPlus'
1111 | },
1112 | title: {
1113 | text: ''
1114 | },
1115 | tooltip: {
1116 | pointFormat: '{series.name}: {point.percentage}%',
1117 | percentageDecimals: 1
1118 | },
1119 | plotOptions: {
1120 | pie: {
1121 | allowPointSelect: true,
1122 | cursor: 'pointer',
1123 | dataLabels: {
1124 | enabled: true,
1125 | color: '#000000',
1126 | connectorColor: '#000000',
1127 | formatter: function() {
1128 | return ''+ this.point.name +': '+ this.percentage.toFixed(1) +' %';
1129 | }
1130 | }
1131 | }
1132 | },
1133 | series: seriesData
1134 | });
1135 | }
1136 | else if(options.type=='geoChart')
1137 | {
1138 | var data = google.visualization.arrayToDataTable(series);
1139 | var optionsMap;
1140 |
1141 | if(options.region=='world'){
1142 | optionsMap = {
1143 | width: $(this.workspace.el).find('.workspace_results').width() - 40,
1144 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
1145 | datalessRegionColor: 'F5F5F5',
1146 | region: options.region,
1147 | displayMode: 'markers'
1148 | };
1149 | }else{
1150 | optionsMap = {
1151 | width: $(this.workspace.el).find('.workspace_results').width() - 40,
1152 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
1153 | datalessRegionColor: 'F5F5F5',
1154 | region: options.region,
1155 | resolution: 'provinces',
1156 | displayMode: 'regions'
1157 | };
1158 | }
1159 |
1160 | var geoChart = new google.visualization.GeoChart(document.getElementById(this.id));
1161 | geoChart.draw(data, optionsMap);
1162 |
1163 | }
1164 | else if(options.type=='geoMap')
1165 | {
1166 | var data =new google.visualization.DataTable();
1167 | data.addRows(series.length);
1168 | data.addColumn('string', series[0][0]);
1169 | data.addColumn('number', series[0][1]);
1170 |
1171 | for (var i=1; i < series.length; i++) {
1172 | data.setCell(i, 0, series[i][0]);
1173 | data.setCell(i, 1, series[i][1], series[i][2]);
1174 | };
1175 |
1176 | var options = {
1177 | width: $(this.workspace.el).find('.workspace_results').width() - 40,
1178 | height: $(this.workspace.el).find('.workspace_results').height() - 40,
1179 | colors: [0xE0FFD4, 0xA5EF63, 0x50AA00, 0x267114],
1180 | region: options.region,
1181 | dataMode: 'regions'
1182 | };
1183 |
1184 | var geoMap = new google.visualization.GeoMap(document.getElementById(this.id));
1185 | google.visualization.events.addListener(geoMap, "error", function errorHandler(e) {
1186 | google.visualization.errors.removeError(e.id);
1187 | });
1188 |
1189 | geoMap.draw(data, options);
1190 |
1191 | }
1192 | /*********End charts draw**************/
1193 | },
1194 |
1195 | receive_data: function(args) {
1196 | return _.delay(this.process_data, 0, args);
1197 | },
1198 |
1199 | process_data: function(args) {
1200 | this.data = {};
1201 | this.data.resultset = [];
1202 | this.data.metadata = [];
1203 | this.data.height = 0;
1204 | this.data.width = 0;
1205 |
1206 | if (args.data.cellset && args.data.cellset.length > 0) {
1207 |
1208 | var lowest_level = 0;
1209 |
1210 | for (var row = 0; row < args.data.cellset.length; row++) {
1211 | if (args.data.cellset[row][0].type == "ROW_HEADER_HEADER") {
1212 | this.data.metadata = [];
1213 | for (var field = 0; field < args.data.cellset[row].length; field++) {
1214 | if (args.data.cellset[row][field].type == "ROW_HEADER_HEADER") {
1215 | this.data.metadata.shift();
1216 | lowest_level = field;
1217 | }
1218 |
1219 | this.data.metadata.push({
1220 | colIndex: field,
1221 | colType: typeof(args.data.cellset[row + 1][field].value) !== "number" &&
1222 | isNaN(args.data.cellset[row + 1][field].value
1223 | .replace(/[^a-zA-Z 0-9.]+/g,'')) ? "String" : "Numeric",
1224 | colName: args.data.cellset[row][field].value
1225 | });
1226 | }
1227 | } else if (args.data.cellset[row][0].value !== "null" && args.data.cellset[row][0].value !== "") {
1228 | var record = [];
1229 | this.data.width = args.data.cellset[row].length;
1230 | for (var col = lowest_level; col < args.data.cellset[row].length; col++) {
1231 | var value = args.data.cellset[row][col].value;
1232 | // check if the resultset contains the raw value, if not try to parse the given value
1233 | if (args.data.cellset[row][col].properties.raw && args.data.cellset[row][col].properties.raw !== "null" && col>0)
1234 | {
1235 | value = parseFloat(args.data.cellset[row][col].properties.raw);
1236 | } else if (typeof(args.data.cellset[row][col].value) !== "number" &&
1237 | parseFloat(args.data.cellset[row][col].value.replace(/[^a-zA-Z 0-9.]+/g,'')) && col>0)
1238 | {
1239 | value = parseFloat(args.data.cellset[row][col].value.replace(/[^a-zA-Z 0-9.]+/g,''));
1240 | }
1241 | record.push(value);
1242 | }
1243 | this.data.resultset.push(record);
1244 | }
1245 | }
1246 | this.data.height = this.data.resultset.length;
1247 | this.render();
1248 | } else {
1249 | $(this.el).text("No results");
1250 | }
1251 | }
1252 | });
1253 |
1254 | function loadCSS(file){
1255 |
1256 | var headID = document.getElementsByTagName("head")[0];
1257 | var cssNode = document.createElement('link');
1258 | cssNode.type = 'text/css';
1259 | cssNode.rel = 'stylesheet';
1260 | cssNode.href = file;
1261 | cssNode.media = 'screen';
1262 | headID.appendChild(cssNode);
1263 | }
1264 |
1265 | function loadJS(file){
1266 |
1267 | var headID = document.getElementsByTagName("head")[0];
1268 | var newScript = document.createElement('script');
1269 | newScript.type = 'text/javascript';
1270 | newScript.src = file;
1271 | headID.appendChild(newScript);
1272 | }
1273 |
1274 | /**
1275 | * Start Plugin
1276 | */
1277 | Saiku.events.bind('session:new', function(session) {
1278 |
1279 | loadCSS('js/saiku/plugins/saiku-chart-plus/css/plugin.css');
1280 |
1281 | loadJS('//www.google.com/jsapi');
1282 | loadJS("js/saiku/plugins/saiku-chart-plus/js/google.js");
1283 |
1284 | loadJS('js/saiku/plugins/saiku-chart-plus/js/highcharts.js');
1285 | loadJS('//code.highcharts.com/modules/exporting.js');
1286 |
1287 |
1288 | function new_workspace(args) {
1289 | // Add stats element
1290 | if (typeof args.workspace.chartPlus == "undefined") {
1291 | args.workspace.chartPlus = new ChartPlus({ workspace: args.workspace });
1292 | }
1293 | }
1294 |
1295 | function clear_workspace(args) {
1296 | if (typeof args.workspace.chartPlus != "undefined") {
1297 | $(args.workspace.chartPlus.nav).hide();
1298 | $(args.workspace.chartPlus.el).parents().find('.workspace_results table').show();
1299 | $(args.workspace.chartPlus.el).hide();
1300 | }
1301 | }
1302 |
1303 |
1304 | // Attach stats to existing tabs
1305 | for(var i = 0; i < Saiku.tabs._tabs.length; i++) {
1306 | var tab = Saiku.tabs._tabs[i];
1307 | new_workspace({
1308 | workspace: tab.content
1309 | });
1310 | };
1311 |
1312 | // Attach stats to future tabs
1313 | Saiku.session.bind("workspace:new", new_workspace);
1314 | Saiku.session.bind("workspace:clear", clear_workspace);
1315 | });
1316 |
--------------------------------------------------------------------------------