问题
I would like to have both solid and dashed lines for different levels of a factor (grouping variable) in a plot created with nPlot. Any suggestions?
library(reshape2)
library(ggplot2)
library(rCharts)
ecm <- reshape2::melt(economics[,c('date', 'uempmed', 'psavert')], id = 'date')
p7 <- nPlot(value ~ date, group = 'variable', data = ecm, type = 'lineWithFocusChart')
Final result:
uempmed (solid line) and psavert (dashed line)
Another option could be to change the thickness of the lines instead.
回答1:
Unfortunately nvd3
has stagnated. This is a great example where a pull request that would allow the ability to specify thickness and dashed styling for lines sits unpulled.
Here is the difficult way to potentially solve your problem. We will need to modify the standard rCharts
script template to add a callback function for the line styling. See here for a rCharts demo and a live code example.
options(viewer=NULL)
library(reshape2)
library(ggplot2)
library(rCharts)
ecm <- reshape2::melt(economics[,c('date', 'uempmed', 'psavert')], id = 'date')
p7 <- nPlot(value ~ date, group = 'variable', data = ecm, type = 'lineWithFocusChart')
#grab template from
#https://github.com/ramnathv/rCharts/blob/master/inst/libraries/nvd3/layouts/chart.html
#modify to add callback on graph render
p7$setTemplate(script = sprintf("
<script type='text/javascript'>
$(document).ready(function(){
draw{{chartId}}()
});
function draw{{chartId}}(){
var opts = {{{ opts }}},
data = {{{ data }}}
if(!(opts.type==='pieChart' || opts.type==='sparklinePlus' || opts.type==='bulletChart')) {
var data = d3.nest()
.key(function(d){
//return opts.group === undefined ? 'main' : d[opts.group]
//instead of main would think a better default is opts.x
return opts.group === undefined ? opts.y : d[opts.group];
})
.entries(data);
}
if (opts.disabled != undefined){
data.map(function(d, i){
d.disabled = opts.disabled[i]
})
}
nv.addGraph(function() {
var chart = nv.models[opts.type]()
.width(opts.width)
.height(opts.height)
if (opts.type != 'bulletChart'){
chart
.x(function(d) { return d[opts.x] })
.y(function(d) { return d[opts.y] })
}
{{{ chart }}}
{{{ xAxis }}}
{{{ x2Axis }}}
{{{ yAxis }}}
//on legend click, line might be deleted
//when redrawn we need to make dashed again
chart.legend.dispatch.on('legendClick', dashedAfterLegend )
function dashedAfterLegend(){
//to make dashed we need to make sure it is drawn first
//not a js expert so might not be best way to handle
window.setTimeout(function dashedDelay(){
makeDashed(opts)
} , 400)
}
d3.select('#' + opts.id)
.append('svg')
.datum(data)
.transition().duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
},%s);
};
%s
</script>
"
,
#here is where you can type your line styling function
"function(){ makeDashed( opts ) } "
# here is the part that was in afterScript but moved to work with shiny
#see this article for help on dashed d3 lines
#http://www.d3noob.org/2013/01/making-dashed-line-in-d3js.html
,"
function makeDashed( opts ){
// select all the lines with d3 both main plot and focus
// see this article for help on dashed d3 lines
// http://www.d3noob.org/2013/01/making-dashed-line-in-d3js.html
d3.select('#' + opts.id).selectAll('.nv-linesWrap .nv-group')
.filter(function(g){return g.key== 'psavert'})
.selectAll('.nv-line')
.style('stroke-dasharray', ('3, 3'))
}
"
))
p7
I understand that this is a lot of Javascript to ask of a R user, so please let me know if any of this does not make sense.
回答2:
var dasheddesign=['10,20','5,5' ,'30,30','20,10,5,5,5,10'];
d3.select('#chart1 svg')
.datum(data)
.call(chart)
.call(function(){
d3.select('#chart1')
.selectAll('.nv-line').each(function( d,i ){
d3.select(this).attr("stroke-dasharray",dasheddesign[i]);
});
});
No delay required
回答3:
This works fine, but thy to Hide and then Unhide series from legend. dash style is gone :(
来源:https://stackoverflow.com/questions/24942366/change-line-type-in-rcharts-nvd3-nplot