susielu / d3-legend

A reusable d3 legend component.
http://d3-legend.susielu.com/
Apache License 2.0
727 stars 104 forks source link

Custom Color and Shape? #83

Closed KyleKing closed 6 years ago

KyleKing commented 6 years ago

Is it possible to specify both the color and shape for each legend element?

I just started working with D3, so hopefully, there is an easy answer. Normally, I would do something like: .attr( 'fill', ( d, i ) => colorScheme[i] ), but with d3-legend it doesn't look like the data binding is directly accessible this way

Below is a modified example from the tutorial:

var colorScheme = ['#FF928B', '#7D82B8', '#EFE9AE']
var triangleU = d3.symbol().type( d3.symbolTriangle )(),
  wye = d3.symbol().type( d3.symbolWye )();

var symbolScale =  d3.scaleOrdinal()
  .domain( ['Red Triangle', 'Blue Wye', 'Yellow Wye'] )
  .range( [ triangleU, wye, wye] );

var svg = d3.select( 'svg' );
svg.append( 'g' )
  .attr( 'class', 'legendSymbol' )
  .attr( 'transform', 'translate(20, 20)' );

var legendPath = d3.legendSymbol()
  .scale( symbolScale )
  .orient( 'horizontal' )
  .labelWrap( 30 )
  .title( 'Symbol Legend Title' )

  // TODO: Specify colors for each symbol?

svg.select( '.legendSymbol' )
  .call( legendPath );
susielu commented 6 years ago

You would just need to select all of the cells after the fact to iterate over your colors. Unfortunately this type of double encoding is not default behavior, but here's a codepen that does something similar with the size legend: https://codepen.io/susielu/pen/RjeNbL

The relevant line for you would be something like this:

svg.selectAll(".cell path").attr("fill", (d, i) => colorScheme[i])
KyleKing commented 6 years ago

Thanks!