File size: 2,342 Bytes
a73f888 e8341d2 a73f888 e8341d2 a73f888 e8341d2 a73f888 e8341d2 a73f888 e8341d2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
import { useRef, useEffect } from 'react'
import * as Plot from '@observablehq/plot'
const CostPlot = ({ data, width = 750, height = 500 }) => {
const containerRef = useRef()
useEffect(() => {
const models = [...data.model_table] // sort copy, not in place
.filter(d => d.average !== null && d.cost > 0)
.sort((a, b) => a.cost - b.cost)
.reduce((acc, curr) => {
const last = acc[acc.length - 1]?.maxAverage || 0
acc.push({
...curr,
maxAverage: Math.max(last, curr.average),
newRecord: curr.average > last
})
return acc
}, [])
let USDollar = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
})
const plot = Plot.plot({
width: width,
height: height,
subtitle: 'Cost vs Performance',
x: {
label: 'Cost (USD)',
type: 'log',
// format dollar / ct
tickFormat: d => USDollar.format(d)
},
y: {
label: 'Language Proficiency Score'
},
symbol: {
legend: true
},
marks: [
Plot.dot(models, {
x: d => d.cost,
y: d => d.average,
symbol: 'provider_name',
stroke: 'provider_name',
title: d =>
`${d.provider_name} - ${d.name} (${
d.size?.toLocaleString('en-US', { notation: 'compact' }) || '?B'
})\nCost: ${USDollar.format(d.cost)}\nScore: ${d.average.toFixed(
2
)}`,
tip: true
}),
Plot.line(
[
...models.filter(d => d.newRecord),
{
cost: models.map(d => d.cost).reduce((a, b) => Math.max(a, b), 0),
maxAverage: models[models.length - 1]?.maxAverage || 0
}
],
{
x: d => d.cost,
y: d => d?.maxAverage || 0,
curve: 'catmull-rom',
strokeOpacity: 0.3
}
)
]
})
containerRef.current.append(plot)
return () => plot.remove()
}, [data, width, height])
return (
<div
ref={containerRef}
style={{
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
/>
)
}
export default CostPlot
|