feat(legends): titles, custom symbols, symbol sizes (svg and canvas)
Addresses #2023
Adds new capabilities to the @nivo/legends package
Includes adjustments to several other nivo packages
Motivation
The existing legends package creates basic legends, but lacks capabilities such as displaying multiple symbol types, or symbols of varying sizes. More flexible legends would be particularly relevant to line charts (with points) and scatter charts.
Features
The PR adds support for several new features:
- title lines
- different symbol shapes within one legend
- symbol borders in color
- symbol sizes
- matching features for svg and canvas charts
- fine-tuning of tick labels on color legends
Examples
Implementation
The PR updates nivo@/legends, but some changes also impact on other packages. These involve typescript type names, function/component names, and function signatures.
There may be breaking changes, but these should be limited to users making use of typescript or advanced features like custom layers in canvas charts. Most existing code should remain functional; the PR includes minimal changes to storybook examples or existing unit tests.
Implementation details
@nivo/legends
- moved the local coordinate system for legend symbols so that (x=0, y=0) refers to the center of the symbol (as opposed to the top-left corner of the bounding box for the symbol). This helps with consistency with custom node/dot functions used to draw points in line and scatterplot charts.
- renamed type
DatumtoLegendDatum. This type describes information about one legend item. The new name is more descriptive, which will make it possible to re-use it in other packages. In particular, it can replaceBarLegendDatain the bar package. - introduced a new legend symbol 'invertedTriangle'
- added support for inherited color definitions for symbol borders
- moved canvas code to a separate folder to mirror structure for svg code. The
srcdirectory now has two subdirectories with closely matched files for svg and canvas. - added support for a legend title line (a line without a symbol)
- removed file/component
LegendSvgand incorporated it intoBoxLegendSvg. - renamed
LegendSvgItemtoBoxLegendSvgItembecause those items are only relevant to box legends (as opposed to legends with continuous colors) - renamed
renderLegendToCanvastorenderBoxLegendToCanvas. This is for consistency withrenderContinuousColorLegendToCanvaswhich includes the legend type in the name of the render function. - removed
LegendPropsas a type to be used by other nivo packages. The typeBoxLegendSpecshould be used instead. The prefix 'Box' is for consistency withContinuousColorLegendSpec. - distinguished between
BoxLegendSpec(used by users to ask for legends with certain features) andBoxLegendProps(props for the rendering function). These two have different optional statuses (the prop 'data' is optional in a user-specified spec, but required when actually drawing a legend). They also differ in interactivity props liketoggleSerie(toggleSerie is boolean as a user-facing setting, while it is a function during actual rendering when it performs internal book-keeping. This dual-use of the same prop name is a legacy implementation). - renamed symbols to include suffixes
SvgorCanvas - added support for inherited color for borders for canvas symbols
- merged
AnchoredContinuousColorLegendSvgandContinuousColorLegendSvg. This removes two files and removes redundant code that computed width/height of the continuous scale. - adjusted types for the continuous colors legends to match the structures for box legends and to reflect removal of
AnchoredContinuousColorLegendSvg. - introduced files
SizeLegendSvgandSizeLegendCanvasas a preparation for specifying legends with variable symbol sizes using a scale, number of ticks. These implementations need more work. - added support custom tick positions for color scales with the quantized colors. This allows placing labels to describe color intervals rather than color thresholds.
(Some naming changes are motivated by my own need to understand existing code. Some of these can be reverted to reduce the number of nominal changes.)
@nivo/colors
- added types
AnyContinuousColorScaleandAnyColorScale. - added
@ts-ignorebefore lines that calculate location of ticks. I think the typescript types provided by@types/d3-scaleare incomplete. These ts-ignore lines can be removed later once the types are corrected.
@nivo/bar
- replaced existing type
LegendData(which is specific to the bar package) by types from legends package - simplified the legend spec to remove the custom
dataFromproperty. It seemed redundant with the existingcolorBy. RemovingdataFromproperty means that the bar package can useBoxLegendSpecfrom the legends package.
@nivo/line
- for
LineCanvas, added support for custom point symbols through proppointSymbol. This functionality matched custom point symbols available for svgLine. - for
LineCanvas, changed the signature of the function that renders custom layers from({ ctx, ...props })to(ctx, { ...props }). This is for consistency with ScatterPlot.
(The current implementation of @nivo/line will be replaced by a typescript version. These changes can be revisited then, if needed.)
@nivo/scatterplot
- added two stories that showcase multiple legend types
- added
themeto the set of props passed to the custom layer rendering function. This is required to allow a canvas layer to draw symbols.
@nivo/heatmap
- added stories with horizontal and vertical legends (to check that edits preserve functionality)
- expanded props to custom layers to include chart dimensions and color scale
other packages
- adjusted legend render functions. For canvas components, changed
renderLegendToCanvastorenderBoxLegendToCanvas. For svg, changedLegendSvgtoBoxLegendSvg. - adjusted legend types from
LegendPropstoBoxLegendSpec. - adjusted unit tests when needed
(Again, some naming changes are motivated by my own need to understand the code. Some names can be reverted to reduce the number of nominal changes. From a different perspective, I would perhaps make further changes, e.g. replacing renderBoxLegendToCanvas to renderBoxLegend or BoxLegendCanvas)
This pull request is automatically built and testable in CodeSandbox.
To see build info of the built libraries, click here or the icon next to each commit SHA.
Latest deployment of this branch, based on commit 0d7deeb8f27ff7e57c6c0333282c06cfa7133f0c:
| Sandbox | Source |
|---|---|
| plouc/nivo | Configuration |
This pull request has been automatically marked as stale. If this pull request is still relevant, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize reviewing it yet. Your contribution is very much appreciated.
Closing this pull request after a prolonged period of inactivity. If this issue is still present in the latest release, please ask for this pull request to be reopened. Thank you!