mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
3.88k stars 1.17k forks source link

[charts] support partial dashed line path for incomplete or projected data points #13140

Closed ohmsl closed 3 weeks ago

ohmsl commented 1 month ago

Summary

In the case of a real-time analytics dashboard, the historic data you see is concrete. However, incomplete data, such as the data points for today or projected data points are not. Therefore it would be beneficial to have some way of denoting what points are complete, and what points are not. In my case this would be a "dashed" line between the last concrete point and the incomplete point today. Specifically on the line chart, though I believe similar cases should be accounted for on other charts.

Examples

This particular implementation is seen on Vercel's analytics dashboard. A screenshot below of my own websites analytics: image

Note the last data point.

I looked up how it's done in visx (the charting lib vercel use) and came across this jsfiddle

Search keywords: dashed line path, incomplete data points

michelengelen commented 1 month ago

great request @ohmsl ... I did add this to the board for the team to have a look 👍🏼

alexfauquette commented 1 month ago

For linear curve it works without any issue with the same technic: create a second line a style it:

https://codesandbox.io/p/sandbox/cold-rain-z8vxd7?file=%2Fsrc%2FDemo.tsx%3A14%2C11

For line chart with more complex curve it might be a more complex topic.

ohmsl commented 1 month ago

@alexfauquette thanks, perfect solution for now as I'm using a linear line anyway. What are your thoughts of making this a built in feature though?

ohmsl commented 1 month ago

Also note the other issues of adding a second series such as the tooltip and legend. image

alexfauquette commented 1 month ago

For sure, we could add a props hideEmptyValues in the axis tooltip content :+1:

ohmsl commented 1 month ago

image That would be good @alexfauquette, however the joining value has to exist to draw the line from the last concrete point and the new incomplete point. As seen in the photo. While awaiting this, is there an immediate fix for the tooltip?

alexfauquette commented 1 month ago

Same issue occurs in the example you provided.

image

Except rewriting the tooltip content, I don't see other solution. To do so, you can use the slots, and for inspiration here is the default content. I assume you can create a similar component that only show the one you want to display https://github.com/mui/mui-x/blob/master/packages/x-charts/src/ChartsTooltip/DefaultChartsAxisTooltipContent.tsx

ohmsl commented 1 month ago

Yeah I noticed that too. I'll have a look at making a custom tooltip. Imagining you further build in support for utilising the chart in this way, perhaps you implement a way of de-duping series if they have the same id, label or something?

And just to confirm, have you made any plans to implement fixes/features for any of the above stuff mentioned, just so I know what to expect in future releases.

Appreciate the reference and info you provided so far!

alexfauquette commented 1 month ago

For the hideEmptyValues it seems valuable for everybody, so we will probably add it. But the de-duping is verry edge cases, and I don't see how to do it without bothering other users by adding additional information in the series. Maybe we will end up creating a demo about how to do your use case such that other dev interested by this usecase can copy custom component for their need.

About the timeline, I've no idea. It will depends of the team bandwidth

ohmsl commented 1 month ago

I don't mind sharing my solution to the problem if/when I get it. Appreciate the help!

Regarding this issue, shall we consider it closed? x

alexfauquette commented 1 month ago

I would prefer to keep it open as long to trak the need. Will close it when we add a demonstration

ohmsl commented 1 month ago

Running into an issue when it comes to stacked line charts.

  1. The second series stacks as well, if I don't specify a stack, they place relative to the axis.

The solution probably involves some sort of "substack" feature.

  1. Creating a second series for every bit of data I have is tedious and inefficient. It's probably possible for me to create a function that programmatically generates the series for me, I feel like it'd be easier and more supported if there was a prop on a series that allows me to specify whether or not a data point is part of a projected or incomplete line. Similar to how you can run a condition on showMark.
alexfauquette commented 1 month ago

The root cause of all those sub issues if that we tweak the data provided to the chart for a rendering purpose.

Here are two solution to customize the line rendering to introduce a notion of limit. The idea is to render 2 lines with two styles and clip them.

The draw back is that tooltip and other components will not be aware that those are extrapolated data.

https://codesandbox.io/p/sandbox/admiring-varahamihira-mn8hlt?file=%2Fsrc%2FDemo.tsx%3A171%2C2

@JCQuintas What do you think about creating a demo with the first solution?

ohmsl commented 1 month ago

Really appreciate this sandbox @alexfauquette. Fully solves my issue! image

JCQuintas commented 3 weeks ago

@alexfauquette Solution seems really nice. What do you think about providing a ClipLineRange component instead and we document how to use it for different styles and area charts as well? 🤔

The draw back is that tooltip and other components will not be aware that those are extrapolated data.

This is something that I'm interested in improving. We should provide a lot more data to allow the customisation of tooltips, labels, anything really 😅

Right now, you could do something like:

        series={[
          {
            type: "line",
            data: [1, 2, 3, 4, 1, 2, 3, 4, 5],
            valueFormatter: (v, i) =>
              `${v}${i.dataIndex > 5 ? " (estimated)" : ""}`,
          },
        ]}
github-actions[bot] commented 3 weeks ago

:warning: This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue. Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

@ohmsl: How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.