Analysis
Norwegian data — pick a dataset, see what’s been done, ask for more
Answers are limited to the selected deployed dataset.
Norwegian data — pick a dataset, see what’s been done, ask for more
---
title: "Analysis"
subtitle: "Norwegian data — pick a dataset, see what's been done, ask for more"
toc: false
---
```{=html}
<div class="kf-tool">
<div class="kf-controls">
<label class="kf-field">
<span>Dataset</span>
<input id="kfDsFilter" class="kf-filter" placeholder="Search datasets…" autocomplete="off">
<select id="kfDataset"></select>
</label>
<label class="kf-field">
<span>Analyses already done</span>
<select id="kfKnown"></select>
</label>
<button id="kfRun" class="btn-koja" type="button">Run</button>
</div>
<p id="kfDsDesc" class="kf-hint"></p>
<div id="kfResult" class="kf-result"></div>
<div class="kf-chat">
<textarea id="kfQ" rows="3"
placeholder="Ask about this dataset, or request a new analysis — e.g. "OLS of avg_wage_nok on ai_exposure", or "scatter employment vs ai_exposure"…"></textarea>
<div class="kf-row">
<button id="kfSend" class="btn-koja" type="button">Ask</button>
<span class="kf-hint">Answers are limited to the selected deployed dataset.</span>
</div>
<div id="kfA" class="kf-answer" hidden></div>
</div>
</div>
<script>
(function () {
const $ = id => document.getElementById(id);
let REG = null, current = null;
const opt = (v, t) => { const o = document.createElement('option'); o.value = v; o.textContent = t; return o; };
function fillDatasets(filter) {
const sel = $('kfDataset'); sel.innerHTML = '';
(REG.datasets || [])
.filter(d => !filter || (d.name + ' ' + d.id).toLowerCase().includes(filter.toLowerCase()))
.forEach(d => sel.appendChild(opt(d.id, d.name)));
onDataset();
}
function onDataset() {
current = (REG.datasets || []).find(d => d.id === $('kfDataset').value) || null;
const k = $('kfKnown'); k.innerHTML = '';
if (current) {
$('kfDsDesc').textContent =
(current.country ? current.country + ' · ' : '') +
(current.year ? current.year + ' · ' : '') + (current.description || '');
(current.known_analyses || []).forEach(a => k.appendChild(opt(a.id, a.title)));
} else { $('kfDsDesc').textContent = ''; }
$('kfResult').innerHTML = '';
}
function renderResult(d) {
const r = $('kfResult');
if (d.error) { r.innerHTML = '<p class="kf-err">' + d.error + '</p>'; return; }
if (d.kind === 'figure') {
r.innerHTML = '<figure><img src="' + d.image + '" alt=""><figcaption>' + (d.caption || '') + '</figcaption></figure>';
return;
}
if (d.kind === 'ols') {
let h = '<table class="kf-ols"><caption>OLS — ' + d.y + ' on ' + d.x +
' (n=' + d.n + ', R² = ' + d.r2 + ')</caption>' +
'<thead><tr><th>term</th><th>coef</th><th>SE</th><th>t</th><th>p</th></tr></thead><tbody>';
d.table.forEach(row => {
h += '<tr><td>' + row.term + '</td><td>' + row.coef + '</td><td>' + row.se +
'</td><td>' + row.t + '</td><td>' + row.p + '</td></tr>';
});
r.innerHTML = h + '</tbody></table>';
return;
}
r.textContent = JSON.stringify(d);
}
async function runKnown() {
const spec = (current && (current.known_analyses || []).find(a => a.id === $('kfKnown').value)) || null;
if (!spec || !current) return;
$('kfResult').innerHTML = '<p class="kf-hint">Running…</p>';
try {
const r = await fetch('/api/analyze', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ dataset_id: current.id, kind: spec.kind, x: spec.x, y: spec.y })
});
renderResult(await r.json());
} catch (e) { $('kfResult').innerHTML = '<p class="kf-err">Error: ' + e.message + '</p>'; }
}
async function ask() {
const q = $('kfQ'); const question = q.value.trim();
if (!question || !current) return;
q.value = '';
const a = $('kfA'); a.hidden = false; a.textContent = 'Thinking…'; $('kfSend').disabled = true;
try {
const r = await fetch('/api/ask', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ question, dataset_id: current.id })
});
const d = await r.json(); a.textContent = d.answer || d.error || 'No response.';
} catch (e) { a.textContent = 'Error: ' + e.message; }
$('kfSend').disabled = false; q.focus();
}
fetch('/api/datasets').then(r => r.json()).then(reg => { REG = reg; fillDatasets(''); })
.catch(() => { $('kfDsDesc').textContent = 'Could not load datasets (the tool works when served by Flask).'; });
$('kfDataset').addEventListener('change', onDataset);
$('kfDsFilter').addEventListener('input', e => fillDatasets(e.target.value));
$('kfRun').addEventListener('click', runKnown);
$('kfSend').addEventListener('click', ask);
$('kfQ').addEventListener('keydown', e => { if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) ask(); });
})();
</script>
```