score weight + quantils tooltip
This commit is contained in:
33
src/components/Tooltip.vue
Normal file
33
src/components/Tooltip.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import { vElementHover } from '@vueuse/components';
|
||||
import { useVModel } from '@vueuse/core';
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
}
|
||||
|
||||
interface Emit {
|
||||
(e: 'update:open', value: boolean): void;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
open: false,
|
||||
});
|
||||
const emit = defineEmits<Emit>();
|
||||
|
||||
const isOpen = useVModel(props, 'open', emit, {passive: true});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div clas="flex flex-col items-center justify-center" :class="{'open': isOpen}">
|
||||
<div v-element-hover="(h: boolean) => isOpen = h" class="m-auto header">
|
||||
<slot name="header" />
|
||||
</div>
|
||||
<div v-if="isOpen" class="m-auto">
|
||||
<div class="z-10 absolute">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
4
src/components/index.ts
Normal file
4
src/components/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export { default as Modal } from './Modal.vue';
|
||||
export { default as SliderCheckbox } from './SliderCheckbox.vue';
|
||||
export { default as Tooltip } from './Tooltip.vue';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import SliderCheckbox from '@/SliderCheckbox.vue';
|
||||
import { SliderCheckbox } from '@/components';
|
||||
import { SortableHeader, useSort } from '@/components/table';
|
||||
import { formatIsk, percentFormater } from '@/formaters';
|
||||
import { MarketType, MarketTypeLabel, TaxInput, useMarketTaxStore } from "@/market";
|
||||
import { SortableHeader, useSort } from '@/table';
|
||||
import { ShoppingCartIcon, TrashIcon } from '@heroicons/vue/24/outline';
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import { computed, ref } from 'vue';
|
||||
@@ -15,7 +15,7 @@ type Result = {
|
||||
buy: number;
|
||||
sell: number;
|
||||
q1: number;
|
||||
mmedian: number;
|
||||
median: number;
|
||||
q3: number;
|
||||
profit: number;
|
||||
score: number;
|
||||
@@ -50,7 +50,7 @@ const { sortedArray, headerProps } = useSort<Result>(computed(() => props.items
|
||||
.map(r => {
|
||||
const quartils = getHistoryQuartils(r.history, days.value);
|
||||
const profit = quartils.q1 === 0 || quartils.q3 === 0 ? 0 : marketTaxStore.calculateProfit(quartils.q1, quartils.q3);
|
||||
const score = profit <= 0 ? 0 : Math.sqrt(quartils.totalVolume * quartils.q1 * profit / (days.value * Math.max(1, r.orderCount)));
|
||||
const score = profit <= 0 ? 0 : Math.sqrt((Math.pow(quartils.totalVolume, 1.1) * Math.pow(quartils.q1, 1.2) * Math.pow(profit, 0.5) * Math.pow(Math.max(1, r.orderCount), -0.7)) / days.value);
|
||||
|
||||
return {
|
||||
type: r.type,
|
||||
@@ -59,7 +59,7 @@ const { sortedArray, headerProps } = useSort<Result>(computed(() => props.items
|
||||
buy: r.buy,
|
||||
sell: r.sell,
|
||||
q1: quartils.q1,
|
||||
mmedian: quartils.median,
|
||||
median: quartils.median,
|
||||
q3: quartils.q3,
|
||||
profit,
|
||||
score
|
||||
@@ -123,7 +123,7 @@ const getLineColor = (result: Result) => {
|
||||
<td class="text-right">{{ formatIsk(r.buy) }}</td>
|
||||
<td class="text-right">{{ formatIsk(r.sell) }}</td>
|
||||
<td class="text-right">{{ formatIsk(r.q1) }}</td>
|
||||
<td class="text-right">{{ formatIsk(r.mmedian) }}</td>
|
||||
<td class="text-right">{{ formatIsk(r.median) }}</td>
|
||||
<td class="text-right">{{ formatIsk(r.q3) }}</td>
|
||||
<td class="text-right">{{ percentFormater.format(r.profit) }}</td>
|
||||
<td class="text-right">{{ scoreFormater.format(r.score) }}</td>
|
||||
@@ -140,4 +140,4 @@ const getLineColor = (result: Result) => {
|
||||
div.end {
|
||||
@apply justify-self-end ms-2;
|
||||
}
|
||||
</style>
|
||||
</style>@/components/table
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import Modal from '@/Modal.vue';
|
||||
import { Modal } from '@/components';
|
||||
import { formatIsk } from '@/formaters';
|
||||
import { MarketType } from '@/market';
|
||||
import { ref } from 'vue';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import Modal from '@/Modal.vue';
|
||||
import { Modal } from '@/components';
|
||||
import { MarketType } from '@/market';
|
||||
import { ref } from 'vue';
|
||||
import { useTrackedItemStore } from './track';
|
||||
|
||||
83
src/market/track/TrackQuantilsTooltip.vue
Normal file
83
src/market/track/TrackQuantilsTooltip.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<script setup lang="ts">
|
||||
import { Tooltip } from '@/components';
|
||||
import { formatIsk } from '@/formaters';
|
||||
import { getHistory, jitaId } from '@/market';
|
||||
import { getHistoryQuartils } from '@/market/scan';
|
||||
import { ArrowTrendingUpIcon } from '@heroicons/vue/24/outline';
|
||||
import { ref, watchEffect } from 'vue';
|
||||
|
||||
interface Props {
|
||||
id: number;
|
||||
buy: number;
|
||||
sell: number;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const open = ref(false);
|
||||
|
||||
const q1 = ref(0);
|
||||
const median = ref(0);
|
||||
const q3 = ref(0);
|
||||
const lineColor = ref('');
|
||||
|
||||
watchEffect(async () => {
|
||||
if (!open.value || !props.id) {
|
||||
return;
|
||||
}
|
||||
const history = await getHistory(jitaId, props.id);
|
||||
const quartils = getHistoryQuartils(history);
|
||||
|
||||
q1.value = quartils.q1;
|
||||
median.value = quartils.median;
|
||||
q3.value = quartils.q3;
|
||||
|
||||
if (props.buy >= quartils.q3) {
|
||||
lineColor.value = 'line-blue';
|
||||
} else if (props.sell >= quartils.q3) {
|
||||
lineColor.value = 'line-green';
|
||||
} else {
|
||||
lineColor.value = '';
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Tooltip v-model:open="open" class="tooltip">
|
||||
<template #header>
|
||||
<ArrowTrendingUpIcon />
|
||||
</template>
|
||||
<template #default>
|
||||
<div class="bg-slate-500 -left-1/2 relative -top-2">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Q1</th>
|
||||
<th>Median</th>
|
||||
<th>Q3</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr :class="lineColor">
|
||||
<td class="text-right">{{ formatIsk(q1) }}</td>
|
||||
<td class="text-right">{{ formatIsk(median) }}</td>
|
||||
<td class="text-right">{{ formatIsk(q3) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
</Tooltip>
|
||||
</template>
|
||||
|
||||
<style scoped lang="postcss">
|
||||
.tooltip {
|
||||
@apply ms-auto;
|
||||
>:deep(div.header) {
|
||||
@apply btn-icon-stroke px-2;
|
||||
}
|
||||
&.open>:deep(div.header) {
|
||||
@apply bg-slate-600 rounded-t;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,11 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { SortableHeader, useSort } from '@/components/table';
|
||||
import { formatIsk, percentFormater } from '@/formaters';
|
||||
import { MarketType, MarketTypeLabel, TaxInput, useMarketTaxStore } from "@/market";
|
||||
import { SortableHeader, useSort } from '@/table';
|
||||
import { MinusIcon, PlusIcon } from '@heroicons/vue/24/outline';
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import { computed, ref } from 'vue';
|
||||
import { TrackedItem } from '.';
|
||||
import TrackQuantilsTooltip from './TrackQuantilsTooltip.vue';
|
||||
|
||||
type Result = {
|
||||
type: MarketType;
|
||||
@@ -97,7 +98,10 @@ const getLineColor = (result: Result) => {
|
||||
<tbody>
|
||||
<tr v-for="r in sortedArray" :key="r.typeID" :class="getLineColor(r)">
|
||||
<td>
|
||||
<MarketTypeLabel :id="r.typeID" :name="r.name" />
|
||||
<div class="flex">
|
||||
<MarketTypeLabel :id="r.typeID" :name="r.name" />
|
||||
<TrackQuantilsTooltip :id="r.typeID" :buy="r.buy" :sell="r.sell" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-right">{{ formatIsk(r.buy) }}</td>
|
||||
<td class="text-right">{{ formatIsk(r.sell) }}</td>
|
||||
@@ -118,4 +122,4 @@ const getLineColor = (result: Result) => {
|
||||
div.end {
|
||||
@apply justify-self-end ms-2;
|
||||
}
|
||||
</style>
|
||||
</style>@/components/table
|
||||
@@ -15,9 +15,11 @@ withDefaults(defineProps<Props>(), {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<img v-if="id" :src="`https://images.evetech.net/types/${id}/icon`" class="inline-block w-5 h-5 me-1" />
|
||||
<template v-if="name">
|
||||
{{ name }}
|
||||
<button class="btn-icon-stroke" @click="copyToClipboard(name)"><ClipboardIcon class="relative top-0.5 !w-4 !h-4" /></button>
|
||||
</template>
|
||||
<div v-if="id || name">
|
||||
<img v-if="id" :src="`https://images.evetech.net/types/${id}/icon`" class="inline-block w-5 h-5 me-1" />
|
||||
<template v-if="name">
|
||||
{{ name }}
|
||||
<button class="btn-icon-stroke" @click="copyToClipboard(name)"><ClipboardIcon class="relative top-0.5 !w-4 !h-4" /></button>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { SortableHeader, useSort } from '@/components/table';
|
||||
import { formatIsk, percentFormater } from '@/formaters';
|
||||
import { MarketTypeLabel } from '@/market/type';
|
||||
import { SortableHeader, useSort } from '@/table';
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import { computed } from 'vue';
|
||||
import BuySellSlider from './BuySellSlider.vue';
|
||||
@@ -59,3 +59,4 @@ const { sortedArray, headerProps } = useSort(computed(() => props.result.map(r =
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
@/components/table
|
||||
Reference in New Issue
Block a user