|
1 | 1 | <template>
|
2 |
| - <div |
3 |
| - :style="{height: isExpanded ? `calc(41px * ${graphData.length + 1} - 1px)` : '40px'}" |
4 |
| - class="bg-white overflow-hidden cursor-pointer relative transition-all duration-500 ease-in-out" |
5 |
| - @click="isExpanded = !isExpanded" |
6 |
| - > |
7 |
| - <div class="absolute inset-x-0 top-0 h-10 bg-gray-300 flex"> |
8 |
| - <div |
9 |
| - v-for="([ore, value]) of graphData" |
10 |
| - :key="ore" |
11 |
| - ref="segments" |
12 |
| - :data-type="ore" |
13 |
| - class="relative transition duration-500 ease-in-out" |
14 |
| - :style="{flex: `${value} 0 1px`}" |
15 |
| - /> |
16 |
| - </div> |
17 |
| - <transition |
18 |
| - enter-class="opacity-0" |
19 |
| - enter-to-class="opacity-100" |
20 |
| - leave-class="opacity-100" |
21 |
| - leave-to-class="opacity-0" |
22 |
| - enter-active-class="transition-opacity duration-300 ease-linear" |
23 |
| - leave-active-class="transition-opacity duration-300 ease-linear" |
| 2 | + <PlayerAsidePanel :title="t('nyaa.player_ore_graph.section_title')"> |
| 3 | + <template #header> |
| 4 | + <transition |
| 5 | + enter-class="opacity-0" |
| 6 | + leave-to-class="opacity-0" |
| 7 | + enter-active-class="transition-opacity duration-300 ease-linear" |
| 8 | + leave-active-class="transition-opacity duration-300 ease-linear" |
| 9 | + > |
| 10 | + <button |
| 11 | + v-show="isExpanded" |
| 12 | + class="text-sm text-blue-600" |
| 13 | + @click="isShowingOriginalData = !isShowingOriginalData" |
| 14 | + > |
| 15 | + <transition v-bind="textTransitionProps"> |
| 16 | + <span v-if="isShowingOriginalData" key="1">{{ t('nyaa.player_ore_graph.control_label.show_net_value') }}</span> |
| 17 | + <span v-else key="0">{{ t('nyaa.player_ore_graph.control_label.show_original_data') }}</span> |
| 18 | + </transition> |
| 19 | + </button> |
| 20 | + </transition> |
| 21 | + </template> |
| 22 | + |
| 23 | + <div |
| 24 | + :style="{height: isExpanded ? `calc(41px * ${graphHeight + 1} - 1px)` : '40px'}" |
| 25 | + class="bg-white cursor-pointer relative transition-all duration-500 ease-in-out" |
| 26 | + @click="isExpanded = !isExpanded" |
24 | 27 | >
|
25 |
| - <dl v-show="isExpanded" class="relative text-sm flex flex-col"> |
26 |
| - <div class="flex-none order-first h-10 px-3 flex items-center"> |
27 |
| - <dt>{{ t('nyaa.player_ore_graph.item_name.total') }}</dt> |
28 |
| - <dd class="ml-auto font-tnum">{{ total }}</dd> |
29 |
| - </div> |
| 28 | + <div class="absolute inset-x-0 top-0 h-10 bg-gray-300 flex"> |
30 | 29 | <div
|
31 |
| - v-for="([ore, value, order]) of graphData" |
| 30 | + v-for="({ore, mined, used, net}) of oreDataFiltered" |
32 | 31 | :key="ore"
|
33 |
| - class="flex-none h-10 mt-px px-3 flex items-center" |
34 |
| - :style="{order}" |
| 32 | + ref="segments" |
| 33 | + :data-type="ore" |
| 34 | + class="bg-gray-300 transition duration-500 ease-in-out" |
| 35 | + :style="{flex: `${net} 0 1px`}" |
35 | 36 | >
|
36 |
| - <dt class="-ml-1 px-1 py-0.5 _text-bg rounded">{{ t(`nyaa.player_ore_graph.item_name.${ore}_ore`) }}</dt> |
37 |
| - <dd class="ml-auto -mr-1 px-1 py-0.5 font-tnum _text-bg rounded">{{ value }}</dd> |
| 37 | + <div |
| 38 | + class="h-full transition-all duration-300 ease-in-out" |
| 39 | + :style="{width: (isExpanded && isShowingOriginalData ? (mined - used) / mined : 1) * 100 + '%'}" |
| 40 | + /> |
38 | 41 | </div>
|
39 |
| - </dl> |
40 |
| - </transition> |
41 |
| - </div> |
| 42 | + </div> |
| 43 | + <transition |
| 44 | + enter-class="opacity-0" |
| 45 | + leave-to-class="opacity-0" |
| 46 | + enter-active-class="transition-opacity duration-300 ease-linear" |
| 47 | + leave-active-class="transition-opacity duration-300 ease-linear" |
| 48 | + > |
| 49 | + <div v-show="isExpanded" class="relative px-3 text-sm flex"> |
| 50 | + <ul class="flex flex-col"> |
| 51 | + <li class="order-first h-10 flex items-center"> |
| 52 | + <transition v-bind="textTransitionProps"> |
| 53 | + <span v-if="isShowingOriginalData" key="1">{{ t('nyaa.player_ore_graph.item_name.original_hint') }}</span> |
| 54 | + <span v-else key="0">{{ t('nyaa.player_ore_graph.item_name.total') }}</span> |
| 55 | + </transition> |
| 56 | + </li> |
| 57 | + <li |
| 58 | + v-for="({ore, order}) of oreData" |
| 59 | + :key="ore" |
| 60 | + class="flex-none h-10 mt-px flex items-center" |
| 61 | + :style="{order}" |
| 62 | + > |
| 63 | + <span class="-ml-1 px-1 py-0.5 _text-bg rounded">{{ t(`nyaa.player_ore_graph.item_name.${ore}_ore`) }}</span> |
| 64 | + </li> |
| 65 | + </ul> |
| 66 | + <transition v-bind="textTransitionProps"> |
| 67 | + <div v-if="isShowingOriginalData" class="ml-auto font-tnum grid row-gap-px items-center"> |
| 68 | + <span :style="{gridRow: 1}">{{ total.mined }}</span> |
| 69 | + <span :style="{gridRow: 1}" class="text-gray-600 flex"> |
| 70 | + <span class="mx-1">/</span> |
| 71 | + <span class="ml-auto">{{ total.used }}</span> |
| 72 | + </span> |
| 73 | + <template v-for="({ore, mined, used, order}) of oreData"> |
| 74 | + <span :key="ore + '-mined'" class="pl-1 py-0.5 _text-bg rounded-l text-right" :style="{gridRow: order + 1}">{{ mined }}</span> |
| 75 | + <span :key="ore + '-used'" class="-mr-1 pr-1 py-0.5 _text-bg rounded-r text-gray-500 flex" :style="{gridRow: order + 1}"> |
| 76 | + <span class="mx-1">/</span> |
| 77 | + <span class="ml-auto">{{ used }}</span> |
| 78 | + </span> |
| 79 | + </template> |
| 80 | + </div> |
| 81 | + <ul v-else class="ml-auto font-tnum flex flex-col items-end"> |
| 82 | + <li class="order-first h-10 flex items-center"> |
| 83 | + <span>{{ total.net }}</span> |
| 84 | + </li> |
| 85 | + <li |
| 86 | + v-for="({ore, net, order}) of oreData" |
| 87 | + :key="ore" |
| 88 | + class="h-10 mt-px flex items-center" |
| 89 | + :style="{order}" |
| 90 | + > |
| 91 | + <span class="-mr-1 px-1 py-0.5 _text-bg rounded">{{ net }}</span> |
| 92 | + </li> |
| 93 | + </ul> |
| 94 | + </transition> |
| 95 | + <div v-if="false" class="ml-auto font-tnum grid"> |
| 96 | + <span class="order-first h-10 flex items-center"> |
| 97 | + <transition v-bind="textTransitionProps"> |
| 98 | + <span v-if="isShowingOriginalData" key="1">{{ total.mined }} / <span class="text-gray-600">{{ total.used }}</span></span> |
| 99 | + <span v-else key="0">{{ total.net }}</span> |
| 100 | + </transition> |
| 101 | + </span> |
| 102 | + <li |
| 103 | + v-for="({ore, mined, used, net, order}) of oreData" |
| 104 | + :key="ore" |
| 105 | + class="flex-none h-10 mt-px flex items-center" |
| 106 | + :style="{order}" |
| 107 | + > |
| 108 | + <span class="-mr-1 px-1 py-0.5 _text-bg rounded"> |
| 109 | + <transition v-bind="textTransitionProps"> |
| 110 | + <span v-if="isShowingOriginalData" key="1">{{ mined }} / <span class="text-gray-500">{{ used }}</span></span> |
| 111 | + <span v-else key="0">{{ net }}</span> |
| 112 | + </transition> |
| 113 | + </span> |
| 114 | + </li> |
| 115 | + </div> |
| 116 | + </div> |
| 117 | + </transition> |
| 118 | + </div> |
| 119 | + </PlayerAsidePanel> |
42 | 120 | </template>
|
43 | 121 |
|
44 | 122 | <script>
|
| 123 | + import PlayerAsidePanel from '@/components/PlayerAsidePanel.vue' |
| 124 | +
|
45 | 125 | const ORES = [
|
46 | 126 | 'coal',
|
47 | 127 | 'iron',
|
|
56 | 136 | export default {
|
57 | 137 | name: 'PlayerOreGraph',
|
58 | 138 |
|
| 139 | + components: { |
| 140 | + PlayerAsidePanel, |
| 141 | + }, |
| 142 | +
|
59 | 143 | props: {
|
60 | 144 | player: {
|
61 | 145 | type: Object,
|
|
65 | 149 |
|
66 | 150 | data () {
|
67 | 151 | return {
|
| 152 | + textTransitionProps: { |
| 153 | + mode: 'out-in', |
| 154 | + enterClass: 'opacity-0', |
| 155 | + leaveToClass: 'opacity-0', |
| 156 | + enterActiveClass: 'transition-opacity duration-100 ease-linear', |
| 157 | + leaveActiveClass: 'transition-opacity duration-100 ease-linear', |
| 158 | + }, |
68 | 159 | isExpanded: false,
|
| 160 | + isShowingOriginalData: false, |
69 | 161 | }
|
70 | 162 | },
|
71 | 163 |
|
72 | 164 | computed: {
|
73 |
| - graphData () { |
| 165 | + oreData () { |
74 | 166 | const data = ORES.map(ore => {
|
75 | 167 | const mined = this.player.stats[`minecraft:mined/minecraft:${ore}_ore`] ?? 0
|
76 | 168 | const used = this.player.stats[`minecraft:used/minecraft:${ore}_ore`] ?? 0
|
77 | 169 | const net = Math.max(mined - used, 0)
|
78 |
| - return net && [ore, net] |
79 |
| - }).filter(Boolean) |
80 |
| - data.slice().sort((b, a) => a[1] - b[1]).forEach((en, idx) => en.push(idx)) |
| 170 | + return { |
| 171 | + ore, |
| 172 | + mined, |
| 173 | + used, |
| 174 | + net, |
| 175 | + } |
| 176 | + }) |
| 177 | + data.slice().sort((b, a) => a.net - b.net).forEach((d, idx) => d.order = idx + 1) |
81 | 178 | return data
|
82 | 179 | },
|
83 | 180 |
|
| 181 | + oreDataFiltered () { |
| 182 | + return this.oreData.filter(d => d.net) |
| 183 | + }, |
| 184 | +
|
| 185 | + graphHeight () { |
| 186 | + return this.isShowingOriginalData ? this.oreData.length : this.oreDataFiltered.length |
| 187 | + }, |
| 188 | +
|
84 | 189 | total () {
|
85 |
| - return this.graphData.reduce((total, [, value]) => total + value, 0) |
| 190 | + return this.oreData.reduce((total, {mined, used, net}) => { |
| 191 | + total.mined += mined |
| 192 | + total.used += used |
| 193 | + total.net += net |
| 194 | + return total |
| 195 | + }, {mined: 0, used: 0, net: 0}) |
86 | 196 | },
|
87 | 197 | },
|
88 | 198 |
|
|
91 | 201 | if (value) {
|
92 | 202 | const containerX = this.$refs.segments[0].parentElement.getBoundingClientRect().x
|
93 | 203 | this.$refs.segments.forEach((/** @type {HTMLDivElement} */ seg, idx) => {
|
94 |
| - seg.style.transform = `translate(${-(Math.round(seg.getBoundingClientRect().x) - containerX)}px, ${41 * (this.graphData[idx][2] + 1)}px)` |
| 204 | + seg.style.transform = `translate(${-(Math.round(seg.getBoundingClientRect().x) - containerX)}px, ${41 * (this.oreDataFiltered[idx].order)}px)` |
95 | 205 | })
|
96 | 206 | } else {
|
97 | 207 | this.$refs.segments.forEach(seg => {
|
|
104 | 214 | </script>
|
105 | 215 |
|
106 | 216 | <style lang="scss" scoped>
|
107 |
| - [data-type=coal] {background: #343434;} |
108 |
| - [data-type=iron] {background: #af8e77;} |
109 |
| - [data-type=lapis] {background: #315ec4;} |
110 |
| - [data-type=gold] {background: #fcee4b;} |
111 |
| - [data-type=diamond] {background: #3de0e5;} |
112 |
| - [data-type=redstone] {background: #ab0600;} |
113 |
| - [data-type=emerald] {background: #00ab28;} |
114 |
| - [data-type=nether_quartz] {background: #eae5de;} |
| 217 | + [data-type=coal] div {background: #343434;} |
| 218 | + [data-type=iron] div {background: #af8e77;} |
| 219 | + [data-type=lapis] div {background: #315ec4;} |
| 220 | + [data-type=gold] div {background: #fcee4b;} |
| 221 | + [data-type=diamond] div {background: #3de0e5;} |
| 222 | + [data-type=redstone] div {background: #ab0600;} |
| 223 | + [data-type=emerald] div {background: #00ab28;} |
| 224 | + [data-type=nether_quartz] div {background: #eae5de;} |
115 | 225 |
|
116 | 226 | ._text-bg {
|
117 | 227 | background: rgba(255, 255, 255, 0.6);
|
118 | 228 | }
|
| 229 | +
|
| 230 | + .grid { |
| 231 | + grid-template-columns: auto auto; |
| 232 | + grid-template-rows: 40px; |
| 233 | + } |
119 | 234 | </style>
|
0 commit comments