|
| 1 | +// $(document).ready(function() { |
| 2 | +// $('#datatabletest').DataTable(); |
| 3 | +// }); |
| 4 | + |
| 5 | +// Fetch data from django rest API |
| 6 | +fetch('http://localhost:8000/tickets/api/tickets') |
| 7 | + .then(response => { |
| 8 | + return response.json(); |
| 9 | + }) |
| 10 | + .then(data => { |
| 11 | + console.log(data); |
| 12 | + drawGraphs(data); |
| 13 | + }); |
| 14 | + |
| 15 | +function drawGraphs(data) { |
| 16 | + let ndx = crossfilter(data); |
| 17 | + drawTicketTypePieChart(ndx); |
| 18 | + drawPriorityPieChart(ndx); |
| 19 | + drawAssignedToRowChart(ndx); |
| 20 | + drawStatusPieChart(ndx); |
| 21 | + drawUpvotesRowChart(ndx); |
| 22 | + drawStatusByMonthBarChart(ndx); |
| 23 | + // drawDataTable(ndx); |
| 24 | + dc.renderAll(); |
| 25 | +} |
| 26 | + |
| 27 | +// Status by month |
| 28 | +function drawStatusByMonthBarChart(ndx) { |
| 29 | + var dateCreatedDim = ndx.dimension(d => d.created_date.substring(0, 10)); |
| 30 | + var statusGroup = dateCreatedDim |
| 31 | + .group() |
| 32 | + .reduce(reduceAdd, reduceRemove, reduceInitial); |
| 33 | + |
| 34 | + function reduceAdd(i, d) { |
| 35 | + i[d.status] = (i[d.status] || 0) + 1; |
| 36 | + return i; |
| 37 | + } |
| 38 | + function reduceRemove(i, d) { |
| 39 | + i[d.status] = (i[d.status] || 0) - 1; |
| 40 | + return i; |
| 41 | + } |
| 42 | + function reduceInitial() { |
| 43 | + return {}; |
| 44 | + } |
| 45 | + |
| 46 | + print_filter(statusGroup); |
| 47 | + |
| 48 | + // Stacked bar chart status by month |
| 49 | + dc.barChart('#statusByMonthBarChart') |
| 50 | + .width(470) |
| 51 | + .height(350) |
| 52 | + .dimension(dateCreatedDim) |
| 53 | + .group(statusGroup, 'New', d => d.value['New']) |
| 54 | + .stack(statusGroup, 'In Progress', d => d.value['In Progress']) |
| 55 | + .stack(statusGroup, 'Resolved', d => d.value['Resolved']) |
| 56 | + .xAxisLabel('Date', 25) |
| 57 | + .yAxisLabel('Number of Tickets', 25) |
| 58 | + .useViewBoxResizing(true) |
| 59 | + .xUnits(dc.units.ordinal) |
| 60 | + .renderHorizontalGridLines(true) |
| 61 | + .ordinalColors(['grey', 'orange', 'green']) |
| 62 | + .gap(60) |
| 63 | + .renderTitle(true) |
| 64 | + .title(function(d) { |
| 65 | + return [ |
| 66 | + d.key + '\n', |
| 67 | + 'New: ' + (d.value['New'] || '0'), |
| 68 | + 'In Progress: ' + (d.value['In Progress'] || '0'), |
| 69 | + 'Resolved: ' + (d.value['Resolved'] || '0') |
| 70 | + ].join('\n'); |
| 71 | + }) |
| 72 | + .margins({ top: 30, left: 60, right: 20, bottom: 70 }) |
| 73 | + .x(d3.scaleOrdinal()); |
| 74 | +} |
| 75 | + |
| 76 | +// TicketType Pie Chart |
| 77 | +function drawTicketTypePieChart(ndx) { |
| 78 | + let ticketTypeDim = ndx.dimension(d => d.ticket_type); |
| 79 | + let ticketTypeGroup = ticketTypeDim.group(); |
| 80 | + |
| 81 | + // Pie chart |
| 82 | + dc.pieChart('#ticketTypePieChart') |
| 83 | + .radius(120) |
| 84 | + .minAngleForLabel(0.2) |
| 85 | + .dimension(ticketTypeDim) |
| 86 | + .group(ticketTypeGroup) |
| 87 | + .ordinalColors(['#0D324D', '#73EEDC']) |
| 88 | + .height(295) |
| 89 | + .width(500) |
| 90 | + .label(d => d.key + ': ' + d.value) |
| 91 | + // .cx(330) |
| 92 | + // .cy(150) |
| 93 | + // .legend( |
| 94 | + // dc |
| 95 | + // .legend() |
| 96 | + // .x(30) |
| 97 | + // .y(65) |
| 98 | + // .autoItemWidth(true) |
| 99 | + // .itemHeight(32) |
| 100 | + // .gap(12) |
| 101 | + // ) |
| 102 | + .useViewBoxResizing(true); |
| 103 | +} |
| 104 | + |
| 105 | +// Priority Pie Chart |
| 106 | +function drawPriorityPieChart(ndx) { |
| 107 | + let priorityDim = ndx.dimension(d => d.priority); |
| 108 | + let priorityGroup = priorityDim.group(); |
| 109 | + |
| 110 | + // Priority Pie chart |
| 111 | + dc.pieChart('#priorityPieChart') |
| 112 | + .radius(120) |
| 113 | + .minAngleForLabel(0.2) |
| 114 | + .dimension(priorityDim) |
| 115 | + .group(priorityGroup) |
| 116 | + .ordinalColors(['green', 'orange', 'red']) |
| 117 | + .height(295) |
| 118 | + .width(500) |
| 119 | + .label(d => d.key + ': ' + d.value) |
| 120 | + // .cx(330) |
| 121 | + // .cy(150) |
| 122 | + // .legend( |
| 123 | + // dc |
| 124 | + // .legend() |
| 125 | + // .x(30) |
| 126 | + // .y(65) |
| 127 | + // .autoItemWidth(true) |
| 128 | + // .itemHeight(32) |
| 129 | + // .gap(12) |
| 130 | + // ) |
| 131 | + .useViewBoxResizing(true); |
| 132 | +} |
| 133 | + |
| 134 | +// Status Pie Chart |
| 135 | +function drawStatusPieChart(ndx) { |
| 136 | + let statusDim = ndx.dimension(d => d.status); |
| 137 | + let statusGroup = statusDim.group(); |
| 138 | + |
| 139 | + // Pie chart |
| 140 | + dc.pieChart('#statusPieChart') |
| 141 | + .radius(120) |
| 142 | + .minAngleForLabel(0.2) |
| 143 | + .dimension(statusDim) |
| 144 | + .group(statusGroup) |
| 145 | + .ordinalColors(['grey', 'orange', 'green']) |
| 146 | + .height(295) |
| 147 | + .width(500) |
| 148 | + .label(d => d.key + ': ' + d.value) |
| 149 | + // .cx(330) |
| 150 | + // .cy(150) |
| 151 | + // .legend( |
| 152 | + // dc |
| 153 | + // .legend() |
| 154 | + // .x(30) |
| 155 | + // .y(65) |
| 156 | + // .autoItemWidth(true) |
| 157 | + // .itemHeight(32) |
| 158 | + // .gap(12) |
| 159 | + // ) |
| 160 | + .useViewBoxResizing(true); |
| 161 | +} |
| 162 | + |
| 163 | +// Assigned To Row Chart |
| 164 | +function drawAssignedToRowChart(ndx) { |
| 165 | + let assignedToDim = ndx.dimension(dc.pluck('assigned_to')); |
| 166 | + let assignedToGroup = assignedToDim.group().reduceCount(); |
| 167 | + |
| 168 | + dc.rowChart('#assignedToRowChart') |
| 169 | + .width(500) |
| 170 | + .height(330) |
| 171 | + .gap(2) |
| 172 | + .renderTitleLabel(true) |
| 173 | + .titleLabelOffsetX(413) |
| 174 | + .label(function() { |
| 175 | + return ''; |
| 176 | + }) |
| 177 | + .rowsCap(5) |
| 178 | + .useViewBoxResizing(true) |
| 179 | + .dimension(assignedToDim) |
| 180 | + .group(assignedToGroup); |
| 181 | +} |
| 182 | + |
| 183 | +// Most Upvoted Tickets |
| 184 | +function drawUpvotesRowChart(ndx) { |
| 185 | + let summaryDim = ndx.dimension(dc.pluck('summary')); |
| 186 | + let upvotesGroup = summaryDim.group().reduceSum(d => +d.upvotes); |
| 187 | + |
| 188 | + dc.rowChart('#upvotesRowChart') |
| 189 | + .width(500) |
| 190 | + .height(330) |
| 191 | + .gap(2) |
| 192 | + // .renderTitleLabel(true) |
| 193 | + // .titleLabelOffsetX(413) |
| 194 | + .label(d => d.key + ': ' + d.value) |
| 195 | + .rowsCap(5) |
| 196 | + .useViewBoxResizing(true) |
| 197 | + .dimension(summaryDim) |
| 198 | + .group(upvotesGroup); |
| 199 | +} |
| 200 | + |
| 201 | +// Test datatable |
| 202 | +// function drawDataTable(ndx) { |
| 203 | +// let dimension = ndx.dimension(d => d.dim); |
| 204 | +// // let group1 = dimension.groupAll(); |
| 205 | +// // let group1 = dimension.group(); |
| 206 | + |
| 207 | +// let table1 = dc |
| 208 | +// .dataTable('#datatabletest') |
| 209 | +// // .tableview('#datatabletest') |
| 210 | +// .dimension(dimension) |
| 211 | +// .height(200) |
| 212 | +// .width(200) |
| 213 | +// .size(Infinity) |
| 214 | +// .columns(['summary', 'ticket_type', 'priority', 'status', 'upvotes']); |
| 215 | +// } |
| 216 | + |
| 217 | +// Reset all chart |
| 218 | +$('.reset').click(function() { |
| 219 | + dc.filterAll(); |
| 220 | + dc.redrawAll(); |
| 221 | +}); |
| 222 | + |
| 223 | +// Print filter |
| 224 | +// * testing only |
| 225 | +function print_filter(filter) { |
| 226 | + var f = eval(filter); |
| 227 | + if (typeof f.length != 'undefined') { |
| 228 | + } else { |
| 229 | + } |
| 230 | + if (typeof f.top != 'undefined') { |
| 231 | + f = f.top(Infinity); |
| 232 | + } else { |
| 233 | + } |
| 234 | + if (typeof f.dimension != 'undefined') { |
| 235 | + f = f |
| 236 | + .dimension(function(d) { |
| 237 | + return ''; |
| 238 | + }) |
| 239 | + .top(Infinity); |
| 240 | + } else { |
| 241 | + } |
| 242 | + console.log( |
| 243 | + filter + |
| 244 | + '(' + |
| 245 | + f.length + |
| 246 | + ') = ' + |
| 247 | + JSON.stringify(f) |
| 248 | + .replace('[', '[\n\t') |
| 249 | + .replace(/}\,/g, '},\n\t') |
| 250 | + .replace(']', '\n]') |
| 251 | + ); |
| 252 | +} |
0 commit comments