Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting lowest and highest possible x and y in a line chart? #4420

Open
RonyKordahi opened this issue Apr 11, 2024 · 22 comments
Open

Getting lowest and highest possible x and y in a line chart? #4420

RonyKordahi opened this issue Apr 11, 2024 · 22 comments
Labels
enhancement Enhancement to a current API feature request Issues that are feature requests

Comments

@RonyKordahi
Copy link

I'm drawing a line chart and adding some custom labels to my lines only on the first dots. I'm trying to display the labels depending on their position in the chart. Is there a way to get the lowest and highest X and Y coordinates for the line chart?

The values change based on screen size and content on the screen and it's making it a little difficult to dynamically adjust them.

@PavelVanecek
Copy link
Collaborator

Hello @RonyKordahi, can you please paste a codesandbox example? There are various integration points depending on where exactly you need this information, I believe we can find one if we know what exactly you are after.

@RonyKordahi
Copy link
Author

RonyKordahi commented Apr 12, 2024

I don't have one myself, the code I'm working on is for a client and I can't share it due to the their data being protected under an NDA, but I took this sample off the web: sample.

What I'm trying to figure out is if there's a way to know what the lowest and highest possible value of the X and Y coordinates could be for a dot in the graph. If for example a dot is generated on the X axis at Page A, is there a way to determine the value of it's CX without having to parse through each dot to find the lowest one and store it?

EDIT: I should specify I need the maximum X and Y drawing coordinates of the chart, not the values of the dots themselves.

@ckifer
Copy link
Member

ckifer commented Apr 12, 2024

Can you explain a bit more about what you're trying to do? Where exactly are you trying to place labels and when? When do they shift position?

Can you give a screenshot or mockup? There is no current way to do what you ask

@RonyKordahi
Copy link
Author

Well for example I have a line who's first dot that has a Y value of 0, which makes it start at the bottom of the graph. The CY coordinate of the dot drawn in the graph is 743, which seems to be the highest value of a Y coordinate for drawing in the graph.

If I resize the graph to fit into the screen of an ipad instead, the CY coordinate is now 855 due to the screen size changing. I'm hoping to adjust the position of the dot's label based on this CY if it is the maximum value in the graph.

I'm trying to make it as dynamic as possible because the client will be using this on several screen sizes ranging from ipads to television screens. Having a way to know the lowest and highest possible X and Y drawing coordinates would help tremendously.

@ckifer
Copy link
Member

ckifer commented Apr 12, 2024

I guess, to frame the question differently, where are you trying to reliably render labels? Only at the beginning and end of your chart data no matter the screen size?

I understand that the cx,cy values change as the screen changes, but maybe we can accomplish what you want in a way that is easier than the approach you are taking

@RonyKordahi
Copy link
Author

Yes only at the beginning of the line, next to the first dot on each line.

@ckifer
Copy link
Member

ckifer commented Apr 12, 2024

Try something like this

    <Line type="monotone" dataKey="pv" stroke="#8884d8" dot>
        <LabelList
          fill="#111"
          position="top"
          valueAccessor={(props, index) => {
            //  { x: 80, y: 188.16, value: 2400, payload: {…} }
            console.log(props, index);
            return index === 0 ? props.value : undefined;
          }}
          // offset={20}
        />
      </Line>

image

@ckifer ckifer added the question Issue that is a question about recharts rather than a bug or a feature request label Apr 12, 2024
@RonyKordahi
Copy link
Author

I have a custom label component handling the label showing up and the positioning:

// Custom label for train names to show up at the beginning of the line
// ↪ Required to be a React component as per the documentation and example
// Documentation: https://recharts.org/en-US/api/Line
// Example: https://recharts.org/en-US/examples/CustomizedLabelLineChart
const CustomizedLabel = (props) => {

    const {
        // Default props
        x,
        y,
        index,
        offset,

        // Custom props
        name,
        color,
        maintenance,
    } = props;

    // console.log(props);

    return (
        index === 0 && (
            <text
                // Default properties
                x={x}
                y={y}
                fontSize={15}
                stroke={color}

                // Label positioning
                // ↪ Maintenance will be positioned over the lines for aesthetic reasons
                dx={
                    x === 60
                        ? 10
                        : maintenance
                            ? 10
                            : -10
                }
                dy={
                    maintenance && x === 60
                        ? -offset * 2
                        : y === 27
                            ? offset * 2
                            : maintenance
                                ? -offset * 2
                                : offset
                }
                textAnchor={
                    x === 60
                        ? "start"
                        : maintenance
                            ? "start"
                            : "end"
                }
            >
                {name}
            </text>
        )
    );
}

