Skip to content

Commit

Permalink
Merge pull request #18 from Astylodon/extend-dashboard-front
Browse files Browse the repository at this point in the history
Add missing info to dashboard
  • Loading branch information
Xwilarg authored Feb 7, 2025
2 parents d42a2e6 + cd25db4 commit c6fdf32
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 22 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18

Expand All @@ -18,7 +18,7 @@ jobs:
- name: Build
run: npm run build

- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: script
path: |
Expand All @@ -30,20 +30,20 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Validate composer.json and composer.lock
run: composer validate --strict

- name: Install dependencies
run: composer install --prefer-dist --no-progress

- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: script
path: public

- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: build
path: .
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ vendor/
*.mmdb
node_modules/
public/shika.js
public/shika.js.map
public/build
.env
82 changes: 68 additions & 14 deletions assets/js/graphs.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,42 @@
import { Chart, BarController, BarElement, CategoryScale, LinearScale, Colors, Tooltip } from "chart.js"
import { Chart, BarController, PieController, BarElement, ArcElement, CategoryScale, LinearScale, Colors, Tooltip, Legend } from "chart.js"
import { ChoroplethController, ProjectionScale, ColorScale, GeoFeature, topojson } from 'chartjs-chart-geo';
import countries50m from "world-atlas/countries-50m.json" with { type: "json" };

// Bundle optimization
Chart.register(BarController, BarElement, CategoryScale, LinearScale, Colors, Tooltip)
Chart.register(BarController, PieController, ChoroplethController, BarElement, ArcElement, CategoryScale, LinearScale, ProjectionScale, ColorScale, GeoFeature, Colors, Tooltip, Legend)

// Current charts
let pagesChart = null
let referrersChart = null
let charts = []

async function displayData(site, time) {
// Destroy the old charts
if (pagesChart !== null) pagesChart.destroy()
if (referrersChart !== null) referrersChart.destroy()
for (let chart of charts) {
chart.destroy()
}
charts = []

// Calculate the from time
const from = (Date.now() / 1000) - time

// Fetch the numbers
const pages = await fetch(`/api/sites/${site}/pages?from=${from}`).then(x => x.json())
const referrers = await fetch(`/api/sites/${site}/referrers?from=${from}`).then(x => x.json())
const browsers = await fetch(`/api/sites/${site}/browsers?from=${from}`).then(x => x.json())
const systems = await fetch(`/api/sites/${site}/operating-systems?from=${from}`).then(x => x.json())
const devices = await fetch(`/api/sites/${site}/device-types?from=${from}`).then(x => x.json())
const countries = await fetch(`/api/sites/${site}/countries?from=${from}`).then(x => x.json())

// Display the charts
pagesChart = displayLineChart("pages", pages.map(x => [x.path, x.count]))
referrersChart = displayLineChart("referrers", referrers.map(x => [x.referrer, x.count]))
const region = new Intl.DisplayNames(['en'], { type: 'region' })
charts.push(displayLineChart("pages", pages.map(x => [x.path, x.count])))
charts.push(displayLineChart("referrers", referrers.map(x => [x.referrer, x.count])))
charts.push(displayPieChart("browsers", browsers.map(x => [x.browser, x.count])))
charts.push(displayPieChart("systems", systems.map(x => [x.operating_system, x.count])))
charts.push(displayPieChart("devices", devices.map(x => [x.device_type, x.count])))
charts.push(displayCountryChart("countries", Object.fromEntries(countries.map(x => [ region.of(x.country), x.count ]))));
}

function displayLineChart(id, values) {
const options = {
indexAxis: "y"
}

function displayChartInternal(type, options, id, values) {
// Map the data
const data = {
labels: values.map(x => x[0]),
Expand All @@ -42,14 +50,60 @@ function displayLineChart(id, values) {

// Display the chart
const chart = new Chart(document.getElementById(id), {
type: "bar",
type: type,
data,
options
})

return chart
}

function displayCountryChart(id, values) {
const countries = topojson.feature(countries50m, countries50m.objects.countries).features;

const chart = new Chart(document.getElementById(id).getContext("2d"), {
type: 'choropleth',
data: {
labels: countries.map((d) => d.properties.name),
datasets: [{
label: 'Countries',
data: countries.map((d) => {
const country = d.properties.name;
return ({feature: d, value: values[country] ? values[country] : 0})
}),
}]
},
options: {
scales: {
projection: {
axis: 'x',
projection: 'equalEarth'
}
}
}
});

return chart;
}

function displayLineChart(id, values) {
const options = {
indexAxis: "y"
}
return displayChartInternal("bar", options, id, values)
}

function displayPieChart(id, values) {
const options = {
plugins: {
legend: {
position: 'top'
}
}
}
return displayChartInternal("pie", options, id, values)
}

function startDisplayData() {
// Get the site and time
const site = document.getElementById("site-select").value
Expand Down
157 changes: 156 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
},
"dependencies": {
"bootstrap": "^5.3.2",
"chart.js": "^4.4.1"
"chart.js": "^4.4.1",
"chartjs-chart-geo": "^4.3.4",
"world-atlas": "^2.0.2"
},
"devDependencies": {
"esbuild": "^0.19.10",
Expand Down
Loading

0 comments on commit c6fdf32

Please sign in to comment.