1/** 2 * @file js/usage-stats-chart.js 3 * 4 * Copyright (c) 2014-2021 Simon Fraser University 5 * Copyright (c) 2000-2021 John Willinsky 6 * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. 7 * 8 * @brief A small handler to initialize Chart.js graphs on the frontend. 9 */ 10(function () { 11 /*global pkpUsageStats, Chart */ 12 13 if ( 14 typeof pkpUsageStats === 'undefined' || 15 typeof pkpUsageStats.data === 'undefined' 16 ) { 17 return; 18 } 19 20 var graphs, noStatsNotice; 21 22 // Check for .querySelectorAll in browser support 23 try { 24 graphs = document.querySelectorAll('.usageStatsGraph'); 25 noStatsNotice = document.querySelectorAll('.usageStatsUnavailable'); 26 } catch (e) { 27 return; 28 } 29 30 // Hide the unavailable stats notice when a chart is loaded 31 document.addEventListener('usageStatsChartLoaded.pkp', function (e) { 32 for (var i = 0; i < noStatsNotice.length; i++) { 33 if ( 34 typeof noStatsNotice[i].dataset.objectType !== 'undefined' && 35 typeof noStatsNotice[i].dataset.objectId !== 'undefined' && 36 noStatsNotice[i].dataset.objectType === e.target.dataset.objectType && 37 noStatsNotice[i].dataset.objectId === e.target.dataset.objectId 38 ) { 39 noStatsNotice[i].parentNode.removeChild(noStatsNotice[i]); 40 } 41 } 42 }); 43 44 // Define default chart options 45 var chartOptions = { 46 legend: { 47 display: false, 48 }, 49 tooltips: { 50 titleFontColor: '#333', 51 bodyFontColor: '#333', 52 footerFontColor: '#333', 53 backgroundColor: '#ddd', 54 cornerRadius: 2, 55 }, 56 elements: { 57 line: { 58 borderColor: 'rgba(0,0,0,0.3)', 59 borderWidth: 1, 60 borderJoinStyle: 'round', 61 backgroundColor: 'rgba(0,0,0,0.3)', 62 }, 63 rectangle: { 64 backgroundColor: 'rgba(0,0,0,0.3)', 65 }, 66 point: { 67 radius: 2, 68 hoverRadius: 6, 69 borderWidth: 0, 70 hitRadius: 5, 71 }, 72 }, 73 scales: { 74 xAxes: [ 75 { 76 gridLines: { 77 color: 'rgba(0,0,0,0.05)', 78 drawTicks: false, 79 }, 80 }, 81 ], 82 yAxes: [ 83 { 84 gridLines: { 85 color: 'rgba(0,0,0,0.05)', 86 drawTicks: false, 87 }, 88 ticks: { 89 beginAtZero: true 90 } 91 }, 92 ], 93 }, 94 }; 95 96 if (pkpUsageStats.config.chartType === 'bar') { 97 chartOptions.scales.xAxes = [ 98 { 99 gridLines: { 100 color: 'transparent', 101 }, 102 }, 103 ]; 104 } 105 106 // Fire an event to allow third-party customization of the options 107 var optionsEvent = document.createEvent('Event'); 108 optionsEvent.initEvent('usageStatsChartOptions.pkp', true, true); 109 optionsEvent.chartOptions = chartOptions; 110 document.dispatchEvent(optionsEvent); 111 112 var graph, objectType, objectId, graphData, initializedEvent; 113 pkpUsageStats.charts = {}; 114 for (var g = 0; g < graphs.length; g++) { 115 graph = graphs[g]; 116 117 // Check for markup we can use 118 if ( 119 typeof graph.dataset.objectType === 'undefined' || 120 typeof graph.dataset.objectId === 'undefined' 121 ) { 122 continue; 123 } 124 125 objectType = graph.dataset.objectType; 126 objectId = graph.dataset.objectId; 127 128 // Check that data exists for this graph 129 if ( 130 typeof pkpUsageStats.data[objectType] === 'undefined' || 131 pkpUsageStats.data[objectType][objectId] === 'undefined' 132 ) { 133 continue; 134 } 135 136 // Do nothing if there's no data for this chart 137 if (typeof pkpUsageStats.data[objectType][objectId].data === 'undefined') { 138 graph.parentNode.removeChild(graph); 139 continue; 140 } 141 142 graphData = pkpUsageStats.data[objectType][objectId]; 143 144 // Turn the data set into an array 145 var dataArray = [], 146 labelsArray = [], 147 currentDate = new Date(), 148 currentYear = currentDate.getFullYear(), 149 currentMonth = currentDate.getMonth(); 150 // Get the data from the last year 151 for (var month = currentMonth + 1; month <= 11; month++) { 152 if (!(currentYear - 1 in graphData.data)) { 153 dataArray.push(0); 154 } else { 155 dataArray.push(graphData.data[currentYear - 1][month + 1]); 156 } 157 labelsArray.push(pkpUsageStats.locale.months[month]); 158 } 159 // Get the data from the current year 160 for (month = 0; month <= currentMonth; month++) { 161 if (!(currentYear in graphData.data)) { 162 dataArray.push(0); 163 } else { 164 dataArray.push(graphData.data[currentYear][month + 1]); 165 } 166 labelsArray.push(pkpUsageStats.locale.months[month]); 167 } 168 pkpUsageStats.charts[objectType + '_' + objectId] = new Chart(graph, { 169 type: pkpUsageStats.config.chartType, 170 data: { 171 labels: labelsArray, 172 datasets: [ 173 { 174 label: graphData.label, 175 data: dataArray, 176 }, 177 ], 178 }, 179 options: chartOptions, 180 }); 181 182 // Fire an event when the chart is initialized 183 initializedEvent = document.createEvent('Event'); 184 initializedEvent.initEvent('usageStatsChartLoaded.pkp', true, true); 185 graph.dispatchEvent(initializedEvent); 186 } 187})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.