export default CustomizedLabel;

The problem is really with the hardcoded X and Y because those are the lowest drawing coordinates based on my screen size. I'm hoping to make those dynamic based on the size of the screen / graph.

@ckifer
Copy link
Member

ckifer commented Apr 12, 2024

Can I see a screenshot of what your ideal label position is? Even if it's on dummy data. It's hard to picture why you need more than the data that the label component gives you

@ckifer
Copy link
Member

ckifer commented Apr 12, 2024

From what I can see:

  1. You always get x and y values from the props that come through to your custom component
  2. When the screen re-sizes x and y change with it
  3. Your offsets (cx, cy) can be the same no matter what screen size you are at and you get the same result (or if desired, store the current height and width of the chart from responsive container and make slight cx,cy adjustments based on that like you would with breakpoints)

If I have something like:

  return (
    index === 0 && (
      <text
        // Default properties
        x={x}
        y={y}
        fontSize={15}
        stroke={color}
        // Label positioning
        // ↪ Maintenance will be positioned over the lines for aesthetic reasons
        // potentially dynamic based on current chart size
        dx={10}
        dy={-10}
        textAnchor={x === 60 ? "start" : maintenance ? "start" : "end"}
      >
        {name}
      </text>
    )
  );

Then I can always reliably position my (first) label where I want to

@RonyKordahi
Copy link
Author

RonyKordahi commented Apr 12, 2024

I quickly modified one of the data points just to try and get it going. This dot now has a Y value of 263 which puts it all the way at the top of the graph:
dot

I'm hoping to detect drawing Y coordinate (25) dynamically based on the size of the chart so I could modify the label's dy property and make it show up lower than it's default position (I've disabled the dy property from the code above just for this screenshot). And I'd like to do the same for dots that have a Y value of 0 and are generated on the bottom of the graph. Likewise for the X drawing coordinates.

EDIT: wrong screenshot

@ckifer
Copy link
Member

ckifer commented Apr 12, 2024

So essentially you want to guarantee that the label is always inside the bounds of the chart?

@RonyKordahi
Copy link
Author

Yes, by having the limits of the X and Y coordinates of the graph if possible.

@ckifer
Copy link
Member

ckifer commented Apr 12, 2024

You could probably hack things to bits and get this to work somehow, but currently it's not possible in a reasonable fashion.

@PavelVanecek this is a good use case for exporting hooks at some point.

I'll label this as a feature request

@ckifer ckifer added enhancement Enhancement to a current API feature request Issues that are feature requests and removed question Issue that is a question about recharts rather than a bug or a feature request labels Apr 12, 2024
@PavelVanecek
Copy link
Collaborator

@RonyKordahi If I understand correctly then if you had hooks useChartWidth() and useChartHeight() would that give you the information you need? These are not present in 2.x but we will ship them in 3.x

@RonyKordahi
Copy link
Author

@PavelVanecek By their names it seems like they would return the maximum height and width of the chart which sounds great!

I would say having the minimum height and width borders (lowest possible X and Y coordinates) would also be very helpful.

@PavelVanecek
Copy link
Collaborator

Lowest possible X and Y coordinates are 0 and 0, are they not?

@ckifer
Copy link
Member

ckifer commented Apr 14, 2024

Looks like we might be talking about separate things.

We have plain chart height and width. And then we have graph area height and width (chart height/width minus margin, minus Legend size, minus axis size, minus anything else that might add to the total chart size).

What needs to be known is the X,Y bounds of where a chart item can be drawn. I can get chart height and width today, it just has all the extra stuff added to it

@RonyKordahi
Copy link
Author

Yep! It's exactly as @ckifer says.

@PavelVanecek
Copy link
Collaborator

Yep we should be able to expose all of that in various hooks in 3.x. And documentation too.

@ckifer
Copy link
Member

ckifer commented Apr 16, 2024

I hesitate to send this because it will change in 3.0 (see #4437)

But here is a sandbox that gets offset in the Customized component and calculates the charts edges with it.

Edit custom-reference-areas

@RonyKordahi
Copy link
Author

Thank you, I'll take a look!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Enhancement to a current API feature request Issues that are feature requests
Projects
Status: In Progress
Development

No branches or pull requests

3 participants