factor-out pickers into jotai atoms

This commit is contained in:
2023-06-18 14:44:24 -04:00
parent 0994a118a9
commit b02c71d206
5 changed files with 205 additions and 118 deletions
+27 -23
View File
@@ -1,34 +1,38 @@
//import Chart from 'chart.js/auto';
import { Chart as ChartJS, Tooltip, Legend, LineElement, CategoryScale, LinearScale, PointElement } from "chart.js";
import { Line } from 'react-chartjs-2';
import Header from './Header';
import { QuoteDatePicker } from "./QuoteDatePicker";
import { HistoricalImpliedVolatilityChart } from "./HistoricalImpliedVolatilityChart";
import { create$Picker } from './Picker';
import { atom as $, useAtomValue } from 'jotai';
ChartJS.register(LineElement, Tooltip, Legend, CategoryScale, LinearScale, PointElement);
const baseUrl = 'http://127.0.0.1:8234';
const $underlyingsUrl = $(`${baseUrl}/option_quotes/underlyings`);
const $underlyingPicker = create$Picker({$url:$underlyingsUrl});
const $quoteDatePicker = create$Picker({
$url: $((get) => `${baseUrl}/option_quotes/${get(get($underlyingPicker).$selectedOption)}/quote_dates`),
$isEnabled: $((get) => get(get($underlyingPicker).$selectedOption)!=='')
});
const $frontMonthPicker = create$Picker({
$url: $((get) => `${baseUrl}/option_quotes/${get(get($underlyingPicker).$selectedOption)}/${get(get($quoteDatePicker).$selectedOption)}/expirations`),
$isEnabled: $((get) => get(get($quoteDatePicker).$selectedOption)!=='' && get(get($underlyingPicker).$selectedOption)!=='')
});
const $backMonthPicker = create$Picker({
$url: $((get) => `${baseUrl}/option_quotes/${get(get($underlyingPicker).$selectedOption)}/${get(get($quoteDatePicker).$selectedOption)}/expirations`),
$isEnabled: $((get) => get(get($quoteDatePicker).$selectedOption)!=='' && get(get($underlyingPicker).$selectedOption)!=='')
});
function App() {
const {Picker:UnderlyingPicker, $selectedOption} = useAtomValue($underlyingPicker);
const {Picker:QuoteDatePicker} = useAtomValue($quoteDatePicker);
const {Picker:FrontMonthPicker} = useAtomValue($frontMonthPicker);
const {Picker:BackMonthPicker} = useAtomValue($backMonthPicker);
return (
<div>
<Header />
<UnderlyingPicker />
<QuoteDatePicker />
<Line
datasetIdKey='id'
data={{
labels: ['Jun', 'Jul', 'Aug'],
datasets: [
{//@ts-ignore
id: 1,
label: '',
data: [5, 6, 7],
},
{//@ts-ignore
id: 2,
label: '',
data: [3, 2, 1],
},
],
}}
/>
<FrontMonthPicker />
<BackMonthPicker />
<HistoricalImpliedVolatilityChart />
</div>
);
}
+27
View File
@@ -0,0 +1,27 @@
import { Chart as ChartJS, Tooltip, Legend, LineElement, CategoryScale, LinearScale, PointElement } from "chart.js";
import { Line } from 'react-chartjs-2';
ChartJS.register(LineElement, Tooltip, Legend, CategoryScale, LinearScale, PointElement);
export function HistoricalImpliedVolatilityChart(){
return (<div>
<Line
datasetIdKey='id'
data={{
labels: ['Jun', 'Jul', 'Aug'],
datasets: [
{//@ts-ignore
id: 1,
label: '',
data: [5, 6, 7],
},
{//@ts-ignore
id: 2,
label: '',
data: [3, 2, 1],
},
],
}}
/>
</div>);
}
+44
View File
@@ -0,0 +1,44 @@
import { useEffect } from "react";
import { atom as $, useAtom, Atom, PrimitiveAtom } from 'jotai';
type PickerInput = { $options?:PrimitiveAtom<Array<string>>, $isLoading?:PrimitiveAtom<boolean>, $selectedOption?:PrimitiveAtom<string>, $url:Atom<string>, $isEnabled?:Atom<boolean> };
export function create$Picker({ $options=$([]), $isLoading=$(false), $selectedOption=$(''), $url=$(''), $isEnabled=$(true) }: PickerInput){
return $({
$options,
$isLoading,
$selectedOption,
$url,
Picker: ()=>{
const [url, setUrl] = useAtom($url);
const [options, setOptions] = useAtom($options);
const [isLoading, setIsLoading] = useAtom($isLoading);
const [selectedOption, setSelectedOption] = useAtom($selectedOption);
const [isEnabled, setIsEnabled] = useAtom($isEnabled);
useEffect(()=>{
if(isEnabled){
fetch(url)
.then(x=>x.json())
.catch((err)=>['AAPL', 'MSFT', 'GOOG'])
.then((underlyings_)=>{ setOptions(underlyings_); setIsLoading(false); })
}
},[isEnabled, url])
return (
<div>
{isLoading
?
<span>Loading...</span>
:
<select value={selectedOption} onChange={(e)=>{ setSelectedOption(e.target.value); }}>
<option key="" value=""></option>
{options.map((date)=>
<option key={date} value={date}>{date}</option>
)}
</select>
}
</div>
);
}
});
}
-32
View File
@@ -1,32 +0,0 @@
import { useEffect, useState } from "react";
import { atom as $, useAtom } from 'jotai';
const $dates = $<Array<string>>([]);
const $isLoading = $<boolean>(false);
export function QuoteDatePicker(){
const [dates, setDates] = useAtom($dates);
const [isLoading, setIsLoading] = useAtom($isLoading);
useEffect(()=>{
fetch('http://127.0.0.1:8234/option_quotes/AAPL/quote_dates')
.then(x=>x.json())
.catch((err)=>['2021-01-02', '2021-01-03', '2021-01-04'])
.then((dates_)=>{ setDates(dates_); setIsLoading(false); })
},[])
return (
<div>
{isLoading
?
<span>Loading...</span>
:
<select>
{dates.map((date)=>
<option key={date} value={date}>{date}</option>
)}
</select>
}
</div>
);
}