1var hoursEachWeek = dummyData["weekly_listening_clock"] 2 ? dummyData["weekly_listening_clock"]["hours_each_week"] 3 : null; 4 5let weekIndicator = ` 6 <div class="indicator-container"> 7 <span id="joy-division-first-week-label">Week 1</span> 8 <span id="joy-division-indicator">0</span> 9 <div> 10 `; 11 12let generateChartHTML = () => { 13 let lines = hoursEachWeek.map((item, index) => { 14 return ` 15 <tr> 16 <td class="joy-division-sparkline" data-sparkline="${item.join(", ")}"/> 17 </tr> 18 `; 19 }); 20 21 return lines; 22}; 23 24// Add all listening hours from every week together 25let sumForEveryHour = hoursEachWeek[0].map((item, index) => 26 hoursEachWeek.reduce((sum, curr) => sum + curr[index], 0) 27); 28let hourOfDayMostListendTo = sumForEveryHour.indexOf( 29 Math.max(...sumForEveryHour) 30); 31 32if (hoursEachWeek) { 33 let elements = document.querySelectorAll("#joy-division-hour-of-day"); 34 elements.forEach((element) => { 35 element.innerHTML = calcTimeOfDay(hourOfDayMostListendTo); 36 }); 37 38 let items = weekIndicator + generateChartHTML().join(""); 39 document.getElementById("tbody-sparkline").innerHTML = items; 40} 41 42let renderChart = () => { 43 Highcharts.SparkLine = function (a, b, c) { 44 const hasRenderToArg = typeof a === "string" || a.nodeName; 45 let options = arguments[hasRenderToArg ? 1 : 0]; 46 47 const defaultOptions = { 48 chart: { 49 type: "area", 50 renderTo: 51 (options.chart && options.chart.renderTo) || (hasRenderToArg && a), 52 backgroundColor: null, 53 borderWidth: 0, 54 width: 233, 55 margin: [0, 0, 0, 0], 56 height: 18, 57 style: { 58 overflow: "visible", 59 }, 60 // Saves some render time for every item 61 skipClone: true, 62 }, 63 64 title: { 65 text: null, 66 }, 67 68 credits: { 69 enabled: false, 70 }, 71 72 xAxis: { 73 endOnTick: true, 74 startOnTick: true, 75 labels: { 76 enabled: false, 77 }, 78 title: { 79 text: null, 80 }, 81 tickPositions: [1, 7, 13, 19, 24], 82 }, 83 84 yAxis: { 85 endOnTick: false, 86 startOnTick: false, 87 labels: { 88 enabled: false, 89 }, 90 title: { 91 text: null, 92 }, 93 }, 94 legend: { 95 enabled: false, 96 }, 97 tooltip: { 98 hideDelay: 0, 99 outside: true, 100 shared: true, 101 }, 102 plotOptions: { 103 series: { 104 fillColor: "#000", 105 cursor: "pointer", 106 animation: false, 107 lineWidth: 1, 108 color: "transparent", 109 connectNulls: true, 110 label: { 111 enabled: false, 112 }, 113 marker: { 114 enabled: false, 115 states: { 116 hover: { 117 enabled: true, 118 radius: 4, 119 }, 120 }, 121 }, 122 fillOpacity: 0, 123 }, 124 }, 125 }; 126 127 options = Highcharts.merge(defaultOptions, options); 128 129 return hasRenderToArg 130 ? new Highcharts.Chart(a, options, c) 131 : new Highcharts.Chart(options, b); 132 }; 133 134 let tds = Array.from(document.querySelectorAll("td[data-sparkline]")); 135 tds.forEach((td, i) => { 136 const stringData = td.dataset.sparkline; 137 const arr = stringData.split("; "); 138 const data = arr[0].split(", ").map(parseFloat); 139 const chart = {}; 140 if (arr[1]) { 141 chart.type = arr[1]; 142 } 143 Highcharts.SparkLine(td, { 144 chart: { 145 style: { 146 overflow: "visible", 147 }, 148 }, 149 series: [ 150 { 151 data: data, 152 pointStart: 1, 153 point: { 154 events: { 155 mouseOver() { 156 tds.forEach((item, index) => { 157 i !== index ? item.classList.add("opaque") : null; 158 }); 159 }, 160 mouseOut() { 161 tds.forEach((item) => { 162 item.classList.remove("opaque"); 163 }); 164 }, 165 }, 166 }, 167 }, 168 ], 169 yAxis: { 170 gridLineWidth: 0, 171 minorGridLineWidth: 0, 172 }, 173 tooltip: { 174 backgroundColor: null, 175 shadow: null, 176 style: { 177 color: "#FAFAFA", 178 }, 179 pointFormatter: function () { 180 let point = this; 181 182 return `<span>
182Week ${i + 1}, ${calcTimeOfDay( 183 point.category - 1 184 )} </span><br/><b>${point.y} Scrobbles </b>`; 185 }, 186 headerFormat: null, 187 }, 188 chart: chart, 189 }); 190 }); 191 192 let doChunk = () => { 193 const time = +new Date(), 194 len = tds.length; 195 196 for (let i = 0; i < len; i += 1) { 197 const td = tds[i]; 198 const stringdata = td.dataset.sparkline; 199 const arr = stringdata.split("; "); 200 const data = arr[0].split(", ").map(parseFloat); 201 const chart = {}; 202 203 if (arr[1]) { 204 chart.type = arr[1]; 205 } 206 207 Highcharts.SparkLine(td, { 208 chart: { 209 style: { 210 overflow: "visible", 211 }, 212 }, 213 series: [ 214 { 215 data: data, 216 pointStart: 1, 217 point: { 218 events: { 219 mouseOver() { 220 tds.forEach((item, index) => { 221 i !== index ? item.classList.add("opaque") : null; 222 }); 223 }, 224 mouseOut() { 225 tds.forEach((item) => { 226 item.classList.remove("opaque"); 227 }); 228 }, 229 }, 230 }, 231 }, 232 ], 233 yAxis: { 234 gridLineWidth: 0, 235 minorGridLineWidth: 0, 236 }, 237 tooltip: { 238 backgroundColor: null, 239 shadow: null, 240 style: { 241 color: "#FAFAFA", 242 }, 243 pointFormatter: () => { 244 let point = this; 245 246 return `<span>Week ${i + 1}, ${calcTimeOfDay( 247 point.category - 1 248 )} </span><br/><b>${point.y} Scrobbles </b>`; 249 }, 250 headerFormat: null, 251 }, 252 chart: chart, 253 }); 254 255 n += 1; 256 257 // If the process takes too much time, run a timeout 258 // to allow interaction with the browser 259 if (new Date() - time > 500) { 260 tds.splice(0, i + 1); 261 setTimeout(doChunk, 0); 262 break; 263 } 264 } 265 }; 266}; 267 268export const renderJoyDivision = () => { 269 renderChart(); 270};
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.