Add DataTables table chart type #21
3 changed files with 45 additions and 14 deletions
|
@ -39,6 +39,12 @@ This document outlines general practices and expectations for AI agents assistin
|
|||
* Use latest CDN version for embedded dashboards
|
||||
* Charts should be rendered from pre-generated JSON blobs in `/json/`
|
||||
|
||||
### Tables: DataTables
|
||||
|
||||
* Use DataTables via CDN for reports with `chart: table`
|
||||
* Requires jQuery from a CDN
|
||||
* Table data comes from the same `/json/` files as charts
|
||||
|
||||
### Styling: Bulma CSS
|
||||
|
||||
* Use via CDN or vendored minified copy (to keep reports fully static)
|
||||
|
|
14
reports.yml
14
reports.yml
|
@ -1,6 +1,6 @@
|
|||
- name: hits
|
||||
label: Hits
|
||||
chart: bar
|
||||
chart: line
|
||||
query: |
|
||||
SELECT {bucket} AS bucket,
|
||||
COUNT(*) AS value
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
- name: cache_status_breakdown
|
||||
label: Cache Status
|
||||
chart: bar
|
||||
chart: polarArea
|
||||
query: |
|
||||
SELECT cache_status AS bucket,
|
||||
COUNT(*) AS value
|
||||
|
@ -30,7 +30,7 @@
|
|||
|
||||
- name: domain_traffic
|
||||
label: Top Domains
|
||||
chart: bar
|
||||
chart: table
|
||||
query: |
|
||||
SELECT host AS bucket,
|
||||
COUNT(*) AS value
|
||||
|
@ -50,7 +50,7 @@
|
|||
|
||||
- name: top_paths
|
||||
label: Top Paths
|
||||
chart: bar
|
||||
chart: table
|
||||
query: |
|
||||
SELECT path AS bucket,
|
||||
COUNT(*) AS value
|
||||
|
@ -65,7 +65,7 @@
|
|||
|
||||
- name: user_agents
|
||||
label: User Agents
|
||||
chart: bar
|
||||
chart: table
|
||||
query: |
|
||||
SELECT user_agent AS bucket,
|
||||
COUNT(*) AS value
|
||||
|
@ -76,7 +76,7 @@
|
|||
|
||||
- name: referrers
|
||||
label: Referrers
|
||||
chart: bar
|
||||
chart: table
|
||||
query: |
|
||||
SELECT referer AS bucket,
|
||||
COUNT(*) AS value
|
||||
|
@ -87,7 +87,7 @@
|
|||
|
||||
- name: status_distribution
|
||||
label: HTTP Statuses
|
||||
chart: bar
|
||||
chart: stackedBar
|
||||
query: |
|
||||
SELECT CASE
|
||||
WHEN status BETWEEN 200 AND 299 THEN '2xx'
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
<meta charset="utf-8">
|
||||
<title>{{ interval.title() }} Report</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
|
||||
</head>
|
||||
<body class="section">
|
||||
<div class="container">
|
||||
|
@ -12,7 +15,11 @@
|
|||
{% for report in reports %}
|
||||
<div class="box">
|
||||
<h2 class="subtitle">{{ report.label }}</h2>
|
||||
{% if report.chart == 'table' %}
|
||||
<table id="table-{{ report.name }}" class="table is-striped"></table>
|
||||
{% else %}
|
||||
<canvas id="chart-{{ report.name }}"></canvas>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
@ -22,10 +29,32 @@
|
|||
fetch(rep.json)
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (rep.chart === 'table') {
|
||||
const rows = data.map(x => [x.bucket, x.value]);
|
||||
new DataTable('#table-' + rep.name, {
|
||||
data: rows,
|
||||
columns: [
|
||||
{ title: 'Bucket' },
|
||||
{ title: 'Value' }
|
||||
]
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const labels = data.map(x => x.bucket);
|
||||
const values = data.map(x => x.value);
|
||||
const chartType = rep.chart === 'stackedBar' ? 'bar' : rep.chart;
|
||||
const options = {
|
||||
scales: {
|
||||
y: { beginAtZero: true }
|
||||
}
|
||||
};
|
||||
if (rep.chart === 'stackedBar') {
|
||||
options.scales.x = { stacked: true };
|
||||
options.scales.y.stacked = true;
|
||||
}
|
||||
new Chart(document.getElementById('chart-' + rep.name), {
|
||||
type: rep.chart,
|
||||
type: chartType,
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: [{
|
||||
|
@ -34,14 +63,10 @@
|
|||
backgroundColor: 'rgba(54, 162, 235, 0.5)',
|
||||
borderColor: 'rgba(54, 162, 235, 1)',
|
||||
borderWidth: 1,
|
||||
fill: rep.chart !== 'bar',
|
||||
fill: rep.chart !== 'bar' && rep.chart !== 'stackedBar',
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
y: { beginAtZero: true }
|
||||
}
|
||||
}
|
||||
options: options
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue