diff --git a/package-lock.json b/package-lock.json index ef8cff6..f362049 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,14 +8,17 @@ "name": "hooks-testnet-explorer", "version": "0.1.0", "dependencies": { + "apexcharts": "^3.37.1", "core-js": "^3.6.5", "jsonlint": "^1.6.3", "jsonlint-mod": "^1.7.6", "mitt": "^2.1.0", "vue": "^2.6.11", + "vue-apexcharts": "^1.6.2", "vue-codemirror": "^4.0.6", "vue-json-pretty": "^1.8.1", "vue-router": "^3.2.0", + "vue-toastification": "^1.7.14", "xrpl-client": "^1.8.0" }, "devDependencies": { @@ -3162,6 +3165,19 @@ "node": ">=0.10.0" } }, + "node_modules/apexcharts": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.37.1.tgz", + "integrity": "sha512-fmQ5Updeb/LASl+S1+mIxXUFxzY0Fa7gexfCs4o+OPP9f2NEBNjvybOtPrah44N4roK7U5o5Jis906QeEQu0cA==", + "dependencies": { + "svg.draggable.js": "^2.2.2", + "svg.easing.js": "^2.0.0", + "svg.filter.js": "^2.0.2", + "svg.pathmorphing.js": "^0.1.3", + "svg.resize.js": "^1.4.3", + "svg.select.js": "^3.0.1" + } + }, "node_modules/aproba": { "version": "1.2.0", "dev": true, @@ -12953,6 +12969,89 @@ "version": "1.0.0", "dev": true }, + "node_modules/svg.draggable.js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz", + "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==", + "dependencies": { + "svg.js": "^2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.easing.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz", + "integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==", + "dependencies": { + "svg.js": ">=2.3.x" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.filter.js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz", + "integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz", + "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==" + }, + "node_modules/svg.pathmorphing.js": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz", + "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==", + "dependencies": { + "svg.js": "^2.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz", + "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==", + "dependencies": { + "svg.js": "^2.6.5", + "svg.select.js": "^2.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js/node_modules/svg.select.js": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz", + "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.select.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz", + "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==", + "dependencies": { + "svg.js": "^2.6.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/svgo": { "version": "1.3.2", "dev": true, @@ -13953,6 +14052,14 @@ "csstype": "^3.1.0" } }, + "node_modules/vue-apexcharts": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/vue-apexcharts/-/vue-apexcharts-1.6.2.tgz", + "integrity": "sha512-9HS3scJwWgKjmkcWIf+ndNDR0WytUJD8Ju0V2ZYcjYtlTLwJAf2SKUlBZaQTkDmwje/zMgulvZRi+MXmi+WkKw==", + "peerDependencies": { + "apexcharts": "^3.26.0" + } + }, "node_modules/vue-codemirror": { "version": "4.0.6", "license": "MIT", @@ -14106,6 +14213,14 @@ "dev": true, "license": "MIT" }, + "node_modules/vue-toastification": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-1.7.14.tgz", + "integrity": "sha512-khZR8t3NWZ/JJ2MZxXLbesHrRJ8AKa75PY5Zq8yMifF9x8lHq8ljYkC0d2PD9yahooygQB5tcFyRDkbbIPx8hw==", + "peerDependencies": { + "vue": "^2.0.0" + } + }, "node_modules/watchpack": { "version": "1.7.5", "dev": true, @@ -16970,6 +17085,19 @@ } } }, + "apexcharts": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.37.1.tgz", + "integrity": "sha512-fmQ5Updeb/LASl+S1+mIxXUFxzY0Fa7gexfCs4o+OPP9f2NEBNjvybOtPrah44N4roK7U5o5Jis906QeEQu0cA==", + "requires": { + "svg.draggable.js": "^2.2.2", + "svg.easing.js": "^2.0.0", + "svg.filter.js": "^2.0.2", + "svg.pathmorphing.js": "^0.1.3", + "svg.resize.js": "^1.4.3", + "svg.select.js": "^3.0.1" + } + }, "aproba": { "version": "1.2.0", "dev": true @@ -23613,6 +23741,70 @@ "version": "1.0.0", "dev": true }, + "svg.draggable.js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz", + "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==", + "requires": { + "svg.js": "^2.0.1" + } + }, + "svg.easing.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz", + "integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==", + "requires": { + "svg.js": ">=2.3.x" + } + }, + "svg.filter.js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz", + "integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==", + "requires": { + "svg.js": "^2.2.5" + } + }, + "svg.js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz", + "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==" + }, + "svg.pathmorphing.js": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz", + "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==", + "requires": { + "svg.js": "^2.4.0" + } + }, + "svg.resize.js": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz", + "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==", + "requires": { + "svg.js": "^2.6.5", + "svg.select.js": "^2.1.2" + }, + "dependencies": { + "svg.select.js": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz", + "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==", + "requires": { + "svg.js": "^2.2.5" + } + } + } + }, + "svg.select.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz", + "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==", + "requires": { + "svg.js": "^2.6.5" + } + }, "svgo": { "version": "1.3.2", "dev": true, @@ -24318,6 +24510,12 @@ "csstype": "^3.1.0" } }, + "vue-apexcharts": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/vue-apexcharts/-/vue-apexcharts-1.6.2.tgz", + "integrity": "sha512-9HS3scJwWgKjmkcWIf+ndNDR0WytUJD8Ju0V2ZYcjYtlTLwJAf2SKUlBZaQTkDmwje/zMgulvZRi+MXmi+WkKw==", + "requires": {} + }, "vue-codemirror": { "version": "4.0.6", "requires": { @@ -24414,6 +24612,12 @@ "version": "1.9.1", "dev": true }, + "vue-toastification": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-1.7.14.tgz", + "integrity": "sha512-khZR8t3NWZ/JJ2MZxXLbesHrRJ8AKa75PY5Zq8yMifF9x8lHq8ljYkC0d2PD9yahooygQB5tcFyRDkbbIPx8hw==", + "requires": {} + }, "watchpack": { "version": "1.7.5", "dev": true, diff --git a/package.json b/package.json index dded871..87e5e01 100644 --- a/package.json +++ b/package.json @@ -8,14 +8,17 @@ "lint": "vue-cli-service lint" }, "dependencies": { + "apexcharts": "^3.37.1", "core-js": "^3.6.5", "jsonlint": "^1.6.3", "jsonlint-mod": "^1.7.6", "mitt": "^2.1.0", "vue": "^2.6.11", + "vue-apexcharts": "^1.6.2", "vue-codemirror": "^4.0.6", "vue-json-pretty": "^1.8.1", "vue-router": "^3.2.0", + "vue-toastification": "^1.7.14", "xrpl-client": "^1.8.0" }, "devDependencies": { @@ -34,5 +37,8 @@ "sass": "^1.26.5", "sass-loader": "^8.0.2", "vue-template-compiler": "^2.6.11" + }, + "engines": { + "node": "16.x" } } diff --git a/src/components/Header.vue b/src/components/Header.vue index 87c409d..551d7a1 100644 --- a/src/components/Header.vue +++ b/src/components/Header.vue @@ -9,29 +9,55 @@ XRPL Explorer XRP Ledger Explorer - + - + - {{ nodeSelectLabel }} + {{ nodeSelectLabel }} Mainnet Testnet - Hooks Testnet V3 - Hooks Testnet V2 + Hooks Testnet V3 + + Hooks Testnet V2 + - - Source + + + Others + + + + Source + + + + + Command + + + + + Analytic + + + - + - Search + Search @@ -137,5 +163,4 @@ export default { } - + diff --git a/src/components/JsonRenderer.vue b/src/components/JsonRenderer.vue index ceb9a4b..572fe16 100644 --- a/src/components/JsonRenderer.vue +++ b/src/components/JsonRenderer.vue @@ -13,15 +13,23 @@ diff --git a/src/main.js b/src/main.js index ec95b35..73d30b1 100644 --- a/src/main.js +++ b/src/main.js @@ -1,16 +1,20 @@ import Vue from 'vue' +import Toast from 'vue-toastification' import App from './App.vue' import Xrpl from './plugins/xrpl' import Ledger from './plugins/ledger' import Mitt from 'mitt' import router from './router' +import 'vue-toastification/dist/index.css' + Vue.config.productionTip = false Vue.prototype.$events = Mitt() Vue.use(Xrpl) Vue.use(Ledger) +Vue.use(Toast, { transition: 'Vue-Toastification__fade' }) router.$ws = Xrpl diff --git a/src/plugins/ledger.js b/src/plugins/ledger.js index de2a6e4..364db63 100644 --- a/src/plugins/ledger.js +++ b/src/plugins/ledger.js @@ -42,7 +42,7 @@ export default { if (this.ledgers.filter(l => l.ledgerIndex === ledgerIndex).length > 0) { console.log('Skip hydrating: known', ledger) } else { - console.log('Hydrate', ledger) + // console.log('Hydrate', ledger) const existingRecordIndex = this.ledgers.map(l => l.ledgerIndex).indexOf(ledgerIndex) if (existingRecordIndex < 0) { @@ -55,7 +55,7 @@ export default { ledgerData }) - console.log('Hydrated', ledger) + // console.log('Hydrated', ledger) return ledgerData } } diff --git a/src/plugins/utils.js b/src/plugins/utils.js new file mode 100644 index 0000000..116b118 --- /dev/null +++ b/src/plugins/utils.js @@ -0,0 +1,7 @@ +const delay = async (ms) => { + return new Promise(resolve => setTimeout(resolve, ms)) +} + +export { + delay +} diff --git a/src/router/index.js b/src/router/index.js index baa5bad..e4b7ea4 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -11,6 +11,7 @@ import NotFound from '../views/NotFound.vue' import CustomCommand from '../views/CustomCommand.vue' import GenericData from '../components/GenericData.vue' import publicCommands from '../plugins/commands' +import Analytic from '../views/Analytic' Vue.use(VueRouter) @@ -124,6 +125,16 @@ const routes = [ replaceParam: 'hash' } }, + { + path: '/analytic', + name: 'analytic', + component: Analytic + }, + { + path: '/analytic/:ledger_from([0-9]{5,20})/:ledger_to([0-9]{5,20})', + name: 'analytic_ledger', + component: Analytic + }, { path: '/namespace/:account(r[a-zA-Z0-9]{15,})/:namespace_id([a-fA-F0-9]{64})', name: 'hooknamespace', diff --git a/src/views/Analytic.vue b/src/views/Analytic.vue new file mode 100644 index 0000000..542d0fc --- /dev/null +++ b/src/views/Analytic.vue @@ -0,0 +1,661 @@ + + + + Connecting... + + + + Play + Paused + Clear All + + + + + Add Ledgers + + + + + Analytic + + + + + Filter by Accounts or Issuers + One address per line only + + Apply + + + + + + Loading: + + + + + + + + + + + + + Selected Transactions + : {{txViewIndex + 1}} of {{selectedTxs.length}} + + prev + next + + + + + + + + + +