stellar / dashboard

https://dashboard.stellar.org
217 stars 139 forks source link

Charts #252

Closed quietbits closed 2 years ago

quietbits commented 2 years ago

Find a charting library or libraries (we have simple as well as more detailed charts) that we can use. Main criteria:

  1. It needs to match as close to our designs as possible (if there is something really good and can't be customized to look the way we want, we can still consider it).
  2. Styled with CSS. We need it to work in light and dark mode easily, so it would be great if we could style charts using CSS variables we already have. A CSS-in-JS solution might work, but pure CSS is preferable.
  3. It would be great if each chart would become a standalone, reusable component that we could later add to the Stellar Design System.

Charts we have on dashboard

image

image

image

image

image

image

italomlp commented 2 years ago

Hey @quietbits. I was coding around the charts, and found recharts as a good fit for our case. I also found the react-chartjs-2, but it's based on canvas, what makes the use of our styles a little bit harder. With recharts, which is based on SVG, we can use CSS classes in some components for customization, and also we can pass our colors and any variables to it, because of the SVG. I started using it to try to bring a POC, but got myself already doing the real changes.

As an example, here is the simple area chart (that we have on "Network modes"): Screen Shot 2022-05-05 at 18 05 45 Screen Shot 2022-05-05 at 18 06 10

If we are not using CSS classes (we can do it in some components), we can pass the colors like this:

<Area
  stroke="var(--pal-graph-primary)" // here
  strokeOpacity={0.6}
  strokeWidth={1.5}
  {/* rest of the properties */}
/>

It sounds kinda CSS-in-JS, but using CSS behind the scenes. What do you think about it? Can I go on with this approach?

quietbits commented 2 years ago

@italomlp, this looks good. We don't mind if the library is using CSS-in-JS under the hood, as long as we can pass CSS variables for colors (not hard coding hex colors directly). :+1:

italomlp commented 2 years ago

Hey @quietbits, another question appeared: do we have a different tooltip for the charts in light mode? In the design file, we only have examples in the dark variant, so I was wondering if we have a different one in the light theme or if we just keep the same for both.

quietbits commented 2 years ago

Hi @italomlp! Currently, we have the same dark tooltip color in both themes. We use CSS variables --pal-background-tooltip for background and --pal-brand-primary-on for text color. Thanks for checking! :slightly_smiling_face:

italomlp commented 2 years ago

Two more questions appeared when I was applying the charts to the already existing sections:

  1. How exactly do we decide the quantity to show on the "battery-like" chart in the operations column? Since I made the component to receive a percentage, what I'm doing right now is (ledger operations count / 1000) * 100 = ledger operations count / 10, which results in something like 65%, 45%, 87%, and so on, that means that 1000 is the max of the chart. I did this to visualize the things but wanted to confirm how exactly the values would be here.

  2. How exactly should I get the values for the Network Nodes section graphs? Since it should be a series, and currently we have just some numeric values, I assumed that I will need to handle the data from somewhere else, maybe the stellar beat url endpoint where we are already getting part of the data. Wanted to ping you for some direction on it.

cc @quietbits @acharb

quietbits commented 2 years ago
  1. Your calculations sound good to me. I don't think we need to be more precise than that.
  2. We were thinking of using v1/month-statistics endpoint from Stellarbeat. If there is anything we can't get from there, we'll probably remove it. I don't think we were planning to create our own data endpoint for this. Right, @acharb ?
italomlp commented 2 years ago

So, trying to map the attributes from the /month-statistics endpoint across the current ones, I got the following:

/* statsItem is representing each item/date/month in the /month-statistics endpoint */

WATCHER_NODES => statsItem.nrOfActiveWatchersSum
VALIDATOR_NODES => statsItem.nrOfActiveValidatorsSum
FULL_VALIDATORS => statsItem.nrOfActiveFullValidatorsSum
ORGANIZATIONS => statsItem.nrOfActiveOrganizationsSum
TOP_TIER_VALIDATORS => statsItem.topTierSum
TOP_TIER_ORGANIZATIONS => statsItem.topTierOrgsSum

Then I can get these values for each date to mount the series for each attribute. Am I using the right attributes?

quietbits commented 2 years ago

@italomlp these seem correct to me but it's hard to tell 100%. I guess we can try and see if we get similar graphs. :sweat_smile:

@acharb do you think we should cache these on the backend for performance? Most of that data won't change much over a year.

acharb commented 2 years ago

@quietbits ya if that data doesn't change often we can cache it on the backend for quicker loading.

@italomlp take a look at this backend method: https://github.com/stellar/dashboard/blob/17cbc05cb3df4a7878b72d07c915e37fac772b2c/backend/app.ts#L12-L21

which runs when the pods are re-deployed. We can add a method in there for caching stellar-beat data, where the backend requests then caches the data in redis on server start, and opens an endpoint that the frontend can hit for that data.

italomlp commented 2 years ago

Just to clarify, don't we need to get these data by the "current date" when the user is accessing the dashboard?

Let's say if we access it today, we would hit this endpoint: https://api.stellarbeat.io/v1/month-statistics?from=2021-05-12T18%3A56%3A21.213Z&to=2022-05-12T18%3A56%3A21.213Z. (2021-05-12 to 2022-05-12)

But if access it tomorrow, we would hit this one: https://api.stellarbeat.io/v1/month-statistics?from=2021-05-13T18%3A56%3A21.213Z&to=2022-05-13T18%3A56%3A21.213Z. (2021-05-13 to 2022-05-12 - Note the difference for the dates)

How exactly should I make these to and from filters if we cache the data? @quietbits @acharb

acharb commented 2 years ago

Oh I didn't know it required a date filter, I'm not too familiar with this endpoint (doesn't look there's documentation for it?). On second thought let's hold off on adding a cache for this. I think we can make sure the data is what we want, and add caching afterward if it looks like it needs it. (sorry for the added nosie 😄 )

quietbits commented 2 years ago

Agree with @acharb. Let's leave optimization for later. I was just thinking about how to save API requests but we don't know right now how up-to-date information we want to show.

italomlp commented 2 years ago

Yeah, I think it makes sense to defer optimization, so let's leave it for later. About the endpoint, I tried it without a filter, but got a response saying "invalid to or from parameters". Anyway, I have no blockers anymore, so I'll open a PR very soon.