Skip to content

Commit

Permalink
IGVF-1305 Redesign home page (#402)
Browse files Browse the repository at this point in the history
* Install nivo core and bar npm packages.
* Display file-set data in an initial nivo chart.
* Change colors and height of chart.
* Make custom Y-axis labels. Move the legend to the bottom.
* Refactor the charting code a bit. Move legend to the left side to make space for a month selector. Remove the chart hover tooltips. Add initial titles and statistics boxes to the home-page header.
* Make the width of the Y-axis label column easily changeable. Fix some of the comments.
* Update the data-provider request to include the creation timestamp.
* Implement the month selector that filters the list of measurement sets displayed.
* Format each bar’s aria label.
* Don’t show fractional scale values.
* Make dark mode work.
* Add home-page title.
* Fix the tick marks so that large values don’t cause the ticks to mush together.
* Fix the bottom-axis tick numbers so they always include 0 and the maximum value. Abbreviate the bottom-axis values.
* Finish the statistics boxes.
* Hide chart on narrow pages.
* Increase the Cypress timeout to 60 seconds from 30 seconds. Add a delay after clearing the text area before typing into it in the Cypress add.cy.js file to avoid having the new text append the existing text.
* Change Cypress timeout from 60s to 65s to see if it finally triggers on CircleCI.
* Try going back to the original 30s timeout, then wait 10s after logging in before calling cy.visit, instead of just one second.
* Maybe cy.visit() breaks the Cypress test. Instead, navigate to the Schemas page for the
* Try not retrieving data for home page to see if this helps Cypress pass. Set Cypress timeout back to 60 seconds.
* Add a command timeout of 60 seconds specifically for add.cy.js to see if that helps.
* Return getServerSideProps() code to retrieve home-page data. Change add.cy.js defaultCommandTimeout to 90 seconds because the last Cypress/CircleCI run had the editor appear exactly the moment Cypress timed out the test. Wait two seconds instead of one after logging in, as the menu commands cut in slightly early.
* Another CircleCI/Cypress failure. Now try not rendering the graph. If that works, I don’t know where to go from there.
* Fix build error in last commit.
* Make home-page chart conditional, only rendering if Cypress doesn’t run.
* Revert many changes to the Cypress tests, and remove the container query from `<App>` as it seems like that caused the Cypress failures for some reason.
* Add IGVF Consortium link to the home-page title area.
* Update the statistics boxes for dark mode. Change the title of the Measurement Set statistics box. Change the Lab statistics box to show total Sample objects.
* Have legend only appear while the user is logged in.
* Reorganize the functions within chart-file-set.js. Correct some comments. Add a Cypress test for the home page.
* Try making the Cypress browser size larger to make the chart appear.
* Do a little code reorganization.
* Use the floating ui package to manage the month-selector popup instead of handling everything here. That lets us take advantage of floating ui’s automatic positioning.
* Move non-React-component functions to a new file in lib/ so we can cover them with Jest tests.
* Have home-page Cypress test work with default igvfd data, not including the MeasurementSet additions I made.
* Make the month selector accessible.
* Add Jest tests for the home.ts library. Convert the home.js library to Typescript.
* Correct a comment.
* Remove Cypress tests for the home page chart bars because they’re all for the same date.
* Change the icon colors.
* Correct some comments. Add some attributes for accessibility.
* Convert statistics panels to linked buttons.
* Colorize the three statistics buttons. Change month-selector button into a primary style.
* Adjust color of the Samples statistics button.
* Add catalog links to the main navigation.
* Change the coloring on the statistics buttons.
* Delete now-unused home-page images.
* Fix a merge marker I missed last time.
* Add the cumulative release chart. Remove Catalog section.
* Format the month labels.
* Abbreviate numbers used in the Y axis labels.
* Make the Y axis legend work with dark mode.
* Replace the month-selection dropdown code with the new dropdown module. Move the text-color Tailwind CSS out of an `<App>` div and into the body tag so that root-level portals get the automatic text color.
* Clean up chart title usage. Change the status chart legend depending on if the user has logged in or not, instead of hiding the legend if the user hasn’t logged in.
* Have home.test.js pass.
* Add Jest test for converting file-set data to release data. Get full coverage for other Jest tests.
* Fix home-page Cypress tests.
* Add Catalog button to the home-page title.
* Make sure the home page works even with no MeasurementSet release data.
* Correct comments. Remove the now-unused NavigationAnchorItem component.
* Reduce the line-chart Y-axis ticks for small amounts.
* Updates from Idan’s feedback.
  • Loading branch information
forresttanaka authored Feb 6, 2024
1 parent 6a58102 commit 196abd0
Show file tree
Hide file tree
Showing 23 changed files with 2,089 additions and 56 deletions.
165 changes: 165 additions & 0 deletions components/chart-file-set-release.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// node_modules
import _ from "lodash";
import dynamic from "next/dynamic";
import PropTypes from "prop-types";
import { useContext } from "react";
// component
import GlobalContext from "./global-context";
// lib
import { abbreviateNumber } from "../lib/general";

// Use a dynamic import to avoid an import error for nivo modules.
// https://github.com/plouc/nivo/issues/2310#issuecomment-1552663752
const ResponsiveLine = dynamic(
() => import("@nivo/line").then((m) => m.ResponsiveLine),
{ ssr: false }
);

/**
* Primary color used in the chart.
*/
const CHART_COLOR = "#00a651";

/**
* Custom X-axis tick that works like the default but with dark-mode support.
*/
function CustomXTick({ value, x, y, rotate }) {
return (
<g transform={`translate(${x},${y + 10}) rotate(${rotate})`}>
<text
x={0}
y={0}
textAnchor="start"
dominantBaseline="central"
className="fill-black dark:fill-white"
fontSize={10}
>
{value}
</text>
</g>
);
}

CustomXTick.propTypes = {
// Value to display
value: PropTypes.string.isRequired,
// X coordinate of the tick
x: PropTypes.number.isRequired,
// Y coordinate of the tick
y: PropTypes.number.isRequired,
// Rotation angle for the tick
rotate: PropTypes.number.isRequired,
};

/**
* Custom Y-axis tick that displays abbreviated numbers (e.g. “550K”) and works with dark mode.
*/
function CustomYTick({ value, y }) {
return (
<g transform={`translate(0,${y})`}>
<text
x={-8}
y={-12}
dy={16}
fontSize={12}
textAnchor="end"
className="fill-black dark:fill-white"
>
{abbreviateNumber(value)}
</text>
</g>
);
}

CustomYTick.propTypes = {
// Value for the tick
value: PropTypes.number.isRequired,
// Y position for the tick
y: PropTypes.number.isRequired,
};

/**
* Render a chart of file-set counts by release date. This appears as a cumulative line chart.
*/
export default function ChartFileSetRelease({ releaseData, title }) {
const data = [
{
id: "release-counts",
data: releaseData,
},
];

// Get the dark-mode setting from the global context for cases we can't use Tailwind CSS.
const { darkMode } = useContext(GlobalContext);
const legendColor = darkMode.enabled ? "#ffffff" : "#000000";
const pointColor = darkMode.enabled ? "#000000" : "#ffffff";

return (
<div className="h-96">
<ResponsiveLine
data={data}
animate={false}
ariaLabel={title}
areaBaselineValue={releaseData[0].y}
areaOpacity={0.2}
axisBottom={{
orient: "bottom",
tickSize: 5,
tickPadding: 5,
tickRotation: 45,
renderTick: CustomXTick,
}}
axisLeft={{
orient: "left",
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
legend: "Cumulative Released Data Sets",
legendOffset: -60,
legendPosition: "middle",
renderTick: CustomYTick,
tickValues: releaseData.at(-1).y < 10 ? 4 : 10,
}}
colors={[CHART_COLOR]}
curve="catmullRom"
enableArea={true}
enableGridX={false}
margin={{
top: 20,
right: 50,
bottom: 50,
left: 70,
}}
pointSize={8}
pointColor={pointColor}
pointBorderWidth={2}
pointBorderColor={CHART_COLOR}
theme={{
grid: { line: { className: "stroke-gray-300 dark:stroke-gray-700" } },
axis: { legend: { text: { fill: legendColor } } },
}}
xScale={{
type: "point",
}}
yScale={{
type: "linear",
stacked: true,
min: "auto",
max: "auto",
}}
/>
</div>
);
}

ChartFileSetRelease.propTypes = {
// Release data to display in the chart
releaseData: PropTypes.arrayOf(
PropTypes.exact({
x: PropTypes.string.isRequired,
y: PropTypes.number.isRequired,
})
).isRequired,
// Title for the chart; used for the chart's aria label
title: PropTypes.string.isRequired,
};
Loading

0 comments on commit 196abd0

Please sign in to comment.