rework hierarchy
This commit is contained in:
@@ -1,94 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { evepraisalAxiosInstance } from '@/service';
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { MarketOrderHistory, MarketResult, getHistory, jitaId } from ".";
|
||||
import MarketReultTable from "./MarketResultTable.vue";
|
||||
import { MarketType, getMarketType, getMarketTypes } from "./type";
|
||||
|
||||
type MarketItemStorage = {
|
||||
typeID: number;
|
||||
history: MarketOrderHistory[];
|
||||
}
|
||||
|
||||
const item = ref("");
|
||||
/**
|
||||
* @deprecated use itemsStorage instead
|
||||
*
|
||||
* TODO: remove this in the future
|
||||
*/
|
||||
const oldStorage = useStorage<MarketItemStorage[]>('market-items', []);
|
||||
const itemsStorage = useStorage<MarketItemStorage[]>('market-scan-items', []);
|
||||
const items = ref<MarketResult[]>([]);
|
||||
const addOrRelaod = async (type: MarketType) => {
|
||||
const typeID = type.id;
|
||||
const [history, price] = await Promise.all([
|
||||
getHistory(jitaId, typeID),
|
||||
evepraisalAxiosInstance.post(`/appraisal.json?market=jita&persist=no&raw_textarea=${type.name}`)
|
||||
]);
|
||||
const item = {
|
||||
type,
|
||||
history,
|
||||
buy: price.data.appraisal.items[0].prices.buy.max,
|
||||
sell: price.data.appraisal.items[0].prices.sell.min
|
||||
};
|
||||
|
||||
if (items.value.some(i => i.type.id === typeID)) {
|
||||
items.value = items.value.map(i => i.type.id === typeID ? item : i);
|
||||
} else {
|
||||
items.value = [ ...items.value, item];
|
||||
}
|
||||
}
|
||||
const reloadAll = async () => {
|
||||
items.value = await Promise.all(items.value.map( async i => ({ ...i, history: await getHistory(jitaId, i.type.id) })));
|
||||
}
|
||||
const addItem = async () => {
|
||||
const type = await getMarketType(item.value.split('\t')[0]);
|
||||
|
||||
item.value = "";
|
||||
addOrRelaod(type);
|
||||
}
|
||||
|
||||
watch(items, itms => itemsStorage.value = itms.map(i => ({ typeID: i.type.id, history: i.history })));
|
||||
onMounted(async () => {
|
||||
|
||||
if (itemsStorage.value.length === 0) {
|
||||
if (oldStorage.value.length > 0) {
|
||||
itemsStorage.value = oldStorage.value;
|
||||
oldStorage.value = [];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const types = await getMarketTypes(itemsStorage.value.map(i => i.typeID));
|
||||
const prices: any = (await evepraisalAxiosInstance.post(`/appraisal.json?market=jita&persist=no&raw_textarea=${types.map(t => t.name).join("%0A")}`)).data;
|
||||
|
||||
items.value = itemsStorage.value.map(i => {
|
||||
const type = types.find(t => t.id === i.typeID) as MarketType;
|
||||
const price = prices.appraisal.items.find((p: any) => p.typeID === i.typeID);
|
||||
|
||||
return {
|
||||
...i,
|
||||
type: type,
|
||||
buy: price.prices.buy.max,
|
||||
sell: price.prices.sell.min
|
||||
};
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid mb-2 mt-4">
|
||||
<div class="w-auto">
|
||||
<span>Item: </span>
|
||||
<input type="text" class="w-96" v-model="item" @keyup.enter="addItem" />
|
||||
<button class="justify-self-end ms-2" @click="addItem">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="items.length > 0">
|
||||
<hr />
|
||||
<MarketReultTable :items="items" @relaod="type => addOrRelaod(type)" @relaodAll="reloadAll" />
|
||||
</template>
|
||||
</template>
|
||||
13
src/market/MarketOrderHistory.ts
Normal file
13
src/market/MarketOrderHistory.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { esiAxiosInstance } from "@/service";
|
||||
|
||||
|
||||
export type MarketOrderHistory = {
|
||||
average: number;
|
||||
date: string;
|
||||
highest: number;
|
||||
lowest: number;
|
||||
order_count: number;
|
||||
volume: number;
|
||||
}
|
||||
|
||||
export const getHistory = async (regionId: number, tyeId: number): Promise<MarketOrderHistory[]> => (await esiAxiosInstance.get(`/markets/${regionId}/history/`, { params: { type_id: tyeId } })).data;
|
||||
@@ -1,2 +1,4 @@
|
||||
export * from './MarketOrderHistory';
|
||||
export * from './market';
|
||||
export * from './type';
|
||||
|
||||
|
||||
@@ -1,80 +1,3 @@
|
||||
import { esiAxiosInstance } from "@/service";
|
||||
import { MarketType } from "./type";
|
||||
|
||||
export const jitaId = 10000002;
|
||||
|
||||
export type MarketOrderHistory = {
|
||||
average: number;
|
||||
date: string;
|
||||
highest: number;
|
||||
lowest: number;
|
||||
order_count: number;
|
||||
volume: number;
|
||||
}
|
||||
|
||||
export type MarketResult = {
|
||||
type: MarketType;
|
||||
history: MarketOrderHistory[];
|
||||
buy: number,
|
||||
sell: number
|
||||
}
|
||||
|
||||
export type HistoryQuartils = {
|
||||
totalVolume: number,
|
||||
q1: number,
|
||||
median: number,
|
||||
q3: number,
|
||||
}
|
||||
|
||||
export const getHistory = async (regionId: number, tyeId: number): Promise<MarketOrderHistory[]> => (await esiAxiosInstance.get(`/markets/${regionId}/history/`, { params: { type_id: tyeId } })).data;
|
||||
|
||||
export const getHistoryQuartils = (history: MarketOrderHistory[], days?: number): HistoryQuartils => {
|
||||
const now = Date.now();
|
||||
|
||||
const volumes = history
|
||||
.flatMap(h => {
|
||||
const volume = h.volume;
|
||||
|
||||
if (volume === 0 || (days && new Date(h.date).getTime() < now - days * 24 * 60 * 60 * 1000)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const e = estimateVolume(h);
|
||||
|
||||
return [[h.highest, e], [h.lowest, volume - e]];
|
||||
})
|
||||
.filter(h => h[1] > 0)
|
||||
.sort((a, b) => a[0] - b[0]);
|
||||
|
||||
const totalVolume = volumes.reduce((acc, [_, v]) => acc + v, 0);
|
||||
const quartilVolume = totalVolume / 4;
|
||||
const quartils: [number, number, number] = [0, 0, 0];
|
||||
|
||||
let currentVolume = 0;
|
||||
let quartil = 0;
|
||||
|
||||
for (const [price, volume] of volumes) {
|
||||
currentVolume += volume;
|
||||
|
||||
if (currentVolume >= quartilVolume * (quartil + 1)) {
|
||||
quartils[quartil] = price;
|
||||
if (quartil === 2) {
|
||||
break;
|
||||
}
|
||||
quartil++;
|
||||
}
|
||||
}
|
||||
return {
|
||||
totalVolume,
|
||||
q1: quartils[0],
|
||||
median: quartils[1],
|
||||
q3: quartils[2],
|
||||
};
|
||||
}
|
||||
|
||||
const estimateVolume = (history: MarketOrderHistory): number => {
|
||||
if (history.volume === 0) {
|
||||
return 0;
|
||||
}
|
||||
return Math.max(1, Math.round(history.volume * ((history.average - history.lowest) / (history.highest - history.lowest))));
|
||||
}
|
||||
59
src/market/scan/HistoryQuartils.ts
Normal file
59
src/market/scan/HistoryQuartils.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { MarketOrderHistory } from "@/market";
|
||||
|
||||
export type HistoryQuartils = {
|
||||
totalVolume: number,
|
||||
q1: number,
|
||||
median: number,
|
||||
q3: number,
|
||||
}
|
||||
|
||||
export const getHistoryQuartils = (history: MarketOrderHistory[], days?: number): HistoryQuartils => {
|
||||
const now = Date.now();
|
||||
|
||||
const volumes = history
|
||||
.flatMap(h => {
|
||||
const volume = h.volume;
|
||||
|
||||
if (volume === 0 || (days && new Date(h.date).getTime() < now - days * 24 * 60 * 60 * 1000)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const e = estimateVolume(h);
|
||||
|
||||
return [[h.highest, e], [h.lowest, volume - e]];
|
||||
})
|
||||
.filter(h => h[1] > 0)
|
||||
.sort((a, b) => a[0] - b[0]);
|
||||
|
||||
const totalVolume = volumes.reduce((acc, [_, v]) => acc + v, 0);
|
||||
const quartilVolume = totalVolume / 4;
|
||||
const quartils: [number, number, number] = [0, 0, 0];
|
||||
|
||||
let currentVolume = 0;
|
||||
let quartil = 0;
|
||||
|
||||
for (const [price, volume] of volumes) {
|
||||
currentVolume += volume;
|
||||
|
||||
if (currentVolume >= quartilVolume * (quartil + 1)) {
|
||||
quartils[quartil] = price;
|
||||
if (quartil === 2) {
|
||||
break;
|
||||
}
|
||||
quartil++;
|
||||
}
|
||||
}
|
||||
return {
|
||||
totalVolume,
|
||||
q1: quartils[0],
|
||||
median: quartils[1],
|
||||
q3: quartils[2],
|
||||
};
|
||||
}
|
||||
|
||||
const estimateVolume = (history: MarketOrderHistory): number => {
|
||||
if (history.volume === 0) {
|
||||
return 0;
|
||||
}
|
||||
return Math.max(1, Math.round(history.volume * ((history.average - history.lowest) / (history.highest - history.lowest))));
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { formatIsk, percentFormater } from '@/formaters';
|
||||
import { MarketType, MarketTypeLabel } from "@/market";
|
||||
import { SortableHeader, useSort } from '@/table';
|
||||
import { ArrowPathIcon } from '@heroicons/vue/24/outline';
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import { computed, ref } from 'vue';
|
||||
import { MarketResult, getHistoryQuartils } from ".";
|
||||
import { MarketType, MarketTypeLabel } from "./type";
|
||||
import { ScanResult, getHistoryQuartils } from '.';
|
||||
|
||||
type Result = {
|
||||
type: MarketType;
|
||||
@@ -20,7 +20,7 @@ type Result = {
|
||||
}
|
||||
|
||||
interface Props {
|
||||
items?: MarketResult[];
|
||||
items?: ScanResult[];
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
4
src/market/scan/index.ts
Normal file
4
src/market/scan/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './HistoryQuartils';
|
||||
export * from './scan';
|
||||
|
||||
export { default as ScanResultTable } from './ScanResultTable.vue';
|
||||
9
src/market/scan/scan.ts
Normal file
9
src/market/scan/scan.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { MarketOrderHistory, MarketType } from "@/market";
|
||||
|
||||
export type ScanResult = {
|
||||
type: MarketType;
|
||||
history: MarketOrderHistory[];
|
||||
buy: number,
|
||||
sell: number
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user