javascriptreactjssvgforeignobject

Position a foreignObject to the top-right of an svg


I'm adding a foreignObject to a chart built upon svg. I want to put it on the top-right of the svg, irrespective of how big/small that svg is. So I don't want a hardcoded solution, I need a dynamic solution.

Setting width={'100%'} height={'100%'} inside the foreignObject isn't workable, because it makes the rest of the chart unclickable.

I've got a non-dynamic solution by setting x and y manually inside foreignObject, but I need a dynamic solution.

How can I achieve this?

enter image description here

<g>
    <foreignObject //x={0} y={0} 
    width={'1'} height={'1'} style={{overflow: 'visible'}} x={50} y={50}>
     <Menu>
        <MenuButton as={Button} rightIcon={<ChevronDownIcon />}         
        transition="all 0.001s"
        borderRadius="md"
        borderWidth="0px"
        _hover={{ bg: "gray.400" }}
        _expanded={{ bg: "blue.400" }}
        _focus={{ boxShadow: "none" }}
        style={{ marginTop: "1px", position: "absolute", right: 0 }}>
          Actions
        </MenuButton>
        <Portal>
        <MenuList zIndex={10}>
          <MenuItem>Download</MenuItem>
          <MenuItem>Create a Copy</MenuItem>
          <MenuItem>Mark as Draft</MenuItem>
          <MenuItem>Delete</MenuItem>
          <MenuItem>Attend a Workshop</MenuItem>
        </MenuList>
        </Portal>
      </Menu>
    </foreignObject>
</g>

Codesandbox:

https://codesandbox.io/s/floral-water-v11gx?file=/src/BasicLineSeries.tsx


Solution

  • Your parent component BasicLineSeries already knows the width, so you can pass that into the component generating the foreignObject as follows:

           <ChartCanvas
              height={height}
              ratio={ratio}
              width={width}
              ...
            >
              <Chart id={1} yExtents={this.yExtents}>
                <LineSeries yAccessor={this.yAccessor} strokeWidth={3} />
                <XAxis />
                <YAxis />
              </Chart>
              <TestMenu width={width} />
            </ChartCanvas>
    
    function TestMenu({width}) {
      return (
        <g className="react-financial-charts-enable-interaction">
          <foreignObject
            width={"1"}
            height={"1"}
            style={{ overflow: "visible" }}
            x={width}
            y={50}
          >