angular.module('cesium.graph.blockchain.controllers', ['chart.js', 'cesium.services', 'cesium.graph.services']) .config(function($stateProvider) { 'ngInject'; $stateProvider .state('app.blockchain_stats', { url: "/blockchain/stats?currency&stepUnit&t&hide&scale", views: { 'menuContent': { templateUrl: "plugins/graph/templates/blockchain/view_stats.html" } } }) .state('app.currency_blockchain_stats', { url: "/:currency/blockchain/stats", views: { 'menuContent': { templateUrl: "plugins/graph/templates/blockchain/view_stats.html" } } }) ; }) .controller('GpBlockchainTxCountCtrl', GpBlockchainTxCountController) .controller('GpBlockchainIssuersCtrl', GpBlockchainIssuersController) ; function GpBlockchainTxCountController($scope, $controller, $q, $state, $filter, $translate, gpData, gpColor) { 'ngInject'; // Initialize the super class and extend it. angular.extend(this, $controller('GpCurrencyAbstractCtrl', {$scope: $scope})); $scope.displayRightAxis = true; $scope.init = function(e, state) { if (state && state.stateParams) { // get the pubkey if (!$scope.formData.issuer && state && state.stateParams && state.stateParams.pubkey) { // Currency parameter $scope.formData.issuer = state.stateParams.pubkey; } } }; $scope.load = function(updateTimePct) { var formData = $scope.formData; return $q.all([ $translate($scope.formData.issuer? 'GRAPH.BLOCKCHAIN.TX_AMOUNT_PUBKEY_TITLE': 'GRAPH.BLOCKCHAIN.TX_AMOUNT_TITLE', formData), // translate i18n keys $translate(['GRAPH.BLOCKCHAIN.TX_AMOUNT_LABEL', 'GRAPH.BLOCKCHAIN.TX_COUNT_LABEL', 'GRAPH.BLOCKCHAIN.TX_AVG_BY_BLOCK', 'COMMON.DATE_PATTERN', 'COMMON.DATE_SHORT_PATTERN', 'COMMON.DATE_MONTH_YEAR_PATTERN']), // get data gpData.blockchain.txCount($scope.formData.currency, formData) ]) .then(function(result) { var title = result[0]; var translations = result[1]; var datePatterns = { hour: translations['COMMON.DATE_PATTERN'], day: translations['COMMON.DATE_SHORT_PATTERN'], month: translations['COMMON.DATE_MONTH_YEAR_PATTERN'] }; result = result[2]; if (!result || !result.times) return; // no data $scope.times = result.times; var formatInteger = $filter('formatInteger'); var formatAmount = $filter('formatDecimal'); $scope.currencySymbol = $filter('currencySymbolNoHtml')($scope.formData.currency, $scope.formData.useRelative); // Data if ($scope.formData.rangeDuration != 'hour') { $scope.data = [ result.amount, result.count ]; } else { $scope.data = [ result.amount, result.count ]; } // Labels var labelPattern = datePatterns[$scope.formData.rangeDuration]; $scope.labels = result.times.reduce(function(res, time) { return res.concat(moment.unix(time).local().format(labelPattern)); }, []); // Colors $scope.colors = gpColor.scale.fix(result.times.length); // Update range options with received values $scope.updateRange(result.times[0], result.times[result.times.length-1], updateTimePct); // Options $scope.options = { responsive: true, maintainAspectRatio: true, title: { display: true, text: title }, scales: { yAxes: [ { id: 'y-axis-amount', position: 'left' }, { id: 'y-axis-count', display: $scope.displayRightAxis, position: 'right', gridLines: { drawOnChartArea: false } } ] }, legend: { display: $scope.displayRightAxis, onClick: $scope.onLegendClick }, tooltips: { enabled: true, intersect: false, mode: 'index', callbacks: { label: function(tooltipItems, data) { if (tooltipItems.datasetIndex === 0) { return data.datasets[tooltipItems.datasetIndex].label + ': ' + formatAmount(tooltipItems.yLabel) + ' ' + $scope.currencySymbol; } return data.datasets[tooltipItems.datasetIndex].label + ': ' + tooltipItems.yLabel; } } } }; // Override dataset config $scope.datasetOverride = [ { yAxisID: 'y-axis-amount', type: 'bar', label: translations['GRAPH.BLOCKCHAIN.TX_AMOUNT_LABEL'], hoverBackgroundColor: gpColor.rgba.calm(0.6) }, { yAxisID: 'y-axis-count', type: 'line', label: translations['GRAPH.BLOCKCHAIN.TX_COUNT_LABEL'], fill: false, borderColor: gpColor.rgba.gray(0.5), borderWidth: 2, backgroundColor: gpColor.rgba.gray(0.5), pointBackgroundColor: gpColor.rgba.gray(0.5), pointBorderColor: gpColor.rgba.white(), pointHoverBackgroundColor: gpColor.rgba.gray(1), pointHoverBorderColor: gpColor.rgba.translucent(), pointRadius: 3 } ]; }); }; $scope.onChartClick = function(data, e, item) { if (!item) return; var from = $scope.times[item._index]; var to = moment.unix(from).utc().add(1, $scope.formData.rangeDuration).unix(); var query = '_exists_:transactions AND medianTime:>={0} AND medianTime:<{1}'.format(from, to); if ($scope.formData.issuer) { query += ' AND issuer:' + $scope.formData.issuer; } $state.go('app.blockchain_search', {q: query}); }; } function GpBlockchainIssuersController($scope, $controller, $q, $state, $translate, gpColor, gpData) { 'ngInject'; // Initialize the super class and extend it. angular.extend(this, $controller('GpCurrencyAbstractCtrl', {$scope: $scope})); $scope.load = function() { return $q.all([ $translate([ 'GRAPH.BLOCKCHAIN.BLOCKS_ISSUERS_TITLE', 'GRAPH.BLOCKCHAIN.BLOCKS_ISSUERS_LABEL' ]), gpData.blockchain.countByIssuer($scope.formData.currency) ]) .then(function(result) { var translations = result[0]; result = result[1]; if (!result || !result.data) return; // Data $scope.data = result.data; // Labels $scope.labels = result.labels; // Data to keep (for click or label) $scope.blockCount = result.blockCount; $scope.issuers = result.issuers; // Options $scope.barOptions = { responsive: true, maintainAspectRatio: $scope.maintainAspectRatio, title: { display: true, text: translations['GRAPH.BLOCKCHAIN.BLOCKS_ISSUERS_TITLE'] }, scales: { yAxes: [{ type: 'linear', ticks: { beginAtZero: true } }] } }; // Colors $scope.colors = gpColor.scale.custom(result.data.length); }); }; $scope.onChartClick = function(data, e, item) { if (!item) return; var issuer = $scope.issuers[item._index]; $state.go('app.wot_identity', issuer); }; }