Merge branch 'master' into mobile-refinements

This commit is contained in:
wiz authored and GitHub committed 2022-03-15 09:28:10 +00:00
commit d769226061
23 files changed
+1079 -179

No files matched your search

@@ -1 +1,554 @@
{"mempoolInfo":{"loaded":true,"size":2322,"bytes":1146158,"usage":4759856,"maxmempool":300000000,"mempoolminfee":0.00001,"minrelaytxfee":0.00001,"unbroadcastcount":0},"vBytesPerSecond":775,"lastDifficultyAdjustment":1626564737,"previousRetarget":-4.8070052684735725,"blocks":[{"id":"00000000000000000006a2edbea88d7ca08abfe3ce26c2200db8efdead8fc7c5","height":692609,"version":805298180,"timestamp":1627227919,"tx_count":2331,"size":1419078,"weight":3858207,"merkle_root":"2c038de9602ef67df93f8bdeba009bec331ccb355917ca1d652fc95bb4482357","previousblockhash":"00000000000000000006fa0817991709a342d5065839d6c9efe09016289830ee","mediantime":1627222954,"nonce":2043835478,"bits":387225124,"difficulty":13672594272814,"reward":632191564,"coinbaseTx":{"vin":[{"scriptsig":"0381910a04e7c2b2314254432e636f6d2f763433737afabe6d6d622bef4ea8c37b21f82d8fc809d1d7b806ddbe3f81f1be57471d3843225eb0cd02000000020bb56c0ec44cc11815290000000000"}],"vout":[{"scriptpubkey_address":"1Bf9sZvBHPFGVPX71WX2njhd1NXKv5y7v5","value":632191564}]},"medianFee":1.9984543048678702,"feeRange":[1,1.0115321252059308,1.1169024571854058,1.6055846422338569,2.026266416510319,3.0403587443946187,6,327.76216216216216],"matchRate":100},{"id":"0000000000000000000405f73eb09df2405875eeb25760efb09ca06f7e6bf0f0","height":692610,"version":538968068,"timestamp":1627228844,"tx_count":2280,"size":1257713,"weight":3303869,"merkle_root":"60e726a80dcba17b000cf417b671a856f24e1ddbfe30d357be64964f00da3702","previousblockhash":"00000000000000000006a2edbea88d7ca08abfe3ce26c2200db8efdead8fc7c5","mediantime":1627223401,"nonce":162576929,"bits":387225124,"difficulty":13672594272814,"reward":636802910,"coinbaseTx":{"vin":[{"scriptsig":"0382910a1b4d696e656420627920416e74506f6f6c3731390c001f02dfb91bf2fabe6d6d5b43fd902c59e4bdcc4894b8410bda69e753862b92c00821ff7135cc82faf9e40200000000000000ebea0100cba30100"}],"vout":[{"scriptpubkey_address":"12dRugNcdxK39288NjcDV4GX7rMsKCGn6B","value":636802910}]},"medianFee":3.282511210762332,"feeRange":[1,2.009049773755656,2.654690618762475,3.1149825783972127,4.0055555555555555,4.72,15.07098653076083,423.2804232804233],"matchRate":100},{"id":"00000000000000000013d736ee3f50af566319440f2312c3ae4c4060a24a9f52","height":692611,"version":1073676292,"timestamp":1627230553,"tx_count":2316,"size":1495664,"weight":3993194,"merkle_root":"fc39ebd749c5e6615e26e6c842021a4842803c022ce3a1514d2de65630b94cb0","previousblockhash":"0000000000000000000405f73eb09df2405875eeb25760efb09ca06f7e6bf0f0","mediantime":1627226771,"nonce":5049303,"bits":387225124,"difficulty":13672594272814,"reward":652290078,"coinbaseTx":{"vin":[{"scriptsig":"0383910a043791fd60fabe6d6d6a9685e1e355c6a267d0b1d9f5af76e2a296e8e1baa13e760a47a0389ea5d971040000004204cb9a62696e616e63652f66723838387860249487223814079594b4baaeef0e000000000000"}],"vout":[{"scriptpubkey_address":"bc1qx9t2l3pyny2spqpqlye8svce70nppwtaxwdrp4","value":652290078}]},"medianFee":7.1198738170347005,"feeRange":[1.0098176718092566,4.009592326139089,4.642533936651584,5.984334203655353,10.04594180704441,17.924619085805933,62.038781163434905,395.3777777777778],"matchRate":99},{"id":"0000000000000000000a560480db3b45065b7248b6f43b7d2ad1b15cda0c29f3","height":692612,"version":536870916,"timestamp":1627230561,"tx_count":1711,"size":1376254,"weight":3993409,"merkle_root":"339c433bb9fe450c004e2d40785e417ae718bcbbc780d34488445c5df91e951a","previousblockhash":"00000000000000000013d736ee3f50af566319440f2312c3ae4c4060a24a9f52","mediantime":1627227432,"nonce":1198122458,"bits":387225124,"difficulty":13672594272814,"reward":627267139,"coinbaseTx":{"vin":[{"scriptsig":"0384910a046191fd6068616e677a686f752f7777772e6f6b65782e636f6d2ffabe6d6d5260c24fd30e59fe89fa070fa69a350c8d0614861a4a1d0eb20d0a12c39ad17a020000004204cb9a21b76f07cd3f000000000000"}],"vout":[{"scriptpubkey_address":"3DPNFXGoe8QGiEXEApQ3QtHb8wM15VCQU3","value":627267139}]},"medianFee":2.4393011510308487,"feeRange":[1.0019887591872028,1.5159574468085106,2.1265126512651267,2.341463414634146,2.6817391304347824,3.013333333333333,3.0657596371882088,175.98499061913697],"matchRate":99},{"id":"00000000000000000014454e83304996581f25da03e8b1bf527ec62f9155fbc1","height":692613,"version":1073733636,"timestamp":1627230729,"tx_count":676,"size":1266823,"weight":3993028,"merkle_root":"ec6f3a39904f4432e5202a1fa86ce24aa0f006fd408f985b8337995734276f2e","previousblockhash":"0000000000000000000a560480db3b45065b7248b6f43b7d2ad1b15cda0c29f3","mediantime":1627227557,"nonce":881591561,"bits":387225124,"difficulty":13672594272814,"reward":629313137,"coinbaseTx":{"vin":[{"scriptsig":"0385910a040192fd602f466f756e6472792055534120506f6f6c202364726f70676f6c642f0586eb224300000000000000"}],"vout":[{"scriptpubkey_address":"19dENFt4wVwos6xtgwStA6n8bbA57WCS58","value":629313137}]},"medianFee":3.0111358574610243,"feeRange":[1,1.0098360655737706,1.0227213371637502,2.345549738219895,3.1332560834298957,5.693363844393593,21.05176663927691,313.3159268929504],"matchRate":98},{"id":"0000000000000000000010714eb049e48f1eecd2eb0777fd343754dc4Line truncated
{
"mempoolInfo": {
"loaded": true,
"size": 15168,
"bytes": 6070217,
"usage": 30922560,
"maxmempool": 300000000,
"mempoolminfee": 0.00001,
"minrelaytxfee": 0.00001,
"unbroadcastcount": 0
},
"vBytesPerSecond": 2249,
"blocks": [
{
"extras": {
"reward": 636429476,
"coinbaseTx": {
"vin": [
{
"scriptsig": "031e190b04a4632f622f466f756e6472792055534120506f6f6c202364726f70676f6c642f12969a355b4c000000000000"
}
],
"vout": [
{
"scriptpubkey_address": "19dENFt4wVwos6xtgwStA6n8bbA57WCS58",
"value": 636429476
}
]
},
"medianFee": 6,
"feeRange": [
1,
3,
5,
6,
10,
16,
272
],
"totalFees": 11429476,
"avgFee": 4177,
"avgFeeRate": 11,
"pool": {
"id": 108,
"name": "Foundry USA"
},
"matchRate": 98
},
"id": "0000000000000000000918db3142fc4ccea865edb9a9f0c05f5a1b507fd7182a",
"height": 727326,
"version": 536870912,
"timestamp": 1647272873,
"bits": 386545523,
"nonce": 105379536,
"difficulty": 27550332084343.84,
"merkle_root": "d39e7d7b8e2374be518a313b9af734a0d0d87c7e8c001b5c19472258790ebfbc",
"tx_count": 2737,
"size": 1714410,
"weight": 3993069,
"previousblockhash": "00000000000000000007b6a24a3caa6b1f320c163b6ae15f763ca4d157a304ab"
},
{
"extras": {
"reward": 634306311,
"coinbaseTx": {
"vin": [
{
"scriptsig": "031f190b1362696e616e63652f3832321c000b0193666a88fabe6d6de404a9ad37192b7a677b62eae09c0d60d2158b037e7250c395a0c4db62e699f20200000000000000bf370000a9600000"
}
],
"vout": [
{
"scriptpubkey_address": "1JvXhnHCi6XqcanvrZJ5s2Qiv4tsmm2UMy",
"value": 634306311
}
]
},
"medianFee": 5,
"feeRange": [
1,
2,
3,
5,
9,
15,
316
],
"totalFees": 9306311,
"avgFee": 2861,
"avgFeeRate": 9,
"pool": {
"id": 102,
"name": "Binance Pool"
},
"matchRate": 98
},
"id": "000000000000000000012de2fedb9f88f071ee149c03b4265cf77667b63c61fe",
"height": 727327,
"version": 536928256,
"timestamp": 1647273549,
"bits": 386545523,
"nonce": 104858074,
"difficulty": 27550332084343.84,
"merkle_root": "d2349186400acd9de2d1812bf2916834bf3299bf4a32d27da91aa2c04a434360",
"tx_count": 3253,
"size": 1610333,
"weight": 3993434,
"previousblockhash": "0000000000000000000918db3142fc4ccea865edb9a9f0c05f5a1b507fd7182a"
},
{
"extras": {
"reward": 629478265,
"coinbaseTx": {
"vin": [
{
"scriptsig": "0320190b215c204d41524120506f6f6c205c000000003766ea3bdd65bc206ece9c55812c0000"
}
],
"vout": [
{
"scriptpubkey_address": "1A32KFEX7JNPmU1PVjrtiXRrTQcesT3Nf1",
"value": 629478265
}
]
},
"medianFee": 2,
"feeRange": [
1,
1,
1,
2,
3,
9,
752
],
"totalFees": 4478265,
"avgFee": 2179,
"avgFeeRate": 4,
"pool": {
"id": 112,
"name": "MARA Pool"
},
"matchRate": 99
},
"id": "0000000000000000000699b7d37e0614c1732f4a67314b039de04e025eb7f901",
"height": 727328,
"version": 543162368,
"timestamp": 1647273774,
"bits": 386545523,
"nonce": 2592684945,
"difficulty": 27550332084343.84,
"merkle_root": "94c744153aebf492935379cc1a1e9d1f28a3fb1f3c669e55e22b34ce09e7929c",
"tx_count": 2056,
"size": 1678108,
"weight": 3992617,
"previousblockhash": "000000000000000000012de2fedb9f88f071ee149c03b4265cf77667b63c61fe"
},
{
"extras": {
"reward": 627516396,
"coinbaseTx": {
"vin": [
{
"scriptsig": "0321190b04be672f622f466f756e6472792055534120506f6f6c202364726f70676f6c642f063791a2b6c3000000000000"
}
],
"vout": [
{
"scriptpubkey_address": "19dENFt4wVwos6xtgwStA6n8bbA57WCS58",
"value": 627516396
}
]
},
"medianFee": 2,
"feeRange": [
1,
1,
1,
2,
5,
14,
347
],
"totalFees": 2516396,
"avgFee": 3122,
"avgFeeRate": 7,
"pool": {
"id": 108,
"name": "Foundry USA"
},
"matchRate": 100
},
"id": "00000000000000000008e79402333f8bb6f03147550d36fe731480cf2c9e2fb8",
"height": 727329,
"version": 536870912,
"timestamp": 1647273918,
"bits": 386545523,
"nonce": 585448784,
"difficulty": 27550332084343.84,
"merkle_root": "db0f5982d7797b74b5e92ff8495280e530c1d98f50e21f7cfe244b03c7fef6ab",
"tx_count": 807,
"size": 540195,
"weight": 1379553,
"previousblockhash": "0000000000000000000699b7d37e0614c1732f4a67314b039de04e025eb7f901"
},
{
"extras": {
"reward": 646529546,
"coinbaseTx": {
"vin": [
{
"scriptsig": "0322190b04b7712f622f706f6f6c696e2e636f6d2ffabe6d6dec3c68ff646d6125f669e43f1053129a5664705728c0574e7db6449db652f4ed01000000000000009287821bd9525598170e94e5beaab395110045c9120000000000"
}
],
"vout": [
{
"scriptpubkey_address": "1GNgwA8JfG7Kc8akJ8opdNWJUihqUztfPe",
"value": 646529546
}
]
},
"medianFee": 12,
"feeRange": [
1,
5,
10,
12,
19,
38,
1815
],
"totalFees": 21529546,
"avgFee": 6715,
"avgFeeRate": 21,
"pool": {
"id": 91,
"name": "Poolin"
},
"matchRate": 95
},
"id": "00000000000000000003ccf134cbee355e976fbcb6e8573613410c61fa7a1b57",
"height": 727330,
"version": 536870916,
"timestamp": 1647276461,
"bits": 386545523,
"nonce": 1527558879,
"difficulty": 27550332084343.84,
"merkle_root": "af3870e45030bf7775b6eb996ab4c26cbe7964f572ca149e7e58efadaaf18dd4",
"tx_count": 3207,
"size": 1463281,
"weight": 3999829,
"previousblockhash": "00000000000000000008e79402333f8bb6f03147550d36fe731480cf2c9e2fb8"
},
{
"extras": {
"reward": 644036960,
"coinbaseTx": {
"vin": [
{
"scriptsig": "0323190b082f5669614254432f2cfabe6d6df26d6c3e2d9050ab39b9332674dd451d68a03cb7e1db64056d4a5e7e235342fe100000000000000010fc7fd917f62bf41977ca2bb5f61d111100000000"
}
],
"vout": [
{
"scriptpubkey_address": "18cBEMRxXHqzWWCxZNtU91F5sbUNKhL5PX",
"value": 644036960
}
]
},
"medianFee": 10,
"feeRange": [
1,
5,
8,
10,
17,
30,
724
],
"totalFees": 19036960,
"avgFee": 6429,
"avgFeeRate": 19,
"pool": {
"id": 70,
"name": "ViaBTC"
},
"matchRate": 91
},
"id": "0000000000000000000270007691145df213b43d62e768052011b7b7d496ac15",
"height": 727331,
"version": 536870912,
"timestamp": 1647277836,
"bits": 386545523,
"nonce": 2078492739,
"difficulty": 27550332084343.84,
"merkle_root": "31df633f82c3ad60e692a9dc8f472167ba37ee00d61cf3e548792e64a6d0264f",
"tx_count": 2962,
"size": 1553257,
"weight": 3993235,
"previousblockhash": "00000000000000000003ccf134cbee355e976fbcb6e8573613410c61fa7a1b57"
},
{
"extras": {
"reward": 636958014,
"coinbaseTx": {
"vin": [
{
"scriptsig": "0324190b0414a005ab627463706f6f6c2f6663637367fabe6d6dfa4a2a451de1d9dd584ea9d0fc8016c5600ca1133eac2ae3fefa82ce4e8d536e020000008e9b20aa0f5ae8f8ee41040000000000"
}
],
"vout": [
{
"scriptpubkey_address": "1Bf9sZvBHPFGVPX71WX2njhd1NXKv5y7v5",
"value": 636958014
}
]
},
"medianFee": 8,
"feeRange": [
1,
6,
7,
8,
10,
15,
503
],
"totalFees": 11958014,
"avgFee": 4527,
"avgFeeRate": 11,
"pool": {
"id": 3,
"name": "BTC.com"
},
"matchRate": 94
},
"id": "00000000000000000008b905d911099327f0f4feb992e58d603e96df3c445aa1",
"height": 727332,
"version": 541065220,
"timestamp": 1647278491,
"bits": 386545523,
"nonce": 2560770713,
"difficulty": 27550332084343.84,
"merkle_root": "fb35644b58e7f37bcb3062dda7e385e5a2c7b9f016039e84fff2043d201ea580",
"tx_count": 2642,
"size": 1365172,
"weight": 3993028,
"previousblockhash": "0000000000000000000270007691145df213b43d62e768052011b7b7d496ac15"
},
{
"extras": {
"reward": 641367077,
"coinbaseTx": {
"vin": [
{
"scriptsig": "0325190b2cfabe6d6dc9a64b2a34a929eab95ca6793bb05a59a4ada9440f2caae4a291527d5fc5876610000000f09f909f092f4632506f6f6c2f65000000000000000000000000000000000000000000000000000000000000000000000005004d270000"
}
],
"vout": [
{
"scriptpubkey_address": "1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY",
"value": 641367077
}
]
},
"medianFee": 10,
"feeRange": [
1,
7,
8,
10,
13,
27,
501
],
"totalFees": 16367077,
"avgFee": 5359,
"avgFeeRate": 16,
"pool": {
"id": 33,
"name": "F2Pool"
},
"matchRate": 98
},
"id": "000000000000000000035194e2331953ecc1c2d4783c6fb692ebd0553795b185",
"height": 727333,
"version": 1073676292,
"timestamp": 1647279951,
"bits": 386545523,
"nonce": 2216944582,
"difficulty": 27550332084343.84,
"merkle_root": "f61bcda97b7b65336bd2b3f3dbea1ba0e00d881f3abb92d364795e971f4417fd",
"tx_count": 3055,
"size": 1511571,
"weight": 3998487,
"previousblockhash": "00000000000000000008b905d911099327f0f4feb992e58d603e96df3c445aa1"
}
],
"conversions": {
"USD": 38723.918
},
"mempool-blocks": [
{
"blockSize": 1552154,
"blockVSize": 998819,
"nTx": 2700,
"totalFees": 13645525,
"medianFee": 9.348948740137697,
"feeRange": [
7.1906428439860015,
7.636363636363637,
8.03366058906031,
8.537102473498233,
10.102654867256637,
12.356010230179027,
17.915194346289752,
350.87719298245617
]
},
{
"blockSize": 1685282,
"blockVSize": 999945.5,
"nTx": 2711,
"totalFees": 6580658,
"medianFee": 6.031858407079646,
"feeRange": [
5.946188340807175,
6.021505376344086,
6.122448979591836,
7.190512129380054
]
},
{
"blockSize": 1598963,
"blockVSize": 991915.25,
"nTx": 2055,
"totalFees": 5267286,
"medianFee": 5.132743362831858,
"feeRange": [
5.007085498346717,
5.095022624434389,
5.322493224932249,
5.946188340807175
]
},
{
"blockSize": 1553568,
"blockVSize": 999920.25,
"nTx": 3688,
"totalFees": 4366448,
"medianFee": 4.106194690265487,
"feeRange": [
3.075103489059728,
3.9575971731448765,
4.559139784946237,
5.0065912336592335
]
},
{
"blockSize": 1638100,
"blockVSize": 999883,
"nTx": 2186,
"totalFees": 2322349,
"medianFee": 2.336283185840708,
"feeRange": [
2.0137103684661524,
2.111358574610245,
2.6007067137809186,
3.075103489059728
]
},
{
"blockSize": 1552617,
"blockVSize": 940875,
"nTx": 1746,
"totalFees": 1351076,
"medianFee": 1.3983842513934581,
"feeRange": [
1.0035005834305717,
1.0972279685560613,
1.7951509153884215,
2.0136986301369864
]
},
{
"blockSize": 224482,
"blockVSize": 122290,
"nTx": 65,
"totalFees": 122659,
"medianFee": 1.0020366598778003,
"feeRange": [
1,
1.0010131712259371,
1.0029268292682927,
1.0034970564976715
]
}
],
"transactions": [
{
"txid": "d9e77f48b573addece8502bd081c39e3a7cd4df426e49ffddd7a45f9ffbc7d73",
"fee": 1136,
"vsize": 141.25,
"value": 50801
},
{
"txid": "6c08a2bacae4dc58eef85d3319256aaf5bd80d5364ffe9fff2e21a25a71d4e4b",
"fee": 1700,
"vsize": 140.25,
"value": 1538700
},
{
"txid": "163ba1ec8c9568821fa787f81e483f4f8216c4caeca30396b6322918b9763868",
"fee": 1850,
"vsize": 247,
"value": 369387
},
{
"txid": "e4d668153578c17d8f32404dd322e46d442c8eb00d58551b2ee51bdd1cf6d338",
"fee": 1369,
"vsize": 152.25,
"value": 723647
},
{
"txid": "7684807a3c6b1171b312be8cacc935883210d211045b6206516728484bc56e9e",
"fee": 845,
"vsize": 141.5,
"value": 464175
},
{
"txid": "249c69312f72cdba3ac5420eaf23a0e504570295daf7da8d0313883350c28778",
"fee": 330,
"vsize": 163.25,
"value": 116248571
}
],
"backendInfo": {
"hostname": "node206.mempool.space",
"gitCommit": "8e61720e09faf5e0ecde1768583b1be9bb32292e",
"version": "2.4.0-dev"
},
"loadingIndicators": {},
"da": {
"progressPercent": 78.02579365079364,
"difficultyChange": -1.3182475819161987,
"estimatedRetargetDate": 1649197503643.8958,
"remainingBlocks": 443,
"remainingTime": 1647550222725.0728,
"previousRetarget": -1.490392872877445,
"nextRetargetHeight": 727776,
"timeAvg": 607909.4854914972,
"timeOffset": 0
}
}
+121 -17
View File
@@ -31,6 +31,7 @@ import { MiningDashboardComponent } from './components/mining-dashboard/mining-d
import { HashrateChartComponent } from './components/hashrate-chart/hashrate-chart.component';
import { HashrateChartPoolsComponent } from './components/hashrates-chart-pools/hashrate-chart-pools.component';
import { MiningStartComponent } from './components/mining-start/mining-start.component';
import { GraphsComponent } from './components/graphs/graphs.component';
import { BlocksList } from './components/blocks-list/blocks-list.component';
let routes: Routes = [
@@ -80,18 +81,6 @@ let routes: Routes = [
path: 'blocks',
component: BlocksList,
},
{
path: 'hashrate',
component: HashrateChartComponent,
},
{
path: 'hashrate/pools',
component: HashrateChartPoolsComponent,
},
{
path: 'pools',
component: PoolRankingComponent,
},
{
path: 'pool',
children: [
@@ -105,7 +94,30 @@ let routes: Routes = [
},
{
path: 'graphs',
component: StatisticsComponent,
component: GraphsComponent,
children: [
{
path: '',
pathMatch: 'full',
redirectTo: 'mempool',
},
{
path: 'mempool',
component: StatisticsComponent,
},
{
path: 'mining/hashrate-difficulty',
component: HashrateChartComponent,
},
{
path: 'mining/pools-dominance',
component: HashrateChartPoolsComponent,
},
{
path: 'mining/pools',
component: PoolRankingComponent,
},
],
},
{
path: 'about',
@@ -224,7 +236,30 @@ let routes: Routes = [
},
{
path: 'graphs',
component: StatisticsComponent,
component: GraphsComponent,
children: [
{
path: '',
pathMatch: 'full',
redirectTo: 'mempool',
},
{
path: 'mempool',
component: StatisticsComponent,
},
{
path: 'mining/hashrate-difficulty',
component: HashrateChartComponent,
},
{
path: 'mining/pools-dominance',
component: HashrateChartPoolsComponent,
},
{
path: 'mining/pools',
component: PoolRankingComponent,
},
]
},
{
path: 'address/:id',
@@ -337,7 +372,30 @@ let routes: Routes = [
},
{
path: 'graphs',
component: StatisticsComponent,
component: GraphsComponent,
children: [
{
path: '',
pathMatch: 'full',
redirectTo: 'mempool',
},
{
path: 'mempool',
component: StatisticsComponent,
},
{
path: 'mining/hashrate-difficulty',
component: HashrateChartComponent,
},
{
path: 'mining/pools-dominance',
component: HashrateChartPoolsComponent,
},
{
path: 'mining/pools',
component: PoolRankingComponent,
},
]
},
{
path: 'address/:id',
@@ -439,7 +497,30 @@ if (browserWindowEnv && browserWindowEnv.BASE_MODULE === 'liquid') {
},
{
path: 'graphs',
component: StatisticsComponent,
component: GraphsComponent,
children: [
{
path: '',
pathMatch: 'full',
redirectTo: 'mempool',
},
{
path: 'mempool',
component: StatisticsComponent,
},
{
path: 'mining/hashrate-difficulty',
component: HashrateChartComponent,
},
{
path: 'mining/pools-dominance',
component: HashrateChartPoolsComponent,
},
{
path: 'mining/pools',
component: PoolRankingComponent,
},
]
},
{
path: 'address/:id',
@@ -548,7 +629,30 @@ if (browserWindowEnv && browserWindowEnv.BASE_MODULE === 'liquid') {
},
{
path: 'graphs',
component: StatisticsComponent,
component: GraphsComponent,
children: [
{
path: '',
pathMatch: 'full',
redirectTo: 'mempool',
},
{
path: 'mempool',
component: StatisticsComponent,
},
{
path: 'mining/hashrate-difficulty',
component: HashrateChartComponent,
},
{
path: 'mining/pools-dominance',
component: HashrateChartPoolsComponent,
},
{
path: 'mining/pools',
component: PoolRankingComponent,
},
]
},
{
path: 'address/:id',
+2
View File
@@ -75,6 +75,7 @@ import { HashrateChartPoolsComponent } from './components/hashrates-chart-pools/
import { MiningStartComponent } from './components/mining-start/mining-start.component';
import { AmountShortenerPipe } from './shared/pipes/amount-shortener.pipe';
import { ShortenStringPipe } from './shared/pipes/shorten-string-pipe/shorten-string.pipe';
import { GraphsComponent } from './components/graphs/graphs.component';
import { DifficultyAdjustmentsTable } from './components/difficulty-adjustments-table/difficulty-adjustments-table.components';
import { BlocksList } from './components/blocks-list/blocks-list.component';
@@ -133,6 +134,7 @@ import { BlocksList } from './components/blocks-list/blocks-list.component';
HashrateChartPoolsComponent,
MiningStartComponent,
AmountShortenerPipe,
GraphsComponent,
DifficultyAdjustmentsTable,
BlocksList,
],
@@ -12,7 +12,7 @@
<ng-template ngbNavContent>
<div class="subtitle"><ng-container i18n="API Docs code example">Code Example</ng-container> <app-clipboard [text]="wrapCommonJS(code)"></app-clipboard></div>
<div class="links">
<a [href]="npmGithubLink()" target="_blank">github repository</a>
<a [href]="npmGithubLink()" target="_blank">GitHub Repo</a>
</div>
<pre><code [innerText]="wrapCommonJS(code)"></code></pre>
</ng-template>
@@ -22,8 +22,8 @@
<ng-template ngbNavContent>
<div class="subtitle"><ng-container i18n="API Docs install lib">Install Package</ng-container> <app-clipboard [text]="wrapImportTemplate()"></app-clipboard></div>
<div class="links">
<a [href]="npmGithubLink()" target="_blank">github repository</a>
<a [href]="npmModuleLink()" target="_blank">npm package</a>
<a [href]="npmGithubLink()" target="_blank">GitHub Repo</a>
<a [href]="npmModuleLink()" target="_blank">NPM Package</a>
</div>
<pre><code [innerText]="wrapImportTemplate()"></code></pre>
<div class="subtitle"><ng-container i18n="API Docs code example">Code Example</ng-container> <app-clipboard [text]="wrapEsModule(code)"></app-clipboard></div>
@@ -0,0 +1,25 @@
<ul ngbNav #nav="ngbNav" class="nav-pills mb-3" style="padding: 0px 35px">
<div class="d-inline-flex flex-wrap menu">
<li ngbNavItem class="menu-li">
<a routerLinkActive="active" [routerLink]="['/graphs/mempool' | relativeUrl]" ngbNavLink>Mempool</a>
</li>
<li ngbNavItem class="menu-li">
<a routerLinkActive="active" [routerLink]="['/graphs/mining/pools' | relativeUrl]" ngbNavLink i18n="mining.pools">
Pools ranking
</a>
</li>
<li ngbNavItem class="menu-li">
<a routerLinkActive="active" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]" ngbNavLink i18n="mining.pools-dominance">
Pools dominance
</a>
</li>
<li ngbNavItem class="menu-li">
<a routerLinkActive="active" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" ngbNavLink
i18n="mining.hashrate-difficulty">
Hashrate & Difficulty
</a>
</li>
</div>
</ul>
<router-outlet></router-outlet>
@@ -0,0 +1,9 @@
.menu {
flex-grow: 1;
max-width: 600px;
}
.menu-li {
flex-grow: 1;
text-align: center;
}
@@ -0,0 +1,14 @@
import { Component, OnInit } from "@angular/core";
@Component({
selector: 'app-graphs',
templateUrl: './graphs.component.html',
styleUrls: ['./graphs.component.scss'],
})
export class GraphsComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
@@ -1,6 +1,25 @@
<div [class]="widget === false ? 'full-container' : ''">
<div *ngIf="widget">
<div class="pool-distribution" *ngIf="(hashrateObservable$ | async) as hashrates; else loadingStats">
<div class="item">
<h5 class="card-title" i18n="mining.hashrate">Hashrate</h5>
<p class="card-text">
{{ hashrates.currentHashrate | amountShortener }}
<span class="symbol">hashes/sec</span>
</p>
</div>
<div class="item">
<h5 class="card-title" i18n="master-page.blocks">Difficulty</h5>
<p class="card-text">
{{ hashrates.currentDifficulty | amountShortener }}
</p>
</div>
</div>
</div>
<div class="card-header mb-0 mb-md-4" [style]="widget ? 'display:none' : ''">
<span i18n="mining.mining-pool-share">Hashrate & Difficulty</span>
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(hashrateObservable$ | async) as hashrates">
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="hashrates.availableTimespanDay >= 90">
@@ -32,3 +51,20 @@
</div>
</div>
<ng-template #loadingStats>
<div class="pool-distribution">
<div class="item">
<h5 class="card-title" i18n="mining.miners-luck">Hashrate</h5>
<p class="card-text">
<span class="skeleton-loader skeleton-loader-big"></span>
</p>
</div>
<div class="item">
<h5 class="card-title" i18n="master-page.blocks">Difficulty</h5>
<p class="card-text">
<span class="skeleton-loader skeleton-loader-big"></span>
</p>
</div>
</div>
</ng-template>
@@ -1,3 +1,11 @@
.card-header {
border-bottom: 0;
font-size: 18px;
@media (min-width: 465px) {
font-size: 20px;
}
}
.main-title {
position: relative;
color: #ffffff91;
@@ -10,13 +18,14 @@
}
.full-container {
padding: 0px 15px;
width: 100%;
height: calc(100% - 100px);
height: calc(100% - 170px);
@media (max-width: 992px) {
height: calc(100% - 140px);
height: calc(100% - 220px);
};
@media (max-width: 576px) {
height: calc(100% - 180px);
@media (max-width: 575px) {
height: calc(100% - 260px);
};
}
@@ -24,18 +33,41 @@
width: 100%;
height: 100%;
padding-bottom: 20px;
padding-right: 20px;
padding-right: 10px;
@media (max-width: 992px) {
padding-bottom: 25px;
}
@media (max-width: 829px) {
padding-bottom: 50px;
}
@media (max-width: 767px) {
padding-bottom: 25px;
}
@media (max-width: 629px) {
padding-bottom: 55px;
}
@media (max-width: 567px) {
padding-bottom: 55px;
}
}
.chart-widget {
width: 100%;
height: 100%;
max-height: 293px;
max-height: 270px;
}
.formRadioGroup {
margin-top: 6px;
display: flex;
flex-direction: column;
@media (min-width: 1130px) {
position: relative;
top: -65px;
}
@media (min-width: 830px) and (max-width: 1130px) {
position: relative;
top: 0px;
}
@media (min-width: 830px) {
flex-direction: row;
float: right;
@@ -48,3 +80,66 @@
}
}
}
.pool-distribution {
min-height: 56px;
display: block;
@media (min-width: 485px) {
display: flex;
flex-direction: row;
}
h5 {
margin-bottom: 10px;
}
.item {
width: 50%;
margin: 0px auto 10px;
display: inline-block;
@media (min-width: 485px) {
margin: 0px auto 10px;
}
@media (min-width: 785px) {
margin: 0px auto 0px;
}
&:last-child {
margin: 0px auto 0px;
}
&:nth-child(2) {
order: 2;
@media (min-width: 485px) {
order: 3;
}
}
&:nth-child(3) {
order: 3;
@media (min-width: 485px) {
order: 2;
display: block;
}
@media (min-width: 768px) {
display: none;
}
@media (min-width: 992px) {
display: block;
}
}
.card-title {
font-size: 1rem;
color: #4a68b9;
}
.card-text {
font-size: 18px;
span {
color: #ffffff66;
font-size: 12px;
}
}
}
}
.skeleton-loader {
width: 100%;
display: block;
max-width: 80px;
margin: 15px auto 3px;
}
@@ -61,6 +61,7 @@ export class HashrateChartComponent implements OnInit {
.pipe(
startWith('1y'),
switchMap((timespan) => {
this.isLoading = true;
return this.apiService.getHistoricalHashrate$(timespan)
.pipe(
tap((data: any) => {
@@ -109,21 +110,10 @@ export class HashrateChartComponent implements OnInit {
(new Date().getTime() / 1000) - (data.oldestIndexedBlockTimestamp)
) / 3600 / 24;
const tableData = [];
for (let i = data.difficulty.length - 1; i > 0; --i) {
const selectedPowerOfTen: any = selectPowerOfTen(data.difficulty[i].difficulty);
const change = (data.difficulty[i].difficulty / data.difficulty[i - 1].difficulty - 1) * 100;
tableData.push(Object.assign(data.difficulty[i], {
change: change,
difficultyShorten: formatNumber(
data.difficulty[i].difficulty / selectedPowerOfTen.divider,
this.locale, '1.2-2') + selectedPowerOfTen.unit
}));
}
return {
availableTimespanDay: availableTimespanDay,
difficulty: this.tableOnly ? tableData.slice(0, 5) : tableData,
currentDifficulty: Math.round(data.difficulty[data.difficulty.length - 1].difficulty * 100) / 100,
currentHashrate: data.hashrates[data.hashrates.length - 1].avgHashrate,
};
}),
retryWhen((errors) => errors.pipe(
@@ -155,6 +145,7 @@ export class HashrateChartComponent implements OnInit {
this.chartOptions = {
title: title,
animation: false,
color: [
new graphic.LinearGradient(0, 0, 0, 0.65, [
{ offset: 0, color: '#F4511E' },
@@ -166,9 +157,10 @@ export class HashrateChartComponent implements OnInit {
'#D81B60',
],
grid: {
top: 30,
right: this.right,
left: this.left,
bottom: this.widget ? 30 : 60,
bottom: this.widget ? 30 : this.isMobile() ? 90 : 60,
},
tooltip: {
show: !this.isMobile() || !this.widget,
@@ -209,7 +201,7 @@ export class HashrateChartComponent implements OnInit {
type: 'time',
splitNumber: (this.isMobile() || this.widget) ? 5 : 10,
},
legend: data.hashrates.length === 0 ? undefined : {
legend: (this.widget || data.hashrates.length === 0) ? undefined : {
data: [
{
name: 'Hashrate',
@@ -241,7 +233,6 @@ export class HashrateChartComponent implements OnInit {
return value.min * 0.9;
},
type: 'value',
name: 'Hashrate',
axisLabel: {
color: 'rgb(110, 112, 121)',
formatter: (val) => {
@@ -259,7 +250,6 @@ export class HashrateChartComponent implements OnInit {
return value.min * 0.9;
},
type: 'value',
name: 'Difficulty',
position: 'right',
axisLabel: {
color: 'rgb(110, 112, 121)',
@@ -301,17 +291,18 @@ export class HashrateChartComponent implements OnInit {
type: 'inside',
realtime: true,
zoomLock: true,
zoomOnMouseWheel: true,
moveOnMouseMove: true,
maxSpan: 100,
minSpan: 10,
moveOnMouseMove: false,
}, {
showDetail: false,
show: true,
type: 'slider',
brushSelect: false,
realtime: true,
bottom: 0,
bottom: this.isMobile() ? 30 : 0,
left: 20,
right: 15,
selectedDataBackground: {
lineStyle: {
color: '#fff',
@@ -1,6 +1,7 @@
<div [class]="widget === false ? 'full-container' : ''">
<div class="card-header mb-0 mb-md-4" [style]="widget ? 'display:none' : ''">
<div class="card-header" [style]="widget ? 'display:none' : ''">
<span *ngIf="!widget" i18n="mining.pools-dominance">Mining pools dominance</span>
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(hashrateObservable$ | async) as hashrates">
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="hashrates.availableTimespanDay >= 90">
@@ -1,3 +1,11 @@
.card-header {
border-bottom: 0;
font-size: 18px;
@media (min-width: 465px) {
font-size: 20px;
}
}
.main-title {
position: relative;
color: #ffffff91;
@@ -10,21 +18,37 @@
}
.full-container {
padding: 0px 15px;
width: 100%;
height: calc(100% - 100px);
@media (max-width: 992px) {
height: calc(100% - 140px);
height: calc(100% - 140px);
@media (max-width: 991px) {
height: calc(100% - 190px);
};
@media (max-width: 576px) {
height: calc(100% - 180px);
@media (max-width: 575px) {
height: calc(100% - 235px);
};
}
.chart {
width: 100%;
height: 100%;
padding-bottom: 20px;
padding-right: 20px;
padding-bottom: 25px;
padding-right: 10px;
@media (max-width: 992px) {
padding-bottom: 25px;
}
@media (max-width: 829px) {
padding-bottom: 50px;
}
@media (max-width: 767px) {
padding-bottom: 50px;
}
@media (max-width: 629px) {
padding-bottom: 85px;
}
@media (max-width: 567px) {
padding-bottom: 85px;
}
}
.chart-widget {
width: 100%;
@@ -36,6 +60,14 @@
margin-top: 6px;
display: flex;
flex-direction: column;
@media (min-width: 1130px) {
position: relative;
top: -65px;
}
@media (min-width: 830px) and (max-width: 1130px) {
position: relative;
top: 0px;
}
@media (min-width: 830px) {
flex-direction: row;
float: right;
@@ -23,7 +23,7 @@ import { poolsColor } from 'src/app/app.constants';
})
export class HashrateChartPoolsComponent implements OnInit {
@Input() widget = false;
@Input() right: number | string = 40;
@Input() right: number | string = 45;
@Input() left: number | string = 25;
radioGroupForm: FormGroup;
@@ -153,11 +153,12 @@ export class HashrateChartPoolsComponent implements OnInit {
this.chartOptions = {
title: title,
animation: false,
grid: {
right: this.right,
left: this.left,
bottom: this.widget ? 30 : 20,
top: this.widget ? 10 : 40,
bottom: this.widget ? 30 : 60,
top: this.widget || this.isMobile() ? 10 : 50,
},
tooltip: {
show: !this.isMobile() || !this.widget,
@@ -206,6 +207,32 @@ export class HashrateChartPoolsComponent implements OnInit {
min: 0,
},
series: data.series,
dataZoom: this.widget ? null : [{
type: 'inside',
realtime: true,
zoomLock: true,
maxSpan: 100,
minSpan: 10,
moveOnMouseMove: false,
}, {
showDetail: false,
show: true,
type: 'slider',
brushSelect: false,
realtime: true,
bottom: 0,
left: 20,
right: 15,
selectedDataBackground: {
lineStyle: {
color: '#fff',
opacity: 0.45,
},
areaStyle: {
opacity: 0,
}
},
}],
};
}
@@ -38,7 +38,7 @@
<a class="nav-link" [routerLink]="['/blocks' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'cubes']" [fixedWidth]="true" i18n-title="master-page.blocks" title="Blocks"></fa-icon></a>
</li>
<li class="nav-item" routerLinkActive="active" id="btn-graphs">
<a class="nav-link" [routerLink]="['/graphs' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'chart-area']" [fixedWidth]="true" i18n-title="master-page.graphs" title="Graphs"></fa-icon></a>
<a class="nav-link" [routerLink]="['/graphs/mempool' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'chart-area']" [fixedWidth]="true" i18n-title="master-page.graphs" title="Graphs"></fa-icon></a>
</li>
<li class="nav-item d-none d-lg-block" routerLinkActive="active" id="btn-tv">
<a class="nav-link" [routerLink]="['/tv' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'tv']" [fixedWidth]="true" i18n-title="master-page.tvview" title="TV view"></fa-icon></a>
@@ -76,7 +76,7 @@
<div class="card" style="height: 385px">
<div class="card-body">
<app-pool-ranking [widget]=true></app-pool-ranking>
<div class="mt-1"><a [routerLink]="['/mining/pools' | relativeUrl]" i18n="dashboard.view-more">View more
<div class="mt-1"><a [routerLink]="['/graphs/mining/pools' | relativeUrl]" i18n="dashboard.view-more">View more
&raquo;</a></div>
</div>
</div>
@@ -86,30 +86,13 @@
<div class="col">
<div class="card" style="height: 385px">
<div class="card-body">
<h5 class="card-title">
Hashrate (1y)
</h5>
<app-hashrate-chart [widget]=true></app-hashrate-chart>
<div class="mt-1"><a [routerLink]="['/mining/hashrate' | relativeUrl]" i18n="dashboard.view-more">View more
<div class="mt-1"><a [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" i18n="dashboard.view-more">View more
&raquo;</a></div>
</div>
</div>
</div>
<!-- pool dominance -->
<!-- <div class="col">
<div class="card" style="height: 385px">
<div class="card-body">
<h5 class="card-title">
Mining Pools Dominance (1y)
</h5>
<app-hashrate-chart-pools [widget]=true></app-hashrate-chart-pools>
<div class="mt-1"><a [routerLink]="['/mining/hashrate/pools' | relativeUrl]" i18n="dashboard.view-more">View
more &raquo;</a></div>
</div>
</div>
</div> -->
<!-- Latest blocks -->
<div class="col">
<div class="card" style="height: 385px">
@@ -124,6 +107,7 @@
</div>
</div>
<!-- Difficult adjustments -->
<div class="col">
<div class="card" style="height: 385px">
<div class="card-body">
@@ -131,11 +115,11 @@
Adjustments
</h5>
<app-difficulty-adjustments-table></app-difficulty-adjustments-table>
<div><a [routerLink]="['/mining/hashrate' | relativeUrl]" i18n="dashboard.view-more">View more
<div class="mt-1"><a [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" i18n="dashboard.view-more">View more
&raquo;</a></div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -125,3 +125,7 @@
max-width: 55px;
}
}
.card-text {
font-size: 22px;
}
@@ -1,7 +1,8 @@
import { ChangeDetectionStrategy, Component, Inject, LOCALE_ID, OnDestroy, OnInit } from '@angular/core';
import { ChangeDetectionStrategy, Component, Inject, LOCALE_ID, OnInit } from '@angular/core';
import { map } from 'rxjs/operators';
import { SeoService } from 'src/app/services/seo.service';
import { StateService } from 'src/app/services/state.service';
import { formatNumber } from '@angular/common';
import { Observable } from 'rxjs';
@Component({
@@ -1,4 +1,4 @@
<div [class]="widget === false ? 'container-xl' : ''">
<div [class]="widget === false ? 'full-container' : ''">
<div *ngIf="widget">
<div class="pool-distribution" *ngIf="(miningStatsObservable$ | async) as miningStats; else loadingReward">
@@ -23,14 +23,10 @@
</div>
</div>
<div [class]="widget ? 'chart-widget' : 'chart'"
echarts [initOpts]="chartInitOptions" [options]="chartOptions" (chartInit)="onChartInit($event)"></div>
<div class="text-center loadingGraphs" *ngIf="isLoading">
<div class="spinner-border text-light"></div>
</div>
<div class="card-header mb-0 mb-lg-4 mt-md-3" [style]="widget ? 'display:none' : ''">
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(miningStatsObservable$ | async) as miningStats">
<div class="card-header" *ngIf="!widget">
<span i18n="mining.mining-pool-share">Mining pools share</span>
<form [formGroup]="radioGroupForm" class="formRadioGroup"
*ngIf="!widget && (miningStatsObservable$ | async) as miningStats">
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="miningStats.availableTimespanDay >= 1">
<input ngbButton type="radio" [value]="'24h'" fragment="24h"> 24h
@@ -66,36 +62,48 @@
</form>
</div>
<table *ngIf="widget === false" class="table table-borderless text-center pools-table">
<thead>
<tr>
<th class="d-none d-md-block" i18n="mining.rank">Rank</th>
<th class=""></th>
<th class="" i18n="mining.pool-name">Pool</th>
<th class="" *ngIf="this.poolsWindowPreference === '24h'" i18n="mining.hashrate">Hashrate</th>
<th class="" i18n="master-page.blocks">Blocks</th>
<th class="d-none d-md-block" i18n="mining.empty-blocks">Empty Blocks</th>
</tr>
</thead>
<tbody *ngIf="(miningStatsObservable$ | async) as miningStats">
<tr *ngFor="let pool of miningStats.pools">
<td class="d-none d-md-block">{{ pool.rank }}</td>
<td class="text-right"><img width="25" height="25" src="{{ pool.logo }}" onError="this.src = './resources/mining-pools/default.svg'"></td>
<td class=""><a [routerLink]="[('/mining/pool/' + pool.poolId) | relativeUrl]">{{ pool.name }}</a></td>
<td class="" *ngIf="this.poolsWindowPreference === '24h' && !isLoading">{{ pool.lastEstimatedHashrate }} {{ miningStats.miningUnits.hashrateUnit }}</td>
<td class="">{{ pool['blockText'] }}</td>
<td class="d-none d-md-block">{{ pool.emptyBlocks }} ({{ pool.emptyBlockRatio }}%)</td>
</tr>
<tr style="border-top: 1px solid #555">
<td class="d-none d-md-block"></td>
<td class="text-right"></td>
<td class="" i18n="mining.all-miners"><b>All miners</b></td>
<td class="" *ngIf="this.poolsWindowPreference === '24h'"><b>{{ miningStats.lastEstimatedHashrate}} {{ miningStats.miningUnits.hashrateUnit }}</b></td>
<td class=""><b>{{ miningStats.blockCount }}</b></td>
<td class="d-none d-md-block"><b>{{ miningStats.totalEmptyBlock }} ({{ miningStats.totalEmptyBlockRatio }}%)</b></td>
</tr>
</tbody>
</table>
<div [class]="!widget ? 'bottom-padding' : 'pb-0'" class="container pb-lg-0">
<div [class]="widget ? 'chart-widget' : 'chart'" echarts [initOpts]="chartInitOptions" [options]="chartOptions"
(chartInit)="onChartInit($event)"></div>
<div class="text-center loadingGraphs" *ngIf="isLoading">
<div class="spinner-border text-light"></div>
</div>
<table *ngIf="widget === false" class="table table-borderless text-center pools-table">
<thead>
<tr>
<th class="d-none d-md-block" i18n="mining.rank">Rank</th>
<th class=""></th>
<th class="" i18n="mining.pool-name">Pool</th>
<th class="" *ngIf="this.poolsWindowPreference === '24h'" i18n="mining.hashrate">Hashrate</th>
<th class="" i18n="master-page.blocks">Blocks</th>
<th class="d-none d-md-block" i18n="mining.empty-blocks">Empty Blocks</th>
</tr>
</thead>
<tbody *ngIf="(miningStatsObservable$ | async) as miningStats">
<tr *ngFor="let pool of miningStats.pools">
<td class="d-none d-md-block">{{ pool.rank }}</td>
<td class="text-right"><img width="25" height="25" src="{{ pool.logo }}"
onError="this.src = './resources/mining-pools/default.svg'"></td>
<td class=""><a [routerLink]="[('/mining/pool/' + pool.poolId) | relativeUrl]">{{ pool.name }}</a></td>
<td class="" *ngIf="this.poolsWindowPreference === '24h' && !isLoading">{{ pool.lastEstimatedHashrate }} {{
miningStats.miningUnits.hashrateUnit }}</td>
<td class="">{{ pool['blockText'] }}</td>
<td class="d-none d-md-block">{{ pool.emptyBlocks }} ({{ pool.emptyBlockRatio }}%)</td>
</tr>
<tr style="border-top: 1px solid #555">
<td class="d-none d-md-block"></td>
<td class="text-right"></td>
<td class="" i18n="mining.all-miners"><b>All miners</b></td>
<td class="" *ngIf="this.poolsWindowPreference === '24h'"><b>{{ miningStats.lastEstimatedHashrate}} {{
miningStats.miningUnits.hashrateUnit }}</b></td>
<td class=""><b>{{ miningStats.blockCount }}</b></td>
<td class="d-none d-md-block"><b>{{ miningStats.totalEmptyBlock }} ({{ miningStats.totalEmptyBlockRatio
}}%)</b></td>
</tr>
</tbody>
</table>
</div>
</div>
@@ -121,4 +129,4 @@
</p>
</div>
</div>
</ng-template>
</ng-template>
@@ -1,7 +1,27 @@
.card-header {
border-bottom: 0;
font-size: 18px;
@media (min-width: 465px) {
font-size: 20px;
}
}
.full-container {
padding: 0px 15px;
width: 100%;
height: calc(100% - 140px);
@media (max-width: 992px) {
height: calc(100% - 190px);
};
@media (max-width: 575px) {
height: calc(100% - 230px);
};
}
.chart {
max-height: 400px;
@media (max-width: 767.98px) {
max-height: 270px;
max-height: 230px;
}
}
.chart-widget {
@@ -17,10 +37,17 @@
margin-top: 6px;
display: flex;
flex-direction: column;
@media (min-width: 1130px) {
position: relative;
top: -65px;
}
@media (min-width: 830px) and (max-width: 1130px) {
position: relative;
top: 0px;
}
@media (min-width: 830px) {
margin-left: 2%;
flex-direction: row;
float: left;
float: right;
margin-top: 0px;
}
.btn-sm {
@@ -31,12 +58,21 @@
}
}
@media (max-width: 767.98px) {
.bottom-padding {
@media (max-width: 992px) {
padding-bottom: 65px
};
@media (max-width: 576px) {
padding-bottom: 65px
};
}
@media (max-width: 767.98px) {
.pools-table th,
.pools-table td {
padding: .3em !important;
}
}
padding: .3em !important;
}
}
.loadingGraphs {
position: absolute;
@@ -44,9 +80,6 @@
left: calc(50% - 15px);
z-index: 100;
}
.loadingGraphs.widget {
top: 25%;
}
.pool-distribution {
min-height: 56px;
@@ -117,7 +117,7 @@ export class PoolRankingComponent implements OnInit {
if (this.isMobile() && this.widget) {
edgeDistance = 0;
} else if (this.isMobile() && !this.widget || this.widget) {
edgeDistance = 35;
edgeDistance = 10;
}
miningStats.pools.forEach((pool) => {
@@ -209,13 +209,13 @@ export class PoolRankingComponent implements OnInit {
network = network.charAt(0).toUpperCase() + network.slice(1);
let radius: any[] = ['20%', '80%'];
let top: any = undefined; let bottom = undefined; let height = undefined;
let top: number = 0; let height = undefined;
if (this.isMobile() && this.widget) {
top = -30;
height = 270;
radius = ['10%', '50%'];
} else if (this.isMobile() && !this.widget) {
top = 0;
top = -40;
height = 300;
radius = ['10%', '50%'];
} else if (this.widget) {
@@ -223,22 +223,12 @@ export class PoolRankingComponent implements OnInit {
top = -20;
height = 330;
} else {
top = 35;
top = 0;
}
this.chartOptions = {
animation: false,
color: chartColors,
title: {
text: this.widget ? '' : $localize`:@@mining.pool-chart-title:${network}:NETWORK: mining pools share`,
left: 'center',
textStyle: {
color: '#FFF',
},
subtextStyle: {
color: '#CCC',
fontStyle: 'italic',
}
},
tooltip: {
trigger: 'item',
textStyle: {
@@ -249,7 +239,6 @@ export class PoolRankingComponent implements OnInit {
{
minShowLabelAngle: 3.6,
top: top,
bottom: bottom,
height: height,
name: 'Mining pool',
type: 'pie',
@@ -1,5 +1,4 @@
import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
import { WebsocketService } from 'src/app/services/websocket.service';
import { StateService } from 'src/app/services/state.service';
import { specialBlocks } from 'src/app/app.constants';
@@ -20,12 +19,10 @@ export class StartComponent implements OnInit {
@ViewChild('blockchainContainer') blockchainContainer: ElementRef;
constructor(
private websocketService: WebsocketService,
private stateService: StateService,
) { }
ngOnInit() {
this.websocketService.want(['blocks', 'stats', 'mempool-blocks']);
this.stateService.blocks$
.subscribe((blocks: any) => {
if (this.stateService.network !== '') {
@@ -40,6 +40,14 @@
margin-top: 6px;
display: flex;
flex-direction: column;
@media (min-width: 1130px) {
position: relative;
top: -65px;
}
@media (min-width: 830px) and (max-width: 1130px) {
position: relative;
top: 0px;
}
@media (min-width: 830px) {
flex-direction: row;
float: right;
@@ -1,39 +1,26 @@
import { Pipe, PipeTransform } from '@angular/core';
// https://medium.com/@thunderroid/angular-short-number-suffix-pipe-1k-2m-3b-dded4af82fb4
@Pipe({
name: 'amountShortener'
})
export class AmountShortenerPipe implements PipeTransform {
transform(number: number, args?: any): any {
if (isNaN(number)) return null; // will only work value is a number
if (number === null) return null;
if (number === 0) return null;
let abs = Math.abs(number);
const rounder = Math.pow(10, 1);
const isNegative = number < 0; // will also work for Negetive numbers
let key = '';
const powers = [
{ key: 'E', value: 10e18 },
{ key: 'P', value: 10e15 },
{ key: 'T', value: 10e12 },
{ key: 'B', value: 10e9 },
{ key: 'M', value: 10e6 },
{ key: 'K', value: 1000 }
];
for (let i = 0; i < powers.length; i++) {
let reduced = abs / powers[i].value;
reduced = Math.round(reduced * rounder) / rounder;
if (reduced >= 1) {
abs = reduced;
key = powers[i].key;
break;
}
transform(num: number, ...args: number[]): unknown {
if (num < 1000) {
return num;
}
return (isNegative ? '-' : '') + abs + key;
const digits = args[0] || 1;
const lookup = [
{ value: 1, symbol: '' },
{ value: 1e3, symbol: 'k' },
{ value: 1e6, symbol: 'M' },
{ value: 1e9, symbol: 'G' },
{ value: 1e12, symbol: 'T' },
{ value: 1e15, symbol: 'P' },
{ value: 1e18, symbol: 'E' }
];
const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
var item = lookup.slice().reverse().find((item) => num >= item.value);
return item ? (num / item.value).toFixed(digits).replace(rx, '$1') + item.symbol : '0';
}
}