I have always loved this post Tufte in R, so I thought with it would be a great example for our new data-ui
sparkline abilities.
I get the data as the post suggest but change the code to use readr
and adjust for new tidyr
and dplyr
API.
# recreate http://motioninsocial.com/tufte/ in dataui # get data and make it long form dd <- readr::read_csv( paste0( "http://gist.githubusercontent.com/GeekOnAcid/da022affd36310c96cd4/", "raw/9c2ac2b033979fcf14a8d9b2e3e390a4bcc6f0e3/us_nr_of_crimes_1960_2014.csv" ) ) %>% pivot_longer( cols = 2:(ncol(dd)), names_to = "Crime.Type", values_to = "Crime.Rate" )
This is the easiest and quickest way to get some colors for our plots. I think a splash of color will liven up the sparklines a little bit. However, normally I would spend a little more time selecting colors.
# color by type colscale <- scales::brewer_pal(palette="Set3")(11)[-2]
Now for our graphics pipeline intentionally done in one long pipe. To accomplish a chart similar to the original would have required much less code. Since we have interactivity and some additional options, I wanted to put them to use. Drag your mouse over the chart to see what it can do.
dd %>% group_by(Crime.Type) %>% summarise( # get our band line values quart1 = quantile(Crime.Rate, 0.25), quart2 = quantile(Crime.Rate, 0.75), rate_last = tail(Crime.Rate, 1), # create our sparkline spk = list(dui_sparkline( # ugly but will make this better soon data = mapply( function(year,rate) {list(year = year, rate = rate)}, Year, Crime.Rate, SIMPLIFY = FALSE ), height = 120, margin = list(top = 40, bottom = 20, right = 150, left = 30), # tell sparkline to get rate for y values valueAccessor = htmlwidgets::JS("(d) => d.rate"), # label is easier but tooltip omore flexible renderTooltip = htmlwidgets::JS(htmltools::HTML(" function (_ref) { var datum = _ref.datum; return React.createElement( 'div', {style: {margin: 0, padding: 0}}, datum.year && React.createElement( 'div', {style: { backgroundColor: 'black', color: 'white', padding: '4px 0px', margin: 0, textAlign: 'center' }}, datum.year ), React.createElement( 'div', {style: {fontWeight: 'bold', fontSize: '1.2em', padding: '6px 0'}}, datum.y ? datum.y.toLocaleString(undefined, {maximumFractionDigits: 0}) : \"--\" ) ); } ")), components = list( dui_sparkpatternlines( id = "band_pattern", height = 4, width = 4, stroke = "#aaa", strokeWidth = 1, orientation = "diagonal" ), dui_sparkbandline( band = list(from = list(y=quart1[[1]]), to = list(y=quart2[[1]])), fill = "url(#band_pattern)" ), dui_sparklineseries( stroke = colscale[cur_group_id()] ), # let JavaScript data-ui determine min/max dui_sparkpointseries( points = list("min","max"), fill = colscale[cur_group_id()], renderLabel = htmlwidgets::JS(" (d) => d.toLocaleString(undefined, {maximumFractionDigits: 0}) ") ), dui_sparklabel( label = Crime.Type[[1]], x = 5, y = -20, anchor = "begin", fill = colscale[cur_group_id()], fillOpacity = 1 ), dui_tooltip( components = list( dui_sparkverticalrefline(strokeDasharray="4,4"), dui_sparkpointseries(fill = "#fff", stroke = colscale[cur_group_id()]) ) ) ) )) ) %>% arrange(desc(rate_last)) %>% pull(spk) %>% tagList() # %>% #> `summarise()` ungrouping output (override with `.groups` argument)
# browsable() %>% # print()