nivo icon indicating copy to clipboard operation
nivo copied to clipboard

feat(legends): titles, custom symbols, symbol sizes (svg and canvas)

Open tkonopka opened this issue 3 years ago • 2 comments

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 Datum to LegendDatum. 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 replace BarLegendData in 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 src directory 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 LegendSvg and incorporated it into BoxLegendSvg.
  • renamed LegendSvgItem to BoxLegendSvgItem because those items are only relevant to box legends (as opposed to legends with continuous colors)
  • renamed renderLegendToCanvas to renderBoxLegendToCanvas. This is for consistency with renderContinuousColorLegendToCanvas which includes the legend type in the name of the render function.
  • removed LegendProps as a type to be used by other nivo packages. The type BoxLegendSpec should be used instead. The prefix 'Box' is for consistency with ContinuousColorLegendSpec.
  • distinguished between BoxLegendSpec (used by users to ask for legends with certain features) and BoxLegendProps (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 like toggleSerie (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 Svg or Canvas
  • added support for inherited color for borders for canvas symbols
  • merged AnchoredContinuousColorLegendSvg and ContinuousColorLegendSvg. 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 SizeLegendSvg and SizeLegendCanvas as 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 AnyContinuousColorScale and AnyColorScale.
  • added @ts-ignore before lines that calculate location of ticks. I think the typescript types provided by @types/d3-scale are 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 dataFrom property. It seemed redundant with the existing colorBy. Removing dataFrom property means that the bar package can use BoxLegendSpec from the legends package.

@nivo/line

  • for LineCanvas, added support for custom point symbols through prop pointSymbol. This functionality matched custom point symbols available for svg Line.
  • 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 theme to 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 renderLegendToCanvas to renderBoxLegendToCanvas. For svg, changed LegendSvg to BoxLegendSvg.
  • adjusted legend types from LegendProps to BoxLegendSpec.
  • 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)

tkonopka avatar Jun 09 '22 16:06 tkonopka

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

codesandbox-ci[bot] avatar Jun 09 '22 16:06 codesandbox-ci[bot]

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.

stale[bot] avatar Sep 20 '22 16:09 stale[bot]

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!

stale[bot] avatar Sep 27 '22 19:09 stale[bot]