Merge pull request #21 from wagesj45/codex/add-datatables-chart-type-and-update-definitions
Add DataTables table chart type
This commit is contained in:
commit
f0653f972f
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
|
* Use latest CDN version for embedded dashboards
|
||||||
* Charts should be rendered from pre-generated JSON blobs in `/json/`
|
* 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
|
### Styling: Bulma CSS
|
||||||
|
|
||||||
* Use via CDN or vendored minified copy (to keep reports fully static)
|
* Use via CDN or vendored minified copy (to keep reports fully static)
|
||||||
|
|
14
reports.yml
14
reports.yml
|
@ -1,6 +1,6 @@
|
||||||
- name: hits
|
- name: hits
|
||||||
label: Hits
|
label: Hits
|
||||||
chart: bar
|
chart: line
|
||||||
query: |
|
query: |
|
||||||
SELECT {bucket} AS bucket,
|
SELECT {bucket} AS bucket,
|
||||||
COUNT(*) AS value
|
COUNT(*) AS value
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
- name: cache_status_breakdown
|
- name: cache_status_breakdown
|
||||||
label: Cache Status
|
label: Cache Status
|
||||||
chart: bar
|
chart: polarArea
|
||||||
query: |
|
query: |
|
||||||
SELECT cache_status AS bucket,
|
SELECT cache_status AS bucket,
|
||||||
COUNT(*) AS value
|
COUNT(*) AS value
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
- name: domain_traffic
|
- name: domain_traffic
|
||||||
label: Top Domains
|
label: Top Domains
|
||||||
chart: bar
|
chart: table
|
||||||
query: |
|
query: |
|
||||||
SELECT host AS bucket,
|
SELECT host AS bucket,
|
||||||
COUNT(*) AS value
|
COUNT(*) AS value
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
|
|
||||||
- name: top_paths
|
- name: top_paths
|
||||||
label: Top Paths
|
label: Top Paths
|
||||||
chart: bar
|
chart: table
|
||||||
query: |
|
query: |
|
||||||
SELECT path AS bucket,
|
SELECT path AS bucket,
|
||||||
COUNT(*) AS value
|
COUNT(*) AS value
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
|
|
||||||
- name: user_agents
|
- name: user_agents
|
||||||
label: User Agents
|
label: User Agents
|
||||||
chart: bar
|
chart: table
|
||||||
query: |
|
query: |
|
||||||
SELECT user_agent AS bucket,
|
SELECT user_agent AS bucket,
|
||||||
COUNT(*) AS value
|
COUNT(*) AS value
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
|
|
||||||
- name: referrers
|
- name: referrers
|
||||||
label: Referrers
|
label: Referrers
|
||||||
chart: bar
|
chart: table
|
||||||
query: |
|
query: |
|
||||||
SELECT referer AS bucket,
|
SELECT referer AS bucket,
|
||||||
COUNT(*) AS value
|
COUNT(*) AS value
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
|
|
||||||
- name: status_distribution
|
- name: status_distribution
|
||||||
label: HTTP Statuses
|
label: HTTP Statuses
|
||||||
chart: bar
|
chart: stackedBar
|
||||||
query: |
|
query: |
|
||||||
SELECT CASE
|
SELECT CASE
|
||||||
WHEN status BETWEEN 200 AND 299 THEN '2xx'
|
WHEN status BETWEEN 200 AND 299 THEN '2xx'
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>{{ interval.title() }} Report</title>
|
<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.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/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>
|
</head>
|
||||||
<body class="section">
|
<body class="section">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@ -12,7 +15,11 @@
|
||||||
{% for report in reports %}
|
{% for report in reports %}
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<h2 class="subtitle">{{ report.label }}</h2>
|
<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>
|
<canvas id="chart-{{ report.name }}"></canvas>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,10 +29,32 @@
|
||||||
fetch(rep.json)
|
fetch(rep.json)
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then(data => {
|
.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 labels = data.map(x => x.bucket);
|
||||||
const values = data.map(x => x.value);
|
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), {
|
new Chart(document.getElementById('chart-' + rep.name), {
|
||||||
type: rep.chart,
|
type: chartType,
|
||||||
data: {
|
data: {
|
||||||
labels: labels,
|
labels: labels,
|
||||||
datasets: [{
|
datasets: [{
|
||||||
|
@ -34,14 +63,10 @@
|
||||||
backgroundColor: 'rgba(54, 162, 235, 0.5)',
|
backgroundColor: 'rgba(54, 162, 235, 0.5)',
|
||||||
borderColor: 'rgba(54, 162, 235, 1)',
|
borderColor: 'rgba(54, 162, 235, 1)',
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
fill: rep.chart !== 'bar',
|
fill: rep.chart !== 'bar' && rep.chart !== 'stackedBar',
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: options
|
||||||
scales: {
|
|
||||||
y: { beginAtZero: true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue