Spaces:
Runtime error
Runtime error
| let dark = document.location.search.includes('dark-theme=true'); | |
| if (dark) | |
| document.body.classList.add('dark-theme'); | |
| var COLORS = dark ? | |
| ['#FF0000', '#00FF00', '#0000FF', '#FF00FF', '#FFFF00', '#0000FF', '#F090F0', '#90F0F0', '#F0F090'] : | |
| ['#CC0000', '#00CC00', '#0000CC', '#CC00CC', '#CCCC00', '#0000CC', '#C060C0', '#60C0C0', '#C0C060'] | |
| const load = () => { | |
| const l0 = document.createElement('div') | |
| const l1 = document.createElement('div') | |
| const l2 = document.createElement('div') | |
| l0.classList.add('lds-ripple') | |
| l0.appendChild(l1) | |
| l0.appendChild(l2) | |
| return l0 | |
| } | |
| const getCheckedOptions = () => { | |
| const options = Array.from(document.querySelectorAll('.option-div')) | |
| .map(e => Array.from(e.children) | |
| .filter(e => e.nodeName == 'DIV')) | |
| .filter(e => e.length) | |
| .flat() | |
| .map(e => e.id) | |
| .filter(e => document.querySelector(`#${e}-checkbox`).checked) | |
| const optionsDict = {} | |
| for (let option of options) { | |
| const key = option.split('-option-')[0] | |
| const value = option.split('-option-')[1] | |
| if (key in optionsDict) | |
| optionsDict[key].push(value) | |
| else | |
| optionsDict[key] = [value] | |
| } | |
| return optionsDict; | |
| } | |
| const addOption = (category, optionName) => { | |
| /* Options for the issue div */ | |
| const issueDiv = document.getElementById(`${category}Div`); | |
| const div = document.createElement('div') | |
| let found = false; | |
| let optionNumber = 0; | |
| while (!found && ++optionNumber < 100) { | |
| let previousOption = document.getElementById(`${category}-option-${optionNumber}`); | |
| found = previousOption === null; | |
| } | |
| div.id = `${category}-option-${optionNumber}`; | |
| issueDiv.appendChild(div); | |
| const checkBox = document.createElement('input'); | |
| checkBox.type = 'checkbox' | |
| checkBox.id = `${category}-option-${optionNumber}-checkbox` | |
| const checkBoxLabel = document.createElement('label'); | |
| const labelSpan = document.createElement('span') | |
| labelSpan.textContent = optionName; | |
| checkBoxLabel.appendChild(checkBox) | |
| checkBoxLabel.appendChild(labelSpan) | |
| div.appendChild(checkBoxLabel) | |
| return optionNumber | |
| } | |
| let charts = []; | |
| const createButton = (title, libraries, methods) => { | |
| const button = document.createElement('button') | |
| button.textContent = title; | |
| button.onclick = async () => { | |
| document.getElementById('pip-graph').innerHTML = '' | |
| document.getElementById('star-graph').innerHTML = '' | |
| document.getElementById('issue-graph').innerHTML = '' | |
| const e = load() | |
| document.body.appendChild(e) | |
| const selectedInternalLibraries = libraries.internal.filter(e => document.querySelector(`#${e}Checkbox`).checked); | |
| const selectedExternalLibraries = libraries.external.filter(e => document.querySelector(`#${e}Checkbox`).checked); | |
| const selectedLibraries = selectedInternalLibraries.concat(selectedExternalLibraries); | |
| const relevantOptions = getCheckedOptions(); | |
| if (charts.length !== 0) { | |
| for (const chart of charts) { | |
| chart.destroy() | |
| } | |
| } | |
| for (const method of methods()) { | |
| charts.push(await method(selectedLibraries, relevantOptions)) | |
| } | |
| document.body.removeChild(e) | |
| }; | |
| return button; | |
| } | |
| const initialize = async () => { | |
| const inferResponse = await fetch(`initialize`); | |
| console.log(inferResponse); | |
| const inferJson = await inferResponse.json(); | |
| console.log(inferJson); | |
| const warnings = document.getElementById("warnings") | |
| const librarySelector = document.getElementById('library-selector'); | |
| const graphSelector = document.getElementById('graph-selector'); | |
| const selectorSubmit = document.getElementById('selector-submit'); | |
| const introSpan = document.createElement("h3") | |
| introSpan.textContent = "Select libraries to display" | |
| librarySelector.appendChild(introSpan); | |
| const graphSpan = document.createElement("h3") | |
| graphSpan.textContent = "Select graphs to display" | |
| graphSelector.appendChild(graphSpan); | |
| if (inferJson.warnings.length > 0) { | |
| for (const warning of inferJson.warnings) { | |
| const div = document.createElement('div'); | |
| div.classList.add('warning-div') | |
| const labelSpan = document.createElement('span'); | |
| labelSpan.textContent = `Warning: ${warning}`; | |
| div.appendChild(labelSpan); | |
| warnings.appendChild(div); | |
| } | |
| } | |
| for (const element of inferJson.internal) { | |
| const div = document.createElement('div'); | |
| const checkBox = document.createElement('input'); | |
| checkBox.type = 'checkbox' | |
| checkBox.id = `${element}Checkbox`; | |
| const checkBoxLabel = document.createElement('label'); | |
| const labelSpan = document.createElement('span') | |
| labelSpan.textContent = element.charAt(0).toUpperCase() + element.slice(1) | |
| checkBoxLabel.appendChild(checkBox) | |
| checkBoxLabel.appendChild(labelSpan) | |
| div.appendChild(checkBoxLabel) | |
| librarySelector.appendChild(div) | |
| } | |
| const externalLibs = document.createElement("h3") | |
| externalLibs.textContent = "External Libraries" | |
| librarySelector.appendChild(externalLibs); | |
| for (const element of inferJson.external) { | |
| const div = document.createElement('div'); | |
| const checkBox = document.createElement('input'); | |
| checkBox.type = 'checkbox' | |
| checkBox.id = `${element}Checkbox`; | |
| const checkBoxLabel = document.createElement('label'); | |
| const labelSpan = document.createElement('span') | |
| labelSpan.textContent = element.charAt(0).toUpperCase() + element.slice(1) | |
| checkBoxLabel.appendChild(checkBox) | |
| checkBoxLabel.appendChild(labelSpan) | |
| div.appendChild(checkBoxLabel) | |
| librarySelector.appendChild(div) | |
| } | |
| for (const element of ['pip', 'stars', 'issue']) { | |
| const div = document.createElement('div'); | |
| div.classList.add('option-div') | |
| div.id = `${element}Div`; | |
| const checkBox = document.createElement('input'); | |
| checkBox.type = 'checkbox' | |
| checkBox.id = `${element}CheckboxGraph`; | |
| const checkBoxLabel = document.createElement('label'); | |
| const labelSpan = document.createElement('span') | |
| labelSpan.textContent = element.charAt(0).toUpperCase() + element.slice(1) | |
| checkBoxLabel.appendChild(checkBox) | |
| checkBoxLabel.appendChild(labelSpan) | |
| div.appendChild(checkBoxLabel) | |
| graphSelector.appendChild(div) | |
| } | |
| addOption('pip', "Cumulated"); | |
| addOption('pip', "Week over week"); | |
| addOption('issue', "Exclude org members"); | |
| addOption('issue', "Week over week"); | |
| addOption('issue', "Cumulated"); | |
| addOption('stars', "Week over week"); | |
| addOption('stars', "Cumulated"); | |
| const fetchButton = createButton('Fetch', inferJson, () => { | |
| const graphNames = ['pip', 'stars', 'issue'].filter(e => document.querySelector(`#${e}CheckboxGraph`).checked); | |
| const graphs = [] | |
| if (graphNames.includes('pip')) | |
| graphs.push(retrievePipInstalls) | |
| if (graphNames.includes('stars')) | |
| graphs.push(retrieveStars) | |
| if (graphNames.includes('issue')) | |
| graphs.push(retrieveIssues) | |
| return graphs | |
| }) | |
| selectorSubmit.appendChild(fetchButton); | |
| }; | |
| const retrievePipInstalls = async (libraryNames, options) => { | |
| const relevantOptions = options['pip'] | |
| const inferResponse = await fetch(`retrievePipInstalls?input=${libraryNames}&options=${relevantOptions}`); | |
| const inferJson = await inferResponse.json(); | |
| const colors = [...COLORS]; | |
| const labels = Array.from(inferJson['day']).map(e => new Date(e)) | |
| const datasets = []; | |
| for (const element in inferJson) { | |
| if (element === 'day') | |
| continue | |
| const color = colors.pop() | |
| datasets.push({ | |
| label: element, | |
| data: inferJson[element], | |
| backgroundColor: color, | |
| borderColor: color, | |
| tension: 0.01, | |
| pointRadius: 1, | |
| borderWidth: 2, | |
| fill: false | |
| }) | |
| } | |
| const ctx = document.getElementById('pip-graph'); | |
| const myChart = new Chart(ctx, { | |
| type: 'line', | |
| data: {labels, datasets}, | |
| options: { | |
| scales: { | |
| y: { | |
| beginAtZero: true | |
| }, | |
| x: { | |
| type: 'time', | |
| } | |
| }, | |
| plugins: { | |
| title: { | |
| display: true, | |
| text: 'Pip installs' | |
| } | |
| } | |
| } | |
| }); | |
| return myChart; | |
| }; | |
| const retrieveStars = async (libraryNames, options) => { | |
| const relevantOptions = options['stars'] | |
| const inferResponse = await fetch(`retrieveStars?input=${libraryNames}&options=${relevantOptions}`); | |
| const inferJson = await inferResponse.json(); | |
| const colors = [...COLORS]; | |
| const labels = Array.from(inferJson['day']).map(e => new Date(e)) | |
| const datasets = []; | |
| for (const element in inferJson) { | |
| if (element === 'day') | |
| continue | |
| const color = colors.pop() | |
| datasets.push({ | |
| label: element, | |
| data: inferJson[element], | |
| backgroundColor: color, | |
| borderColor: color, | |
| tension: 0.01, | |
| pointRadius: 1, | |
| borderWidth: 2, | |
| fill: false | |
| }) | |
| } | |
| const ctx = document.getElementById('star-graph'); | |
| const myChart = new Chart(ctx, { | |
| title: "Stars", | |
| type: 'line', | |
| data: {labels, datasets}, | |
| options: { | |
| scales: { | |
| y: { | |
| beginAtZero: true | |
| }, | |
| x: { | |
| type: 'time', | |
| } | |
| }, | |
| plugins: { | |
| title: { | |
| display: true, | |
| text: 'Number of stargazers' | |
| } | |
| } | |
| } | |
| }); | |
| return myChart; | |
| }; | |
| const retrieveIssues = async (libraryNames, options) => { | |
| const relevantOptions = options['issue'] | |
| const inferResponse = await fetch(`retrieveIssues?input=${libraryNames}&options=${relevantOptions}`); | |
| const inferJson = await inferResponse.json(); | |
| const colors = [...COLORS]; | |
| const labels = Array.from(inferJson['day']).map(e => new Date(e)) | |
| const datasets = []; | |
| for (const element in inferJson) { | |
| if (element === 'day') | |
| continue | |
| const color = colors.pop() | |
| datasets.push({ | |
| label: element, | |
| data: inferJson[element], | |
| backgroundColor: color, | |
| borderColor: color, | |
| tension: 0.01, | |
| pointRadius: 1, | |
| borderWidth: 2, | |
| fill: false | |
| }) | |
| } | |
| const ctx = document.getElementById('issue-graph'); | |
| const myChart = new Chart(ctx, { | |
| title: "Issues", | |
| type: 'line', | |
| data: {labels, datasets}, | |
| options: { | |
| scales: { | |
| y: { | |
| beginAtZero: true | |
| }, | |
| x: { | |
| type: 'time', | |
| } | |
| }, | |
| plugins: { | |
| title: { | |
| display: true, | |
| text: 'Cumulated number of issues, PRs, and comments' | |
| } | |
| } | |
| } | |
| }); | |
| return myChart; | |
| }; | |
| ( | |
| async () => { | |
| const e = load() | |
| document.body.appendChild(e) | |
| await initialize() | |
| document.body.removeChild(e) | |
| } | |
| )(); |