susielu / d3-legend

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

Add labelFloor and labelCeil to API #36

Closed gemfarmer closed 8 years ago

gemfarmer commented 8 years ago

@susielu Hi! I added two available legend options to the color, shape, and size APIs for quantize scales only.

Usage should look something like:

var legend = d3.legend.color()
              .labelFormat(legendFormat)
              .labelFloor(false)
              .useClass(false)
              .ascending(true)
              .orient(orient)
              .shapeWidth(shapeWidth)
              .labelDelimiter(legendDelimiter)
              .shapePadding(6)
              .scale(scale);

Both labelFloor and labelCeil default to true Setting one to false makes it so that only one displays without the delimiter. Setting both to false nullifies the action, returning the full delimited label as if neither options were set to false.

This will look something like:

screen shot 2016-07-27 at 4 12 12 pm

But why??

On one of my projects, we are using a quantize scale that is sometimes vertical and sometimes horizontal. When it is vertical, a delimited label works great, but when the legend is vertical, the delimited fields lead to a cramped display. Given this constraint, I am OK with using a single value to represent a quantize scale domain.

I am assuming that other people who will be considering this option will likely default to wanting to display the floor or ceiling for a given domain "bucket", and thus the labelCeil and labelFloor names.

susielu commented 8 years ago

Hey Brian,

Thank you for taking the time to make this pull request. In the latest version of the legend (2.13.0) I ended up making a more general solution to this problem. The labels parameter now takes a function. You can see an example here: http://d3-legend.susielu.com/#color-threshold

So now you can just make a custom function that would go into the labels parameter. Let me know if it makes sense and if you have any troubles using it.

Thanks, Susie

susielu commented 8 years ago

Some documentation on how the function works and how you access it:

labels([string] or function(options)) Passing a string: Sets the legend labels to the array of strings passed to the legend. If the array is not the same length as the array the legend calculates, it merges the values and gives the calculated labels for the remaining items.

Passing a function: This function is called for each generated label and gives you the options:

i: current index genLength: total length of generated labels generatedLabels: array of generated labels domain: array from input scale range: array from input scale

gemfarmer commented 8 years ago

@susielu I think your solution makes more sense than mine! Thanks for the review!