[READ-ONLY] Mirror of https://github.com/probablykasper/starchart. GitHub star history graph starchart.kasper.space
chart github github-api github-star graph history star star-history stargazers stars
0

Configure Feed

Select the types of activity you want to include in your feed.

Store localStorage data more efficiently

Kasper (Mar 3, 2023, 7:32 AM +0100) e845c14a a191e967

+64 -28
+5 -6
src/routes/+page.svelte
··· 48 48 const newData = stargazers.starTimes.map((starTime) => { 49 49 count++ 50 50 return { 51 - t: Math.ceil(new Date(starTime).getTime() / 1000) as UTCTimestamp, 51 + t: Math.floor(new Date(starTime).getTime() / 1000) as UTCTimestamp, 52 52 v: count, 53 53 } 54 54 }) 55 - chart.appendLineData(line, newData) 55 + chart.appendStargazers(line, newData) 56 56 } while (endCursor) 57 - line.final = { 58 - t: Math.ceil(new Date().getTime() / 1000) as UTCTimestamp, 57 + chart.addFinal(line, { 58 + t: Math.floor(new Date().getTime() / 1000) as UTCTimestamp, 59 59 v: totalCount, 60 - } 61 - chart.appendLineData(line, [line.final]) 60 + }) 62 61 chart.save() 63 62 } 64 63
+7 -6
src/routes/Tooltip.svelte
··· 35 35 $chart.container.removeEventListener('mousemove', onMouseMove) 36 36 }) 37 37 38 - function findDayEndDataPoint(arr: DataPoint[], max: UTCTimestamp) { 38 + /** Binary search */ 39 + function findLatestDataPoint(arr: DataPoint[], max: UTCTimestamp) { 39 40 let start = 0 40 41 let end = arr.length - 1 41 42 let result: DataPoint | null = null ··· 53 54 return result 54 55 } 55 56 56 - // update tooltip 57 - function mouseEventHandler(param: MouseEventParams) { 57 + function updateTooltipOnMouseEvent(param: MouseEventParams) { 58 58 values = [] 59 59 if ( 60 60 param.point === undefined || ··· 76 76 for (const line of $chart.lines) { 77 77 const maxDate = new Date(time.year, time.month - 1, time.day, 23, 59, 59, 999) 78 78 const maxTimestamp = (maxDate.getTime() / 1000) as UTCTimestamp 79 - const dataPoint = findDayEndDataPoint(line.data, maxTimestamp) 79 + const dataPoint = findLatestDataPoint(line.data, maxTimestamp) 80 + 80 81 if (dataPoint) { 81 82 values.push({ 82 83 line: line, ··· 87 88 values.sort((a, b) => b.value - a.value) 88 89 values = values 89 90 } 90 - $chart.instance.subscribeCrosshairMove(mouseEventHandler) 91 + $chart.instance.subscribeCrosshairMove(updateTooltipOnMouseEvent) 91 92 onDestroy(() => { 92 - $chart.instance.unsubscribeCrosshairMove(mouseEventHandler) 93 + $chart.instance.unsubscribeCrosshairMove(updateTooltipOnMouseEvent) 93 94 }) 94 95 </script> 95 96
+52 -16
src/routes/chart.ts
··· 11 11 import { bottomColors, hexColors, topColors } from './color' 12 12 13 13 export type DataPoint = { t: UTCTimestamp; v: number } 14 - type LineJson = { 14 + type LineBase = { 15 15 name: string 16 16 data: DataPoint[] 17 17 color: number 18 18 /** Loading if absent */ 19 19 final?: DataPoint 20 20 } 21 - export interface Line extends LineJson { 21 + export interface Line extends LineBase { 22 22 instance: ISeriesApi<'Area'> 23 23 deleted: boolean 24 24 } 25 25 26 + type LineJson = { 27 + name: string 28 + /** Star count = index + 1 */ 29 + data: UTCTimestamp[] 30 + color: number 31 + /** Loading if absent */ 32 + final?: DataPoint 33 + } 34 + 26 35 /** Used to invalidate old localStorage */ 27 - const jsonTypeVersion = 2 36 + const jsonTypeVersion = 3 28 37 type Json = { 29 38 lines: LineJson[] 30 39 v: number ··· 38 47 return value 39 48 } 40 49 41 - function loadJsonLines(): LineJson[] { 50 + function loadJsonLines(): LineBase[] { 42 51 try { 43 52 const seriesLocalStorage = JSON.parse(localStorage.getItem('starchart-series') || '{}') 44 53 if (seriesLocalStorage?.v === jsonTypeVersion && seriesLocalStorage?.expiry > Date.now()) { 45 - return (seriesLocalStorage as Json).lines 54 + const lines = (seriesLocalStorage as Json).lines 55 + return lines.map( 56 + (line): LineBase => ({ 57 + color: line.color, 58 + data: line.data.map((utcTimestamp, i): DataPoint => { 59 + return { 60 + t: utcTimestamp, 61 + v: i + 1, 62 + } 63 + }), 64 + final: line.final, 65 + name: line.name, 66 + }) 67 + ) 46 68 } else { 47 69 localStorage.removeItem('starchart-series') 48 70 } ··· 79 101 const store = { 80 102 subscribe, 81 103 82 - addLine(lineJson: LineJson) { 104 + addLine(lineJson: LineBase) { 83 105 const series = chart.instance.addAreaSeries({ 84 106 priceLineVisible: false, 85 107 topColor: topColors[lineJson.color], ··· 120 142 set(chart) 121 143 }, 122 144 123 - appendLineData(line: Line, data: DataPoint[]) { 145 + _appendChartData(line: Line, data: DataPoint[]) { 124 146 if (data.length === 0) { 125 147 return 126 148 } ··· 136 158 line.instance.update(dataPoint) 137 159 } 138 160 } 139 - line.data.push(...data) 161 + 140 162 updateFiller(chart.lines) 141 163 if (fresh) { 142 164 store.resetZoom() 143 165 } 166 + }, 144 167 168 + appendStargazers(line: Line, data: DataPoint[]) { 169 + store._appendChartData(line, data) 170 + line.data.push(...data) 171 + set(chart) 172 + }, 173 + 174 + addFinal(line: Line, data: DataPoint) { 175 + store._appendChartData(line, [data]) 176 + line.final = data 145 177 set(chart) 146 178 }, 147 179 ··· 175 207 lowestDate = dataPoint.t 176 208 } 177 209 } 210 + const now = new Date() 178 211 const dt = new Date(lowestDate * 1000) 179 212 const date = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate()) 180 213 181 214 const dates = [date] 182 - while (dates[dates.length - 1] < new Date()) { 215 + while (dates[dates.length - 1] < now) { 183 216 dates.push( 184 217 new Date( 185 218 dates[dates.length - 1].getFullYear(), ··· 199 232 }) 200 233 } 201 234 235 + const day = 1000 * 60 * 60 * 24 202 236 function save(chart: ChartData) { 203 237 if (chart.lines.length === 0) { 204 238 localStorage.removeItem('starchart-series') 205 239 return 206 240 } 207 - const day = 1000 * 60 * 60 * 24 208 - const jsonLines: LineJson[] = chart.lines.map((line) => ({ 209 - name: line.name, 210 - data: line.data, 211 - color: line.color, 212 - final: line.final, 213 - })) 241 + 242 + const jsonLines = chart.lines.map( 243 + (line): LineJson => ({ 244 + name: line.name, 245 + data: line.data.map((dataPoint) => dataPoint.t), 246 + color: line.color, 247 + final: line.final, 248 + }) 249 + ) 214 250 const json: Json = { 215 251 lines: jsonLines, 216 252 v: jsonTypeVersion,