Optional: Add charts

Optional: Add charts

Sometimes, it's better to display data as charts and you can easily do it by using one of JavaScript charting libraries. Chart.js is the perfect choice.

Add Chart.js CDN URL to "JavaScript URLs":

 

Add HTML to "HTML to append" editor:

<div id="comp-issues-cont" style="padding:10px;"> <canvas style="max-width:400px; max-height:400px;" /> <span style="display: inline-block; vertical-align: top; padding-top: 40px; font-size: 26px;" /> </div>

We are going to improve the JavaScript:

  • To fetch number of issues in To Do status

  • To display a pie chart that shows number of issues in To Do, Completed and Other statuses

 Here is the Jira Cloud code with the AMD module declaration omitted (in Jira Data Center, the AMD module is required to access the API object).

var $msgDiv = $("#comp-issues-cont"); // find attached DOM element API.getGadgetContentEl().append($msgDiv); // function to call from success ajax callbacks var showInfo = function(created, done) { if (created !== undefined && done !== undefined) { // only if 2 vars are defined // Chart.js magic new Chart($msgDiv.find("canvas").get(0), { type: "pie", data: { labels: ["Created", "Done"], datasets: [{ label: "# of Issues", data: [created, done], backgroundColor: [ "rgba(255, 0, 0, 0.7)", "rgba(0, 255, 0, 0.7)" ] }] } }); $msgDiv.find("span").append("Created: " + created + "</br>Done: " + done); API.resize(); } }; // function for error displaying var showError = function(url) { $msgDiv.empty(); AJS.messages["error"]($msgDiv, { title : "Error!", body : "Failed to retrieve data for URL: " + url }); API.resize(); }; var url, created, done; // initially are undefined url = "/rest/api/2/search/jql?jql=" + encodeURIComponent("createdDate > startOfMonth() and createdDate < endOfMonth()") + "&maxResults=5000"; // in Jira Cloud (Forge), you can call the Jira REST API using requestJira (https://developer.atlassian.com/platform/forge/apis-reference/ui-api-bridge/requestJira/) requestJira(url, { method: "GET", headers: { 'Accept': 'application/json' }, }).then(response => { if (!response.ok) { throw new Error("HTTP " + response.status); } return response.json(); }).then(data => { created = data.issues.length; showInfo(created, done); // call it 2 times since ajax methods are asynchronous and we are not sure about their completion order }).catch(() => { showError(url); }); url = "/rest/api/2/search/jql?jql=" + encodeURIComponent("status = Done AND status changed to Done after startOfMonth() before endOfMonth()") + "&maxResults=5000"; // in Jira Cloud (Forge), you can call the Jira REST API using requestJira (https://developer.atlassian.com/platform/forge/apis-reference/ui-api-bridge/requestJira/) requestJira(url, { method: "GET", headers: { 'Accept': 'application/json' }, }).then(response => { if (!response.ok) { throw new Error("HTTP " + response.status); } return response.json(); }).then(data => { done = data.issues.length; showInfo(created, done); // call it 2 times since ajax methods are asynchronous and we are not sure about their completion order }).catch(() => { showError(url); });


Jira DC version:

define("_ujgrestAndCharts", [ "jquery", "_ujgUtil" ], function($, util) { var MyGadget = function(API) { var $msgDiv = $("#comp-issues-cont"); // find attached DOM element API.getGadgetContentEl().append($msgDiv); // function to call from success ajax callbacks var showInfo = function(created, done) { if (created !== undefined && done !== undefined) { // only if 2 vars are defined // Chart.js magic new Chart($msgDiv.find("canvas").get(0), { type: "pie", data: { labels: ["Created", "Done"], datasets: [{ label: "# of Issues", data: [created, done], backgroundColor: [ "rgba(255, 0, 0, 0.7)", "rgba(0, 255, 0, 0.7)" ] }] } }); $msgDiv.find("span").append("Created: " + created + "</br>Done: " + done); API.resize(); } }; // function for error displaying var showError = function(url) { $msgDiv.empty(); AJS.messages["error"]($msgDiv, { title : "Error!", body : "Failed to retrieve data for URL: " + url }); API.resize(); }; var url, created, done; // initially are undefined url = "/rest/api/2/search?jql=" + encodeURIComponent("createdDate > startOfMonth() and createdDate < endOfMonth()") + "&maxResults=0"; // make a call for number of created issues // util.makeAjaxCall is an internal wrapper functions, please make Ajax call via AP.request for JIRA Cloud and $.ajax for JIRA Server $.ajax ({ url: url, dataType: "json", success : function(data) { created = data.total; showInfo(created, done); // call it 2 times since ajax methods are asynchronous and we are not sure about thier completion order }, error : function(data) { showError(url); } }); url = "/rest/api/2/search?jql=" + encodeURIComponent("status = Done AND status changed to Done after startOfMonth() before endOfMonth()") + "&maxResults=0"; // util.makeAjaxCall is an internal wrapper functions, please make Ajax call via AP.request for JIRA Cloud and $.ajax for JIRA Server $.ajax ({ url: url, dataType: "json", success : function(data) { done = data.total; showInfo(created, done); // call it 2 times since ajax methods are asynchronous and we are not sure about thier completion order }, error : function(data) { showError(url); } }); }; return MyGadget; });

As result, we have a beautiful and colorful chart: