├── BarChartWebPart.txt ├── IncludeScriptsWebPart.txt ├── PieChartWebPart.txt ├── README.md ├── StackedBarChartWebPart.txt ├── engagementcharts.query.js ├── engagementcharts.utilities.js └── engagementcharts.viewmodel.js /BarChartWebPart.txt: -------------------------------------------------------------------------------- 1 | 2 | 9 | 15 |
16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /IncludeScriptsWebPart.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PieChartWebPart.txt: -------------------------------------------------------------------------------- 1 | 2 | 9 | 15 |
16 |
17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ChartsInSharePoint2013 2 | ====================== 3 | 4 | Building Charts in SharePoint 2013 using JavaScript and REST 5 | -------------------------------------------------------------------------------- /StackedBarChartWebPart.txt: -------------------------------------------------------------------------------- 1 | 2 | 9 | 15 |
16 |
17 | 18 | -------------------------------------------------------------------------------- /engagementcharts.query.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var EngagementChartBuilder = window.EngagementChartBuilder || {}; 4 | 5 | //The module for executing a REST query 6 | EngagementChartBuilder.RESTQuery = function (listTitle, query) { 7 | var execute = function (listTitle, query) { 8 | var restUrl = _spPageContextInfo.webServerRelativeUrl + 9 | "/_api/web/lists/getByTitle('" + listTitle + "')/items"; 10 | if (query != "") { 11 | restUrl = restUrl + "?" + query; 12 | } 13 | var deferred = $.ajax({ 14 | url: restUrl, 15 | type: "GET", 16 | headers: { 17 | "accept": "application/json;odata=verbose", 18 | "X-RequestDigest": $("#__REQUESTDIGEST").val() 19 | } 20 | }); 21 | 22 | return deferred.promise() 23 | }; 24 | 25 | return { 26 | execute: execute 27 | } 28 | }(); 29 | 30 | -------------------------------------------------------------------------------- /engagementcharts.utilities.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var EngagementChartBuilder = window.EngagementChartBuilder || {}; 4 | 5 | EngagementChartBuilder.Utilities = function () { 6 | var buildCategoryCounts = function (countArray, dataArray) { 7 | if (countArray == undefined) { 8 | countArray = []; 9 | } 10 | 11 | for (var i = 0; i < dataArray.length; i++) { 12 | var currValue = dataArray[i]; 13 | var found = false; 14 | for (var j = 0; j < countArray.length; j++) { 15 | if (countArray[j][0] == currValue) { 16 | found = true; 17 | var newCount = countArray[j][1]; 18 | countArray[j][1] = newCount + 1; 19 | } 20 | } 21 | if (!found) { 22 | countArray.push([currValue, 1]); 23 | } 24 | } 25 | return countArray; 26 | }, 27 | loadPieChart = function (countArray, divId, chartTitle) { 28 | //Build Pie Chart 29 | Highcharts.setOptions({ 30 | }) 31 | $(divId).highcharts({ 32 | chart: { 33 | plotBackgroundColor: null, 34 | plotBorderWidth: null, 35 | plotShadow: false 36 | }, 37 | credits: { 38 | enabled: false 39 | }, 40 | title: { 41 | text: chartTitle 42 | }, 43 | tooltip: { 44 | pointFormat: '{series.name}: {point.y}', 45 | percentageDecimals: 0 46 | }, 47 | plotOptions: { 48 | pie: { 49 | allowPointSelect: true, 50 | cursor: 'pointer', 51 | dataLabels: { 52 | enabled: false 53 | }, 54 | showInLegend: true 55 | } 56 | }, 57 | series: [{ 58 | type: 'pie', 59 | name: chartTitle, 60 | data: countArray 61 | }] 62 | }); 63 | }, 64 | loadBarChart = function (xCategories, seriesData, divId, chartTitle, yAxisTitle) { 65 | //Build Bar Chart 66 | $(divId).highcharts({ 67 | chart: { 68 | type: 'bar' 69 | }, 70 | credits: { 71 | enabled: false 72 | }, 73 | title: { 74 | text: chartTitle 75 | }, 76 | xAxis: { 77 | categories: xCategories 78 | }, 79 | yAxis: { 80 | min: 0, 81 | title: { 82 | text: yAxisTitle 83 | } 84 | }, 85 | legend: { 86 | enabled: false 87 | }, 88 | plotOptions: { 89 | bar: { 90 | dataLabels: { 91 | enabled: false 92 | } 93 | }, 94 | series: { 95 | animation: false 96 | } 97 | }, 98 | series: [{ 99 | name: yAxisTitle, 100 | data: seriesData 101 | }] 102 | }); 103 | }, 104 | loadStackedBarChart = function (xCategories, seriesData, divId, chartTitle, yAxisTitle) { 105 | //Build Stacked Bar Chart 106 | $(divId).highcharts({ 107 | chart: { 108 | type: 'bar' 109 | }, 110 | credits: { 111 | enabled: false 112 | }, 113 | title: { 114 | text: chartTitle 115 | }, 116 | xAxis: { 117 | categories: xCategories 118 | }, 119 | yAxis: { 120 | min: 0, 121 | title: { 122 | text: yAxisTitle 123 | } 124 | }, 125 | legend: { 126 | backgroundColor: '#FFFFFF', 127 | reversed: true 128 | }, 129 | plotOptions: { 130 | series: { 131 | animation: false, 132 | stacking: 'normal' 133 | } 134 | }, 135 | series: seriesData 136 | }); 137 | } 138 | return { 139 | buildCategoryCounts: buildCategoryCounts, 140 | loadPieChart: loadPieChart, 141 | loadBarChart: loadBarChart, 142 | loadStackedBarChart: loadStackedBarChart 143 | } 144 | }(); 145 | -------------------------------------------------------------------------------- /engagementcharts.viewmodel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var EngagementChartBuilder = window.EngagementChartBuilder || {}; 4 | 5 | EngagementChartBuilder.EngagementsPieChart = function () { 6 | var load = function () { 7 | $.when( 8 | //Independent Engagements List - retrieving Engagement Type field to get Enterprise or Rebel type 9 | EngagementChartBuilder.RESTQuery.execute("Independent%20Engagements", "$select=Engagement_x0020_Type"), 10 | //Rebel Engagements List 11 | EngagementChartBuilder.RESTQuery.execute("Rebel%20Engagements", "$select=ID"), 12 | //Empire Engagements List 13 | EngagementChartBuilder.RESTQuery.execute("Empire%20Engagements", "$select=ID") 14 | ).done( 15 | function (engagements1, engagements2, engagements3) { 16 | var dataArray = []; 17 | var countArray = []; 18 | //Add count of Rebel Engagements list 19 | countArray.push(["Rebel", engagements2[0].d.results.length]); 20 | //Add count of Empire Engagements list 21 | countArray.push(["Empire", engagements3[0].d.results.length]); 22 | //Get data from Independent Engagements list 23 | var results = engagements1[0].d.results; 24 | for (var i = 0; i < results.length; i++) { 25 | var engagementType = results[i].Engagement_x0020_Type.results; 26 | for (var j = 0; j < engagementType.length; j++) { 27 | dataArray.push(engagementType[j]); 28 | } 29 | } 30 | countArray = EngagementChartBuilder.Utilities.buildCategoryCounts(countArray, dataArray); 31 | //Build Chart 32 | EngagementChartBuilder.Utilities.loadPieChart(countArray, "#engagementPieChart", "Engagements"); 33 | } 34 | ).fail( 35 | function (engagements1, engagements2, engagements3) { 36 | $("#engagementPieChart").html("An error has occurred."); 37 | } 38 | ); 39 | }; 40 | 41 | return { 42 | load: load 43 | } 44 | }(); 45 | 46 | EngagementChartBuilder.LeaderEngagementsByStatusChart = function () { 47 | var load = function () { 48 | $.when( 49 | //Rebel Engagements List 50 | EngagementChartBuilder.RESTQuery.execute("Rebel%20Engagements", "$select=Leader,Status"), 51 | //Empire Engagements List 52 | EngagementChartBuilder.RESTQuery.execute("Empire%20Engagements", "$select=Leader,Status") 53 | ).done( 54 | function (engagements1, engagements2) { 55 | var data = []; 56 | //Get results from Rebel Engagements 57 | var results = engagements1[0].d.results; 58 | for (var i = 0; i < results.length; i++) { 59 | var found = false; 60 | for (var j = 0; j < data.length; j++) { 61 | if (data[j].leaderName == results[i].Leader && data[j].statusName == results[i].Status) { 62 | data[j].statusCount = data[j].statusCount + 1; 63 | found = true; 64 | } 65 | } 66 | if (!found) { 67 | data.push(new EngagementChartBuilder.StatusByLeader(results[i].Leader, results[i].Status, 1)); 68 | } 69 | } 70 | //Get results from Empire Engagements Engagements 71 | var results = engagements2[0].d.results; 72 | for (var i = 0; i < results.length; i++) { 73 | var found = false; 74 | for (var j = 0; j < data.length; j++) { 75 | if (data[j].leaderName == results[i].Leader && data[j].statusName == results[i].Status) { 76 | data[j].statusCount = data[j].statusCount + 1; 77 | found = true; 78 | } 79 | } 80 | if (!found) { 81 | data.push(new EngagementChartBuilder.StatusByLeader(results[i].Leader, results[i].Status, 1)); 82 | } 83 | } 84 | //Put data into format for stacked bar chart 85 | var seriesData = []; 86 | var xCategories = []; 87 | var xStatus = []; 88 | var i, j, cat, stat; 89 | //Get Categories (Leader Name) 90 | for (i = 0; i < data.length; i++) { 91 | cat = data[i].leaderName; 92 | if (xCategories.indexOf(cat) === -1) { 93 | xCategories[xCategories.length] = cat; 94 | } 95 | } 96 | //Get Status values 97 | for (i = 0; i < data.length; i++) { 98 | stat = data[i].statusName; 99 | if (xStatus.indexOf(stat) === -1) { 100 | xStatus[xStatus.length] = stat; 101 | } 102 | } 103 | //Create initial series data with 0 values 104 | for (i = 0; i < xStatus.length; i++) { 105 | var dataArray = []; 106 | for (j = 0; j < xCategories.length; j++) { 107 | dataArray.push(0); 108 | } 109 | seriesData.push({ name: xStatus[i], data: dataArray }); 110 | } 111 | //Cycle through data to assign counts to the proper location in the series data 112 | for (i = 0; i < data.length; i++) { 113 | var leaderIndex = xCategories.indexOf(data[i].leaderName); 114 | for(j = 0; j < seriesData.length; j++){ 115 | if(seriesData[j].name == data[i].statusName){ 116 | seriesData[j].data[leaderIndex] = data[i].statusCount; 117 | break; 118 | } 119 | } 120 | } 121 | //Build Chart 122 | EngagementChartBuilder.Utilities.loadStackedBarChart(xCategories, seriesData, "#engagementsByStatusChart", "Engagements by Status", "Total Engagements"); 123 | } 124 | ); 125 | }; 126 | 127 | return { 128 | load: load 129 | } 130 | }(); 131 | 132 | EngagementChartBuilder.LeaderEngagementsChart = function () { 133 | var load = function () { 134 | $.when( 135 | //Rebel Engagements List 136 | EngagementChartBuilder.RESTQuery.execute("Rebel%20Engagements", "$select=Leader"), 137 | //Empire Engagements List 138 | EngagementChartBuilder.RESTQuery.execute("Empire%20Engagements", "$select=Leader") 139 | ).done( 140 | function (engagements1, engagements2) { 141 | var dataArray = []; 142 | var countArray = []; 143 | //Get data from Rebel Engagements list 144 | var results = engagements1[0].d.results; 145 | for (var i = 0; i < results.length; i++) { 146 | var leader = results[i].Leader; 147 | dataArray.push(leader); 148 | } 149 | //Get data from Empire Engagements list 150 | var results = engagements2[0].d.results; 151 | for (var i = 0; i < results.length; i++) { 152 | var leader = results[i].Leader; 153 | dataArray.push(leader); 154 | } 155 | countArray = EngagementChartBuilder.Utilities.buildCategoryCounts(countArray, dataArray); 156 | //Put data into format for bar chart 157 | var seriesData = []; 158 | var xCategories = []; 159 | for (var i = 0; i < countArray.length; i++) { 160 | xCategories.push(countArray[i][0]); 161 | seriesData.push(countArray[i][1]); 162 | } 163 | //Build Chart 164 | EngagementChartBuilder.Utilities.loadBarChart(xCategories, seriesData, "#engagementsByLeaderChart", "Engagements by Person", "Total Engagements"); 165 | } 166 | ).fail( 167 | function (engagements1, engagements2) { 168 | $("#engagementsByLeaderChart").html("An error has occurred."); 169 | } 170 | ); 171 | }; 172 | 173 | return { 174 | load: load 175 | } 176 | }(); 177 | 178 | //object for holding a category instance 179 | EngagementChartBuilder.StatusByLeader = function (name, status, count) { 180 | var leaderName = name, 181 | statusName = status, 182 | statusCount = count 183 | 184 | return { 185 | leaderName: name, 186 | statusName: statusName, 187 | statusCount: statusCount 188 | } 189 | } 190 | --------------------------------------------------------------------------------