MediaWiki:Common.js: Unterschied zwischen den Versionen

Keine Bearbeitungszusammenfassung
Markierung: Manuelle Zurücksetzung
Keine Bearbeitungszusammenfassung
Zeile 743: Zeile 743:




// Chart.js aus CDN laden (einmalig)
function ensureChartJS(cb){
function ensureChartJS(cb){
   if (window.Chart) return cb();
   if (window.Chart) return cb();
Zeile 752: Zeile 751:
}
}


// Nimmt die ERSTE Tabelle NACH einem .ados-chart-Container und baut daraus ein Chart
const ADOS_COLORS = {
function renderAdosCharts($scope){
  'A Dream of Scotland':                    '#ef4444', // rot
   var blocks = ($scope || document).querySelectorAll('.ados-chart');
  'A Dream of Ireland':                    '#10b981', // grün
  if (!blocks.length) return;
   'A Dream of... – Der Rest der Welt':      '#8b5cf6', // violett
  'Friendly Mr. Z':                        '#0ea5e9', // blau
  'Die Whisky Elfen':                      '#14b8a6', // türkis
  'The Fine Art of Whisky':                '#e11d48'  // pink-rot
};
const COLOR_CYCLE = ['#2563eb','#16a34a','#f97316','#dc2626','#a855f7','#0ea5e9','#f59e0b','#10b981'];


  ensureChartJS(function(){
function toYear(x){ const n=parseInt(String(x).replace(/[^\d]/g,''),10); return isFinite(n)?n:null; }
    blocks.forEach(function(block){
function getColor(name, used){ return ADOS_COLORS[name] || COLOR_CYCLE[(used.size)%COLOR_CYCLE.length] && (used.add(name), COLOR_CYCLE[(used.size-1)%COLOR_CYCLE.length]); }
      // nächste Tabelle nach dem Block finden
      var tbl = block.nextElementSibling;
      while (tbl && tbl.tagName !== 'TABLE') { tbl = tbl.nextElementSibling; }
      if (!tbl) return;


      // Kopf + Zeilen auslesen (erwartet: Jahr | Anzahl)
function buildDatasetsFromTable(tbl){
      var rows = Array.from(tbl.querySelectorAll('tr'));
  const rows=[...tbl.querySelectorAll('tr')]; if(rows.length<2) return {labels:[],datasets:[]};
      if (rows.length < 2) return;
  const years=new Set(), map=new Map();
 
  rows.slice(1).forEach(tr=>{
      var labels = [], data = [];
    const tds=tr.querySelectorAll('td,th'); if(tds.length<3) return;
      rows.slice(1).forEach(function(tr){
    const y=toYear(tds[0].textContent), s=tds[1].textContent.trim(), v=parseFloat(tds[2].textContent.replace(',','.'))||0;
        var tds = tr.querySelectorAll('td,th');
    if(y==null) return; years.add(y); if(!map.has(s)) map.set(s,new Map()); map.get(s).set(y,v);
        if (tds.length >= 2){
  });
          labels.push(tds[0].textContent.trim());
  const labels=[...years].sort((a,b)=>a-b).map(String);
          var v = parseFloat(tds[1].textContent.replace(',','.')) || 0;
  const used=new Set();
          data.push(v);
  const datasets=[...map.entries()].map(([name,ym])=>{
        }
    const data=labels.map(y=>ym.get(+y)||0); const c=getColor(name,used);
      });
    return { label:name, data, borderColor:c, backgroundColor:c+'80', tension:.25, pointRadius:3 };
 
  });
      // Canvas einsetzen
  return {labels,datasets};
      var wrap = document.createElement('div');
}
      wrap.style.position='relative';
      wrap.style.height='420px';
      wrap.style.width='100%';
      var canvas = document.createElement('canvas');
      wrap.appendChild(canvas);
      block.innerHTML = ''; block.appendChild(wrap);


      // Chart zeichnen
function renderMultiChart(block){
      var type = block.dataset.type || 'line';
  let tbl=block.nextElementSibling; while(tbl && tbl.tagName!=='TABLE') tbl=tbl.nextElementSibling;
      var title = block.dataset.title || '';
  if(!tbl) return;
      new Chart(canvas.getContext('2d'), {
  const {labels,datasets}=buildDatasetsFromTable(tbl); if(!labels.length||!datasets.length) return;
        type: type,
  const wrap=document.createElement('div'); wrap.style.position='relative'; wrap.style.height='440px'; wrap.style.width='100%';
        data: {
  const canvas=document.createElement('canvas'); wrap.appendChild(canvas); block.innerHTML=''; block.appendChild(wrap);
          labels: labels,
  const type=(block.dataset.type||'line').toLowerCase(); const title=block.dataset.title||'';
          datasets: [{
  new Chart(canvas.getContext('2d'), {
            label: title || 'Werte',
    type, data:{labels,datasets},
            data: data,
    options:{ responsive:true, maintainAspectRatio:false,
            tension: 0.25,
      scales:{ y:{ beginAtZero:true, ticks:{ precision:0 } } },
            pointRadius: 3
      plugins:{ legend:{ position:'bottom' }, title:{ display:!!title, text:title } }
          }]
     }
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          scales: { y: { beginAtZero: true } },
          plugins: {
            legend: { display: !!title },
            title: { display: !!title, text: title }
          }
        }
      });
     });
   });
   });
}
}


// auf jeder Seite, nach Content-Ladung
mw.hook('wikipage.content').add(function($c){
mw.hook('wikipage.content').add(function($c){
   renderAdosCharts($c[0] || document);
   const scope=($c&&$c[0])?$c[0]:document;
  const blocks=scope.querySelectorAll('.ados-chart-multi');
  if(!blocks.length) return;
  ensureChartJS(()=>blocks.forEach(renderMultiChart));
});
});