Historical data about wars is usually incomplete. The term fog of war applies to participants, but could also be extended to data available later for historians and new generations.
Here is a chart presentation of wars in the last 500 years. Data
comes from Wikipedia and hyperlinks go back to Wikipedia.
All charts are interactive - zoom, pan, hover tooltips and click.
Data sources: ‘Modern’
wars, World
population
Data extraction with rvest, build levels for
timeline, tooltips and clickable links.
Each war’s duration is represented by a line. Lines are double-coded
for war deaths - by width (wider means more), and by
color (red means more). Tooltips show up when hovering
either end of a line. Clicking there opens a Wikipedia
info page.
Toggle all labels by top-right icon.
library(stringr); library(dplyr); library(echarty)
con <- url('https://helgasoft.github.io/echarty/test/wars.RData')
load(con)
jscode <- "window.flag = true;
window.togglePlay = function() {
chart = get_e_charts('cid');
opt = chart.getOption();
opt.series.map(ss => {ss.endLabel.show = window.flag;} );
chart.setOption(opt, true);
window.flag = !window.flag;
}"
s0 <- list(show=FALSE)
alab <- list(formatter= ec.clmn('%R@', -1))
p <- ec.init( elementId= 'cid', js= jscode,
title= list(text='Wars timeline, last 500 years', left= 'center',
subtext= 'source: Wikipedia',
sublink= 'https://en.wikipedia.org/wiki/List_of_wars_by_death_toll#:~:text=source%C2%A0needed%5D-,Modern,-%5Bedit%5D'),
xAxis= list(scale= TRUE, maxInterval= 50, axisLine= s0, axisLabel= alab,
min= min(df2$from), max= as.numeric(format(Sys.Date(),'%Y')) ),
yAxis= list(scale= TRUE, min=-3, show= FALSE, axisLine= s0, axisTick= s0),
tooltip= list(trigger= 'item'),
dataZoom= list(
list(type='inside', filterMode='none', start= 10),
list(type='slider', filterMode='none', labelPrecision= 0, start= 10,
selectedDataBackground= list(lineStyle= list(opacity=0), areaStyle= list(opacity=0)),
dataBackground= list(lineStyle= list(opacity=0), areaStyle= list(opacity=0)) ) ),
toolbox= list(
list(right= '20%', feature= list(myTT= list(
show=TRUE, title= 'toggle labels', icon= togi,
onclick= htmlwidgets::JS("function() { togglePlay(); }")
))),
list(right= '15%', feature= ec.util(cmd='fullscreen'))
),
series= lst
) |> ec.theme('dark-mushroom')
p$x$on <- list(list(
event='selectchanged',
handler= htmlwidgets::JS("function(v) {
sel = v.fromActionPayload.seriesIndex;
chart = get_e_charts('cid');
opt = chart.getOption();
window.open(opt.series[sel].data[1][2]);
}")
))
p
fmt1 <- htmlwidgets::JS("(v) => v>=1000000 ? v/1000000+'M' : v")
p <- df2 |> mutate(colr= ifelse(from >= 1939, 'red', 'PaleTurquoise')) |>
arrange(-DeathMean) |>
dplyr::select(War, DeathMean, ttip, colr, link) |>
ec.init(elementId= 'wid', ctype='bar', tooltip= list(show=TRUE),
yAxis= list(type='log', name='war death toll average, log scale',
nameRotate=90, nameGap= 60, nameLocation='center',
axisLabel= list(formatter= fmt1) ),
xAxis= list(name= 'Wars since 1500 sorted by death toll, WW2 and after in red',
nameLocation='middle', axisLabel= s0),
grid= list(containLabel= TRUE),
dataZoom= list(type='inside', filterMode='none'),
series= list(list( colorBy= 'data', itemStyle= list(color= ec.clmn('%@',4)),
#encode= list(x='War', y='DeathMean'),
label= list(show= TRUE, formatter= ec.clmn('%@',1),
position= 'top', align= 'left', rotate= 45),
labelLayout= list(hideOverlap= TRUE),
tooltip= list(formatter= ec.clmn('%@',3)))),
toolbox= list(
list(right= '15%', feature= ec.util(cmd='fullscreen'))
)
) |>
ec.theme('dark')
p$x$on <- list(list(event='selectchanged',
handler= htmlwidgets::JS("function(v) {
sel = v.fromActionPayload.dataIndexInside + 1;
chart = get_e_charts('wid');
opt = chart.getOption();
window.open(opt.dataset[0].source[sel][4]);
}")
))
p
The average death toll is spread out evenly over all years of war’s duration.
#' sources:
#' https://www.worldometers.info/world-population/world-population-by-year/
#' https://en.wikipedia.org/wiki/Estimates_of_historical_world_population
tmp <- "year popM
1500 460
1600 579
1750 770
1800 985
1820 1093
1850 1278
1870 1347
1875 1383
1900 1645
1910 1790
1913 1829
1920 1924
1925 2007
1930 2100
1940 2324
1950 2525
1960 3026
1970 3691
1980 4449
1990 5320
2000 6127
2010 6916
2011 6997
2012 7080
2013 7162
2014 7243
2015 7349
2016 7464
2017 7547
2018 7631
2019 7713
2020 7795
2021 7837
2022 7984
"
wpop <- read.csv(text= tmp, sep= '\t') |> mutate(popM= as.numeric(popM))
ydw <- data.frame(year= 1494:2022, det=rep(0,529), cnt=rep(0,529)) |>
left_join(wpop)
ydw$year <- as.integer(ydw$year)
for(i in 1:nrow(df)) {
yy <- df$to[i]-df$from[i] +1; incd <- round(df$DeathMean[i]/yy)
for(k in df$from[i]:df$to[i]) {
j <- k-1493;
ydw$det[j] <- ydw$det[j] + incd;
ydw$cnt[j] <- ydw$cnt[j] +1
}
}
colors <- c('OrangeRed','Chartreuse','cyan')
ydw |> ec.init( preset=FALSE, color= colors,
grid= list(containLabel= TRUE),
dataZoom= list(type='inside', startValue=1830, filterMode='none'),
xAxis= list(name= 'year', nameTextStyle= list(verticalAlign= 'bottom', padding= c(0,0,-20,-8)),
scale=TRUE, axisLabel= alab,
min= min(ydw$year), max=max(ydw$year) ),
yAxis= list(
list(scale=TRUE,
name='war deaths average (M)', nameRotate=90, nameGap=25,
nameLocation='center', nameTextStyle= list(color= colors[1]),
axisLabel= list(formatter= ec.clmn('%R@', -1, scale=0.000001), color=colors[1]),
offset= 43, splitLine= s0),
list(scale=TRUE, name='active wars count', nameRotate=90, nameGap=20,
nameLocation='center', nameTextStyle= list(color= colors[2]),
min=1, max=max(ydw$cnt), axisLine= s0, splitLine= s0),
list(scale=TRUE, name='world population (M)', nameRotate=90, nameGap=-20,
nameLocation='center', nameTextStyle= list(color= colors[3]),
min=min(wpop$popM), max=max(wpop$popM), position= 'left', splitLine= s0,
axisLabel= list(color=colors[3])
)
),
series= list(
list(type='line', symbol='none', name='death.avg.M'),
list(type='line', symbol='none', name='active.wars',
encode= list(x='year', y='cnt'),
xAxisIndex=1, yAxisIndex=2),
list(type='line', symbol='circle', name='world.pop.M',
encode= list(x='year', y='popM'), connectNulls= TRUE,
xAxisIndex=1, yAxisIndex=3)
),
tooltip= list(trigger= 'axis',
formatter=
ec.clmn('year <b>%@</b><br>death.avg <b>%L@</b><br>world pop <b>%L@</b><br>active wars <b>%@</b>',
1.1, 1.2, 1.4, 1.3) )
) |> ec.theme('dark-mushroom')
Best viewed on widescreen desktop in Full-Screen mode.