VictoryLabel coordinates don't match VictoryChart domain

877 views Asked by At

I'm displaying stock data in a VictoryChart where x is a number representing days (i.e. simply 0, 1, 2, 3... etc.) and y is the price for that day.

I've set a domain for the VictoryChart (from the lowest values to the highest) and I've got a VictoryLine that's displaying correctly.

I wanted to add some "floating" labels (not on image below) where the lowest and highest prices are and I'm having issues with the x and y coordinates of the labels as they don't seem to match the domain I've defined.

I notice that if I place a label into the chart with position x = 0, y = 0, then it's located at the top left corner (I expected bottom left). This is how it looks currently, with some test labels:

Victory chart graph

Code:

<VictoryChart
  domain={{ x: [startPrice.x, endPrice.x], y: [Math.floor(lowestPrice.y), Math.ceil(highestPrice.y)] }}
>
  <VictoryLine
    style={{
      data: { stroke: '#4CB872', strokeWidth: 4 },
    }}
    data={chartData}
    animate={{
      duration: 1000,
      onLoad: { duration: 1000 },
    }}
  />
  <VictoryLine
    style={{ data: { stroke: Colors.Beige, strokeDasharray: '2,5', strokeWidth: 1, opacity: 0.5 } }}
    data={chartData.map((datum) => ({ x: datum.x, y: chartData[0].y }))}
    animate={{
      duration: 1000,
      onLoad: { duration: 1000 },
    }}
  ></VictoryLine>
  <VictoryLabel text='x10 y10' x={10} y={10} />
  <VictoryLabel text='x100 y100' x={100} y={100} />
  <VictoryLabel text='x200 y200' x={200} y={200} />
</VictoryChart>

chartData is e.g.:

"chartData": [
   {
      "date": "2020-09-21",
      "x": 0,
      "y": 142.31579017,
    },
    {
      "date": "2020-09-22",
      "x": 1,
      "y": 142.31420395,
    },
    {
      "date": "2020-09-23",
      "x": 2,
      "y": 142.16096094,
    },
    {
      "date": "2020-09-24",
      "x": 3,
      "y": 142.09860251,
    },
...

How can I use x/y positioning on VictoryLabels to place them on the graph with regards to the domain I defined? E.g. the Label marked "x100 y100" should not be at position x=100,y=100 but instead x=5,y=142.5 or thereabouts.

1

There are 1 answers

0
jorundur On BEST ANSWER

Thanks to @boygirl from FormidableLabs I now have the solution, see (https://github.com/FormidableLabs/victory-native/issues/637)

As they wrote there:

The x, y, props on VictoryLabel correspond to svg coordinate space, not data coordinate space. You can create a custom label that uses the scale prop passed in by VictoryChart to translate data coordinates to svg coordinates

Your custom label might look something like this:

    const MyLabel = props => {
      const x = props.scale.x(props.x);
      const y = props.scale.y(props.y)
      return <VictoryLabel {...props} x={x} y={y}/>
    }

and you would use it like this:

    <VictoryChart>
      <MyLabel x={10} y={10} />
    </VictoryChart>