diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/App.vue | 33 | ||||
| -rw-r--r-- | src/HeroDraftGrid.vue | 6 | ||||
| -rw-r--r-- | src/HeroTalentTable.vue | 10 | ||||
| -rw-r--r-- | src/Highlights.vue | 22 | ||||
| -rw-r--r-- | src/Home.vue | 41 | ||||
| -rw-r--r-- | src/IntroBox.vue | 2 | ||||
| -rw-r--r-- | src/ModeTab.vue | 42 | ||||
| -rw-r--r-- | src/ReportService.js | 131 | ||||
| -rw-r--r-- | src/ReportTable.vue | 8 | ||||
| -rw-r--r-- | src/TopTalentsBox.vue | 8 | ||||
| -rw-r--r-- | src/index.js | 18 | ||||
| -rw-r--r-- | src/report-service.js | 133 |
12 files changed, 228 insertions, 226 deletions
diff --git a/src/App.vue b/src/App.vue index a4d0811..dc470cb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -13,7 +13,17 @@ </div> </section> - <router-view></router-view> + <div class="tabs is-fullwidth"> + <ul> + <li v-for="mode in modes" :key="mode" :class="(mode == selectedMode ? 'is-active' : '')"> + <a @click="selectedMode = mode"> + <span>{{ getMode(mode) }}</span> + </a> + </li> + </ul> + </div> + + <mode-tab class="tab"></mode-tab> <footer class="footer"> <div class="container"> @@ -49,17 +59,32 @@ ), url('/dist/assets/TalentGrab.jpg') center center; background-size: cover; } + +.tab { + padding-left: 1em; + padding-right: 1em; +} </style> <script> +import ModeTab from './ModeTab.vue'; +import RouterParamMixin from './RouterParamMixin'; +import ReportService from './ReportService'; +import * as maps from './maps/maps'; + export default { name: 'App', - props: [ 'reportService' ], + mixins: [ RouterParamMixin ], data: function() { return { - totalMatches: Math.floor(this.reportService.getTotalMatches()/100)*100, - lastUpdate: this.reportService.getLastUpdate(), + totalMatches: Math.floor(ReportService.getTotalMatches()/100)*100, + lastUpdate: ReportService.getLastUpdate(), + modes: ReportService.getModes(), + getMode: maps.getMode, }; }, + components: { + ModeTab, + }, }; </script> diff --git a/src/HeroDraftGrid.vue b/src/HeroDraftGrid.vue index 5f6e2ed..bdf6cbf 100644 --- a/src/HeroDraftGrid.vue +++ b/src/HeroDraftGrid.vue @@ -27,15 +27,15 @@ import Vue from 'vue'; import TalentImage from './TalentImage.vue'; import HeroImage from './HeroImage.vue'; -import RouterParamMixin from './RouterParamMixin.js'; +import RouterParamMixin from './RouterParamMixin'; +import ReportService from './ReportService'; import * as maps from './maps/maps'; export default Vue.component('hero-draft-grid', { - props: [ 'reportService' ], mixins: [ RouterParamMixin ], data: function() { return { - actors: this.reportService.getActors().sort(), + actors: ReportService.getActors().sort(), getHero: maps.getHero, getTalentName: maps.getTalentName, }; diff --git a/src/HeroTalentTable.vue b/src/HeroTalentTable.vue index 87d6f50..0e4509b 100644 --- a/src/HeroTalentTable.vue +++ b/src/HeroTalentTable.vue @@ -1,7 +1,6 @@ <template> <div class="box"> <div style="display: flex; align-items: center; justify-content: space-between;"> - <h3 class="title is-3">{{ getHero(selectedActor) }}</h3> <hero-image :actor="selectedActor" class="is-64x64"></hero-image> </div> @@ -30,24 +29,23 @@ import Vue from 'vue'; import TalentImage from './TalentImage.vue'; import HeroImage from './HeroImage.vue'; -import RouterParamMixin from './RouterParamMixin.js'; +import RouterParamMixin from './RouterParamMixin'; +import ReportService from './ReportService'; import * as maps from './maps/maps'; export default Vue.component('hero-talent-table', { - props: [ 'reportService' ], mixins: [ RouterParamMixin ], data: function() { return { - getHero: maps.getHero, getTalentName: maps.getTalentName, }; }, computed: { totalPicks: function() { - return this.reportService.getTotalPicks(this.selectedMode); + return ReportService.getTotalPicks(this.selectedMode); }, heroReport: function() { - return this.reportService.getReport(this.selectedMode) + return ReportService.getReport(this.selectedMode) .filter((entry) => entry.Actor == this.selectedActor); }, totalHeroPicks: function() { diff --git a/src/Highlights.vue b/src/Highlights.vue index c4d288d..85a8c2b 100644 --- a/src/Highlights.vue +++ b/src/Highlights.vue @@ -76,24 +76,24 @@ <script> import Vue from 'vue'; import TalentBox from './TalentBox.vue'; -import RouterParamMixin from './RouterParamMixin.js'; +import RouterParamMixin from './RouterParamMixin'; +import ReportService from './ReportService'; import * as maps from './maps/maps.js'; export default Vue.component('highlights', { - props: [ 'reportService' ], mixins: [ RouterParamMixin ], computed: { stats: function() { return { - topWin: this.reportService.getTopWin(this.selectedMode), - topUnpopularWin: this.reportService.getTopUnpopularWin(this.selectedMode), - topPick: this.reportService.getTopPick(this.selectedMode), - totalPicks: this.reportService.getTotalPicks(this.selectedMode), - highestLevelAvg: this.reportService.getHighestLevelAvg(this.selectedMode), - topRareWin: this.reportService.getTopRareWins(this.selectedMode), - topEpicWin: this.reportService.getTopEpicWins(this.selectedMode), - topLegendaryWin: this.reportService.getTopLegendaryWins(this.selectedMode), - lowestLevelAvg: this.reportService.getLowestLevelAvg(this.selectedMode), + topWin: ReportService.getTopWin(this.selectedMode), + topUnpopularWin: ReportService.getTopUnpopularWin(this.selectedMode), + topPick: ReportService.getTopPick(this.selectedMode), + totalPicks: ReportService.getTotalPicks(this.selectedMode), + highestLevelAvg: ReportService.getHighestLevelAvg(this.selectedMode), + topRareWin: ReportService.getTopRareWins(this.selectedMode), + topEpicWin: ReportService.getTopEpicWins(this.selectedMode), + topLegendaryWin: ReportService.getTopLegendaryWins(this.selectedMode), + lowestLevelAvg: ReportService.getLowestLevelAvg(this.selectedMode), }; }, playersPerMatch: function() { diff --git a/src/Home.vue b/src/Home.vue deleted file mode 100644 index b18a3d3..0000000 --- a/src/Home.vue +++ /dev/null @@ -1,41 +0,0 @@ -<template> - <b-tabs v-model="tabIndex" expanded type="is-toggle"> - <b-tab-item v-for="mode in modes" :label="getMode(mode)" :key="mode"> - <mode-tab :reportService="reportService"></mode-tab> - </b-tab-item> - </b-tabs> - </div> -</template> - - -<script> -import Vue from 'vue'; -import ModeTab from './ModeTab.vue'; -import RouterParamMixin from './RouterParamMixin.js'; -import * as maps from './maps/maps'; - -export default Vue.component('home', { - props: [ 'reportService' ], - mixins: [ RouterParamMixin ], - data: function() { - return { - modes: this.reportService.getModes(), - getMode: maps.getMode, - }; - }, - computed: { - tabIndex: { - get: function() { - return this.reportService.getModes().indexOf(this.selectedMode); - }, - set: function(index) { - const mode = this.reportService.getModes()[index]; - this.selectedMode = mode; - }, - }, - }, - components: { - ModeTab, - }, -}); -</script> diff --git a/src/IntroBox.vue b/src/IntroBox.vue index b4d4600..918a6de 100644 --- a/src/IntroBox.vue +++ b/src/IntroBox.vue @@ -3,7 +3,7 @@ <button class="delete" @click="hideIntro = true"></button> <div class="content"> <h3>Hi There!</h3> - <img style="float: right" class="image is-64x64" src="/dist/assets/gwenbarf.png"></img> + <img style="float: right" class="image is-64x64" src="/dist/assets/gwenbarf.png"></img> <p> Broken Talents Fun will help you find the best Talents for the Vainglory mobile MOBA game. <br /> diff --git a/src/ModeTab.vue b/src/ModeTab.vue index 681b219..465f1e8 100644 --- a/src/ModeTab.vue +++ b/src/ModeTab.vue @@ -5,28 +5,48 @@ <div class="columns is-multiline"> <div class="column" v-if="hasTalents"> <h2 class="title is-2">Highlights</h2> - <highlights :reportService="reportService"></highlights> + <highlights></highlights> </div> <div class="column is-narrow"> <h2 class="title is-2">Top 10</h2> - <top-talents-box :reportService="reportService"></top-talents-box> + <top-talents-box></top-talents-box> </div> </div> + <div class="notification" v-show="adActive[0]"> + <button class="delete" @click="adActive[0] = false"></button> + <h3 class="title is-3">Ad</h3> + <Adsense + data-ad-client="ca-pub-6856963757796636" + data-ad-slot="4801023518"> + </Adsense> + </div> + <div class="columns is-multiline" v-if="hasTalents"> - <h2 class="title is-2">Individual Hero Statistics</h2> <div class="column is-two-thirds"> - <hero-draft-grid :reportService="reportService"></hero-draft-grid> + <h2 class="title is-2">Individual Hero Statistics</h2> + <h3 class="subtitle">Select a Hero</h3> + <hero-draft-grid></hero-draft-grid> </div> <div class="column is-one-third"> - <hero-talent-table :reportService="reportService"></hero-talent-table> + <h2 class="title is-2">{{ getHero(selectedActor) }} Statistics</h2> + <hero-talent-table></hero-talent-table> </div> </div> + <div class="notification" v-show="adActive[1]"> + <button class="delete" @click="adActive[1] = false"></button> + <h3 class="title is-3">Ad</h3> + <Adsense + data-ad-client="ca-pub-6856963757796636" + data-ad-slot="3898218968"> + </Adsense> + </div> + <div> <h2 class="title is-2">All Hero Statistics</h2> - <report-table :reportService="reportService"></report-table> + <report-table></report-table> </div> </div> </template> @@ -43,8 +63,16 @@ import IntroBox from './IntroBox.vue'; import * as maps from './maps/maps.js'; export default Vue.component('mode-tab', { - props: [ 'reportService' ], mixins: [ RouterParamMixin ], + data: function() { + return { + getHero: maps.getHero, + adActive: { + 0: true, + 1: true, + }, + }; + }, computed: { hasTalents: function() { return maps.hasTalents(this.selectedMode); diff --git a/src/ReportService.js b/src/ReportService.js new file mode 100644 index 0000000..ed0200c --- /dev/null +++ b/src/ReportService.js @@ -0,0 +1,131 @@ +import * as maps from './maps/maps'; +import * as metadata from '../data/95fb1cdb/metadata.json'; + +const POPULAR_THRESHOLD = 1.0; // percent + +const report = require('../data/95fb1cdb/report.json') + .filter((entry) => entry.Actor != undefined); // bad data from API downtime + +const reports = new Map(); +const totalPicks = new Map(); +const top10Relevancy = new Map(); +const topPicks = new Map(); +const topWins = new Map(); +const topRareWins = new Map(); +const topEpicWins = new Map(); +const topLegendaryWins = new Map(); +const topLeveledUp = new Map(); +const topLeveledDown = new Map(); +const topUnpopularWins = new Map(); +let totalMatches = 0; +let actors = []; +const modes = metadata.config.api.modes; + +for(let mode of modes) { + const relevancy = (entry) => (entry.Count / totalPicks.get(mode)) * entry.Winner; + const playersPerMatch = maps.playersPerMatch(mode); + + reports.set(mode, report.filter((entry) => entry.Mode == mode)); + totalPicks.set(mode, report.map((entry) => entry.Count).reduce((agg, cur) => agg + cur, 0)); + totalMatches += totalPicks.get(mode) / maps.playersPerMatch(mode); + top10Relevancy.set(mode, reports.get(mode) + .sort((entry1, entry2) => relevancy(entry2) - relevancy(entry1)) + .slice(0, 10)); + topPicks.set(mode, reports.get(mode).sort((entry1, entry2) => entry2.Count - entry1.Count)[0]); + topWins.set(mode, reports.get(mode) + .filter((entry) => 100 * playersPerMatch * entry.Count / totalPicks.get(mode) > POPULAR_THRESHOLD) + .sort((entry1, entry2) => entry2.Winner - entry1.Winner)[0]); + topUnpopularWins.set(mode, reports.get(mode) + .filter((entry) => 100 * playersPerMatch * entry.Count / totalPicks.get(mode) <= POPULAR_THRESHOLD) + .sort((entry1, entry2) => entry2.Winner - entry1.Winner)[0]); + topRareWins.set(mode, reports.get(mode) + .filter((entry) => maps.getTalentRarity(entry.Talent) == 'Rare' && 100 * playersPerMatch * entry.Count / totalPicks.get(mode)) + .sort((entry1, entry2) => entry2.Winner - entry1.Winner)[0]); + topEpicWins.set(mode, reports.get(mode) + .filter((entry) => maps.getTalentRarity(entry.Talent) == 'Epic' && 100 * playersPerMatch * entry.Count / totalPicks.get(mode)) + .sort((entry1, entry2) => entry2.Winner - entry1.Winner)[0]); + topLegendaryWins.set(mode, reports.get(mode) + .filter((entry) => maps.getTalentRarity(entry.Talent) == 'Legendary' && 100 * playersPerMatch * entry.Count / totalPicks.get(mode)) + .sort((entry1, entry2) => entry2.Winner - entry1.Winner)[0]); + topLeveledUp.set(mode, reports.get(mode).sort((entry1, entry2) => { + if (!entry1.Level) return 1; + if (!entry2.Level) return -1; + return entry1.Level < entry2.Level ? 1 : -1; + })[0]); + topLeveledDown.set(mode, reports.get(mode).sort((entry1, entry2) => { + if (!entry1.Level) return 1; + if (!entry2.Level) return -1; + + return entry1.Level < entry2.Level ? -1 : 1; + })[0]); + + if (actors.length == 0) { + actors = [...new Set(reports.get(mode).map((entry) => entry.Actor))]; + } +} + +export default { + getReport(mode) { + return reports.get(mode); + }, + + getTotalPicks(mode) { + return totalPicks.get(mode); + }, + + getTopPick(mode) { + return topPicks.get(mode); + }, + + getTop10Picks(mode) { + return top10Relevancy.get(mode); + }, + + getHighestLevelAvg(mode) { + return topLeveledUp.get(mode); + }, + + getLowestLevelAvg(mode) { + return topLeveledDown.get(mode); + }, + + getTopWin(mode) { + return topWins.get(mode); + }, + + getTopUnpopularWin(mode) { + return topUnpopularWins.get(mode); + }, + + getTopRareWins(mode) { + return topRareWins.get(mode); + }, + + getTopEpicWins(mode) { + return topEpicWins.get(mode); + }, + + getTopLegendaryWins(mode) { + return topLegendaryWins.get(mode); + }, + + getBestUnpopular(mode) { + return topUnpopular.get(mode); + }, + + getActors() { + return actors; + }, + + getModes() { + return modes; + }, + + getTotalMatches() { + return totalMatches; + }, + + getLastUpdate() { + return metadata.lastUpdate; + }, +}; diff --git a/src/ReportTable.vue b/src/ReportTable.vue index 9d3cea1..75a1369 100644 --- a/src/ReportTable.vue +++ b/src/ReportTable.vue @@ -63,11 +63,11 @@ <script> import Vue from 'vue'; import HeroImage from './HeroImage.vue'; -import RouterParamMixin from './RouterParamMixin.js'; +import RouterParamMixin from './RouterParamMixin'; +import ReportService from './ReportService'; import * as maps from './maps/maps'; export default Vue.component('report-table', { - props: [ 'reportService' ], mixins: [ RouterParamMixin ], data: function() { return { @@ -78,10 +78,10 @@ export default Vue.component('report-table', { }, computed: { report: function() { - return this.reportService.getReport(this.selectedMode); + return ReportService.getReport(this.selectedMode); }, totalPicks: function() { - return this.reportService.getTotalPicks(this.selectedMode); + return ReportService.getTotalPicks(this.selectedMode); }, playersPerMatch: function() { return maps.playersPerMatch(this.selectedMode); diff --git a/src/TopTalentsBox.vue b/src/TopTalentsBox.vue index 44a4e16..88d5fb7 100644 --- a/src/TopTalentsBox.vue +++ b/src/TopTalentsBox.vue @@ -30,11 +30,11 @@ import Vue from 'vue'; import TalentImage from './TalentImage.vue'; import HeroImage from './HeroImage.vue'; -import RouterParamMixin from './RouterParamMixin.js'; +import RouterParamMixin from './RouterParamMixin'; +import ReportService from './ReportService'; import * as maps from './maps/maps'; export default Vue.component('top-talents-box', { - props: [ 'reportService' ], mixins: [ RouterParamMixin ], data: function() { return { @@ -44,13 +44,13 @@ export default Vue.component('top-talents-box', { }, computed: { top10Talents: function() { - return this.reportService.getTop10Picks(this.selectedMode); + return ReportService.getTop10Picks(this.selectedMode); }, hasTalents: function() { return maps.hasTalents(this.selectedMode); }, totalPicks: function() { - return this.reportService.getTotalPicks(this.selectedMode); + return ReportService.getTotalPicks(this.selectedMode); }, playersPerMatch: function() { return maps.playersPerMatch(this.selectedMode); diff --git a/src/index.js b/src/index.js index 1c1bfaf..1c498bb 100644 --- a/src/index.js +++ b/src/index.js @@ -2,32 +2,26 @@ import Vue from 'vue'; import VueRouter from 'vue-router'; import Buefy from 'buefy' import 'buefy/lib/buefy.css' +import Ads from 'vue-google-adsense'; import App from './App.vue'; -import Home from './Home.vue'; - -import ReportService from './report-service.js'; +import ModeTab from './ModeTab.vue'; Vue.use(VueRouter); Vue.use(Buefy); - -const reportService = new ReportService(); +Vue.use(require('vue-script2')) +Vue.use(Ads.Adsense) const router = new VueRouter({ routes: [ { path: '/', name: 'home', - component: Home, - props: (route) => ({ - reportService, - }), + component: ModeTab, } ] }); new Vue({ router, el: '#app', - render: h => h(App, { - props: { reportService }, - }), + render: h => h(App), }); diff --git a/src/report-service.js b/src/report-service.js deleted file mode 100644 index 2469ea9..0000000 --- a/src/report-service.js +++ /dev/null @@ -1,133 +0,0 @@ -import * as maps from './maps/maps'; - -const POPULAR_THRESHOLD = 1.0; // percent - -export default class ReportService { - constructor() { - this.report = require('../data/95fb1cdb/report.json') - .filter((entry) => entry.Actor != undefined); // bad data from API downtime - this.metadata = require('../data/95fb1cdb/metadata.json'); - - this.reports = new Map(); - this.totalPicks = new Map(); - this.top10Relevancy = new Map(); - this.topPicks = new Map(); - this.topWins = new Map(); - this.topRareWins = new Map(); - this.topEpicWins = new Map(); - this.topLegendaryWins = new Map(); - this.topLeveledUp = new Map(); - this.topLeveledDown = new Map(); - this.topUnpopularWins = new Map(); - this.totalMatches = 0; - this.actors = []; - this.modes = this.metadata.config.api.modes; - - for(let mode of this.modes) { - const relevancy = (entry) => (entry.Count / this.totalPicks.get(mode)) * entry.Winner; - const playersPerMatch = maps.playersPerMatch(mode); - - this.reports.set(mode, this.report.filter((entry) => entry.Mode == mode)); - this.totalPicks.set(mode, this.report.map((entry) => entry.Count).reduce((agg, cur) => agg + cur, 0)); - this.totalMatches += this.totalPicks.get(mode) / maps.playersPerMatch(mode); - this.top10Relevancy.set(mode, this.reports.get(mode) - .sort((entry1, entry2) => relevancy(entry2) - relevancy(entry1)) - .slice(0, 10)); - this.topPicks.set(mode, this.reports.get(mode).sort((entry1, entry2) => entry2.Count - entry1.Count)[0]); - this.topWins.set(mode, this.reports.get(mode) - .filter((entry) => 100 * playersPerMatch * entry.Count / this.totalPicks.get(mode) > POPULAR_THRESHOLD) - .sort((entry1, entry2) => entry2.Winner - entry1.Winner)[0]); - this.topUnpopularWins.set(mode, this.reports.get(mode) - .filter((entry) => 100 * playersPerMatch * entry.Count / this.totalPicks.get(mode) <= POPULAR_THRESHOLD) - .sort((entry1, entry2) => entry2.Winner - entry1.Winner)[0]); - this.topRareWins.set(mode, this.reports.get(mode) - .filter((entry) => maps.getTalentRarity(entry.Talent) == 'Rare' && 100 * playersPerMatch * entry.Count / this.totalPicks.get(mode)) - .sort((entry1, entry2) => entry2.Winner - entry1.Winner)[0]); - this.topEpicWins.set(mode, this.reports.get(mode) - .filter((entry) => maps.getTalentRarity(entry.Talent) == 'Epic' && 100 * playersPerMatch * entry.Count / this.totalPicks.get(mode)) - .sort((entry1, entry2) => entry2.Winner - entry1.Winner)[0]); - this.topLegendaryWins.set(mode, this.reports.get(mode) - .filter((entry) => maps.getTalentRarity(entry.Talent) == 'Legendary' && 100 * playersPerMatch * entry.Count / this.totalPicks.get(mode)) - .sort((entry1, entry2) => entry2.Winner - entry1.Winner)[0]); - this.topLeveledUp.set(mode, this.reports.get(mode).sort((entry1, entry2) => { - if (!entry1.Level) return 1; - if (!entry2.Level) return -1; - return entry1.Level < entry2.Level ? 1 : -1; - })[0]); - this.topLeveledDown.set(mode, this.reports.get(mode).sort((entry1, entry2) => { - if (!entry1.Level) return 1; - if (!entry2.Level) return -1; - - return entry1.Level < entry2.Level ? -1 : 1; - })[0]); - - if (this.actors.length == 0) { - this.actors = [...new Set(this.reports.get(mode).map((entry) => entry.Actor))]; - } - } - } - - getReport(mode) { - return this.reports.get(mode); - } - - getTotalPicks(mode) { - return this.totalPicks.get(mode); - } - - getTopPick(mode) { - return this.topPicks.get(mode); - } - - getTop10Picks(mode) { - return this.top10Relevancy.get(mode); - } - - getHighestLevelAvg(mode) { - return this.topLeveledUp.get(mode); - } - - getLowestLevelAvg(mode) { - return this.topLeveledDown.get(mode); - } - - getTopWin(mode) { - return this.topWins.get(mode); - } - - getTopUnpopularWin(mode) { - return this.topUnpopularWins.get(mode); - } - - getTopRareWins(mode) { - return this.topRareWins.get(mode); - } - - getTopEpicWins(mode) { - return this.topEpicWins.get(mode); - } - - getTopLegendaryWins(mode) { - return this.topLegendaryWins.get(mode); - } - - getBestUnpopular(mode) { - return this.topUnpopular.get(mode); - } - - getActors() { - return this.actors; - } - - getModes() { - return this.modes; - } - - getTotalMatches() { - return this.totalMatches; - } - - getLastUpdate() { - return this.metadata.lastUpdate; - } -} |
