Widget:Grafico: differenze tra le versioni
Da WikiLectio.
m test |
m test |
||
| Riga 1: | Riga 1: | ||
<div style=" | <!-- Widget:Grafico — Chart.js con supporto a 4 serie + punto di equilibrio --> | ||
<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'}-->" | |||
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> | </div> | ||
<!-- Chart.js (CDN) --> | |||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |||
{literal} | |||
<script> | |||
(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; } | |||
function buildDataset(title, data, type, color){ | |||
if(!title || !data) return null; | |||
return { | |||
label: title, | |||
data: csvToNum(data), | |||
type: (type || 'line'), | |||
fill: false, | |||
borderColor: color || undefined, | |||
backgroundColor: color || undefined, | |||
tension: 0, | |||
pointRadius: 2 | |||
}; | |||
} | |||
document.querySelectorAll("canvas[id^='canvas_']").forEach(function(c){ | |||
var ds = c.dataset; | |||
var labels = csvToArray(ds.labels); | |||
var datasets = []; | |||
[['series1Title','series1Data','series1Type','series1Color'], | |||
['series2Title','series2Data','series2Type','series2Color'], | |||
['series3Title','series3Data','series3Type','series3Color'], | |||
['series4Title','series4Data','series4Type','series4Color'] | |||
].forEach(function(keys){ | |||
var d = buildDataset(ds[keys[0].toLowerCase()], ds[keys[1].toLowerCase()], ds[keys[2].toLowerCase()], ds[keys[3].toLowerCase()]); | |||
if(d) datasets.push(d); | |||
}); | |||
// 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: "#000000", | |||
backgroundColor: "#000000" | |||
}); | |||
} | |||
var numericLabels = labels.every(l => !isNaN(Number(l))); | |||
var cfg = { | |||
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 | |||
} | |||
} | |||
} | |||
}; | |||
new Chart(c.getContext('2d'), cfg); | |||
}); | |||
})(); | |||
</script> | |||
{/literal} | |||
Versione delle 16:25, 19 set 2025
<canvas id="canvas_"
width=""
height=""
data-id=""
data-title=""
data-x-title=""
data-y-title=""
data-labels=""
data-series1-title=""
data-series1-data=""
data-series1-type=""
data-series1-color=""
data-series2-title=""
data-series2-data=""
data-series2-type=""
data-series2-color=""
data-series3-title=""
data-series3-data=""
data-series3-type=""
data-series3-color=""
data-series4-title=""
data-series4-data=""
data-series4-type=""
data-series4-color=""
data-eqx=""
data-eqy=""
data-show-legend=""
data-responsive=""
data-xmin=""
data-xmax=""
data-ymin=""
data-ymax=""
></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
{literal} <script> (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; }
function buildDataset(title, data, type, color){
if(!title || !data) return null;
return {
label: title,
data: csvToNum(data),
type: (type || 'line'),
fill: false,
borderColor: color || undefined,
backgroundColor: color || undefined,
tension: 0,
pointRadius: 2
};
}
document.querySelectorAll("canvas[id^='canvas_']").forEach(function(c){
var ds = c.dataset;
var labels = csvToArray(ds.labels);
var datasets = [];
[['series1Title','series1Data','series1Type','series1Color'],
['series2Title','series2Data','series2Type','series2Color'],
['series3Title','series3Data','series3Type','series3Color'],
['series4Title','series4Data','series4Type','series4Color']
].forEach(function(keys){
var d = buildDataset(ds[keys[0].toLowerCase()], ds[keys[1].toLowerCase()], ds[keys[2].toLowerCase()], ds[keys[3].toLowerCase()]);
if(d) datasets.push(d);
});
// 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: "#000000",
backgroundColor: "#000000"
});
}
var numericLabels = labels.every(l => !isNaN(Number(l)));
var cfg = {
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
}
}
}
};
new Chart(c.getContext('2d'), cfg);
});
})(); </script> {/literal}