User:Cobaltcigs/HistoryGraph.js: Difference between revisions
Content deleted Content added
Cobaltcigs (talk | contribs) m tweak |
Cobaltcigs (talk | contribs) re-writ |
||
Line 1: | Line 1: | ||
var wgPageName = mw.config.get('wgPageName'); |
|||
function AddGraphLink() { |
|||
var wgCurRevisionId = mw.config.get('wgCurRevisionId'); |
|||
if(wgAction != "history") return; |
|||
// var wgAction = mw.config.get('wgAction'); |
|||
var div = document.getElementById("histlegend"); |
|||
var wgAction = new URLSearchParams(location.href).get("action"); // detect fake actions |
|||
if(div == null) return; |
|||
var ul = div.getElementsByTagName("ul")[0]; |
|||
function HistoryGraph() { |
|||
if(ul == null) return; |
|||
if(wgCurRevisionId == 0) return; |
|||
ul.innerHTML += '<li><a onclick="ShowGraph()">Show graph</a></li>'; |
|||
var hist = document.getElementById("ca-history"); |
|||
} |
|||
if(!hist) return; |
|||
function HideGraph() { |
|||
var |
var li = document.createElement('li'); |
||
var a = document.createElement('a'); |
|||
if(old) old.style.visibility = "hidden"; |
|||
li.id = 'ca-graph'; |
|||
} |
|||
a.href = `/w/index.php?title=${wgPageName}&action=graph`; |
|||
function ShowGraph() { |
|||
a.title = "View graph of page history"; |
|||
var old = document.getElementById("history-graph"); |
|||
a.innerText = "Graph"; |
|||
if(old) { |
|||
li.appendChild(a); |
|||
old.style.visibility = "visible"; |
|||
hist.insertAdjacentElement("afterend", li); |
|||
return; |
|||
if(wgAction != "graph") return; |
|||
} |
|||
var contentDiv = document.getElementById("mw-content-text"); |
|||
var width = 640, height = 480, color = "red", stroke_width = 2; |
|||
contentDiv.innerHTML = ''; |
|||
var b = []; |
|||
var fakeTitle = wgPageName.replace(/_/g, " ") + ": History graph"; |
|||
var e = document.getElementsByClassName("history-size"); |
|||
document.getElementById("firstHeading").innerHTML = fakeTitle; |
|||
if(e.length == 0) return; |
|||
document.title = fakeTitle; |
|||
for(var i = 0; i < e.length; i++) { |
|||
var v = parseInt(e[i].innerText.replace(/\D/g, "")); |
|||
var ym = new Date().toJSON().match(/^(\d+)\-(\d+)/); |
|||
if(isNaN(v)) continue; |
|||
var yyyy = parseInt(ym[1]), mm = parseInt(ym[2]), d1 = "01T00:00:00Z"; |
|||
b.push(v); |
|||
var f = function(d) { return d.toString().padStart(2,'0'); } |
|||
var url_base_dbg = '/w/api.php?action=query&prop=revisions&rvlimit=1&rvprop=size|timestamp|ids'; |
|||
var url_base = '/w/api.php?action=query&prop=revisions&rvlimit=1&rvprop=size&format=json'; |
|||
var f1 = function(r1) { return r1.json(); }; |
|||
var sz = []; |
|||
var doneLoading = function() { |
|||
var divs = contentDiv.getElementsByTagName("div"); |
|||
divs[divs.length-1].innerHTML += " (No more found!)"; |
|||
sz.push(0); |
|||
drawGraph(); |
|||
} |
} |
||
var loop = function() { |
|||
if(b.length == 1) b.push(b[0]); // flat line for single rev |
|||
var time = [f(yyyy), f(mm), d1].join('-'); |
|||
b.reverse(); |
|||
var url_i = `&titles=${wgPageName}&rvstart=${time}`; |
|||
var max = Math.max.apply(null, b), min = Math.min.apply(null, b); |
|||
var url = url_base + url_i; |
|||
var dbg_url = url_base_dbg + url_i; |
|||
contentDiv.innerHTML += `<div><a>Fetching last edit before ${time}...</a></div>`; |
|||
var dy = height/db; |
|||
var f2 = function(r2) { |
|||
var jtxt = JSON.stringify(r2.query); |
|||
var ms = jtxt.match(/"size"\:(\d+)/); |
|||
if(!ms) { doneLoading(); return; } |
|||
var db = Math.floor(max/dd)*dd; |
|||
sz.push(parseInt(ms[1])); |
|||
var pts = []; |
|||
mm--; |
|||
for(var i = 0; i < b.length; i++) |
|||
if(mm==0) { mm = 12; yyyy--; } |
|||
pts.push(`${(i * dx)}, ${height - (b[i]-min) * dy}`); |
|||
loop(); |
|||
var gpath = [], gtext = []; |
|||
}; |
|||
for(var i = da; i <= db; i += dd) { |
|||
fetch(url).then(f1).then(f2); |
|||
var y = height - (i - min) * dy; |
|||
}; |
|||
gpath.push(`<path d="M0,${y} L${width},${y}" />`); |
|||
loop(); |
|||
gtext.push(`<text x="40" y="${y}">${i}</text>`); |
|||
var drawGraph = function() { |
|||
var height = 480, color = "red", stroke_width = 2; |
|||
var q = "JFMAMJJASOND"; |
|||
sz.reverse(); |
|||
var max = Math.max.apply(null, sz); |
|||
var dl = Math.pow(10, Math.floor(Math.log10(max)-0.5)); |
|||
var dx = 20; |
|||
var dy = height/max; |
|||
var lmax = Math.floor(max/dl)*dl; |
|||
var width = dx * (sz.length + 1); |
|||
var pts = []; |
|||
var vpath=[], vtext = [], ytext = []; |
|||
for(var i = 0; i < sz.length; i++) { |
|||
pts.push(`${(i * dx)}, ${height - (sz[i] * dy)}`); |
|||
var x = i * dx; |
|||
var h = (mm==1)? (height+40) : height; |
|||
vpath.push(`<path d="M${x},0 L${x},${h}" />`); |
|||
vtext.push(`<text x="${x}" y="${height+20}">${q[mm-1]}</text>`); |
|||
if(i == 0 || mm == 1) |
|||
ytext.push(`<text x="${x}" y="${height+40}">${yyyy}</text>`); |
|||
mm++; |
|||
if(mm > 12) { mm = 1; yyyy++; } |
|||
} |
|||
var hpath = [], htext = []; |
|||
for(var i = 0; i <= lmax; i += dl) { |
|||
var y = height - (i * dy); |
|||
hpath.push(`<path d="M0,${y} L${width},${y}" />`); |
|||
htext.push(`<text x="40" y="${y}">${i}</text>`); |
|||
} |
|||
var path = `<path d="M${pts.join(' L')}" stroke="${color}" stroke-width="${stroke_width}" fill="none" />`; |
|||
var g1 = `<g stroke="gray" stroke-width="1" fill="none">${hpath.join('')}${vpath.join('')}</g>`; |
|||
var g2 = `<g font-family="monospace" font-size="12px" text-align="right" color="black">${htext.join('')}${vtext.join('')}${ytext.join('')}</g>`; |
|||
var svg = `<svg style="width:${width}px; height:${height+60}px;">${g1}${path}${g2}</svg>`; |
|||
contentDiv.innerHTML = svg; |
|||
} |
} |
||
var path = `<path d="M${pts.join(' L')}" stroke="${color}" stroke-width="${stroke_width}" fill="none" />`; |
|||
var g1 = `<g stroke="gray" stroke-width="1" fill="none">${gpath.join('')}</g>`; |
|||
var g2 = `<g font-family="monospace" font-size="12px" text-align="right" color="black">${gtext.join('')}</g>`; |
|||
var svg = `<svg style="width:${width}px; height:${height}px;">${g1}${path}${g2}</svg>`; |
|||
var divStyle = `position:fixed; top:50%; left:50%; transform:translate(-50%, -50%); display:inline-block; border: 1px solid black; background-color:white;`; |
|||
var xbox = `<button style="float:right; height: 25px; width: 25px; font-size:20px; line-height:100%; font-weight: bolder; background-color:red; color:white;" onclick="HideGraph()">×</button>`; |
|||
var div = `<div id="history-graph" style="${divStyle}">${xbox}${svg}</div>`; |
|||
document.body.innerHTML += div; |
|||
} |
} |
||
HistoryGraph(); |
Revision as of 10:16, 16 October 2019
var wgPageName = mw.config.get('wgPageName');
var wgCurRevisionId = mw.config.get('wgCurRevisionId');
// var wgAction = mw.config.get('wgAction');
var wgAction = new URLSearchParams(location.href).get("action"); // detect fake actions
function HistoryGraph() {
if(wgCurRevisionId == 0) return;
var hist = document.getElementById("ca-history");
if(!hist) return;
var li = document.createElement('li');
var a = document.createElement('a');
li.id = 'ca-graph';
a.href = `/w/index.php?title=${wgPageName}&action=graph`;
a.title = "View graph of page history";
a.innerText = "Graph";
li.appendChild(a);
hist.insertAdjacentElement("afterend", li);
if(wgAction != "graph") return;
var contentDiv = document.getElementById("mw-content-text");
contentDiv.innerHTML = '';
var fakeTitle = wgPageName.replace(/_/g, " ") + ": History graph";
document.getElementById("firstHeading").innerHTML = fakeTitle;
document.title = fakeTitle;
var ym = new Date().toJSON().match(/^(\d+)\-(\d+)/);
var yyyy = parseInt(ym[1]), mm = parseInt(ym[2]), d1 = "01T00:00:00Z";
var f = function(d) { return d.toString().padStart(2,'0'); }
var url_base_dbg = '/w/api.php?action=query&prop=revisions&rvlimit=1&rvprop=size|timestamp|ids';
var url_base = '/w/api.php?action=query&prop=revisions&rvlimit=1&rvprop=size&format=json';
var f1 = function(r1) { return r1.json(); };
var sz = [];
var doneLoading = function() {
var divs = contentDiv.getElementsByTagName("div");
divs[divs.length-1].innerHTML += " (No more found!)";
sz.push(0);
drawGraph();
}
var loop = function() {
var time = [f(yyyy), f(mm), d1].join('-');
var url_i = `&titles=${wgPageName}&rvstart=${time}`;
var url = url_base + url_i;
var dbg_url = url_base_dbg + url_i;
contentDiv.innerHTML += `<div><a href="${dbg_url}">Fetching last edit before ${time}...</a></div>`;
var f2 = function(r2) {
var jtxt = JSON.stringify(r2.query);
var ms = jtxt.match(/"size"\:(\d+)/);
if(!ms) { doneLoading(); return; }
sz.push(parseInt(ms[1]));
mm--;
if(mm==0) { mm = 12; yyyy--; }
loop();
};
fetch(url).then(f1).then(f2);
};
loop();
var drawGraph = function() {
var height = 480, color = "red", stroke_width = 2;
var q = "JFMAMJJASOND";
sz.reverse();
var max = Math.max.apply(null, sz);
var dl = Math.pow(10, Math.floor(Math.log10(max)-0.5));
var dx = 20;
var dy = height/max;
var lmax = Math.floor(max/dl)*dl;
var width = dx * (sz.length + 1);
var pts = [];
var vpath=[], vtext = [], ytext = [];
for(var i = 0; i < sz.length; i++) {
pts.push(`${(i * dx)}, ${height - (sz[i] * dy)}`);
var x = i * dx;
var h = (mm==1)? (height+40) : height;
vpath.push(`<path d="M${x},0 L${x},${h}" />`);
vtext.push(`<text x="${x}" y="${height+20}">${q[mm-1]}</text>`);
if(i == 0 || mm == 1)
ytext.push(`<text x="${x}" y="${height+40}">${yyyy}</text>`);
mm++;
if(mm > 12) { mm = 1; yyyy++; }
}
var hpath = [], htext = [];
for(var i = 0; i <= lmax; i += dl) {
var y = height - (i * dy);
hpath.push(`<path d="M0,${y} L${width},${y}" />`);
htext.push(`<text x="40" y="${y}">${i}</text>`);
}
var path = `<path d="M${pts.join(' L')}" stroke="${color}" stroke-width="${stroke_width}" fill="none" />`;
var g1 = `<g stroke="gray" stroke-width="1" fill="none">${hpath.join('')}${vpath.join('')}</g>`;
var g2 = `<g font-family="monospace" font-size="12px" text-align="right" color="black">${htext.join('')}${vtext.join('')}${ytext.join('')}</g>`;
var svg = `<svg style="width:${width}px; height:${height+60}px;">${g1}${path}${g2}</svg>`;
contentDiv.innerHTML = svg;
}
}
HistoryGraph();