var executions = {}; var inmates = {}; var demographics = {}; var chances = {}; var year = ""; var view = "population"; var perspective = "black"; var showPies = true; var showAccusations = true; var includeUsageLevel = false; var dampenOn = true; var chart; var prettyPerspective = { white: "White", black: "Black", hispanic: "Hispanic/Latino", asian: "Asian", amInd: "American Indian
and
Alaska Native", other: "Other" }; var prettyView = { population: "the actual population", executions: "executions since '77", inmates: "current death row inmates" }; var regions = [ 'Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'District of Columbia', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming', ]; var regionOffsets = { 'California': {lon: 0, drawConnector: false}, 'Connecticut': {lat: -1.5, lon: 1}, 'Delaware': {lat: -1.3, lon: 2}, 'District of Columbia': {lat: -2, lon: 2}, 'Hawaii': {lat: -0.5, lon: 0.5, drawConnector: false}, 'Maryland': {lon: 0.6, drawConnector: false}, 'Minnesota': {lon: -1, drawConnector: false}, 'New Jersey': {lat: -1, lon: 1.2}, 'Rhode Island': {lat: -0.7, lon: 1.7}, 'Vermont': {lat: 2} }; async function setHistoricDeathRowData() { var ex = await $.ajax({ url: "death-penalty-map/data/executions.json", dataType: "json" }); for(var i=0; idistribution of
' + prettyView[view] + ',
you could argue
that state seems...


' }, useHTML: true, align: 'right', verticalAlign: 'middle', padding: 75 }; } function getColorAxis() { return { layout: 'vertical', min: 0, minPadding: 50, max: 100, maxPadding: 50, stops: [ [0.0, '#CC6800'], [0.15, '#A98967'], [0.5, '#AAAAAA'], [0.85, '#68A196'], [1.0, '#00BD9A'] ], tickInterval: 50, marker: { color: '#00AF00' }, labels: { formatter: function() { var prettyDg = prettyPerspective[perspective]; var lnbr = prettyDg.length > 15 ? "
" : ""; switch(this.value) { case 0: return "Anti-" + lnbr + prettyDg; case 50: return "Just right"; case 100: return prettyDg + lnbr + "-supremacist"; } } } }; } var avgTotalPct = null; function getAvgTotalPctPopulation() { if(avgTotalPct == null) { avgTotalPct = 0; var numNonZero = 0; for(var i=0; i 0) { avgTotalPct += totalPctPop; numNonZero++; } } avgTotalPct /= numNonZero; } return avgTotalPct; } function getRelativePctPopulation(state) { var stateSize = getTotalPctPopulation(state); var avgStateSize = getAvgTotalPctPopulation(); return Math.sqrt(stateSize / avgStateSize); } function setYearSelect() { for(var yr in demographics) { if(demographics.hasOwnProperty(yr)) { $("#year-select").append(''); } } } function deviationFromExpectation(state) { var score = 0.5; if(showAccusations) { if(chances.hasOwnProperty(state)) { if(chances[state].hasOwnProperty(view)) { if(chances[state][view].hasOwnProperty(perspective)) { score = chances[state][view][perspective]; } } } } return score * 100; } function getStateDemographicsRow(state) { var white = parseInt(demographics[year][state]["White"]); var black = parseInt(demographics[year][state]["Black"]); var hispanic = parseInt(demographics[year][state]["Hispanic"]); var asian = parseInt(demographics[year][state]["Asian"]); var amInd = parseInt(demographics[year][state]["American Indian/Alaska Native"]); var other = parseInt(demographics[year][state]["Native Hawaiian/Other Pacific Islander"]); var total = (white + black + hispanic + asian + amInd + other); return { state: state, white: white, black: black, hispanic: hispanic, asian: asian, amInd: amInd, other: other, total: total }; } function getStateExecutionsRow(state) { var stateExecution = executions[state]; if (stateExecution != null) { var total = stateExecution.total; var white = stateExecution.white; var black = stateExecution.black; var hispanic = stateExecution.hispanic; var asian = stateExecution.asian; var amInd = stateExecution.amInd; var other = (total - white - black - hispanic - asian - amInd); return { state: state, white: white, black: black, hispanic: hispanic, asian: asian, amInd: amInd, other: other, total: total }; } return { state: state, white: 0, black: 0, hispanic: 0, asian: 0, amInd: 0, other: 0, total: 0 }; } function getStateInmatesRow(state) { var stateInmates = inmates[state]; if (stateInmates != null) { var white = stateInmates["White"]; var black = stateInmates["Black"]; var hispanic = stateInmates["Latinx"]; var asian = stateInmates["Asian"]; var amInd = stateInmates["Native American"]; var other = stateInmates["Unknown"]; var total = (white + black + hispanic + asian + amInd + other); return { state: state, white: white, black: black, hispanic: hispanic, asian: asian, amInd: amInd, other: other, total: total }; } return { state: state, white: 0, black: 0, hispanic: 0, asian: 0, amInd: 0, other: 0, total: 0 }; } function getStateRow(state) { switch(view) { case "inmates": return getStateInmatesRow(state); case "executions": return getStateExecutionsRow(state); default: return getStateDemographicsRow(state); } } function getStateDataset() { if(includeUsageLevel) { var maxUsageLevel = 0; var usageLevels = {}; for(var i=0; i 0, false); // Do the same for the connector point if it exists var connector = Highcharts.find(chart.series[2].points, function (item) { return item.name === point.id; }); if (connector) { connector.setVisible(point.total > 0, false); } }); for(var i=3; i\u25CF ' + (line[0] === hoverGroup ? '' : '') + line[0] + ': ' + (isPie ? Highcharts.numberFormat(100*line[1]/line[3], 0) + "%" : Highcharts.numberFormat(line[1], 0)) + (line[0] === hoverGroup ? '' : '') + '
'; } }).join(''); var totalPct = ' (' + Highcharts.numberFormat(100 * (this.total / getStateDemographicsRow(this.id).total), 5) + '% curr. pop.)'; var total = '
Total: ' + Highcharts.numberFormat(this.total, 0) + (view != 'population' ? totalPct : ''); var body = groupList.length ? groupList + total : '
No ' + prettyView[view]; return '' + this.id + '
' + body; } } }, { name: 'Separators', id: 'us-all', type: 'mapline', data: Highcharts.geojson(Highcharts.maps['countries/us/us-all'], 'mapline'), color: '#707070', showInLegend: false, enableMouseTracking: false, colorAxis: false }, { name: 'Connectors', type: 'mapline', color: 'rgba(130, 130, 130, 0.5)', zIndex: 5, showInLegend: false, enableMouseTracking: false, colorAxis: false }], colorAxis: getColorAxis() }); // Add the pies after chart load, optionally with offset and connectors Highcharts.each(chart.series[0].points, function (state) { if (!state.id) { return; // Skip points with no data, if any } var pieOffset = state.pieOffset || {}, centerLat = parseFloat(state.properties.latitude), centerLon = parseFloat(state.properties.longitude); // Add the pie for this state chart.addSeries({ type: 'mappie', name: state.id, linkedMap: 'us-all', zIndex: 6, // Keep pies above connector lines colorAxis: false, sizeFormatter: function () { return this.chart.chartWidth / 35 * getRelativePctPopulation(state.id); }, tooltip: { // Use the state tooltip for the pies as well pointFormatter: function () { return state.series.tooltipOptions.pointFormatter.call({ id: state.id, hoverGroup: this.name, white: state.white, black: state.black, hispanic: state.hispanic, asian: state.asian, amInd: state.amInd, other: state.other, total: state.total }); } }, data: [{ name: 'White', y: state.white, color: whiteColor }, { name: 'Black', y: state.black, color: blackColor }, { name: 'Hispanic', y: state.hispanic, color: hispanicColor }, { name: 'Asian', y: state.asian, color: asianColor }, { name: 'American Indian / Alaska Native', y: state.amInd, color: amIndColor }, { name: 'Other', y: state.other, color: otherColor }], center: { lat: centerLat + (pieOffset.lat || 0), lon: centerLon + (pieOffset.lon || 0) } }, false); // Draw connector to state center if the pie has been offset if (pieOffset.drawConnector !== false) { var centerPoint = chart.fromLatLonToPoint({ lat: centerLat, lon: centerLon }), offsetPoint = chart.fromLatLonToPoint({ lat: centerLat + (pieOffset.lat || 0), lon: centerLon + (pieOffset.lon || 0) }); chart.series[2].addPoint({ name: state.id, path: 'M' + offsetPoint.x + ' ' + offsetPoint.y + 'L' + centerPoint.x + ' ' + centerPoint.y }, false); } }); // Only redraw once all pies and connectors have been added chart.redraw(true); } var loaded = false; async function main() { await getData(); createChart() loaded = true; } $(document).ready(function() { main(); $("#perspective .btn").click(function() { $("#perspective .btn").removeClass("active"); $(this).addClass('active'); perspective = this.id; buildSeries(); }); $("#sample .btn").click(function() { $("#sample .btn").removeClass("active"); $(this).addClass('active'); view = this.id; avgTotalPct = null; buildSeries(); }); $("#year-select").change(function() { year = this.value; buildSeries(); }); $('#show-pies').bootstrapSwitch(); $('#show-pies').on('switchChange.bootstrapSwitch', function(event, state) { showPies = $(this).bootstrapSwitch('state'); buildSeries(); }); $('#show-accusations').bootstrapSwitch(); $('#show-accusations').on('switchChange.bootstrapSwitch', function(event, state) { showAccusations = $(this).bootstrapSwitch('state'); buildSeries(); }); });