Thursday, April 14, 2016

Create Graphs and Charts from SharePoint lists using charts.js

Chart.js is an HTML5 responsive library to build beautiful charts.

Now that charts web part is no longer available in SharePoint 2013, I decide to go for this option. We can also use excel services , but I like this better :)


We will be using REST api to pull items from the list and draw out charts
Create a canvas tag
<canvas id="myChart" width="600" height="400"></canvas>
Include  jquery.js , chart.js and underscore.js  and the below script will do the work.

Make sure to change the List name and use internal name for columns instead of display name. Add this to the script editor or content editor web parts . If you are on one site and want to get data from another site you have to modify the code.

var chartX = []; //X-Axis Labels
var chartY = []; //Y-Axis Values

var chartJs = "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js";

var chartId = "myChart"; //Chart Canvas Div    
var charts = ["Line", "Bar", "Radar", "Polar Area", "Pie", "Doughnut"];
var colors = ["#009EA0", "#A7A9AC", "#D15F27", "#BAD80A", "#E0AA0F", "#754760", "#373535"]

var listName = "Incoming Requests"; //Data List Name
var xAxisName = "Request_x0020_Category"; //X-Axis Label Names from List
var yAxisName = "Time_x0020_Calc"; //Y-Axis Values from List

//Set chart number to render different charts
// 0 = Line Chart
// 1 = Bar Chart
// 2 = Radar Chart 
// 3 = Polar Area Chart
// 4 = Pie Chart
// 5 = Doughnut Chart    
var chartNumber = 3;
//Set group by boolean to create chart based on count of x Axis 
var boolGroupByXAxis = true;
var numberOfItemsFromList = null; //Limit number of items returned from the list , for unlimited items type null 

$(document).ready(function() {

    console.log(_spPageContextInfo.webAbsoluteUrl);
    var Url = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('" + listName + "')/items"; //
    if (numberOfItemsFromList != null) {
        Url = Url + "?$top=" + numberOfItemsFromList;
    }
    getItems(Url, boolGroupByXAxis, charts[chartNumber]);




});

function getItems(url, groupby, chartType) {
    $.ajax({
        url: url,
        method: 'GET',
        beforeSend: function(XMLHttpRequest) {

            XMLHttpRequest.setRequestHeader("Accept", "application/json; odata=verbose");
        },

        cache: true,
        error: function(data) {},

        success: function(data) {
            if (!groupby) {
                $.each(data.d.results, function(i, item) {
                    chartX.push(item[xAxisName]);
                    chartY.push(item[yAxisName]);
                });
            } else {
                var arrCount = _.countBy(data.d.results, function(obj) {
                    return obj[xAxisName];
                });
                console.log(arrCount);
                chartX = _.keys(arrCount);
                chartY = _.values(arrCount);
            }
            loadJS(chartJs, function() {

                //Generate Data
                var data = [];
                if (chartType == "Line" || chartType == "Bar" || chartType == "Radar") {
                    data = {
                        labels: this.chartX,
                        datasets: [{
                            fillColor: "rgba(0,160,175,0.5)",
                            strokeColor: "rgba(0,160,175,0.8)",
                            highlightFill: "rgba(0,160,175,0.75)",
                            highlightStroke: "rgba(0,160,175,1)",
                            data: this.chartY
                        }]
                    };
                } else if (chartType == "Pie" || chartType == "Doughnut" || chartType == "Polar Area") {
                    $.each(chartX, function(i, item) {
                        data.push({
                            value: chartY[i],
                            color: colors[i],
                            label: item
                        });
                    });
                    console.log(data);

                }

                //Display Chart
                var ctx = document.getElementById(chartId).getContext("2d");
                switch (chartType) {
                    case "Line":
                        var myNewChart = new Chart(ctx).Line(data);
                        break;
                    case "Bar":
                        var myNewChart = new Chart(ctx).Bar(data);
                        break;
                    case "Radar":
                        var myNewChart = new Chart(ctx).Radar(data);
                        break;
                    case "Polar Area":
                        var myNewChart = new Chart(ctx).PolarArea(data);
                        break;
                    case "Pie":
                        var myNewChart = new Chart(ctx).Pie(data);
                        break;
                    case "Doughnut":
                        var myNewChart = new Chart(ctx).Doughnut(data);
                        break;
                    default:
                        var myNewChart = new Chart(ctx).Line(data)
                }

            });
        }
    });
}


function loadJS(src, callback) {
    var s = document.createElement('script');
    s.src = src;
    s.async = true;
    s.onreadystatechange = s.onload = function() {
        var state = s.readyState;
        if (!callback.done && (!state || /loaded|complete/.test(state))) {
            callback.done = true;
            callback();
        }
    };