Nivo: Adding image or SVG inside a bar

Created on 6 Jun 2019  路  8Comments  路  Source: plouc/nivo

Is your feature request related to a problem? Please describe.
Instead of a text/string label, I would like to put an image/icon in its place (center of the bar)

Describe the solution you'd like
Found this website on how to add SVG Image directly on d3, but since I am new to this, I don't know how to access the d3 directly using Nivo.
https://fabiofranchino.com/blog/how-to-load-image-in-svg-with-d3js/

Describe alternatives you've considered
I am trying to find ways to access d3 directly, but I cannot get my head around it.

Additional context
image
This is what I am aiming for.

bar question

Most helpful comment

Yes, I realised that later on. I already had done some customisation before on the line, so I used the same concept to add the image on the SVG using the layers.

const Image = ({ bars }) => {
  let size = 24
  let images = bars.map(({ key, x, y, width, height }) => {
    return (
      <image
        key={key}
        xlinkHref="/img/maintenance.svg"
        x={x + width / 2 - size / 2}
        y={y + height / 2 - size / 2}
        height={size}
        width={size}
      />
    )
  })
  return <g>{images}</g>
}

And then just added the Image on the layers of the

<ResponsiveBar layers={['grid','axes','bars', Image, 'markers','legends', 'annotations' ]}>

Thanks for the response @plouc.

All 8 comments

nivo behaves differently, you don't have access to d3 as it's only used to compute things, not to manipulate the DOM (the way it's done in the example you provided).

If you want to customize the bars, you can use a custom component, you've got an example here and the code is available here.

Yes, I realised that later on. I already had done some customisation before on the line, so I used the same concept to add the image on the SVG using the layers.

const Image = ({ bars }) => {
  let size = 24
  let images = bars.map(({ key, x, y, width, height }) => {
    return (
      <image
        key={key}
        xlinkHref="/img/maintenance.svg"
        x={x + width / 2 - size / 2}
        y={y + height / 2 - size / 2}
        height={size}
        width={size}
      />
    )
  })
  return <g>{images}</g>
}

And then just added the Image on the layers of the

<ResponsiveBar layers={['grid','axes','bars', Image, 'markers','legends', 'annotations' ]}>

Thanks for the response @plouc.

Nice, I'm glad that you found a solution, you can also add style={{ pointerEvents: 'none' }} on the image element if you don't want it to interfer with the mouse handlers (like the one used for tooltips).

Brilliant. Thanks for the tip @plouc That is really helpfull.

@plouc On a related note, how do I pass extra information through the data?

You can add extra data to the original prop, you'll be able to retrieve it from the data key of the bar.
For now the format of the input data isn't ideal though, I might change it to use the same format as the scatterplot or the line charts, it could also ease switching from one chart type to another while prototyping.

You can add extra data to the original prop, you'll be able to retrieve it from the data key of the bar.
For now the format of the input data isn't ideal though, I might change it to use the same format as the scatterplot or the line charts, it could also ease switching from one chart type to another while prototyping.

Oh yes, the way the Line is organised is great to what I want to achieve. I need to pass at least 7 attributes per stacked generated rect to be used in the tooltip and the generated rect and image

{
   "burger": 80,
   "burgerColor": "hsl(1, 70%, 50%)",
}

Is there any other way of passing data similar to Color? perhaps 'burgerExtra': { } ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gcloeval picture gcloeval  路  3Comments

tj picture tj  路  4Comments

indvstry picture indvstry  路  3Comments

barnapisti1994 picture barnapisti1994  路  3Comments

stahlmanDesign picture stahlmanDesign  路  3Comments