User:Magicpiano/NRBot/NRHPmap.js
Appearance
< User:Magicpiano | NRBot
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:Magicpiano/NRBot/NRHPmap. |
/* jshint maxerr: 3000 */
function NRHPmapbutton() {
if (mw.config.get('wgPageName')!="Wikipedia:WikiProject_National_Register_of_Historic_Places/Progress"||location.href.indexOf('action')!=-1) {
return;
}
var button=document.getElementById("NRHPUpdateMapButton");
if (button !== null) return;
button = document.createElement("input");
button.setAttribute("type", "button");
button.setAttribute("value", "Generate SVG Output");
button.setAttribute("onclick", "MapButtonClick()");
button.id = "NRHPUpdateMapButton";
var content=document.getElementById('mw-content-text');
content.parentNode.insertBefore(button, content);
}
function MapButtonClick() {
var button = document.getElementById('NRHPUpdateMapButton');
button.disabled = true;
var SVGDiv = document.getElementById('SVGDiv');
if (SVGDiv === null) {
SVGDiv = document.createElement('div');
SVGDiv.setAttribute('id', 'SVGDiv');
SVGDiv.setAttribute("style", "width:500px; border:1px solid black; padding:5px");
button.parentNode.insertBefore(SVGDiv, button);
}
SVGDiv.innerHTML = "Fetching wikitext...";
getSVGtext("Wikipedia:WikiProject National Register of Historic Places/Progress/SVG");
}
function getSVGtext(title) { // get SVG code from /SVG page
var SVGtext="";
$.ajax({
dataType: "json",
url: mw.util.wikiScript('api'),
data: {
format: 'json',
action: 'query',
prop: 'revisions',
rvprop: 'content',
titles: title,
indexpageids: true,
redirects: 'true'
},
error: function() {SVGtext="error"},
success: function(output) {
for (var page in output.query.pages) {
SVGtext=output.query.pages[page].revisions[0]['*'];
}
},
complete: function() {
if (SVGtext=="error") {
var SVGDiv=document.getElementById("SVGDiv");
SVGDiv.innerHTML+=" Unable to fetch wikitext! Script aborted.";
} else {
getProgressText(SVGtext,"Wikipedia:WikiProject National Register of Historic Places/Progress");
}
}
});
}
function getProgressText(SVGtext,title) { // get progress page wikitext
var ProgressText="";
$.ajax({
dataType: "json",
url: mw.util.wikiScript('api'),
data: {
format: 'json',
action: 'query',
prop: 'revisions',
rvprop: 'content',
titles: title,
indexpageids: true,
redirects: 'true'
},
error: function() {ProgressText="error"},
success: function(output) {
for (var page in output.query.pages) {
ProgressText=output.query.pages[page].revisions[0]['*'];
}
},
complete: function() {
if (ProgressText=="error") {
var SVGDiv=document.getElementById("SVGDiv");
SVGDiv.innerHTML+=" Unable to fetch wikitext! Script aborted.";
} else {
ExtractMapInfo(SVGtext,ProgressText);
}
}
});
}
function ExtractMapInfo(SVGtext,ProgressText) {
var SVGDiv=document.getElementById("SVGDiv");
SVGDiv.innerHTML+=" Done!";
ProgressText=ProgressText.split("==State totals==")[1]; // get rid of header
var StateNames= ["OVERALL STATE PERCENTAGES","ALABAMA","ALASKA","ARIZONA","ARKANSAS","CALIFORNIA","COLORADO","CONNECTICUT","DELAWARE"];
StateNames.push("D.C.","FLORIDA","GEORGIA","HAWAII","IDAHO","ILLINOIS","INDIANA","IOWA","KANSAS","KENTUCKY","LOUISIANA","MAINE");
StateNames.push("MARYLAND","MASSACHUSETTS","MICHIGAN","MINNESOTA","MISSISSIPPI","MISSOURI","MONTANA","NEBRASKA","NEVADA");
StateNames.push("NEW HAMPSHIRE","NEW JERSEY","NEW MEXICO","NEW YORK","NORTH CAROLINA","NORTH DAKOTA","OHIO","OKLAHOMA","OREGON");
StateNames.push("PENNSYLVANIA","RHODE ISLAND","SOUTH CAROLINA","SOUTH DAKOTA","TENNESSEE","TEXAS","UTAH","VERMONT");
StateNames.push("VIRGINIA","WASHINGTON","WEST VIRGINIA","WISCONSIN","WYOMING");
var StateAbbrs= ['XX','AL','AK','AZ','AR','CA','CO','CT','DE','DC','FL','GA','HI','ID','IL','IN','IA','KS','KY','LA','ME','MD'];
StateAbbrs.push('MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','OH','OK','OR','PA','RI','SC','SD');
StateAbbrs.push('TN','TX','UT','VT','VA','WA','WV','WI','WY','PR','GU','VI','MP','AS');
var TempStartIndex;
var TempEndIndex;
var i,j,k;
var nextID;
var nextRowText;
var StatsToCheck=["Illustrated","Articled","Start+","Net Quality"];
for (var currentStat=0; currentStat<StatsToCheck.length; currentStat++ ) { // loop through each statistic to create SVG code
var ThisStatText="";
var OverallStatePercentagesText="";
var NoListings=[];
var total;
var illustrated;
var stubs;
var NRISonly;
var startPlus;
var unassessed;
var untagged;
var articled;
var Percentage=0;
var TableStartIndex=0;
for (i=0; i<StateNames.length; i++) { // loop through all states, i=0 corresponds to national table
var StateTable={"100Percent":[], "90Percent":[], "80Percent":[], "70Percent":[], "60Percent":[], "50Percent":[], "40Percent":[], "30Percent":[], "20Percent":[], "10Percent":[], "00Percent":[]};
TableStartIndex=ProgressText.indexOf("{|",TableStartIndex+1);
var TableEndIndex=ProgressText.indexOf("|}",TableStartIndex)+2;
var TableText=ProgressText.substr(TableStartIndex,TableEndIndex-TableStartIndex);
var RowStartIndex=0;
var RowNumber=0;
var DCdone=false;
while (RowStartIndex!=-1) { // loop until no more rows
RowStartIndex=TableText.indexOf("\n|-",RowStartIndex+1); // find next row in table
var RowEndIndex=TableText.indexOf("\n|-",RowStartIndex+1);
if (RowEndIndex==-1) RowEndIndex=TableText.length; // last row ends at end of table
var RowText=TableText.substr(RowStartIndex,RowEndIndex-RowStartIndex);
RowNumber++;
if (i===0&&RowNumber==StateAbbrs.length) break; // manual break for national table since some rows aren't on the map
var ID=RowText.match(/(\d{5}|-----|ddddd)/g);
if (i===0) ID=StateAbbrs[RowNumber];
if (ID===null||ID[0]=="ddddd"||ID[0]=="-----") continue; // skip duplicate rows, sublists, and state total row
if (i!==0) ID=ID[0];
if (ID=="02230"||ID=="02275"||ID=="02063") continue; // skip special cases in Alaska, taken care of below
if (ID=="02105") { // special case for Hoonah–Angoon Census Area, Alaska
TempStartIndex=RowStartIndex;
nextID="00000";
while (nextID!="02230") { // look for Skagway
TempStartIndex=TableText.indexOf("\n|-",TempStartIndex+1);
TempEndIndex=TableText.indexOf("\n|-",TempStartIndex+1);
if (TempEndIndex==-1) TempEndIndex=TableText.length;
nextRowText=TableText.substr(TempStartIndex,TempEndIndex-TempStartIndex);
nextID=nextRowText.match(/(\d{5}|-----|ddddd)/g);
if (nextID!==null) nextID=nextID[0];
}
var HoonahStats=RowText.match(/[^\d](\d{1,3},)*\d{1,3}(?!(%|\.|\d))/g);
var SkagwayStats=nextRowText.match(/[^\d](\d{1,3},)*\d{1,3}(?!(%|\.|\d))/g);
switch(currentStat) {
case 0: // Illustrated
total=parseFloat(HoonahStats[0])+parseFloat(SkagwayStats[0]);
illustrated=parseFloat(HoonahStats[1])+parseFloat(SkagwayStats[1]);
Percentage=Math.round(illustrated/total*1000)/10;
break;
case 1: // Articled
total=parseFloat(HoonahStats[0])+parseFloat(SkagwayStats[0]);
articled=parseFloat(HoonahStats[2])+parseFloat(SkagwayStats[2]);
Percentage=Math.round(articled/total*1000)/10;
break;
case 2: // Start+
total=parseFloat(HoonahStats[0])+parseFloat(SkagwayStats[0]);
startPlus=parseFloat(HoonahStats[5])+parseFloat(SkagwayStats[5]);
Percentage=Math.round(startPlus/total*1000)/10;
break;
case 3: // Net Quality
total=parseFloat(HoonahStats[0])+parseFloat(SkagwayStats[0]);
illustrated=parseFloat(HoonahStats[1])+parseFloat(SkagwayStats[1]);
stubs=parseFloat(HoonahStats[3])+parseFloat(SkagwayStats[3]);
NRISonly=parseFloat(HoonahStats[4])+parseFloat(SkagwayStats[4]);
startPlus=parseFloat(HoonahStats[5])+parseFloat(SkagwayStats[5]);
unassessed=parseFloat(HoonahStats[6])+parseFloat(SkagwayStats[6]);
untagged=parseFloat(HoonahStats[7])+parseFloat(SkagwayStats[7]);
Percentage=startPlus+0.5*stubs+0.5*unassessed-0.5*untagged-0.75*NRISonly;
Percentage=Math.round((0.75*Percentage/total+0.25*illustrated/total)*1000)/10;
if (Percentage<0) Percentage = 0;
break;
}
ID="02232"; // set special ID for map
} else if (ID=="02280") { // special case for Petersburg Census Area, Alaska
TempStartIndex=RowStartIndex;
nextID="00000";
while (nextID!="02275") { // look for Wrangell
TempStartIndex=TableText.indexOf("\n|-",TempStartIndex+1);
TempEndIndex=TableText.indexOf("\n|-",TempStartIndex+1);
if (TempEndIndex==-1) TempEndIndex=TableText.length;
nextRowText=TableText.substr(TempStartIndex,TempEndIndex-TempStartIndex);
nextID=nextRowText.match(/(\d{5}|-----|ddddd)/g);
if (nextID!==null) nextID=nextID[0];
}
var PetersburgStats=RowText.match(/[^\d](\d{1,3},)*\d{1,3}(?!(%|\.|\d))/g);
var WrangellStats=nextRowText.match(/[^\d](\d{1,3},)*\d{1,3}(?!(%|\.|\d))/g);
Percentage=0;
switch(currentStat) {
case 0: // Illustrated
total=parseFloat(PetersburgStats[0])+parseFloat(WrangellStats[0]);
illustrated=parseFloat(PetersburgStats[1])+parseFloat(WrangellStats[1]);
Percentage=Math.round(illustrated/total*1000)/10;
break;
case 1: // Articled
total=parseFloat(PetersburgStats[0])+parseFloat(WrangellStats[0]);
articled=parseFloat(PetersburgStats[2])+parseFloat(WrangellStats[2]);
Percentage=Math.round(articled/total*1000)/10;
break;
case 2: // Start+
total=parseFloat(PetersburgStats[0])+parseFloat(WrangellStats[0]);
startPlus=parseFloat(PetersburgStats[5])+parseFloat(WrangellStats[5]);
Percentage=Math.round(startPlus/total*1000)/10;
break;
case 3: // Net Quality
total=parseFloat(PetersburgStats[0])+parseFloat(WrangellStats[0]);
illustrated=parseFloat(PetersburgStats[1])+parseFloat(WrangellStats[1]);
stubs=parseFloat(PetersburgStats[3])+parseFloat(WrangellStats[3]);
NRISonly=parseFloat(PetersburgStats[4])+parseFloat(WrangellStats[4]);
startPlus=parseFloat(PetersburgStats[5])+parseFloat(WrangellStats[5]);
unassessed=parseFloat(PetersburgStats[6])+parseFloat(WrangellStats[6]);
untagged=parseFloat(PetersburgStats[7])+parseFloat(WrangellStats[7]);
Percentage=startPlus+0.5*stubs+0.5*unassessed-0.5*untagged-0.75*NRISonly;
Percentage=Math.round((0.75*Percentage/total+0.25*illustrated/total)*1000)/10;
if (Percentage<0) Percentage = 0;
break;
}
} else if (ID == "02061") { // former Valdez-Cordova Census Area, now placeholder for Copper River
TempStartIndex=RowStartIndex;
nextID="00000";
while (nextID!="02063") { // look for Chugach Census Area
TempStartIndex=TableText.indexOf("\n|-",TempStartIndex+1);
TempEndIndex=TableText.indexOf("\n|-",TempStartIndex+1);
if (TempEndIndex==-1) TempEndIndex=TableText.length;
nextRowText=TableText.substr(TempStartIndex,TempEndIndex-TempStartIndex);
nextID=nextRowText.match(/(\d{5}|-----|ddddd)/g);
if (nextID!==null) nextID=nextID[0];
}
var CopperRiverStats=RowText.match(/[^\d](\d{1,3},)*\d{1,3}(?!(%|\.|\d))/g);
var ChugachStats=nextRowText.match(/[^\d](\d{1,3},)*\d{1,3}(?!(%|\.|\d))/g);
Percentage=0;
switch(currentStat) {
case 0: // Illustrated
total=parseFloat(CopperRiverStats[0])+parseFloat(ChugachStats[0]);
illustrated=parseFloat(CopperRiverStats[1])+parseFloat(ChugachStats[1]);
Percentage=Math.round(illustrated/total*1000)/10;
break;
case 1: // Articled
total=parseFloat(CopperRiverStats[0])+parseFloat(ChugachStats[0]);
articled=parseFloat(CopperRiverStats[2])+parseFloat(ChugachStats[2]);
Percentage=Math.round(articled/total*1000)/10;
break;
case 2: // Start+
total=parseFloat(CopperRiverStats[0])+parseFloat(ChugachStats[0]);
startPlus=parseFloat(CopperRiverStats[5])+parseFloat(ChugachStats[5]);
Percentage=Math.round(startPlus/total*1000)/10;
break;
case 3: // Net Quality
total=parseFloat(CopperRiverStats[0])+parseFloat(ChugachStats[0]);
illustrated=parseFloat(CopperRiverStats[1])+parseFloat(ChugachStats[1]);
stubs=parseFloat(CopperRiverStats[3])+parseFloat(ChugachStats[3]);
NRISonly=parseFloat(CopperRiverStats[4])+parseFloat(ChugachStats[4]);
startPlus=parseFloat(CopperRiverStats[5])+parseFloat(ChugachStats[5]);
unassessed=parseFloat(CopperRiverStats[6])+parseFloat(ChugachStats[6]);
untagged=parseFloat(CopperRiverStats[7])+parseFloat(ChugachStats[7]);
Percentage=startPlus+0.5*stubs+0.5*unassessed-0.5*untagged-0.75*NRISonly;
Percentage=Math.round((0.75*Percentage/total+0.25*illustrated/total)*1000)/10;
if (Percentage<0) Percentage = 0;
break;
}
} else if (ID=="11001") { // special case for DC
if (DCdone) continue; // only record DC once
DCdone=true;
TempStartIndex=RowStartIndex;
var matched=false;
while (!matched) { // look for total row
TempStartIndex=TableText.indexOf("\n|-",TempStartIndex+1);
TempEndIndex=TableText.indexOf("\n|-",TempStartIndex+1);
if (TempEndIndex==-1) TempEndIndex=TableText.length;
nextRowText=TableText.substr(TempStartIndex,TempEndIndex-TempStartIndex);
var test=nextRowText.match("State Total");
if (test!==null) matched=true;
}
Percentage=nextRowText.match(/(\d|\.)+(?=%)/g);
Percentage=parseFloat(Percentage[currentStat]);
} else {
Percentage=RowText.match(/(\d|\.)+(?=%)/g); // extract percentages from row text
if (Percentage===null) {NoListings.push(ID); continue} // if no percentages, must be no listings
Percentage=parseFloat(Percentage[currentStat]); // get relevant percentage for this stat
}
if (Percentage==100) {StateTable["100Percent"].push(ID)}
else if (Percentage>=90) {StateTable["90Percent"].push(ID)}
else if (Percentage>=80) {StateTable["80Percent"].push(ID)}
else if (Percentage>=70) {StateTable["70Percent"].push(ID)}
else if (Percentage>=60) {StateTable["60Percent"].push(ID)}
else if (Percentage>=50) {StateTable["50Percent"].push(ID)}
else if (Percentage>=40) {StateTable["40Percent"].push(ID)}
else if (Percentage>=30) {StateTable["30Percent"].push(ID)}
else if (Percentage>=20) {StateTable["20Percent"].push(ID)}
else if (Percentage>=10) {StateTable["10Percent"].push(ID)}
else {StateTable["00Percent"].push(ID)}
}
ThisStatText+="/* *******************************************************************\n";
ThisStatText+=" " + StateNames[i] + "\n";
ThisStatText+="******************************************************************** */\n";
var colors=["313695","4575B4","74ADD1","ABD9E9","E0F3F8","FFFFBF","FEE090","FDAE61","F46D43","D73027","A50026"];
for (j=10; j>-1; j--) { // loop through each percentage
ThisStatText+="/* ";
if (j!==0) ThisStatText+=j;
ThisStatText+="0% "+StatsToCheck[currentStat]+" */\n ";
for (k=0; k<StateTable[j+"0Percent"].length; k++) {
if (i===0) {
ThisStatText+="."+StateTable[j+"0Percent"][k]+", ";
} else {
ThisStatText+=".c"+StateTable[j+"0Percent"][k]+", ";
}
}
if (StateTable[j+"0Percent"].length>0) ThisStatText=ThisStatText.substr(0,ThisStatText.length-2)+" ";
ThisStatText+="{fill: #"+colors[j]+"; }\n";
}
ThisStatText+="\n";
if (i===0) { // wait to add state totals to end of list
OverallStatePercentagesText=ThisStatText.substr(0,ThisStatText.length-2); // remove final line breaks
ThisStatText="";
}
}
// now add no listings text
ThisStatText+="/* *******************************************************************\n";
ThisStatText+=" NO LISTINGS IN COUNTY\n";
ThisStatText+="******************************************************************** */\n ";
for (k=0; k<NoListings.length; k++) {
ThisStatText+=".c"+NoListings[k]+", ";
}
if (NoListings.length>0) ThisStatText=ThisStatText.substr(0,ThisStatText.length-2)+" ";
ThisStatText+="{fill: #000000; }\n\n";
// finally add state totals text
ThisStatText+=OverallStatePercentagesText;
// now update SVG text
var StartIndex = 0;
var InsertLocations = [];
var SearchStr = 'overflow:scroll">';
for (i=0; i<StatsToCheck.length; i++) {
InsertLocations[i] = SVGtext.indexOf(SearchStr, StartIndex) + SearchStr.length + 1;
StartIndex = InsertLocations[i];
}
StartIndex = 0;
var EndInsertLocations = [];
SearchStr = '</pre>';
for (i=0; i<StatsToCheck.length; i++) {
EndInsertLocations[i] = SVGtext.indexOf(SearchStr, StartIndex) - 1;
StartIndex = EndInsertLocations[i] + SearchStr.length + 1;
}
var oldStatText=SVGtext.substr(InsertLocations[currentStat],EndInsertLocations[currentStat]-InsertLocations[currentStat]);
SVGtext=SVGtext.replace(oldStatText,ThisStatText);
}
// now edit page with updated SVG text
var d=new Date();
var months = ['January','February','March','April','May','June','July','August','September','October'];
months.push('November','December');
var year=d.getYear();
if (year < 1000) year += 1900;
var DateStr = months[d.getMonth()]+" "+d.getDate()+", "+year;
var summary="Updating SVG output as of "+DateStr+" using [[User:Magicpiano/NRBot/NRHPmap.js|script]].";
SVGDiv.innerHTML+="<br>Editing page...";
editMapPage("Wikipedia:WikiProject National Register of Historic Places/Progress/SVG",SVGtext,summary);
}
function editMapPage(title,text,summary) { // edit page when done
$.ajax({
dataType: 'json',
url: mw.util.wikiScript( 'api' ),
type: 'POST',
data: {
format: 'json',
action: 'edit',
title: title,
text: text,
summary: summary,
token: mw.user.tokens.get( 'csrfToken' )
},
success: function( data ) {
if (data && data.edit && data.edit.result && data.edit.result == 'Success') {
console.log('Page edit succeeded');
} else {
var msg;
if (data && data.error) {
msg = "Error editing page: ";
msg += " code=" + data.error.code;
msg += " info=" + data.error.info;
} else {
msg = "Error editing page (no data or error)";
}
alert(msg);
}
},
error: function(ajaxResponse,status,errorThrown) {ajaxResponse.errorThrown=errorThrown},
complete: function(ajaxResponse,status) {MapPageEdited(ajaxResponse,status)}
});
}
function MapPageEdited(ajaxResponse,status) {
var SVGDiv=document.getElementById("SVGDiv");
if (status!="success") {
SCGDiv.innerHTML+="Edit failed!";
return;
}
var responseText=JSON.parse(ajaxResponse.responseText);
var diff=responseText.edit.newrevid;
var linkStr="//en.wikipedia.org/w/index.php?diff="+diff;
SVGDiv.innerHTML+="Page edited! Click <a href='"+linkStr+"'>here</a> for diff.";
}
function MakePreCopyable() {
if (mw.config.get('wgPageName') != "Wikipedia:WikiProject_National_Register_of_Historic_Places/Progress/SVG") return;
var pres = document.getElementsByTagName('pre');
while (pres.length>0) {
var textarea = document.createElement('textarea');
textarea.innerHTML = pres[0].innerHTML;
pres[0].parentNode.insertBefore(textarea,pres[0].nextSibling);
pres[0].parentNode.removeChild(pres[0]);
textarea.setAttribute('style', 'width: 580px; height: 300px');
textarea.setAttribute('onclick', 'this.focus();this.select()');
}
}
$.when($.ready).then(function () { NRHPmapbutton(); MakePreCopyable();});