Widget:Grafico: differenze tra le versioni
Da WikiLectio.
m test |
m test |
||
| Riga 1: | Riga 1: | ||
<includeonly> | <includeonly> | ||
<div id=" | <div id="chartwrap_<!--{$id|escape:'html'}-->" | ||
style="width:<!--{$width|default:600|escape:'html'}-->px;height:<!--{$height|default:380|escape:'html'}-->px;"> | |||
<canvas id="canvas_<!--{$id|escape:'html'}-->" | |||
width="<!--{$width|default:600|escape:'html'}-->" | |||
<div id=" | height="<!--{$height|default:380|escape:'html'}-->" | ||
data-id="<!--{$id|escape:'html'}-->" | |||
data-title="<!--{$title|escape:'html'}-->" | |||
data-x-title="<!--{$xTitle|default:'Quantità di appartamenti'|escape:'html'}-->" | |||
data-y-title="<!--{$yTitle|default:'Prezzo dell\'affitto'|escape:'html'}-->" | |||
data-labels="<!--{$labels|default:'0,2,4,6,8,10'|escape:'html'}-->" | |||
data-series1-title="<!--{$series1title|escape:'html'}-->" | |||
data-series1-data="<!--{$series1data|escape:'html'}-->" | |||
data-series1-type="<!--{$series1type|default:'line'|escape:'html'}-->" | |||
data-series1-color="<!--{$series1color|escape:'html'}-->" | |||
data-series2-title="<!--{$series2title|escape:'html'}-->" | |||
data-series2-data="<!--{$series2data|escape:'html'}-->" | |||
data-series2-type="<!--{$series2type|default:'line'|escape:'html'}-->" | |||
data-series2-color="<!--{$series2color|escape:'html'}-->" | |||
data-series3-title="<!--{$series3title|escape:'html'}-->" | |||
data-series3-data="<!--{$series3data|escape:'html'}-->" | |||
data-series3-type="<!--{$series3type|default:'line'|escape:'html'}-->" | |||
data-series3-color="<!--{$series3color|escape:'html'}-->" | |||
data-series4-title="<!--{$series4title|escape:'html'}-->" | |||
data-series4-data="<!--{$series4data|escape:'html'}-->" | |||
data-series4-type="<!--{$series4type|default:'line'|escape:'html'}-->" | |||
data-series4-color="<!--{$series4color|escape:'html'}-->" | |||
data-eqx="<!--{$eqX|escape:'html'}-->" | |||
data-eqy="<!--{$eqY|escape:'html'}-->" | |||
data-show-legend="<!--{$showLegend|default:'true'|escape:'html'}-->" | |||
data-responsive="<!--{$responsive|default:'true'|escape:'html'}-->" | |||
data-xmin="<!--{$xMin|escape:'html'}-->" | |||
data-xmax="<!--{$xMax|escape:'html'}-->" | |||
data-ymin="<!--{$yMin|escape:'html'}-->" | |||
data-ymax="<!--{$yMax|escape:'html'}-->" | |||
></canvas> | |||
<div id="chartmsg_<!--{$id|escape:'html'}-->" style="font-size:12px;color:#a00;margin-top:4px;"></div> | |||
</div> | </div> | ||
<!-- Carica Chart.js (se il CDN è bloccato, vedi nota in fondo) --> | |||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | ||
<script> | <script> | ||
(function(){ | (function(){ | ||
function csvToArray(str){ if(!str) return []; return str.split(',').map(s=>s.trim()); } | |||
function csvToNum(str){ return csvToArray(str).map(v=>{const n=Number(v); return isNaN(n)?null:n;}); } | |||
function truthy(s){ return String(s||'').toLowerCase() !== 'false'; } | |||
function numOrUndef(s){ const n = Number(s); return isNaN(n) ? undefined : n; } | |||
var id = "<!--{$id|escape:'html'}-->"; | |||
var c = document.getElementById("canvas_" + id); | |||
var msg = document.getElementById("chartmsg_" + id); | |||
new Chart(c.getContext('2d'), { | if(!c){ if(msg) msg.textContent = "Canvas non trovato (id="+id+")"; return; } | ||
if(typeof Chart === "undefined"){ if(msg) msg.textContent = "Chart.js non caricato (CDN bloccato?)"; return; } | |||
try { | |||
}); | var ds = c.dataset; | ||
var labels = csvToArray(ds.labels); | |||
// Usa camelCase per leggere i data-attributes | |||
var seriesDefs = [ | |||
{ t: ds.series1Title, d: ds.series1Data, ty: ds.series1Type, c: ds.series1Color }, | |||
{ t: ds.series2Title, d: ds.series2Data, ty: ds.series2Type, c: ds.series2Color }, | |||
{ t: ds.series3Title, d: ds.series3Data, ty: ds.series3Type, c: ds.series3Color }, | |||
{ t: ds.series4Title, d: ds.series4Data, ty: ds.series4Type, c: ds.series4Color } | |||
]; | |||
var datasets = []; | |||
seriesDefs.forEach(function(s){ | |||
if(s.t && s.d){ | |||
datasets.push({ | |||
label: s.t, | |||
data: csvToNum(s.d), | |||
type: (s.ty || 'line'), | |||
fill: false, | |||
borderColor: s.c || undefined, | |||
backgroundColor: s.c || undefined, | |||
tension: 0, | |||
pointRadius: 2 | |||
}); | |||
} | |||
}); | |||
// Punto di equilibrio opzionale | |||
var eqx = Number(ds.eqx), eqy = Number(ds.eqy); | |||
if(!isNaN(eqx) && !isNaN(eqy)){ | |||
datasets.push({ | |||
label: 'Equilibrio', | |||
type: 'scatter', | |||
data: [{x:eqx, y:eqy}], | |||
showLine: false, | |||
pointRadius: 5, | |||
pointHoverRadius: 6, | |||
borderColor: '#000', backgroundColor: '#000' | |||
}); | |||
} | |||
var numericLabels = labels.every(function(l){ return !isNaN(Number(l)); }); | |||
new Chart(c.getContext('2d'), { | |||
type: 'line', | |||
data: { labels: labels, datasets: datasets }, | |||
options: { | |||
responsive: truthy(ds.responsive), | |||
maintainAspectRatio: false, | |||
plugins: { | |||
title: { display: !!ds.title, text: ds.title }, | |||
legend: { display: truthy(ds.showLegend) }, | |||
tooltip: { enabled: true } | |||
}, | |||
elements: { line: { borderWidth: 2 } }, | |||
scales: { | |||
x: numericLabels ? { | |||
type: 'linear', | |||
title: { display: true, text: ds.xTitle || 'Quantità di appartamenti' }, | |||
min: numOrUndef(ds.xmin), max: numOrUndef(ds.xmax) | |||
} : { | |||
type: 'category', | |||
title: { display: true, text: ds.xTitle || 'Quantità di appartamenti' } | |||
}, | |||
y: { | |||
title: { display: true, text: ds.yTitle || "Prezzo dell'affitto" }, | |||
min: numOrUndef(ds.ymin), max: numOrUndef(ds.ymax), | |||
beginAtZero: false | |||
} | |||
} | |||
} | |||
}); | |||
if (msg) msg.textContent = ""; | |||
} catch(e){ | |||
if (msg) msg.textContent = "Errore rendering: " + (e && e.message ? e.message : e); | |||
console.error("[Widget:Grafico] errore:", e); | |||
} | |||
})(); | })(); | ||
</script> | </script> | ||
<!-- | |||
Se il tuo hosting blocca il CDN, scarica Chart.js (chart.umd.js) e servilo in locale: | |||
1) carica /resources/chart.umd.js | |||
2) sostituisci la riga del CDN con: | |||
<script src="/resources/chart.umd.js"></script> | |||
--> | |||
</includeonly> | </includeonly> | ||