Markers not working in a Nivo ResponsiveLineCanvas

348 Views Asked by At

I'm trying to switch from a ResponsiveLine to a ResponsiveLineCanvas using Javascript library Nivo version 0.80.0 and React 18.2.0, but markers are just not shown. Not sure what I am missing, so I created an example to reproduce the issue

https://codesandbox.io/embed/fast-leftpad-q6ypqr?fontsize=14&hidenavigation=1&theme=dark

It is sufficient to switch from ResponsiveLineCanvas to ResponsiveLine and the marker get shown.

From the docs I cannot guess if the feature is unsupported in ResponsiveLineCanvas. So, am I missing any configuration?

import React, { useEffect, useState } from "react";
import { ResponsiveLineCanvas } from "@nivo/line";
import { ResponsiveLine } from "@nivo/line";

const commonProperties = {
  width: 900,
  height: 400,
  margin: { top: 20, right: 20, bottom: 60, left: 80 },
  animate: true,
  enableSlices: "x"
};
const App = () => (
  <div style={{ height: 600 }}>
    <ResponsiveLineCanvas
      {...commonProperties}
      data={[
        {
          id: "Id of serie",
          data: [
            { x: 0, y: 0.2 },
            { x: 1, y: 0.3 },
            { x: 2, y: 0.5 },
            { x: 3, y: 0.4 },
            { x: 4, y: 0.3 },
            { x: 5, y: 0.5 },
            { x: 6, y: 0.3 },
            { x: 7, y: 0.1 }
          ]
        }
      ]}
      markers={[
        {
          axis: "x",
          value: 2,
          lineStyle: { stroke: "#6aa84f", strokeWidth: 3, opacity: 0.95 },
          legend: "Budget line"
        }
      ]}
      layers={[
        "grid",
        "axes",
        "areas",
        "lines",
        "points",
        "slices",
        "mesh",
        "legends",
        "markers"
      ]}
      enableGridX={false}
      colors={["rgb(97, 205, 187)", "rgb(244, 117, 96)"]}
      xScale={{
        type: "linear"
      }}
      yScale={{
        type: "linear",
        stacked: false,
        min: 0,
        max: 1
      }}
      enableArea={true}
      areaOpacity={1}
      enableSlices={false}
      useMesh={true}
      crosshairType="cross"
    />
  </div>
);
export default App;
1

There are 1 best solutions below

2
On BEST ANSWER

Looking at the source code, it's clear that support for markers has not been implemented in the LineCanvas and ResponsiveLineCanvas components. There is no mention of markers anywhere in the component source. The markers prop is not included in the destructuring assignment so that prop will be ignored and have no effect.

As for the layers prop, this Canvas version goes through a bunch of if statements to check for known layer types. "marker" is not one of these types. There is no else statement that lets you know if a provided layer was invalid, it just doesn't do anything.

The supported values of the layers prop, per the source code, are:

  • "grid"
  • "axes"
  • "areas"
  • "lines"
  • "points"
  • "mesh"
  • "legends"
  • custom functions

On the other hand, the SVG-based Line and ResponsiveLine components do use the markers prop and support layers=["markers"]. You can see here how the markers prop is passed off to a CartesianMarkers component from the @nivo/core package and the resulting element is stored in the layerById dictionary.