Iterate Through a Chart with rCharts and dimplejs
Yesterday I saw this chart (these are not my views) in a presentation by an undisclosed fixed income shop (unless they tell me they want me to disclose their identity). Likely due to my immersion in d3
and rCharts
I paid no attention to the content and my mind went immediately to
Could this be better designed?
and soon after ...
Could I do it withrCharts
anddimplejs
?
source: not me
Since the data is a summary view, manually inputting it into a data.frame
is really easy. We'll name it views
and express our view with a scale 1 (don't like) to 6 (really like).
require(rCharts)
options(stringsAsFactors=F)
views <- data.frame(
Asset = c(
"U.S. Treasuries"
,"Curve Positions"
,"Non US Developed"
,"Emerging Markets"
,"Mortgage-Backed Securities"
,"Investment Grade Credit"
,"High Yield"
,"Municipals"
,"Currency"
),
View = c(
3
,6
,3
,2
,4
,3
,3
,4
,2
)
)
The beauty of rCharts is that we do not have to break our workflow as we explore and iterate. Often the hardest part of iteration is finding a starting point when we are staring at a blank page or canvas. I overcome this by just doing something and expecting it to be bad.
dP <- dPlot(
Asset ~ View,
data = views,
type = "bar",
height = 600,
width = 600,
bounds = list( x= 240, y = 50 , width = 360, height = 500)
)
dP$xAxis( type = "addMeasureAxis" )
dP$yAxis( type = "addCategoryAxis" )
dP$show(chartId = "example1")
Some color might help. dimplejs
makes a color scale easy. Although there is colorbrewer.js
, we can avoid a js dependency and plug in RColorBrewer
colors from R
. With a couple lines of new code we can get a heat map type color scheme with red, yellow, and green. Sorry to the color blind readers, but I thought I would try to match the color scheme from the original.
#need some color
dP$colorAxis(
type = "addColorAxis",
colorSeries = "View",
palette = RColorBrewer::brewer.pal(n=5,"RdYlGn")
)
dP$show(chartId = "example2")
This dimplejs
block matrix example might be a better option than a traditional bar chart. Block matrix charts have two categorical or discrete axes. Let's make our xAxis
categorical.
#probably need x to be Category Axis
dP$xAxis( type = "addCategoryAxis" )
dP$show(chartId = "example3")
Now that our xAxis
is categorical, we lost 1 and 5 since we don't have this view on any of the opportunities. As of now, I do not think dimplejs
allows us to manually specify a domain for our categorical axes, but we can fool dimplejs
by providing a dummy 1 and 5 then deleting it with javascript.
#but what about views without an asset
#in this case 1 and 5
#dimple does not allow easy way of specifying explicit
#categorical domain for axis scale
#we will fool it and then remove
dP$params$data = rbind(
views,
data.frame(
Asset = rep("Currency",2),
View = c(1,5)
)
)
#now for the manual removal of the byproduct of fooling dimple
dP$setTemplate(
afterScript = "
<script>
d3.select('#example4').selectAll('#All_1_Currency_,#All_5_Currency_').remove()
</script>
"
)
dP$show(chartId = "example4")
I did not make the original chart, but I will assume that the ordering of the opportunity set (yAxis
) was intentional. dimplejs
will assume natural sort order or alphabetical for text, but we can manually specify our sort order with a different variable or by providing an array. The data.frame
is in the correct order so let's give dimplejs
that with the following code.
#now our y Axis gets sorted in a way we might not like
dP$yAxis(
orderRule = rev(views$Asset)
)
dP$show(chartId = "example5")
Not sure if this helps viewers understand our chart or not, but colored labels for the xAxis
might get style points. A little d3.js
can help us make the change.
#one last bit of cleanup
#label the axes as in the original
dP$setTemplate(
afterScript = "
<script>
//get rid of dummy data
d3.select('#example6').selectAll('#All_1_Currency_,#All_5_Currency_').remove()
//get rid of text labels on x axis
d3.select('#example6').select('.axis:nth-child(2)').selectAll('.tick text').remove()
//label with text from original
d3.select('#example6').select('.axis:nth-child(2)').select('.tick').append('text')
.text('Minimum Allocation')
.attr('dy','1.5em')
.style('fill',myChart.axes[0].colors[0])
d3.select('#example6').select('.axis:nth-child(2)').select('.tick:last-of-type').append('text')
.text('Maximum Allocation')
.attr('text-anchor','end')
.attr('dy','1.5em')
.style('fill',myChart.axes[0].colors[4])
</script>
"
)
dP$show(chartId = "example6")
Here is where some formal training might help, but I wanted to see if a different sort order might help. Let's sort and in effect group opportunities by our view.
#but if we want to sort our y Axis by view
#could do this
dP$yAxis(
orderRule = views$Asset[order(views$View,decreasing=T)]
)
dP$show(chartId = "example7")
This is hard to show before and after, but I thought it would be nice to use the same fonts from html in our dimplejs
charts. dimplejs
allows full custom formatting with noFormats
, but I just want to change the font. Let's use a little d3.js
to change the font for our svg text
.
<script>
d3.selectAll('svg text').style("font-family",d3.select("body").style("font-family"))
</script>
I still have many things I want to try to improve this chart and its interactivity, but we'll stop here. If anybody really wants a part 2, please let me know.
As I hope you can tell, this post was more a function of the efforts of others than of my own.
Thanks specifically: