Giter Site home page Giter Site logo

d3-legend's People

Contributors

christophe-g avatar colineberhardt avatar eflanagan0 avatar eversojk avatar floribon avatar hanneskuettner avatar hypercubed avatar john-guerra avatar mbostock avatar robinhouston avatar saisankargochhayat avatar seripap avatar susielu avatar tamc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

d3-legend's Issues

New release

Hi, could you please publish a new release? I use bower for dependency management and latest release has some serious bugs (undefined vars) that are already fixed in the master. Thanks!

Include indexRollup.js.map in the package.json file list

Problem: Webpack source map loader expects indexRollup.js.map to exist in this library, producing a warning because it is missing.
Solution: Include indexRollup.js.map in the package.json file list and re-publish the npm module.

It is a one line change, if given permission I can make a pull request for it. If you sanction a pull request please let me know any etiquette such as re-generating builds or formatting commit messages that I must adhere to.

Thanks

Threshold labels at extremes not labelled correctly when using custom formatter

Without formatter:

Less than -0.1
More than 0.1

With percentage formatter labelFormat(d3.format('+.1%')):

+NaN% to -12.0%
More than +15.0% to +NaN%

This is due to the replacements made in helpers.js relying on the formatter returning exactly NaN. This would also cause an issue if the default labelDelimiter is changed from "to".

Workaround: copy and adapt the helper.

Any chance of legend hierarchy?

Hi, You did a fantastic job with the legend implementation using d3. Wanted to know if implementation of hierarchical legend in in line?

Library is not included in webpack bundle

Hello,
unfortunately cannot include d3-legend into my project. I am using npm, typescript and webpack(with pretty default configurations).
So, when I import d3-legend via import * as legend from 'd3-svg-legend';, webpack copies lib-file into assets folder instead of including it into the main bundle. And when I log that legend variable, it contains only string-path to file in assets folder, like '/assets/build/assets/f7cef8a85c1c33ef2fdaf592dca074c1.js'.

P.S. I am using a lot of libraries, including d3 itself, and all they import fine.

Manually set the padding between legendTitle and legendCells

Hi,

I wanted to reduce the space between the title and the cells but I didn't find the option.
capture d ecran 2017-09-27 a 16 18 27

I found here the transform of the cells.

The fix is simple but not very pretty. Do you have an option to do it?

// For exemple, a padding of 7px
svg.select('.legendCells').attr('transform', 'translate(0, 7)')

capture d ecran 2017-09-27 a 16 24 56

Thanks

Put the label next to the legend

Hi,
I am new on Javascript, may I know how to put the label next to the legend? I see all examples are putting the label under the legend in different ways.

Thank you very much.
Bruce

SVG of minimum size

Currently I have to set a fixed size for the legend to look good on my maps. But the problem is that I don't know the label lengths or number of legend entries in advance, and doing computations for width/height myself seems too complicated. Is this something which can be easily done here? Ideally, the SVG size should actually adjust to its contents. I'm new to D3, maybe this is a more general issue.

Legend filtering

First of all, great work @susielu ! I have really enjoyed using your legend.

A useful setting would be a .filter() or .cull() method that made it easy to only display legend cells that are in a particular dataset.

I am happy to do this when I can get around to it!

An example implementation might look something like below,
where only the 0th, 1st, and 3rd cells are appended to the legend

var dataset = [0, 150, 500, 250, 500, 250, 500];

var quantize = d3.scale.quantize()
  .domain([0, 1000])
  .range([0,1,2,3,4]);

var svg = d3.select(this)
  .select("svg");

svg.append("g")
  .attr("class", "legendQuant");

var legend = d3.legend.color()
  .labelFormat(d3.format.si)
  .useClass(false)
  .filter(_.uniq(dataset)) // _.uniq(dataset) => [0,1,3]
  .scale(quantize);

Bug in legendColor() updating?

I believe there is a bug in legendColor when passing it updated scales. If I start with scale data like so (omitting quotes):

domain = [a, b, c] and range = [green, blue, gold]

The initial legend renders fine. But if I then call it again with:

domain = [b, c] and range = [blue, gold]

then the first two cells are both blue.

Likewise, updating by progressively dropping the last cell and adding it back with subsequent calls causes the last cell color to repeat.

I am using D3 v4. Looking at the source code, legendColor appears to be updating, exiting, and entering, but it is not updating correctly on the screen, and I can't see where the issue is. I noted though that it does not appear to be using a key function.

This is being done on a closed system, so unfortunately I cannot post the code.

Support for hover and click highlight

Nice lib!

I've seen scenarios where user wants to highlight legends on visualization. I did an experiment with choropleth. Here's my highlight code:

d3.select(".legendQuant").selectAll(".cell")
.on("mouseover", function() {
var className = d3.select(this).select("rect").attr("class").split(/\s+/)[1];
d3.selectAll("." + className).style("fill", "#bbb");
})
.on("mouseout", function() {
var className = d3.select(this).select("rect").attr("class").split(/\s+/)[1];
d3.selectAll("." + className).style("fill", "");
});

https://vida.io/documents/jspBB83bm6EvEYE3n

It'd be nice to have some support from the lib to turn on highlight.

Support for d3.scaleThreshold

I tried making a color legend using a d3.scaleThreshold, and here's what the legend looks like:

image

Here's the relevant bit of code for setting up the scale and the legend:

var colorScale = d3.scaleThreshold()
  .domain([ 0, 1000, 2500, 5000, 10000 ])
  .range(["#ffffb2","#fed976","#feb24c","#fd8d3c","#f03b20","#bd0026"]);
var legend = d3.legendColor()
  .scale(colorScale);

A nice solution to this would:

  • replace "1000.0 to NaN" with "Greater than 1000.0"
  • replace "NaN to 0" with "Less than 0"
  • provide options for omitting the "Less than 0" or "Greater than 1000.0" legend boxes.

changes labels (and colors) after legend creation

Hi! I'd like to change the labels (and maybe colors) of a legend after it is created, like this page. Please drag the slider to see the labels of the legend change dynamically.

The gist of the problem is summarized in this short piece.

In the function rescaleLegend() I try two ways of updating the legend. Presently it works by manually picking out the labels [ selectAll('.label') ] and manually changing their text. Obviously this is not in the API and may well break when the internal workings of d3-legend.js changes. The ideal solution would be to change the scale of the legend and somehow re-apply it to the legend, like the commented out statement: [ legendBuilder.scale(createScale(cap)); ] Unfortunately this does not work.

To simplify things, let's assume that the cell number remains the same. If it does not, then it probably makes more sense simply to delete the old legend and create a new one.

I am not even sure how to request for a nice API to do this. Does anybody have similar needs? What would you suggest?

Thanks to susielu and all for this nice library!

option to reverse the direction of the legend

Can we have an option to reverse the direction of the legend? For example with a rainfall graph having a vertical legend, it is customary to have larger amount of rainfall on top and lower amount at the bottom. Thanks for the great work!

Namespacing CSS

First off, awesome work with this library. It really makes legends super easy!

One issue I ran into while using d3-legend was namespace clashes. For example, the labels in d3-legend have the class label, and if you use it with bootstrap, they look really weird as the fonts are displayed at 75% of their size.

One way to solve this issue would be to allow uses to specify a prefix for all classes introduced by d3-legend. It could default to "" to maintain backward compatibility. This way, one could specify a prefix d3-legend- and style appropriately, without having to worry about namespace clashes.

I would be happy to contribute a PR if you think this is something you would like to incorporate.

d3 version 4 updates

Hi,

First of all: thanks for your amazing legend api.

My wish: can update the API to support the newest version of d3?
Since version 4 some major changes prevent me from using your api.

best regarfs,

jT

ShapeWidth for Symbols?

This library is awesome! For my purposes, I just want to scale the symbols in my symbol legend so they're a little more visible. I think this is the "ShapeWidth" feature, which is available for color and size legends but not symbol legends?

When it works with Angular's iElement, I get some error

angular.min.js:108 TypeError: shapes.nodes is not a function
    at Array.legend (http://localhost:3000/lib/d3/d3-legend.js:4101:36)
    at Array.d3_selectionPrototype.call (http://localhost:3000/lib/d3/d3.js:975:14)
    at post (http://localhost:3000/js/directives.js:2505:22)
    at ea (http://localhost:3000/lib/angular/angular.min.js:74:16)
    at w (http://localhost:3000/lib/angular/angular.min.js:61:340)
    at g (http://localhost:3000/lib/angular/angular.min.js:54:250)
    at g (http://localhost:3000/lib/angular/angular.min.js:54:267)
    at g (http://localhost:3000/lib/angular/angular.min.js:54:267)
    at g (http://localhost:3000/lib/angular/angular.min.js:54:267)
    at g (http://localhost:3000/lib/angular/angular.min.js:54:267) <div my-legend-info="">
  var linear = d3.scale.linear()
                    .domain([0,10])
                    .range(["rgb(46, 73, 123)", "rgb(71, 187, 94)"]);

                d3.select(iElement[0]).remove("svg");
                var svg = d3.select(iElement[0]).append("svg");


                svg.append("g")
                    .attr("class", "legendLinear")
                    .attr("transform", "translate(20,20)");

                var legendLinear = d3.legendColor()
                    .shapeWidth(30)
                    .orient('horizontal')
                    .scale(linear);

                svg.select(".legendLinear")
                    .call(legendLinear);

Legend Size Scales By Radius, Not Area

Hi Susie,

Awesome library. Definitely simplifies my life quite a bit.

There seems to be a bug with the implementation of the d3.legendSize() computations, as per Tufte's data-ink ratio.

If you take the circles example, you can see the computed radius mappings are 5.0->20px and 10.0->30px.
screen shot 2017-03-09 at 3 47 39 pm

For the purposes of simplifying the mapping, I will assume that the scale should be zeroed (where 0->0px, 5.0->10px, 10.0->20px). According to Tufte's data-ink theory, the entire area of each circle should scale linearly. However, in the rendered example 5.0->10px radius->100 sq px area and 10.0->20px radius->400 sq. px area. As you can see, double the radius is 4x the area. 5.0 should be mapped to 14px radius if the radius of 10.0->20px.

This bug affects rects as well.

Line wrapping

Is it possible to add line wrapping for long legend titles?

Custom shape not working ?

Hello,
I can't manage to customize shape of my legend using your example.
Here is my HTML: <svg id="d3legend"></svg>
And my Javascript:
var colorPalette = d3.scaleLinear().domain(steps).range(shades);
var legend = d3.legendColor()
.shape("path", d3.symbol().type(d3.symbolTriangle).size(150)) /* doesn't work */
.scale(colorPalette);
var svg = d3.select("#d3legend");
svg.empty();
svg.append("g")
.attr("class", "legend")
.attr("transform", "translate(20, 20)");
svg.select(".legend").call(window.legend);

Generated output:
output

How to set a background color?

Hello, I've made my legend, but I want it over the chart, so obviously I need to set a background color?
Can you tell me how can I make this?

Decimal numbers not displayed

Whenever I try to display numbers somewhere between 0 (0.002, 0.02, 0.2, ...) and 1, the tool rounds the numbers to either 0 or 1. Is there a way to not let it do that?

Feature? Legend title

Add a method to set the legend title. This way it can be automatically styled similar to the legend labels. Users could always use the returned object to translate the title if they wish to reposition it.

cell.exit().transition not a function

I'm using d3 v4 with the new release

cell.exit().transition().style("opacity", 0).remove();

throws the error when I do .call(legend).

TypeError: cell.exit(...).transition is not a function

Last threshold's "more than x" label should be "x or more"

Threshold scale domain values indicate the lower bound of every slice except the first. They are inclusive:

var color = d3.scaleThreshold()
    .domain([      0,       1])
    .range(["red", "white", "green"]);

color(-1);   // "red"
color(-0.5); // "red"
color(0);    // "white"
color(0.5);  // "white"
color(1);    // "green"

Given the above scale and .labels(d3.legendHelpers.thresholdLabels), d3-scale will produce the following legend:

RED   Less than 0.0
WHITE 0.0 to 1.0
GREEN More than 1.0

... where the last label being "more than" incorrectly suggests that 1.0 would not be green. In other words, the slice is inclusive but its label is exclusive.

It should say "1.0 or more".

"Less than" at the other end of the scale is correct, because 0 is the upper bound of that slice and is therefore exclusive.

Wrong colors used in scaleOrdinal w/ not all of range used

It looks like the wrong colors are used when colorLegend is passed a scale whose range includes more colors than values in the domain.

As an example, the mismatched colors will result when using d3.scaleOrdinal(d3.schemeCategory10) when only two values in the domain are present.

Uncaught TypeError: a.getBBox is not a function

I get the error "Uncaught TypeError: a.getBBox is not a function" when I try to pass a d3.legend.color the following scale:

d3.scale.linear().domain([0, 0.25353535353535356]).range(["#ffff99", "#ff6600"]);

d.getBBox is not a function (running in NodeJS + JSDom)

Hi,
I am running D3 in NodeJS with JSDom so I can render images server side. The d3 chart rendered fine when I copied it from my client-side test, but when I copied the d3-legend code I received this error.

Here is my include:

const fs = require('fs'),
d3 = require('d3'),
d3_legend = require('d3-svg-legend'),

and my legend creation:

svg.append("g")
  .attr("class", "legendLinear")
  .attr("transform", `translate(80,${padding})`);

const legendLinear = d3_legend.legendColor()
    .title("Noise Level (dB)")
    .titleWidth(200)
  .shapeWidth(40)
  .cells(10)
  .orient('horizontal')
  .scale(colorRange);

svg.select(".legendLinear")
  .call(legendLinear); // note, this is line 130

Here is the error I receive when I run my Node process:

return d.getBBox();
^

TypeError: d.getBBox is not a function
at node_modules\d3-svg-legend\indexRollup.js:298:16
at Array.map (native)
at legend (\node_modules\d3-svg-legend\indexRollup.js:297:33)
at Selection.selection_call [as call] (\node_modules\d3-selection\build\d3-selection.js:500:12)
at generateGraph (\ScatterPlot.js:130:8)
at Request._callback (\ScatterPlot.js:29:13)
at Request.self.callback (\node_modules\request\request.js:188:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request. (\node_modules\request\request.js:1171:10)

Thanks,
William

register d3-legend as bower package?

Thanks for such a useful package, I can tell I'm going to use this one a lot!

Would you be able to register d3-legend as a bower package? Many front-end developers (myself included) use bower to manage front-end packages. I have to jump through some kludgy hoops to utilize non-bower packages in my deployment workflow.

Thanks again.

Here's the bower docs for packaging and registering libraries:

http://bower.io/docs/creating-packages/

Feature Request: Nested Size Legend

Hi Susie,

First, thanks for creating and maintaining this plugin - it truly is great! I wanted to request a new feature that would allow you to create a nested legend for the size scales. An example of what I'm talking about is this circular legend.

It would be nice if you could specify the number of items in the legend, although that might be better suited to using the default .ticks() on the scale itself.

Thanks for considering!

labelOffset and legendSize

The doc says:

A value that determines how far the label is from the symbol in each legend item. Default set to 10px.

But I think there is a problem, here are screenshots:

capture d ecran 2017-11-20 a 17 33 22
capture d ecran 2017-11-20 a 17 33 32

The code used to generate the legend:

legendSize()
.title(legendTitle.charAt(0).toUpperCase() + legendTitle.slice(1))
.scale(reportScale) // a quantitative scale with two values
.shape('line')
.shapePadding(10)
.shapeWidth(2)
.labelOffset(5)
.labelFormat('.0f')
.labelAlign('start')
.labels(({ i, domain }) => domain[i])
.orient('horizontal')

Also I set the font size to 11px in css.

Am I missing something?

d3-legend does not span full range of log scale

Great tool! Alas, when I use it with my log scale that contains a mid point like this

var color = d3.scale.log().range(colors).domain([colorlo, 100, colorhi]);
var legend = d3.legend.color().scale(color).cells(6);
map.call(legend);

The legend that is created runs from colorlo (3) to the midpoint (100), rather than up to colorhi (32004).

Padding between shape and legend title for d3.legendSize() w/ circle

Hi Susie, I'm having some trouble with spacing between legend shapes and the title. For the legend in question I'm using:

  • d3.legendSize()
  • shape is 'circle'
  • orient is 'vertical'
  • shapePadding is 30

It looks like it calculates the top spacing off of the top shape, because if I change it to '.ascending(false)' the space decreases (with smaller circle on top).

Is there any way to set the spacing manually via the translate values for the "legendCells"?

screen shot 2017-03-16 at 4 26 53 pm

Consider adding tags for the repo.

Hi~
Adding tags for repo could specify points in history and mark release points.
It's helpful for user to know the version and status of repository.
Would you please consider on using tags?

Thank you!
Piicksarn

Row/Column Wrapping

If there are too many labels, cells can fall off the edge of the svg. I currently use a wrapper function to postprocess cells and wrap them to the next column/row when necessary. It would be nice to include this as part of d3-legend.

Uncaught TypeError: d.getBBox is not a function

Thanks for the awesome library! Am trying to incorporate it into a project that uses d3 v. 4.2.6, using the CDN at <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.9.0/d3-legend.js"></script> and am getting the following error:

Uncaught TypeError: d.getBBox is not a function

which points to function at d3-legend/2.9.0/src/color.js:53. My guess was that perhaps my exact version of d3 v. 4 wasn't right, though on double-checking the project's bower.json, it looks like the right version should be "d3": "~3.5.6", while the README says that the master branch should depend on v4.

Which version of d3 should I be using? If I am using the right version, any thoughts on what might be going?

Thanks!

Custom legend labels for quantile scale

Hi, thank you so much for this package, helped me a lot!
However, I have a small question, it seems that I'm missing some simple idea about creating custom legend labels. Right now I have labels that look like '40 to 102', but I would like to have something like '≤ 102'.
For example, I have:

var colorScale = d3.scale.quantile()
  .domain([d3.min(values), d3.max(values)])
  .range(colorbrewer.Blues[8]);

// I thought that I could just map the values to format I wanted:
var newLabels = colorScale.quantiles().map( function(i) {
  return ' ≤ ' + i;
 });

var legend = d3.legend.color()
  .cells(newLabels)
  .scale(colorScale);

svg.select(".legendQuant")
  .call(legend);

However, when I do this, nothing changes, I still have the same '40 to 102' type of labels. Can you suggest how I can troubleshoot this?

Thank you!

d3 legend does not work with d3 v3

I am using this version of d3 https://d3js.org/d3.v3.min.js. Which version from cdnjs is the one that is usable with the suggested d3 version? When I use that one https://cdnjs.com/libraries/d3-legend and I try d3.legend.color() it says that this is not defined. Looking into the code, its d3.legendColor(). When I go onto this site http://d3-legend-v3.susielu.com/ and then click "Include file directly - All legends" I get directed to this URL https://raw.githubusercontent.com/susielu/d3-legend/master/d3-legend.min.js which again has d3.legendColor() in it...

Its rather frustrating...

Last item in array for custom labels being skipped.

Whenever I try to pass an array with labels for a legend, the last item never appears for my pie charts. What results is my pie chart has more values than my legend, despite the data being present in the array.

TypeError: cell.transition is not a function

Receiving the following error while using d3-svg-legend with d3 v4:

screen shot 2017-06-08 at 10 47 39 am

Work around that seems to work is to import d3-transition into my file.

import * as d3 from 'd3-transition'

syntax error in npm package

Hey Susie,

thanks for this cool d3 legend plugin. Unfortunately, when I try to bundle the npm package with webpack. I got the following syntax error:


ERROR in ./~/d3-svg-legend/index.js
Module parse failed: /home/djan/dev/client/node_modules/d3-svg-legend/index.js Line 2: Unexpected token .
You may need an appropriate loader to handle this file type.
| var d3 = require('d3'),
| d3.legend = require('./no-extend')
|
| module.exports = d3;
@ ./app/components/Legend.jsx 19:0-24


Best regards
Jan

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.