1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2025-02-05 05:28:32 +00:00

Drop graph/linechart from web header

This resolves #1669.

Also bumped some dependencies.
This commit is contained in:
Brenden Matthews 2023-11-08 14:32:02 -05:00
parent 42cdca055f
commit 370a02f087
7 changed files with 258 additions and 1048 deletions

View File

@ -1,12 +1,10 @@
import Link from 'next/link' import Link from 'next/link'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import GitHub from './GitHub' import GitHub from './GitHub'
import { LineChart } from './LineChart'
import ThemeSwitcher from './ThemeSwitcher' import ThemeSwitcher from './ThemeSwitcher'
type HeaderProps = { type HeaderProps = {
name: string name: string
darkMode: boolean
setDarkMode: (state: boolean) => void setDarkMode: (state: boolean) => void
searchIndex: SearchIndex searchIndex: SearchIndex
} }
@ -14,7 +12,7 @@ type HeaderProps = {
import * as React from 'react' import * as React from 'react'
import Search from './Search' import Search from './Search'
import { SearchIndex, SearchItem } from '../utils/search' import { SearchIndex, SearchItem } from '../utils/search'
import Fuse from 'fuse.js' import Fuse, { IFuseOptions } from 'fuse.js'
interface NavLinkProps { interface NavLinkProps {
href: string href: string
@ -38,13 +36,12 @@ const NavLink: React.FunctionComponent<NavLinkProps> = (props) => {
export default function Header({ export default function Header({
name, name,
darkMode,
setDarkMode, setDarkMode,
searchIndex, searchIndex,
}: HeaderProps) { }: HeaderProps) {
const router = useRouter() const router = useRouter()
const fuse = React.useMemo(() => { const fuse = React.useMemo(() => {
const options: Fuse.IFuseOptions<SearchItem> = {} const options: IFuseOptions<SearchItem> = {}
return new Fuse( return new Fuse(
searchIndex.list, searchIndex.list,
options, options,
@ -67,7 +64,7 @@ export default function Header({
<NavLink href="/lua" name="Lua" /> <NavLink href="/lua" name="Lua" />
</div> </div>
)} )}
<LineChart width={380} height={40} darkMode={darkMode} /> <div className="flex-grow" />
<Search fuse={fuse} /> <Search fuse={fuse} />
<div className="flex"> <div className="flex">
<div className="border-r mx-1 px-1 border-slate-700"> <div className="border-r mx-1 px-1 border-slate-700">

View File

@ -51,7 +51,6 @@ export default function Layout({ children, searchIndex }: LayoutProps) {
<Header <Header
searchIndex={searchIndex} searchIndex={searchIndex}
name="Conky" name="Conky"
darkMode={darkMode}
setDarkMode={setDarkMode} setDarkMode={setDarkMode}
/> />
</div> </div>

View File

@ -1,124 +0,0 @@
import { useEffect, useMemo, useRef } from 'react'
import * as d3 from 'd3'
import { random } from 'colord'
type DataPoint = { x: number; y: number }
type LineChartProps = {
width: number
height: number
darkMode: boolean
}
function getRandomArbitrary(min: number, max: number): number {
return Math.random() * (max - min) + min
}
function updateData(width: number, data: Array<DataPoint>): Array<DataPoint> {
while (data.length >= width) {
data.shift()
}
const prev = data.at(data.length - 1)
if (prev) {
data.push({
x: prev.x + 1,
y: Math.max(0, prev.y + getRandomArbitrary(-120, 120)),
})
} else {
data.push({
x: 0,
y: getRandomArbitrary(0, 100),
})
}
return data
}
function fetchData() {
const storedData =
typeof window === 'undefined'
? '[]'
: localStorage.getItem('chartData') || '[]'
const data = JSON.parse(storedData)
return data || []
}
const data = fetchData()
export const LineChart = ({ width, height, darkMode }: LineChartProps) => {
const timerRef = useRef<NodeJS.Timeout>()
const svgRef = useRef(null)
const stroke = useMemo(() => random(), [])
useEffect(() => {
const doIt = (data: DataPoint[]) => {
data = updateData(width, data)
// Y axis
const [min, max] = d3.extent(data, (d) => d.y)
const yScale = d3
.scaleLinear()
.domain([min || 0, max || 0])
.range([height, 0])
// X axis
const [, xMax] = d3.extent(data, (d) => d.x)
const xScale = d3
.scaleLinear()
.domain([(xMax || 0) - width, xMax || 0])
.range([0, width])
if (!svgRef.current) {
return
}
d3.select(svgRef.current)
.selectAll('rect')
.data(data)
.join(
(enter) =>
enter
.append('rect')
.style(
'stroke',
darkMode ? stroke.lighten().toHex() : stroke.darken().toHex()
)
.style('stroke-opacity', '0.7')
.attr('x', (d) => xScale(d.x))
.attr('y', (d) => yScale(d.y))
.attr('height', (d) => yScale((max || 0) - d.y))
.attr('width', () => 1),
(update) =>
update
.transition()
.duration(1000)
.style(
'stroke',
darkMode ? stroke.lighten().toHex() : stroke.darken().toHex()
)
.attr('x', (d) => xScale(d.x))
.attr('y', (d) => yScale(d.y))
.attr('height', (d) => yScale((max || 0) - d.y))
.attr('width', () => 1),
(exit) => exit.call((d) => d.transition().remove())
)
localStorage.setItem('chartData', JSON.stringify(data))
timerRef.current = setTimeout(() => {
doIt(data)
}, 1000)
}
doIt(data)
return () => clearTimeout(timerRef.current)
}, [darkMode, stroke, height, width])
return (
<svg
width={width}
height={height}
viewBox={`0 0 ${width} ${height}`}
preserveAspectRatio="none"
ref={svgRef}
className="fill-transparent bg-transparent grow"
/>
)
}

View File

@ -1,4 +1,4 @@
import Fuse from 'fuse.js' import Fuse, { FuseResult } from 'fuse.js'
import React, { Fragment, useCallback, useEffect, useState } from 'react' import React, { Fragment, useCallback, useEffect, useState } from 'react'
import { Search as SearchIcon } from 'react-feather' import { Search as SearchIcon } from 'react-feather'
import { SearchItem } from '../utils/search' import { SearchItem } from '../utils/search'
@ -10,7 +10,7 @@ export interface SearchProps {
} }
interface SearchResultProps { interface SearchResultProps {
result: Fuse.FuseResult<SearchItem> result: FuseResult<SearchItem>
selected: boolean selected: boolean
active: boolean active: boolean
} }
@ -60,9 +60,9 @@ const SearchResult: React.FunctionComponent<SearchResultProps> = (props) => {
const Search: React.FunctionComponent<SearchProps> = ({ fuse }) => { const Search: React.FunctionComponent<SearchProps> = ({ fuse }) => {
const router = useRouter() const router = useRouter()
const [searchText, setSearchText] = useState('') const [searchText, setSearchText] = useState('')
const [searchResults, setSearchResults] = useState< const [searchResults, setSearchResults] = useState<FuseResult<SearchItem>[]>(
Fuse.FuseResult<SearchItem>[] []
>([]) )
const [isOpen, setIsOpen] = useState(false) const [isOpen, setIsOpen] = useState(false)
const handleKeyPress = useCallback( const handleKeyPress = useCallback(
@ -94,7 +94,7 @@ const Search: React.FunctionComponent<SearchProps> = ({ fuse }) => {
const searchResult = fuse.search(value) const searchResult = fuse.search(value)
setSearchResults(searchResult) setSearchResults(searchResult)
} }
const onChange = (value?: Fuse.FuseResult<SearchItem>) => { const onChange = (value?: FuseResult<SearchItem>) => {
if (value) { if (value) {
if (value.item.kind === 'var') { if (value.item.kind === 'var') {
router.push(`/variables#${value.item.name}`, undefined, { router.push(`/variables#${value.item.name}`, undefined, {

1114
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -21,40 +21,38 @@
"e2e:headless": "start-server-and-test dev http://localhost:3000 \"cypress run --e2e\"" "e2e:headless": "start-server-and-test dev http://localhost:3000 \"cypress run --e2e\""
}, },
"dependencies": { "dependencies": {
"@fontsource-variable/fira-code": "^5.0.13", "@fontsource-variable/fira-code": "^5.0.15",
"@fontsource-variable/inter": "^5.0.13", "@fontsource-variable/inter": "^5.0.15",
"@fontsource-variable/newsreader": "^5.0.14", "@fontsource-variable/newsreader": "^5.0.16",
"@headlessui/react": "^1.7.17", "@headlessui/react": "^1.7.17",
"@mapbox/rehype-prism": "^0.8.0", "@mapbox/rehype-prism": "^0.8.0",
"@netlify/plugin-nextjs": "^4.40.2", "@netlify/plugin-nextjs": "^4.41.1",
"@tailwindcss/typography": "^0.5.10", "@tailwindcss/typography": "^0.5.10",
"classnames": "^2.3.2", "classnames": "^2.3.2",
"colord": "^2.9.3", "colord": "^2.9.3",
"d3": "^7.8.5", "fuse.js": "^7.0.0",
"fuse.js": "^6.6.2",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"inter-ui": "^3.19.3", "inter-ui": "^3.19.3",
"next": "^13.5.4", "next": "^14.0.1",
"prismjs": "^1.29.0", "prismjs": "^1.29.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-feather": "^2.0.10" "react-feather": "^2.0.10"
}, },
"devDependencies": { "devDependencies": {
"@types/d3": "^7.4.1", "@types/eslint": "^8.44.7",
"@types/eslint": "^8.44.4", "@types/js-yaml": "^4.0.9",
"@types/js-yaml": "^4.0.6",
"@types/mapbox__rehype-prism": "^0.8.1", "@types/mapbox__rehype-prism": "^0.8.1",
"@types/node": "^20.8.4", "@types/node": "^20.9.0",
"@types/prismjs": "^1.26.1", "@types/prismjs": "^1.26.3",
"@types/react": "^18.2.27", "@types/react": "^18.2.37",
"@types/react-dom": "^18.2.12", "@types/react-dom": "^18.2.15",
"@typescript-eslint/eslint-plugin": "^6.7.5", "@typescript-eslint/eslint-plugin": "^6.10.0",
"@typescript-eslint/parser": "^6.7.5", "@typescript-eslint/parser": "^6.10.0",
"autoprefixer": "^10.4.15", "autoprefixer": "^10.4.16",
"cypress": "^13.3.0", "cypress": "^13.4.0",
"eslint": "^8.51.0", "eslint": "^8.53.0",
"eslint-config-next": "^13.5.4", "eslint-config-next": "^14.0.1",
"eslint-config-prettier": "^9.0.0", "eslint-config-prettier": "^9.0.0",
"eslint-plugin-cypress": "^2.15.1", "eslint-plugin-cypress": "^2.15.1",
"eslint-plugin-mdx": "^2.2.0", "eslint-plugin-mdx": "^2.2.0",
@ -65,8 +63,8 @@
"postcss": "^8.4.31", "postcss": "^8.4.31",
"rehype-stringify": "^9.0.4", "rehype-stringify": "^9.0.4",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"start-server-and-test": "^2.0.1", "start-server-and-test": "^2.0.2",
"tailwindcss": "^3.3.3", "tailwindcss": "^3.3.5",
"typescript": "^5.2.2" "typescript": "^5.2.2"
} }
} }

View File

@ -1,4 +1,4 @@
import Fuse from 'fuse.js' import Fuse, { FuseIndexRecords } from 'fuse.js'
import { getConfigSettings, getLua, getVariables } from './doc-utils' import { getConfigSettings, getLua, getVariables } from './doc-utils'
export interface SearchItem { export interface SearchItem {
kind: string kind: string
@ -8,7 +8,7 @@ export interface SearchItem {
export interface SearchIndex { export interface SearchIndex {
index: { index: {
keys: readonly string[] keys: readonly string[]
records: Fuse.FuseIndexRecords records: FuseIndexRecords
} }
list: SearchItem[] list: SearchItem[]
} }