User:Timeshifter/Sandbox
Maternal mortality rates per 100,000 births. 2018-2021
Map of maternal mortality rates per 100,000 births by US state. 2018-2021. Centers for Disease Control (CDC).
.title { font-size:30px; letter-spacing:0; }
.legend { font-size:30px; }
.state { font-size:17px; }
.value { font-size:17px; }
.min { fill:#99ffff; }
.max { fill:#ff6600; }
.n_a { fill:#eeeeee; }
Maternal mortality rates per 100,000 births. 2018-2021
10.1
43.5
41.4
n/a
31.4
43.5
10.1
15.2
16.7
n/a
26.3
33.9
n/a
n/a
17.3
31.1
20.2
22.0
38.4
39.0
n/a
21.2
15.3
19.4
12.6
43.0
25.7
n/a
26.2
21.7
n/a
25.7
30.2
21.7
26.5
n/a
23.8
30.3
16.4
16.7
n/a
32.7
n/a
41.7
28.1
16.1
n/a
29.1
20.4
n/a
11.6
n/a
n/a
Alaska
Alabama
Arkansas
Arizona
California
Colorado
Connecticut
Delaware
Florida
Georgia
Hawaii
Iowa
Idaho
Illinois
Indiana
Kansas
Kentucky
Louisiana
Massachusetts
Maryland
Maine
Michigan
Minnesota
Missouri
Mississippi
Montana
N.Carolina
North Dakota
Nebraska
New Hampshire
New Jersey
New Mexico
Nevada
New York
Ohio
Oklahoma
Oregon
Pennsylvania
Rhode x="0" y="-2ex">Island
S.Carolina
South Dakota
Tennessee
Texas
Utah
Virginia
Vermont
Washington
Wisconsin
W.Virginia
Wyoming
D. C.
/// To recover the generator script, delete the "!" and 2 "-" on the line above
/// and the 2 "-" on the last line below. Amend the SVG-specific JavaScript as
/// needed. Open the file in Firefox. Save As another SVG to upload to Commons.
const outs = []; /// SVG may be pushed into this array even if outs is a const.
/// ======================== SVG-specific JavaScript ==========================
/** User-editable data for the choropleth map below until the next ///
http://commons.wikimedia.org/wiki/File_talk:Template_map_of_US_states_and_District_of_Columbia.svg/Instructions
has more detailed instructions */
const out_title = 'Maternal mortality rates per 100,000 births. 2018-2022';
const out_desc = 'Map of maternal mortality rates per 100,000 births by US state. 2018-2022. Centers for Disease Control (CDC).';
const no_data_value = 'n/a';
const decimal_place = 1;
const out_style = `
.title { font-size:30px; letter-spacing:0; }
.legend { font-size:30px; }
.state { font-size:17px; }
.value { font-size:17px; }
.min { fill:#99ffff; }
.max { fill:#ff6600; }
.n_a { fill:#eeeeee; }
`;
const state_space_value = `
Alabama 38.6
Alaska
Arizona 30.0
Arkansas 38.3
California 10.5
Colorado 16.0
Connecticut 15.6
Delaware
Florida 24.1
Georgia 32.1
Hawaii
Idaho 20.0
Illinois 18.1
Indiana 30.9
Iowa 19.5
Kansas 22.8
Kentucky 34.6
Louisiana 37.3
Maine
Maryland 21.3
Massachusetts 16.4
Michigan 19.1
Minnesota 12.3
Mississippi 39.1
Missouri 23.8
Montana
Nebraska 25.1
Nevada 20.4
New Hampshire
New Jersey 26.0
New Mexico 28.0
New York 22.4
North Carolina 26.7
North Dakota
Ohio 24.5
Oklahoma 29.6
Oregon 16.6
Pennsylvania 17.5
Rhode Island
South Carolina 32.3
South Dakota
Tennessee 41.1
Texas 28.2
Utah 15.5
Vermont
Virginia 32.7
Washington 18.0
West Virginia 23.9
Wisconsin 13.2
Wyoming
Washington DC
`; /// list state name (optionally then a space and value) above
const map_states = {'alabama':'AL','alaska':'AK','arizona':'AZ',
'arkansas':'AR', 'california':'CA', 'colorado':'CO', 'connecticut':'CT',
'delaware':'DE', 'florida':'FL', 'georgia':'GA', 'hawaii':'HI',
'idaho':'ID', 'illinois':'IL', 'indiana':'IN', 'iowa':'IA', 'kansas':'KS',
'kentucky':'KY', 'louisiana':'LA', 'maine':'ME', 'maryland':'MD',
'massachusetts':'MA', 'michigan':'MI', 'minnesota':'MN', 'mississippi':'MS',
'missouri':'MO', 'montana':'MT', 'nebraska':'NE', 'nevada':'NV',
'newhampshire':'NH', 'newjersey':'NJ', 'newmexico':'NM', 'newyork':'NY',
'northcarolina':'NC', 'northdakota':'ND', 'ohio':'OH', 'oklahoma':'OK',
'oregon':'OR', 'pennsylvania':'PA', 'rhodeisland':'RI',
'southcarolina':'SC', 'southdakota':'SD', 'tennessee':'TN', 'texas':'TX',
'utah':'UT', 'vermont':'VT', 'virginia':'VA', 'washington':'WA',
'westvirginia':'WV', 'wisconsin':'WI', 'wyoming':'WY', 'washingtondc':'DC'};
const datass = [];
var value_min = Infinity;
var value_max = -Infinity;
function round_to_string(x, decimal_places=2, do_trim=false) {
const str = parseFloat(x).toFixed(decimal_places);
return do_trim ? str.replace(/\.0*$|(\.\d+?)0+$/, '$1') : str;
}
function sanitise(x) { return x.replace(/\W/g, '').toLowerCase(); }
/// From http://copyprogramming.com/howto/levenshtein-distance-in-javascript
function levenshtein(str1, str2) {
const track = Array(str2.length + 1).fill(null).map(() =>
Array(str1.length + 1).fill(null));
for (var i = 0; i <= str1.length; ++i) { track[0][i] = i; }
for (var j = 0; j <= str2.length; ++j) { track[j][0] = j; }
for (var j = 1; j <= str2.length; ++j) {
for (var i = 1; i <= str1.length; ++i) {
const indicator = str1[i - 1] === str2[j - 1] ? 0 : 1;
track[j][i] = Math.min(
track[j][i - 1] + 1, /// deletion
track[j - 1][i] + 1, /// insertion
track[j - 1][i - 1] + indicator, /// substitution
);
}
}
return track[str2.length][str1.length];
};
/// Replace the first column of datass with codes in maps
/// TODO: Prevent a code appearing more than once in datass
function replace_names_with_codes(datass, maps) {
datass.forEach(function(datas) {
var name = sanitise(datas[0]);
if (!(name in maps)) { /// if name unrecognised, find closest name
var fom_best = Infinity, name_best;
for (const name_map in maps) {
/// if given name is a code itself, just use it, else use edit distance
if (name == sanitise(maps[name_map])) { name_best = name_map; break; }
const fom = levenshtein(name, name_map);
if (fom_best > fom) { fom_best = fom; name_best = name_map; }
// console.log(name_map, fom, fom_best, name_best);
}
name = name_best;
}
datas[0] = maps[name];
});
}
/// Ensure map is sanitised
for (const name in map_states) { map_states[sanitise(name)]=map_states[name]; }
/// Iterate create data table and find minimum and maximum values
state_space_value.trim().split(/\r?\n/).forEach(function(row) {
const datas = row.trim().match(/^([^\d]+)(\S*)/);
var value = datas[2];
if (value.length > 0) {
value = parseFloat(value);
if (value_min > value) { value_min = value; }
if (value_max < value) { value_max = value; }
} else { value = null; }
datass.push([datas[1].trim(), value]);
});
console.log(value_min, value_max);
/// Replace state names with codes in data table
replace_names_with_codes(datass, map_states);
/// Append missing states
const missing_codes = new Set();
for (const name in map_states) { missing_codes.add(map_states[name]); }
datass.forEach(function(datas) { missing_codes.delete(datas[0]); });
console.log(missing_codes);
for (const code of missing_codes) { datass.push([code, null]); }
console.log(datass);
/// Output SVG
const out_min = round_to_string(value_min, decimal_place);
const out_max = round_to_string(value_max, decimal_place);
outs.push(`
${out_title}
${out_min}
${out_max} `);
datass.forEach(function(datas) {
const code = datas[0];
const value = datas[1];
const out_value = value === null ? no_data_value :
round_to_string(value, decimal_place);
const opacity = value === null ? null : round_to_string(
(value - value_min) / (value_max - value_min), 3, true);
const out_use = value === null ? '' :
``;
console.log(code, out_value, value, opacity);
outs.push(`
${out_use}
${out_value} `);});
// console.log(outs);
document.getElementsByTagName('title')[0].innerHTML = out_title;
document.getElementsByTagName('desc' )[0].innerHTML = out_desc;
/// ============= JavaScript SVG generator by TilmannR and cmglee =============
document.getElementById('GENERATED_CONTENT').innerHTML =
`\n${outs.join('')}\n\n `;
const generator = document.getElementById('GENERATOR_SCRIPT');
generator.innerHTML = generator.innerHTML.
replace(/[<]script[^>]*/, `
replace(/<[/]script>/, ``);
]]>