diff --git a/spotlight-client/package.json b/spotlight-client/package.json index 65ca3641..1ab17f4c 100644 --- a/spotlight-client/package.json +++ b/spotlight-client/package.json @@ -19,6 +19,7 @@ "@reach/router": "^1.3.4", "@types/classnames": "^2.2.11", "@types/d3-array": "^2.8.0", + "@types/d3-color": "^2.0.1", "@types/d3-format": "^2.0.0", "@types/d3-interpolate": "^2.0.0", "@types/d3-scale": "^3.2.2", @@ -35,6 +36,7 @@ "change-case": "^4.1.2", "classnames": "^2.2.6", "d3-array": "^2.9.1", + "d3-color": "^2.0.0", "d3-format": "^2.0.0", "d3-interpolate": "^2.0.1", "d3-scale": "^3.2.3", diff --git a/spotlight-client/src/UiLibrary/Dropdown/Dropdown.tsx b/spotlight-client/src/UiLibrary/Dropdown/Dropdown.tsx index 82fbaf55..9156acf0 100644 --- a/spotlight-client/src/UiLibrary/Dropdown/Dropdown.tsx +++ b/spotlight-client/src/UiLibrary/Dropdown/Dropdown.tsx @@ -21,7 +21,7 @@ import React, { useState } from "react"; import Measure from "react-measure"; import { animated, useSpring, useSprings } from "react-spring/web.cjs"; import styled from "styled-components/macro"; -import { colors } from "../colors"; +import { colors } from ".."; import zIndex from "../zIndex"; const BUTTON_HEIGHT = 40; diff --git a/spotlight-client/src/UiLibrary/Pill/LinkPill.tsx b/spotlight-client/src/UiLibrary/Pill/LinkPill.tsx deleted file mode 100644 index 8d90441c..00000000 --- a/spotlight-client/src/UiLibrary/Pill/LinkPill.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from "react"; -import styled from "styled-components/macro"; - -import { PillContainer, PillValue } from "./shared"; - -const LinkPillContainer = styled(PillContainer)``; - -const LinkPillLink = styled.a` - text-decoration: none; -`; - -const LinkPillValue = styled(PillValue)``; - -/** - * HTML link component styled like a `Pill`. Props other than `children` - * will be passed on to a `styled.a` component. - */ -const LinkPill: React.FC = (props) => { - const { children, ...linkProps } = props; - - return ( - - - {children} - - - ); -}; - -export default LinkPill; diff --git a/spotlight-client/src/UiLibrary/Pill/Pill.tsx b/spotlight-client/src/UiLibrary/Pill/Pill.tsx deleted file mode 100644 index e5488301..00000000 --- a/spotlight-client/src/UiLibrary/Pill/Pill.tsx +++ /dev/null @@ -1,30 +0,0 @@ -// Recidiviz - a data platform for criminal justice reform -// Copyright (C) 2021 Recidiviz, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ============================================================================= - -import React from "react"; - -import { PillContainer, PillValue } from "./shared"; - -const Pill: React.FC = ({ children }) => { - return ( - - {children} - - ); -}; - -export default Pill; diff --git a/spotlight-client/src/UiLibrary/Pill/index.ts b/spotlight-client/src/UiLibrary/Pill/index.ts deleted file mode 100644 index 1833ea4f..00000000 --- a/spotlight-client/src/UiLibrary/Pill/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Recidiviz - a data platform for criminal justice reform -// Copyright (C) 2021 Recidiviz, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ============================================================================= - -export { default as Pill } from "./Pill"; -export { default as LinkPill } from "./LinkPill"; -export { PillContainer, PillValue } from "./shared"; diff --git a/spotlight-client/src/UiLibrary/Pill/shared.tsx b/spotlight-client/src/UiLibrary/Pill/shared.tsx deleted file mode 100644 index 3989a1a8..00000000 --- a/spotlight-client/src/UiLibrary/Pill/shared.tsx +++ /dev/null @@ -1,46 +0,0 @@ -// Recidiviz - a data platform for criminal justice reform -// Copyright (C) 2021 Recidiviz, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ============================================================================= - -import styled from "styled-components/macro"; -import animation from "../animation"; -import { colors } from "../colors"; - -const PILL_HEIGHT = 40; - -export const PillContainer = styled.div` - align-items: center; - display: flex; - height: ${PILL_HEIGHT}px; -`; - -export const PillValue = styled.span` - align-items: center; - background: ${colors.buttonBackground}; - border-radius: ${PILL_HEIGHT / 2}px; - color: ${colors.text}; - display: inline-flex; - font-size: 13px; - height: ${PILL_HEIGHT}px; - justify-content: center; - min-width: ${PILL_HEIGHT * 1.5}px; - padding: 8px ${PILL_HEIGHT / 2}px; - transition: background-color ${animation.defaultDuration}; - - &:hover { - background: ${colors.buttonBackgroundHover}; - } -`; diff --git a/spotlight-client/src/UiLibrary/colors.ts b/spotlight-client/src/UiLibrary/colors.ts index 1cb35cdf..9f701665 100644 --- a/spotlight-client/src/UiLibrary/colors.ts +++ b/spotlight-client/src/UiLibrary/colors.ts @@ -15,9 +15,6 @@ // along with this program. If not, see . // ============================================================================= -import { color } from "d3-color"; -import { interpolateRgb } from "d3-interpolate"; - const gray = "#D6DCDC"; const pine = "#00413E"; const pineBright = "#25B894"; @@ -40,7 +37,7 @@ const dataVizColorMap = new Map([ ["skyBlue", "#5F8FD9"], ]); -export const colors = { +export default { accent: pineBright, background: white, buttonBackground: white, @@ -60,26 +57,3 @@ export const colors = { timeWindowStroke: pine, tooltipBackground: pineDark, }; - -const FADE_AMOUNT = 0.45; - -export function highlightFade( - baseColor: string, - { useOpacity = false } = {} -): string { - if (useOpacity) { - // in cases where we actually want the color to be transparent, - // this is a relatively straightforward opacity change - const fadedColor = color(baseColor); - - // can't do anything with an invalid color - if (!fadedColor) return baseColor; - - fadedColor.opacity = FADE_AMOUNT; - return fadedColor.toString(); - } - // in cases where we don't want a transparent color (which is most cases), - // this will create a tint ramp from background color to baseColor; - // the ramp goes from 0 to 1 with values analogous to opacity - return interpolateRgb(colors.background, baseColor)(FADE_AMOUNT); -} diff --git a/spotlight-client/src/UiLibrary/index.ts b/spotlight-client/src/UiLibrary/index.ts index 4670fc95..dd0edff8 100644 --- a/spotlight-client/src/UiLibrary/index.ts +++ b/spotlight-client/src/UiLibrary/index.ts @@ -15,7 +15,7 @@ // along with this program. If not, see . // ============================================================================= -export * from "./colors"; +export { default as colors } from "./colors"; export { default as typefaces } from "./typefaces"; export { default as zIndex } from "./zIndex"; export { default as Chevron } from "./Chevron"; diff --git a/spotlight-client/src/charts/ColorLegend.tsx b/spotlight-client/src/charts/ColorLegend.tsx index 120e3ba1..6f61150b 100644 --- a/spotlight-client/src/charts/ColorLegend.tsx +++ b/spotlight-client/src/charts/ColorLegend.tsx @@ -18,8 +18,9 @@ import classNames from "classnames"; import React from "react"; import styled from "styled-components/macro"; -import { animation, highlightFade } from "../UiLibrary"; +import { animation } from "../UiLibrary"; import { ItemToDisplay, ItemToHighlight } from "./types"; +import { highlightFade } from "./utils"; const ColorLegendWrapper = styled.div` display: flex; diff --git a/spotlight-client/src/charts/WindowedTimeSeries.tsx b/spotlight-client/src/charts/WindowedTimeSeries.tsx index 1d057f5e..92b024b5 100644 --- a/spotlight-client/src/charts/WindowedTimeSeries.tsx +++ b/spotlight-client/src/charts/WindowedTimeSeries.tsx @@ -21,10 +21,10 @@ import { format, isEqual } from "date-fns"; import React, { useCallback, useEffect, useState } from "react"; import MinimapXYFrame from "semiotic/lib/MinimapXYFrame"; import styled from "styled-components/macro"; -import { animation, colors, highlightFade } from "../UiLibrary"; +import { animation, colors } from "../UiLibrary"; import { formatAsNumber } from "../utils"; import BaseChartWrapper from "./ChartWrapper"; -import { getDataWithPct } from "./utils"; +import { getDataWithPct, highlightFade } from "./utils"; import ColorLegend from "./ColorLegend"; import XHoverController from "./XHoverController"; import { HistoricalPopulationBreakdownRecord } from "../metricsApi"; diff --git a/spotlight-client/src/charts/utils.ts b/spotlight-client/src/charts/utils.ts index e1e15a8e..dee96580 100644 --- a/spotlight-client/src/charts/utils.ts +++ b/spotlight-client/src/charts/utils.ts @@ -16,13 +16,15 @@ // ============================================================================= import { sum } from "d3-array"; +import { color } from "d3-color"; +import { interpolateRgb } from "d3-interpolate"; +import { colors } from "../UiLibrary"; /** * Given a series of records, sums up their values and computes the value of each * as a percentage of that total. Returns a copy of the records with `pct` field * included as a number between 0 and 1. */ -// eslint-disable-next-line import/prefer-default-export export function getDataWithPct( data: RecordFormat[] ): (RecordFormat & { pct: number })[] { @@ -33,3 +35,26 @@ export function getDataWithPct( pct: record.value / totalValue, })); } + +const FADE_AMOUNT = 0.45; + +export function highlightFade( + baseColor: string, + { useOpacity = false } = {} +): string { + if (useOpacity) { + // in cases where we actually want the color to be transparent, + // this is a relatively straightforward opacity change + const fadedColor = color(baseColor); + + // can't do anything with an invalid color + if (!fadedColor) return baseColor; + + fadedColor.opacity = FADE_AMOUNT; + return fadedColor.toString(); + } + // in cases where we don't want a transparent color (which is most cases), + // this will create a tint ramp from background color to baseColor; + // the ramp goes from 0 to 1 with values analogous to opacity + return interpolateRgb(colors.background, baseColor)(FADE_AMOUNT); +} diff --git a/yarn.lock b/yarn.lock index 7346f908..2f29ebfb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1983,7 +1983,7 @@ resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-2.8.0.tgz#4b70ccb0c6d2ef28dac1e7e653b3ecd1f4b1d1ee" integrity sha512-Q0ubcGHAmCRPh90/hoYB4eKWhxYKUxphwSeQrlz2tiabQ8S9zqhaE2CZJtCaLH2cjqKcjr52WPvmOA7ha0O4ZA== -"@types/d3-color@*": +"@types/d3-color@*", "@types/d3-color@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-2.0.1.tgz#570ea7f8b853461301804efa52bd790a640a26db" integrity sha512-u7LTCL7RnaavFSmob2rIAJLNwu50i6gFwY9cHFr80BrQURYQBRkJ+Yv47nA3Fm7FeRhdWTiVTeqvSeOuMAOzBQ== @@ -4727,7 +4727,7 @@ d3-color@1, d3-color@^1.4.1: resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== -"d3-color@1 - 2": +"d3-color@1 - 2", d3-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==