diff --git a/.env.example b/.env.example index 25efb03893891ddab73d5ad74675c249c811be55..6c2907b0b0a9f639a9008c3c4439b273524b3471 100644 --- a/.env.example +++ b/.env.example @@ -14,6 +14,8 @@ DB_USERNAME=root DB_PASSWORD= SIGN_UP=false +FORGETTING_FACTOR=0.99 +FOLLOWER_FACTOR=100 BROADCAST_DRIVER=log CACHE_DRIVER=file diff --git a/app/ExtensionDelegationElection.php b/app/ExtensionDelegationElection.php index 5947ff01c17bab21e5062c50c618aeaba05448c0..d3eec36b19aeba0ffcc1eb33d0496ea54ecc6853 100644 --- a/app/ExtensionDelegationElection.php +++ b/app/ExtensionDelegationElection.php @@ -16,6 +16,8 @@ class ExtensionDelegationElection extends Model 'as_follower', 'as_independent', 'weight_a', - 'weight_b' + 'weight_b', + 'reputation_a', + 'reputation_b' ]; } diff --git a/app/Http/Controllers/APIController.php b/app/Http/Controllers/APIController.php index 016877f0dacfd08d26880987d80c4988c475ef0c..ba61f55a8a00efaa06995fe918d67f0ba158b00e 100644 --- a/app/Http/Controllers/APIController.php +++ b/app/Http/Controllers/APIController.php @@ -10,6 +10,7 @@ use App\Population; use App\Voter; use Illuminate\Http\Request; use Illuminate\Http\Response; +use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\DB; use Illuminate\Validation\ValidationException; @@ -268,6 +269,9 @@ class APIController extends Controller ->append(['elections_stats', 'voters_stats']) ->makeHidden('elections', 'voters'); + $data->forgetting_percent = 100 - (100 * Config::get('app.forgetting_factor', 0)); + $data->follower_factor = Config::get('app.follower_factor'); + return response()->json($data, Response::HTTP_OK); } @@ -375,10 +379,12 @@ class APIController extends Controller /** * @param $population + * @param null $forgettingFactor + * @param null $followerFactor * @return \stdClass * @throws \Exception */ - private function runSingleMajorityElection($population): \stdClass + private function runSingleMajorityElection($population, $forgettingFactor = null, $followerFactor = null): \stdClass { $startTime = microtime(true); $election = Election::create([ @@ -466,8 +472,11 @@ class APIController extends Controller $startTime = microtime(true); $elections = array(); + $data->forgetting_factor = Config::get('app.forgetting_factor',0.99); + $data->follower_factor = Config::get('app.follower_factor', 100); + for( $i = 0; $i < $numberOfElections; $i++) { - $singleElectionStats = $this->$electionMethod($existingPopulation); + $singleElectionStats = $this->$electionMethod($existingPopulation, $data->forgetting_factor, $data->follower_factor); $elections[] = $singleElectionStats; } $data->number_of_elections = $numberOfElections; @@ -493,11 +502,13 @@ class APIController extends Controller * No changes to voters' attributes * * @param Population $population + * @param $forgettingFactor + * @param $followerFactor * @return \stdClass * @throws \Exception */ - private function runSingleDelegationElectionVersion1(Population $population) { - return $this->runSingleDelegationElection($population, false, 'd1', false); + private function runSingleDelegationElectionVersion1(Population $population, $forgettingFactor, $followerFactor) { + return $this->runSingleDelegationElection($population, false, 'd1', false, $forgettingFactor, $followerFactor); } /** @@ -505,11 +516,13 @@ class APIController extends Controller * Modify Reputation only after each election * * @param Population $population + * @param $forgettingFactor + * @param $followerFactor * @return \stdClass * @throws \Exception */ - private function runSingleDelegationElectionVersion2 (Population $population) { - return $this->runSingleDelegationElection($population, true, 'd2', false); + private function runSingleDelegationElectionVersion2 (Population $population, $forgettingFactor, $followerFactor) { + return $this->runSingleDelegationElection($population, true, 'd2', false, $forgettingFactor, $followerFactor); } /** @@ -517,11 +530,13 @@ class APIController extends Controller * Modify Reputation, Following and Leadership after each election * * @param Population $population + * @param $forgettingFactor + * @param $followerFactor * @return \stdClass * @throws \Exception */ - private function runSingleDelegationElectionVersion3 (Population $population) { - return $this->runSingleDelegationElection($population, true, 'd3', true); + private function runSingleDelegationElectionVersion3 (Population $population, $forgettingFactor, $followerFactor) { + return $this->runSingleDelegationElection($population, true, 'd3', true, $forgettingFactor, $followerFactor); } /* private function runSingleDelegationElectionVersion1(Population $population) { @@ -688,6 +703,8 @@ class APIController extends Controller * @param bool $modifyReputation * @param string $type * @param bool $modifyAttributes + * @param $forgettingFactor + * @param $followerFactor * @return \stdClass * @throws \Exception */ @@ -695,17 +712,18 @@ class APIController extends Controller Population $population, $modifyReputation = false, $type = 'd1', - $modifyAttributes = false + $modifyAttributes = false, + $forgettingFactor, + $followerFactor ) { $startTime = microtime(true); $election = Election::create([ 'population_id' => $population->id, 'type' => $type ]); - $votes = array(); $electionStats = new \stdClass(); - $electionStats->type = "d2"; + $electionStats->type = "d2"; // for chart $asDelegate = 0; $asFollower = 0; $asIndependent = 0; @@ -727,13 +745,17 @@ class APIController extends Controller $votingWeightA = 0; $votingWeightB = 0; + $sumReputationA = 0; + $sumReputationB = 0; foreach ($population->voters as $voter) { $voterWeight = $voter->reputation > 0 ? $voter->reputation : 1; if ($voter->group == "A") { $votingWeightA += $voterWeight; + $sumReputationA += $voter->reputation; } else { $votingWeightB += $voterWeight; + $sumReputationB+= $voter->reputation; } $tresholdFollowing = $voter->following; $tresholdIndependent = $tresholdFollowing + $voter->confidence; @@ -828,11 +850,11 @@ class APIController extends Controller $delegatesSavedVotes[$voterID]->save(); // adjust voter reputation if ($delegatesSavedVotes[$voterID]->vote_final > 0) { - $voter->reputation += (2 * $noOfFollowers); + $voter->reputation += ($followerFactor * $noOfFollowers); if($modifyAttributes && $voter->leadership < 100) $voter->leadership++; } else { - $voter->reputation -= (2 * $noOfFollowers); + $voter->reputation -= ($followerFactor * $noOfFollowers); if($modifyAttributes && $voter->leadership > 1) $voter->leadership--; } @@ -854,11 +876,12 @@ class APIController extends Controller } // balance voter reputation over time between elections - if ($voter->reputation < 0) { + $voter->reputation = round($voter->reputation * $forgettingFactor); + /*if ($voter->reputation < 0) { $voter->reputation++; } elseif ($voter->reputation > 0) { $voter->reputation--; - } + }*/ if ($previousReputation != $voter->reputation) { $voter->save(); @@ -893,7 +916,9 @@ class APIController extends Controller 'as_follower' => $asFollower, 'as_independent' => $asIndependent, 'weight_a' => $votingWeightA, - 'weight_b' => $votingWeightB + 'weight_b' => $votingWeightB, + 'reputation_a' => $sumReputationA, + 'reputation_b' => $sumReputationB ]); DelegationOneVote::insert($followersVotes); @@ -1013,14 +1038,18 @@ class APIController extends Controller $movingAverage = isset($attributes['moving_average']) ? $attributes['moving_average'] : 0; $data->elections_type = $attributes['type']; - $data->no_of_voters = $population->noOfVoters; + + $countA = $population->voters()->where('group', '=', 'A')->count(); + $countB = $population->voters()->where('group', '=', 'B')->count(); + + $data->no_of_voters = $countA + $countB; if ($data->no_of_voters < 1) { return response()->json(['error' => 'No voters in population'], Response::HTTP_NOT_FOUND); } - $countA = $population->voters()->where('group', '=', 'A')->count(); - $countB = $population->voters()->where('group', '=', 'B')->count(); + $data->no_of_voters_a = $countA; + $data->no_of_voters_b = $countB; $elections = Election::where('population_id', '=', $population->id) ->where('type', '=', $attributes['type']) @@ -1031,27 +1060,28 @@ class APIController extends Controller $weightsTimeline = array(); foreach ($elections as $election) { + $weightSum = $election->extension->weight_a + $election->extension->weight_b; $newWeight = new \stdClass(); if ($countA > 0) { - - $newWeight->weight_a = $election->extension->weight_a; + $newWeight->reputation_a = $election->extension->reputation_a; $newWeight->avg_weight_a = $election->extension->weight_a / $countA; } else { - - $newWeight->weight_a = 0; + $newWeight->reputation_a = 0; $newWeight->avg_weight_a = 0; } - if ($countB > 0) { - $newWeight->weight_b = $election->extension->weight_b; + $newWeight->reputation_b = $election->extension->reputation_b; $newWeight->avg_weight_b = $election->extension->weight_b / $countB; + //$newWeight->weight_share_b = 100 * $newWeight->avg_weight_b / ($newWeight->avg_weight_a + $newWeight->avg_weight_b); + $newWeight->weight_share_b = 100 * $election->extension->weight_b / ($election->extension->weight_a + $election->extension->weight_b); } else { - $newWeight->weight_b = 0; + $newWeight->reputation_b = 0; $newWeight->avg_weight_b = 0; + $newWeight->weight_share_b = 0; } array_push($weightsTimeline, $newWeight); } - $data->weigths = $weightsTimeline; + $data->weights = $weightsTimeline; /* if($movingAverage > 0) { $flattenData = []; diff --git a/config/app.php b/config/app.php index 4bd5d6eb6fb19b57adcc75d051f7cf992226b607..0be78c010c6d6a2af609ed54d11dc3c0990c75db 100644 --- a/config/app.php +++ b/config/app.php @@ -229,6 +229,8 @@ return [ ], - 'sign-up' => env('SIGN_UP', false) + 'sign-up' => env('SIGN_UP', false), + 'forgetting_factor' => env('FORGETTING_FACTOR', 0.99), + 'follower_factor' => env('FOLLOWER_FACTOR', 100) ]; diff --git a/database/migrations/2021_03_16_084517_create_extension_delegation_elections_table.php b/database/migrations/2021_03_16_084517_create_extension_delegation_elections_table.php index a3ba374129afb255c426f7c4ed0e05b27c5725ce..48ed50fe98cec036d7bdbd824fdaa9084891d2f4 100644 --- a/database/migrations/2021_03_16_084517_create_extension_delegation_elections_table.php +++ b/database/migrations/2021_03_16_084517_create_extension_delegation_elections_table.php @@ -24,6 +24,8 @@ class CreateExtensionDelegationElectionsTable extends Migration $table->integer('as_independent', false, true)->nullable(false)->default(0); $table->integer('weight_a', false, true)->nullable(false)->default(0); $table->integer('weight_b', false, true)->nullable(false)->default(0); + $table->integer('reputation_a', false, false)->nullable(false)->default(0); + $table->integer('reputation_b', false, false)->nullable(false)->default(0); }); } diff --git a/public/js/app.js b/public/js/app.js index 71714eb9e94365d1943a737e935ce64cfc6221ca..d4d586bf61ad8e51944af9dd4ccf5a3e0c67c4db 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -2921,6 +2921,94 @@ __webpack_require__.r(__webpack_exports__); // // // +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// @@ -2934,6 +3022,12 @@ __webpack_require__.r(__webpack_exports__); }, data: function data() { return { + show_population_stats: true, + show_majority_distribution: false, + show_last_election_chart: false, + show_voters_graph: false, + show_timeline_graph: false, + show_weights_timeline_graph: false, custom_number_elections: 1, current_election_timeline_key: null, election_timeline_selector: [{ @@ -2952,11 +3046,10 @@ __webpack_require__.r(__webpack_exports__); elections_timeline: null, moving_average: 0, auto_fetch_elections_timeline: false, - show_timeline_graph: true, + weights_timeline: null, + auto_fetch_weights_timeline: false, running_elections_lock: false, auto_fetch_voters: false, - show_voters_graph: false, - show_last_election_chart: false, auto_fetch_distribution: false, feedback: null, population_id: route().params.population_id, @@ -3334,6 +3427,58 @@ __webpack_require__.r(__webpack_exports__); yAxisID: 'left-y-axis' }] }; + }, + weights_timeline_chart_data: function weights_timeline_chart_data() { + console.log('computing weights chart data'); + var labels = []; + var avg_weight_a = []; + var avg_weight_b = []; + var reputation_a = []; + var reputation_b = []; + var weight_share_b = []; + this.weights_timeline.weights.forEach(function (value, idx) { + labels.push(idx); + avg_weight_a.push(value.avg_weight_a); + avg_weight_b.push(value.avg_weight_b); + reputation_a.push(value.reputation_a); + reputation_b.push(value.reputation_b); + weight_share_b.push(value.weight_share_b); + }); + return { + labels: labels, + datasets: [{ + label: 'Group A (avg Weight per voter)', + borderColor: '#6b9c3a', + fill: false, + data: avg_weight_a, + yAxisID: 'left-y-axis' + }, { + label: 'Group B (avg Weight per voter)', + borderColor: '#01439b', + fill: false, + data: avg_weight_b, + yAxisID: 'left-y-axis' + }, { + label: 'Group A - Reputation sum', + borderColor: '#929c84', + fill: false, + data: reputation_a, + yAxisID: 'left-y-axis' + }, { + label: 'Group B - Reputation sum', + borderColor: '#6c739b', + fill: false, + data: reputation_b, + yAxisID: 'left-y-axis' + }, { + label: 'Group B - Weight share: wB/(wA+wB)', + borderColor: '#b77959', + backgroundColor: '#b77959', + fill: true, + data: weight_share_b, + yAxisID: 'right-y-axis' + }] + }; } }, methods: { @@ -3378,6 +3523,10 @@ __webpack_require__.r(__webpack_exports__); if (_this3.auto_fetch_elections_timeline) { _this3.fetchElectionsTimeline(); } + + if (_this3.auto_fetch_weights_timeline) { + _this3.fetchWeightsTimeline(); + } })["catch"](function (err) { _this3.feedback = 'population stats fetching error'; }); @@ -3399,10 +3548,10 @@ __webpack_require__.r(__webpack_exports__); number: multi }).then(function (response) { _this4.feedback = 'voting done, fetching updated population stats..'; + console.log(_this4); _this4.fetchPopulationStats(); - console.log(response.data); _this4.last_elections_data = response.data; _this4.running_elections_lock = false; })["catch"](function (err) { @@ -3458,6 +3607,25 @@ __webpack_require__.r(__webpack_exports__); })["catch"](function (err) { _this7.feedback = 'election timeline fetching error'; }); + }, + fetchWeightsTimeline: function fetchWeightsTimeline() { + var _this8 = this; + + console.log(this.current_election_timeline_key); + axios.get(route('internal.api.population.get.weights.timeline', { + "template": this.template_id, + "population": this.population_id + }), { + params: { + 'type': this.current_election_timeline_key.value, + 'moving_average': this.moving_average + } + }).then(function (response) { + _this8.weights_timeline = response.data; + _this8.feedback = 'weights timeline fetched'; + })["catch"](function (err) { + _this8.feedback = 'weights timeline fetching error'; + }); } } }); @@ -79623,30 +79791,58 @@ var render = function() { ? _c("div", { staticClass: "card-body" }, [ _vm.population_stats.stage === "l" ? _c("div", [ - _c("h5", [_vm._v("Learning stage")]), + _c("h5", [ + _vm._v( + "Learning stage (" + _vm._s(_vm.election_name) + ")" + ) + ]), _vm._v(" "), - _vm.population_stats.stage === "l" - ? _c( - "button", - { - on: { - click: function($event) { - $event.preventDefault() - return _vm.switchToPerformanceStage() + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _vm.population_stats.stage === "l" + ? _c( + "button", + { + on: { + click: function($event) { + $event.preventDefault() + return _vm.switchToPerformanceStage() + } } - } - }, - [ - _vm._v( - "\n Finish Learning stage\n " - ) - ] - ) - : _vm._e(), + }, + [ + _vm._v( + "\n Finish Learning stage\n " + ) + ] + ) + : _vm._e() + ]), _vm._v(" "), - _c("h5", [_vm._v(_vm._s(_vm.election_name) + ":")]), + _c("h5", [_vm._v("Reputation modifiers:")]), _vm._v(" "), - _c("div", [ + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c("ul", [ + _c("li", { staticClass: "text-info" }, [ + _vm._v( + "Forgetting percent: " + + _vm._s( + _vm.population_stats.forgetting_percent + ) + ) + ]), + _vm._v(" "), + _c("li", { staticClass: "text-info" }, [ + _vm._v( + "Follower multiplier: " + + _vm._s(_vm.population_stats.follower_factor) + ) + ]) + ]) + ]), + _vm._v(" "), + _c("h5", [_vm._v("Elections")]), + _vm._v(" "), + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ _c("label", { staticClass: "text-info" }, [ _vm._v("Number of elections: ") ]), @@ -79677,51 +79873,47 @@ var render = function() { $event.target.value } } - }) - ]), - _vm._v(" "), - _c( - "button", - { - staticClass: "btn btn-sm btn-outline-info", - attrs: { disabled: _vm.running_elections_lock }, - on: { - click: function($event) { - $event.preventDefault() - return _vm.runElections( - _vm.population_stats.election_type, - _vm.custom_number_elections - ) + }), + _vm._v(" "), + _c( + "button", + { + staticClass: "btn btn-sm btn-outline-info", + attrs: { disabled: _vm.running_elections_lock }, + on: { + click: function($event) { + $event.preventDefault() + return _vm.runElections( + _vm.population_stats.election_type, + _vm.custom_number_elections + ) + } } - } - }, - [ - _vm._v( - "\n Run " + - _vm._s(_vm.custom_number_elections) + - " election" - ), - _vm.custom_number_elections > 1 - ? _c("span", [_vm._v("s")]) - : _vm._e(), - _vm._v(" "), - _c("i", [ + }, + [ _vm._v( - "(" + - _vm._s(_vm.population_stats.election_type) + - ")" - ) - ]) - ] - ), - _vm._v(" "), - _c("hr") + "\n Run " + + _vm._s(_vm.custom_number_elections) + + " election" + ), + _vm.custom_number_elections > 1 + ? _c("span", [_vm._v("s")]) + : _vm._e() + ] + ) + ]) ]) : _vm.population_stats.stage === "p" ? _c("div", [ - _c("h5", [_vm._v("Performance stage")]), + _c("h5", [ + _vm._v( + "Performance stage (" + + _vm._s(_vm.election_name) + + ")" + ) + ]), _vm._v(" "), - _c("h5", [_vm._v(_vm._s(_vm.election_name) + ":")]), + _c("h5", [_vm._v("Elections")]), _vm._v(" "), _c("div", [ _c("label", { staticClass: "text-info" }, [ @@ -79754,135 +79946,63 @@ var render = function() { $event.target.value } } - }) - ]), - _vm._v(" "), - _c( - "button", - { - staticClass: "btn btn-sm btn-outline-info", - attrs: { disabled: _vm.running_elections_lock }, - on: { - click: function($event) { - $event.preventDefault() - return _vm.runElections( - "d1", - _vm.custom_number_elections - ) + }), + _vm._v(" "), + _c( + "button", + { + staticClass: "btn btn-sm btn-outline-info", + attrs: { disabled: _vm.running_elections_lock }, + on: { + click: function($event) { + $event.preventDefault() + return _vm.runElections( + "d1", + _vm.custom_number_elections + ) + } } - } - }, - [ - _vm._v( - "\n Run " + - _vm._s(_vm.custom_number_elections) + - " election" - ), - _vm.custom_number_elections > 1 - ? _c("span", [_vm._v("s")]) - : _vm._e(), - _vm._v(" "), - _c("i", [_vm._v("(type d1)")]) - ] - ), - _vm._v(" "), - _c("hr") + }, + [ + _vm._v( + "\n Run " + + _vm._s(_vm.custom_number_elections) + + " election" + ), + _vm.custom_number_elections > 1 + ? _c("span", [_vm._v("s")]) + : _vm._e() + ] + ) + ]) ]) : _c("div", [ _c("i", { staticClass: "text-warning" }, [ _vm._v("Unrecognized stage code.") ]) - ]) - ]) - : _c("div", [ - _c("i", [ - _vm._v( - "Population stage not defined. Cannot run elections." - ) - ]) - ]) - ]) - ]) - ]), - _vm._v(" "), - _c("div", { staticClass: "col-md-9 col-lg-9" }, [ - _c("div", { staticClass: "row" }, [ - _vm.feedback - ? _c( - "div", - { staticClass: "alert alert-info col-md-12 col-lg-12" }, - [ - _vm._v( - "\n INFO: " + - _vm._s(_vm.feedback) + - "\n " - ), - _c( - "button", - { - staticClass: "float-right btn btn-sm btn-outline-info", - on: { - click: function($event) { - $event.preventDefault() - return _vm.resetFeedback($event) - } - } - }, - [_vm._v("x")] - ) - ] - ) - : _vm._e() - ]), - _vm._v(" "), - _c("div", { staticClass: "row mt-1" }, [ - _c("div", { staticClass: "col-md-12" }, [ - _c("div", { staticClass: "card" }, [ - _c("div", { staticClass: "card-header" }, [ - _vm._v("Voters' attributes charts") - ]), - _vm._v(" "), - _c("div", { staticClass: "card-body" }, [ - _c("div", { staticClass: "row" }, [ - _c("div", { staticClass: "col-md-4" }, [ - _c( - "button", - { - staticClass: "btn btn-sm btn-outline-info", - on: { - click: function($event) { - $event.preventDefault() - return _vm.fetchPopulationDetails($event) - } - } - }, - [_vm._v("Fetch Voters Data")] - ) - ]), + ]), _vm._v(" "), - _c("div", { staticClass: "col-md-4" }, [ - _c("label", { staticClass: "text-info" }, [ - _vm._v("Auto update voters' details after election") - ]), - _vm._v(" "), + _c("h5", [_vm._v("Chart display options")]), + _vm._v(" "), + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ _c("input", { directives: [ { name: "model", rawName: "v-model", - value: _vm.auto_fetch_voters, - expression: "auto_fetch_voters" + value: _vm.show_population_stats, + expression: "show_population_stats" } ], attrs: { type: "checkbox" }, domProps: { - checked: Array.isArray(_vm.auto_fetch_voters) - ? _vm._i(_vm.auto_fetch_voters, null) > -1 - : _vm.auto_fetch_voters + checked: Array.isArray(_vm.show_population_stats) + ? _vm._i(_vm.show_population_stats, null) > -1 + : _vm.show_population_stats }, on: { change: function($event) { - var $$a = _vm.auto_fetch_voters, + var $$a = _vm.show_population_stats, $$el = $event.target, $$c = $$el.checked ? true : false if (Array.isArray($$a)) { @@ -79890,26 +80010,73 @@ var render = function() { $$i = _vm._i($$a, $$v) if ($$el.checked) { $$i < 0 && - (_vm.auto_fetch_voters = $$a.concat([$$v])) + (_vm.show_population_stats = $$a.concat([$$v])) } else { $$i > -1 && - (_vm.auto_fetch_voters = $$a + (_vm.show_population_stats = $$a .slice(0, $$i) .concat($$a.slice($$i + 1))) } } else { - _vm.auto_fetch_voters = $$c + _vm.show_population_stats = $$c } } } - }) + }), + _vm._v(" "), + _c("label", { staticClass: "text-info" }, [ + _vm._v("Show population stats") + ]) ]), _vm._v(" "), - _c("div", { staticClass: "col-md-4" }, [ - _c("label", { staticClass: "text-info" }, [ - _vm._v("Show voters graph") - ]), + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.show_last_election_chart, + expression: "show_last_election_chart" + } + ], + attrs: { type: "checkbox" }, + domProps: { + checked: Array.isArray(_vm.show_last_election_chart) + ? _vm._i(_vm.show_last_election_chart, null) > -1 + : _vm.show_last_election_chart + }, + on: { + change: function($event) { + var $$a = _vm.show_last_election_chart, + $$el = $event.target, + $$c = $$el.checked ? true : false + if (Array.isArray($$a)) { + var $$v = null, + $$i = _vm._i($$a, $$v) + if ($$el.checked) { + $$i < 0 && + (_vm.show_last_election_chart = $$a.concat([ + $$v + ])) + } else { + $$i > -1 && + (_vm.show_last_election_chart = $$a + .slice(0, $$i) + .concat($$a.slice($$i + 1))) + } + } else { + _vm.show_last_election_chart = $$c + } + } + } + }), _vm._v(" "), + _c("label", { staticClass: "text-info" }, [ + _vm._v("Show last elections chart") + ]) + ]), + _vm._v(" "), + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ _c("input", { directives: [ { @@ -79947,666 +80114,998 @@ var render = function() { } } } + }), + _vm._v(" "), + _c("label", { staticClass: "text-info" }, [ + _vm._v("Show voters graph") + ]) + ]), + _vm._v(" "), + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.show_timeline_graph, + expression: "show_timeline_graph" + } + ], + attrs: { type: "checkbox" }, + domProps: { + checked: Array.isArray(_vm.show_timeline_graph) + ? _vm._i(_vm.show_timeline_graph, null) > -1 + : _vm.show_timeline_graph + }, + on: { + change: function($event) { + var $$a = _vm.show_timeline_graph, + $$el = $event.target, + $$c = $$el.checked ? true : false + if (Array.isArray($$a)) { + var $$v = null, + $$i = _vm._i($$a, $$v) + if ($$el.checked) { + $$i < 0 && + (_vm.show_timeline_graph = $$a.concat([$$v])) + } else { + $$i > -1 && + (_vm.show_timeline_graph = $$a + .slice(0, $$i) + .concat($$a.slice($$i + 1))) + } + } else { + _vm.show_timeline_graph = $$c + } + } + } + }), + _vm._v(" "), + _c("label", { staticClass: "text-info" }, [ + _vm._v("Show timeline graph (results)") + ]) + ]), + _vm._v(" "), + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.show_weights_timeline_graph, + expression: "show_weights_timeline_graph" + } + ], + attrs: { type: "checkbox" }, + domProps: { + checked: Array.isArray(_vm.show_weights_timeline_graph) + ? _vm._i(_vm.show_weights_timeline_graph, null) > -1 + : _vm.show_weights_timeline_graph + }, + on: { + change: function($event) { + var $$a = _vm.show_weights_timeline_graph, + $$el = $event.target, + $$c = $$el.checked ? true : false + if (Array.isArray($$a)) { + var $$v = null, + $$i = _vm._i($$a, $$v) + if ($$el.checked) { + $$i < 0 && + (_vm.show_weights_timeline_graph = $$a.concat([ + $$v + ])) + } else { + $$i > -1 && + (_vm.show_weights_timeline_graph = $$a + .slice(0, $$i) + .concat($$a.slice($$i + 1))) + } + } else { + _vm.show_weights_timeline_graph = $$c + } + } + } + }), + _vm._v(" "), + _c("label", { staticClass: "text-info" }, [ + _vm._v("Show timeline graph (weights)") + ]) + ]) + ]) + : _c("div", [ + _c("i", [ + _vm._v( + "Population stage not defined. Cannot run elections." + ) + ]) + ]) + ]), + _vm._v(" "), + _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v("Voters' attributes charts") + ]), + _vm._v(" "), + _c("div", { staticClass: "card-body" }, [ + _c("div", { staticClass: "row" }, [ + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.auto_fetch_voters, + expression: "auto_fetch_voters" + } + ], + attrs: { type: "checkbox" }, + domProps: { + checked: Array.isArray(_vm.auto_fetch_voters) + ? _vm._i(_vm.auto_fetch_voters, null) > -1 + : _vm.auto_fetch_voters + }, + on: { + change: function($event) { + var $$a = _vm.auto_fetch_voters, + $$el = $event.target, + $$c = $$el.checked ? true : false + if (Array.isArray($$a)) { + var $$v = null, + $$i = _vm._i($$a, $$v) + if ($$el.checked) { + $$i < 0 && + (_vm.auto_fetch_voters = $$a.concat([$$v])) + } else { + $$i > -1 && + (_vm.auto_fetch_voters = $$a + .slice(0, $$i) + .concat($$a.slice($$i + 1))) + } + } else { + _vm.auto_fetch_voters = $$c + } + } + } + }), + _vm._v(" "), + _c("label", { staticClass: "text-info" }, [ + _vm._v("Auto update voters' details after election") + ]) + ]), + _vm._v(" "), + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c( + "button", + { + staticClass: "btn btn-sm btn-outline-info", + on: { + click: function($event) { + $event.preventDefault() + return _vm.fetchPopulationDetails($event) + } + } + }, + [_vm._v("Fetch Voters Data")] + ) + ]) + ]) + ]) + ]), + _vm._v(" "), + _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v("Elections timeline (type selector)") + ]), + _vm._v(" "), + _c("div", { staticClass: "card-body" }, [ + _c("div", { staticClass: "row" }, [ + _c( + "div", + { staticClass: "col-md-12 col-lg-12" }, + [ + _c("v-select", { + attrs: { + options: _vm.election_timeline_selector, + id: "election_timeline_selector", + placeholder: "Choose election type", + label: "text" + }, + model: { + value: _vm.current_election_timeline_key, + callback: function($$v) { + _vm.current_election_timeline_key = $$v + }, + expression: "current_election_timeline_key" + } }) + ], + 1 + ) + ]) + ]) + ]), + _vm._v(" "), + _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v("Elections timeline (results)") + ]), + _vm._v(" "), + _c("div", { staticClass: "card-body" }, [ + _c("div", { staticClass: "row" }, [ + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c("label", { staticClass: "text-info" }, [ + _vm._v("Moving average") + ]), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.moving_average, + expression: "moving_average" + } + ], + staticStyle: { width: "70px" }, + attrs: { type: "number", min: "0", step: "1" }, + domProps: { value: _vm.moving_average }, + on: { + input: function($event) { + if ($event.target.composing) { + return + } + _vm.moving_average = $event.target.value + } + } + }) + ]), + _vm._v(" "), + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.auto_fetch_elections_timeline, + expression: "auto_fetch_elections_timeline" + } + ], + attrs: { type: "checkbox" }, + domProps: { + checked: Array.isArray(_vm.auto_fetch_elections_timeline) + ? _vm._i(_vm.auto_fetch_elections_timeline, null) > -1 + : _vm.auto_fetch_elections_timeline + }, + on: { + change: function($event) { + var $$a = _vm.auto_fetch_elections_timeline, + $$el = $event.target, + $$c = $$el.checked ? true : false + if (Array.isArray($$a)) { + var $$v = null, + $$i = _vm._i($$a, $$v) + if ($$el.checked) { + $$i < 0 && + (_vm.auto_fetch_elections_timeline = $$a.concat([ + $$v + ])) + } else { + $$i > -1 && + (_vm.auto_fetch_elections_timeline = $$a + .slice(0, $$i) + .concat($$a.slice($$i + 1))) + } + } else { + _vm.auto_fetch_elections_timeline = $$c + } + } + } + }), + _vm._v(" "), + _c("label", { staticClass: "text-info" }, [ + _vm._v("Auto update timeline after election") ]) ]), _vm._v(" "), - _vm.voters_fetched - ? _c("div", [ - _vm.show_voters_graph - ? _c( - "div", - [ - _c("line-chart", { - attrs: { - "chart-data": _vm.voters_chart_data, - options: _vm.voters_chart_options, - styles: _vm.h_300_chart_styles - } - }) - ], - 1 - ) - : _c("i", [_vm._v("select show graph")]) - ]) - : _c("div", [_c("i", [_vm._v("N/A")])]) + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c( + "button", + { + staticClass: "btn-xs", + class: { + "btn-primary": _vm.current_election_timeline_key + }, + attrs: { disabled: !_vm.current_election_timeline_key }, + on: { + click: function($event) { + $event.preventDefault() + return _vm.fetchElectionsTimeline($event) + } + } + }, + [ + _vm.current_election_timeline_key + ? _c("i", [ + _vm._v( + "Fetch " + + _vm._s(_vm.current_election_timeline_key.text) + + " results timeline" + ) + ]) + : _c("i", [_vm._v("Select election type")]) + ] + ) + ]) + ]) + ]) + ]), + _vm._v(" "), + _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v("Elections timeline (weights)") + ]), + _vm._v(" "), + _c("div", { staticClass: "card-body" }, [ + _c("div", { staticClass: "row" }, [ + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.auto_fetch_weights_timeline, + expression: "auto_fetch_weights_timeline" + } + ], + attrs: { type: "checkbox" }, + domProps: { + checked: Array.isArray(_vm.auto_fetch_weights_timeline) + ? _vm._i(_vm.auto_fetch_weights_timeline, null) > -1 + : _vm.auto_fetch_weights_timeline + }, + on: { + change: function($event) { + var $$a = _vm.auto_fetch_weights_timeline, + $$el = $event.target, + $$c = $$el.checked ? true : false + if (Array.isArray($$a)) { + var $$v = null, + $$i = _vm._i($$a, $$v) + if ($$el.checked) { + $$i < 0 && + (_vm.auto_fetch_weights_timeline = $$a.concat([ + $$v + ])) + } else { + $$i > -1 && + (_vm.auto_fetch_weights_timeline = $$a + .slice(0, $$i) + .concat($$a.slice($$i + 1))) + } + } else { + _vm.auto_fetch_weights_timeline = $$c + } + } + } + }), + _vm._v(" "), + _c("label", { staticClass: "text-info" }, [ + _vm._v("Auto update weights timeline after election") + ]) + ]), + _vm._v(" "), + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c( + "button", + { + staticClass: "btn-xs", + class: { + "btn-primary": _vm.current_election_timeline_key + }, + attrs: { disabled: !_vm.current_election_timeline_key }, + on: { + click: function($event) { + $event.preventDefault() + return _vm.fetchWeightsTimeline($event) + } + } + }, + [ + _vm.current_election_timeline_key + ? _c("i", [ + _vm._v( + "Fetch " + + _vm._s(_vm.current_election_timeline_key.text) + + " weights timeline" + ) + ]) + : _c("i", [_vm._v("Select election type")]) + ] + ) + ]) ]) ]) ]) + ]) + ]), + _vm._v(" "), + _c("div", { staticClass: "col-md-9 col-lg-9" }, [ + _c("div", { staticClass: "row mt-1" }, [ + _vm.feedback + ? _c( + "div", + { staticClass: "alert alert-info col-md-12 col-lg-12" }, + [ + _c( + "button", + { + staticClass: "btn btn-sm btn-outline-info", + on: { + click: function($event) { + $event.preventDefault() + return _vm.resetFeedback($event) + } + } + }, + [_vm._v("x")] + ), + _vm._v( + "\n INFO: " + + _vm._s(_vm.feedback) + + "\n " + ) + ] + ) + : _vm._e() ]), _vm._v(" "), + _vm.population_stats + ? _c("div", { staticClass: "row mt-1" }, [ + _c("div", { staticClass: "col-md-12" }, [ + _vm.show_voters_graph + ? _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v("Voters' attributes charts") + ]), + _vm._v(" "), + _c("div", { staticClass: "card-body" }, [ + _vm.voters_fetched + ? _c("div", [ + _vm.show_voters_graph + ? _c( + "div", + [ + _c("line-chart", { + attrs: { + "chart-data": _vm.voters_chart_data, + options: _vm.voters_chart_options, + styles: _vm.h_300_chart_styles + } + }) + ], + 1 + ) + : _c("i", [_vm._v("select show graph")]) + ]) + : _c("div", [_c("i", [_vm._v("N/A")])]) + ]) + ]) + : _vm._e() + ]) + ]) + : _vm._e(), + _vm._v(" "), _vm.population_stats ? _c("div", { staticClass: "row mt-1" }, [ _c("div", { staticClass: "col-md-12 col-lg-12" }, [ - _c("div", { staticClass: "card" }, [ - _c("div", { staticClass: "card-header" }, [ - _vm._v("Elections timeline") - ]), - _vm._v(" "), - _c("div", { staticClass: "card-body" }, [ - _c("div", [ - _c("div", { staticClass: "row" }, [ - _c( - "div", - { staticClass: "col-md-4" }, - [ - _c("v-select", { - attrs: { - options: _vm.election_timeline_selector, - id: "election_timeline_selector", - placeholder: "Choose election type", - label: "text" - }, - model: { - value: _vm.current_election_timeline_key, - callback: function($$v) { - _vm.current_election_timeline_key = $$v - }, - expression: "current_election_timeline_key" - } - }), - _vm._v(" "), - _c("br"), - _vm._v(" "), - _c( - "button", - { - staticClass: "btn-xs", - class: { - "btn-primary": - _vm.current_election_timeline_key - }, - attrs: { - disabled: !_vm.current_election_timeline_key - }, - on: { - click: function($event) { - $event.preventDefault() - return _vm.fetchElectionsTimeline($event) - } - } - }, - [ - _vm.current_election_timeline_key - ? _c("i", [ - _vm._v( - "Fetch " + - _vm._s( - _vm.current_election_timeline_key - .text - ) + - " timeline" - ) - ]) - : _c("i", [_vm._v("Select election type")]) - ] - ) - ], - 1 - ), - _vm._v(" "), - _c("div", { staticClass: "col-md-4" }, [ - _c("label", { staticClass: "text-info" }, [ - _vm._v("Auto update timeline after election") - ]), - _vm._v(" "), - _c("input", { - directives: [ - { - name: "model", - rawName: "v-model", - value: _vm.auto_fetch_elections_timeline, - expression: "auto_fetch_elections_timeline" - } - ], - attrs: { type: "checkbox" }, - domProps: { - checked: Array.isArray( - _vm.auto_fetch_elections_timeline - ) - ? _vm._i( - _vm.auto_fetch_elections_timeline, - null - ) > -1 - : _vm.auto_fetch_elections_timeline - }, - on: { - change: function($event) { - var $$a = _vm.auto_fetch_elections_timeline, - $$el = $event.target, - $$c = $$el.checked ? true : false - if (Array.isArray($$a)) { - var $$v = null, - $$i = _vm._i($$a, $$v) - if ($$el.checked) { - $$i < 0 && - (_vm.auto_fetch_elections_timeline = $$a.concat( - [$$v] - )) - } else { - $$i > -1 && - (_vm.auto_fetch_elections_timeline = $$a - .slice(0, $$i) - .concat($$a.slice($$i + 1))) - } - } else { - _vm.auto_fetch_elections_timeline = $$c - } - } - } - }), - _vm._v(" "), - _c("br"), - _vm._v(" "), - _c("label", { staticClass: "text-info" }, [ - _vm._v("Moving average") - ]), - _vm._v(" "), - _c("input", { - directives: [ - { - name: "model", - rawName: "v-model", - value: _vm.moving_average, - expression: "moving_average" - } - ], - staticStyle: { width: "70px" }, - attrs: { type: "number", min: "0", step: "1" }, - domProps: { value: _vm.moving_average }, - on: { - input: function($event) { - if ($event.target.composing) { - return - } - _vm.moving_average = $event.target.value - } - } - }) - ]), - _vm._v(" "), - _c("div", { staticClass: "col-md-4" }, [ - _c("label", { staticClass: "text-info" }, [ - _vm._v("Show timeline graph") - ]), - _vm._v(" "), - _c("input", { - directives: [ - { - name: "model", - rawName: "v-model", - value: _vm.show_timeline_graph, - expression: "show_timeline_graph" - } - ], - attrs: { type: "checkbox" }, - domProps: { - checked: Array.isArray(_vm.show_timeline_graph) - ? _vm._i(_vm.show_timeline_graph, null) > -1 - : _vm.show_timeline_graph - }, - on: { - change: function($event) { - var $$a = _vm.show_timeline_graph, - $$el = $event.target, - $$c = $$el.checked ? true : false - if (Array.isArray($$a)) { - var $$v = null, - $$i = _vm._i($$a, $$v) - if ($$el.checked) { - $$i < 0 && - (_vm.show_timeline_graph = $$a.concat([ - $$v - ])) - } else { - $$i > -1 && - (_vm.show_timeline_graph = $$a - .slice(0, $$i) - .concat($$a.slice($$i + 1))) - } - } else { - _vm.show_timeline_graph = $$c - } - } - } - }) - ]) + _vm.show_timeline_graph + ? _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v("Elections timeline (results)") ]), _vm._v(" "), - _c("hr"), + _c("div", { staticClass: "card-body" }, [ + _vm.elections_timeline + ? _c("div", [ + _c("hr"), + _vm._v( + "\n Election type: " + ), + _c("i", [ + _vm._v( + _vm._s(_vm.elections_timeline.elections_type) + ) + ]), + _vm._v( + ",\n Number of elections: " + ), + _c("i", [ + _vm._v( + _vm._s(_vm.elections_timeline.no_of_elections) + ) + ]), + _vm._v( + ",\n Number of voters: " + ), + _c("i", [ + _vm._v( + _vm._s(_vm.elections_timeline.no_of_voters) + ) + ]), + _vm._v(" "), + _vm.show_timeline_graph + ? _c( + "div", + [ + _c("line-chart", { + attrs: { + "chart-data": + _vm.election_timeline_chart_data, + options: { + maintainAspectRatio: false, + scales: { + yAxes: [ + { + id: "left-y-axis", + type: "linear", + position: "left", + ticks: { min: 0, max: 100 } + } + ] + } + }, + styles: _vm.h_500_chart_styles + } + }) + ], + 1 + ) + : _c("div", [ + _c("i", [_vm._v("select show graph")]) + ]) + ]) + : _c("div", [_c("i", [_vm._v("N/A")])]) + ]) + ]) + : _vm._e(), + _vm._v(" "), + _vm.show_weights_timeline_graph + ? _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v("Elections timeline (weights)") + ]), _vm._v(" "), - _vm.elections_timeline - ? _c("div", [ - _vm._v( - "\n Election type: " - ), - _c("i", [ + _c("div", { staticClass: "card-body" }, [ + _vm.weights_timeline + ? _c("div", [ + _c("hr"), _vm._v( - _vm._s(_vm.elections_timeline.elections_type) - ) - ]), - _vm._v( - ",\n Number of elections: " - ), - _c("i", [ + "\n Election type: " + ), + _c("i", [ + _vm._v( + _vm._s(_vm.weights_timeline.elections_type) + ) + ]), _vm._v( - _vm._s(_vm.elections_timeline.no_of_elections) - ) - ]), - _vm._v( - ",\n Number of voters: " - ), - _c("i", [ + ",\n Number of elections: " + ), + _c("i", [ + _vm._v( + _vm._s(_vm.weights_timeline.no_of_elections) + ) + ]), _vm._v( - _vm._s(_vm.elections_timeline.no_of_voters) - ) - ]), - _vm._v(" "), - _vm.show_timeline_graph - ? _c( - "div", - [ - _c("line-chart", { - attrs: { - "chart-data": - _vm.election_timeline_chart_data, - options: { - maintainAspectRatio: false, - scales: { - yAxes: [ - { - id: "left-y-axis", - type: "linear", - position: "left", - ticks: { min: 0, max: 100 } - } - ] - } - }, - styles: _vm.h_500_chart_styles - } - }) - ], - 1 + ",\n Number of voters: " + ), + _c("i", [ + _vm._v( + _vm._s(_vm.weights_timeline.no_of_voters) + + " (A:" + + _vm._s( + _vm.weights_timeline.no_of_voters_a + ) + + ", B:" + + _vm._s( + _vm.weights_timeline.no_of_voters_b + ) + + ")" ) - : _c("div", [ - _c("i", [_vm._v("select show graph")]) - ]) - ]) - : _c("div", [_c("i", [_vm._v("N/A")])]) + ]), + _vm._v(" "), + _vm.show_weights_timeline_graph + ? _c( + "div", + [ + _c("h5", [ + _vm._v( + "Timeline for delegation weights" + ) + ]), + _vm._v(" "), + _c("line-chart", { + attrs: { + "chart-data": + _vm.weights_timeline_chart_data, + options: { + maintainAspectRatio: false, + scales: { + yAxes: [ + { + id: "left-y-axis", + type: "linear", + position: "left" + }, + { + id: "right-y-axis", + type: "linear", + position: "right", + ticks: { min: 0, max: 100 } + } + ] + } + }, + styles: _vm.h_500_chart_styles + } + }) + ], + 1 + ) + : _c("div", [ + _c("i", [_vm._v("select show graph")]) + ]) + ]) + : _c("div", [_c("i", [_vm._v("N/A")])]) + ]) ]) - ]) - ]) + : _vm._e() ]) ]) : _vm._e(), _vm._v(" "), - _c("div", { staticClass: "row mt-2" }, [ - _c("div", { staticClass: "col-md-6 col-lg-6 col-sm-6" }, [ - _vm.population_stats - ? _c("div", { staticClass: "row mt-1" }, [ - _c("div", { staticClass: "col-md-6 col-lg-6" }, [ - _c("div", { staticClass: "card" }, [ - _c("div", { staticClass: "card-header" }, [ - _vm._v("Election stats") - ]), - _vm._v(" "), - _vm.population_stats.elections_stats - ? _c( - "div", - { staticClass: "card-body" }, - [ - _c("bar-chart", { - attrs: { - "chart-data": - _vm.population_election_stats_chart_data, - options: { - maintainAspectRatio: true, - scales: { - yAxes: [ - { - id: "left-y-axis", - type: "linear", - position: "left", - ticks: { min: 0, max: 100 } + _c("div", { staticClass: "row mt-1" }, [ + _vm.show_population_stats + ? _c("div", { staticClass: "col-md-6 col-lg-6 col-sm-6" }, [ + _vm.population_stats + ? _c("div", { staticClass: "row mt-1" }, [ + _c("div", { staticClass: "col-md-6 col-lg-6" }, [ + _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v("Election stats") + ]), + _vm._v(" "), + _vm.population_stats.elections_stats + ? _c( + "div", + { staticClass: "card-body" }, + [ + _c("bar-chart", { + attrs: { + "chart-data": + _vm.population_election_stats_chart_data, + options: { + maintainAspectRatio: true, + scales: { + yAxes: [ + { + id: "left-y-axis", + type: "linear", + position: "left", + ticks: { min: 0, max: 100 } + } + ] } - ] + } } - } - } - }) - ], - 1 - ) - : _c("div", { staticClass: "card-body" }, [ - _c("i", [_vm._v("N/A")]) - ]) - ]) - ]), - _vm._v(" "), - _c("div", { staticClass: "col-md-6 col-lg-6" }, [ - _c("div", { staticClass: "card" }, [ - _c("div", { staticClass: "card-header" }, [ - _vm._v("Voters stats") + }) + ], + 1 + ) + : _c("div", { staticClass: "card-body" }, [ + _c("i", [_vm._v("N/A")]) + ]) + ]) ]), _vm._v(" "), - _vm.population_stats.voters_stats - ? _c( - "div", - { staticClass: "card-body" }, - [ - _c("bar-chart", { - attrs: { - "chart-data": - _vm.population_voters_stats_chart_data, - options: { - maintainAspectRatio: true, - scales: { - yAxes: [ - { - id: "left-y-axis", - type: "linear", - position: "left", - ticks: { min: 0, max: 100 } + _c("div", { staticClass: "col-md-6 col-lg-6" }, [ + _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v("Voters stats") + ]), + _vm._v(" "), + _vm.population_stats.voters_stats + ? _c( + "div", + { staticClass: "card-body" }, + [ + _c("bar-chart", { + attrs: { + "chart-data": + _vm.population_voters_stats_chart_data, + options: { + maintainAspectRatio: true, + scales: { + yAxes: [ + { + id: "left-y-axis", + type: "linear", + position: "left", + ticks: { min: 0, max: 100 } + } + ] } - ] + } + } + }) + ], + 1 + ) + : _c("div", { staticClass: "card-body" }, [ + _c("i", [_vm._v("N/A")]) + ]) + ]) + ]) + ]) + : _vm._e(), + _vm._v(" "), + _vm.show_majority_distribution + ? _c("div", { staticClass: "row mt-1" }, [ + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v("Majority elections distribution") + ]), + _vm._v(" "), + _c("div", { staticClass: "card-body" }, [ + _c("div", [ + _c("label", { staticClass: "text-info" }, [ + _vm._v( + "Auto update ME distribution after elections" + ) + ]), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.auto_fetch_distribution, + expression: "auto_fetch_distribution" + } + ], + attrs: { type: "checkbox" }, + domProps: { + checked: Array.isArray( + _vm.auto_fetch_distribution + ) + ? _vm._i( + _vm.auto_fetch_distribution, + null + ) > -1 + : _vm.auto_fetch_distribution + }, + on: { + change: function($event) { + var $$a = _vm.auto_fetch_distribution, + $$el = $event.target, + $$c = $$el.checked ? true : false + if (Array.isArray($$a)) { + var $$v = null, + $$i = _vm._i($$a, $$v) + if ($$el.checked) { + $$i < 0 && + (_vm.auto_fetch_distribution = $$a.concat( + [$$v] + )) + } else { + $$i > -1 && + (_vm.auto_fetch_distribution = $$a + .slice(0, $$i) + .concat($$a.slice($$i + 1))) + } + } else { + _vm.auto_fetch_distribution = $$c } } } }) - ], - 1 - ) - : _c("div", { staticClass: "card-body" }, [ - _c("i", [_vm._v("N/A")]) + ]), + _vm._v(" "), + _vm.me_distribution_metadata + ? _c("div", [ + _vm.majority_elections_distribution + ? _c("div", [ + _c( + "div", + { staticClass: "row" }, + [ + _c("bar-chart", { + staticClass: "col-md-6", + attrs: { + "chart-data": _vm.me_chart_data, + options: { + maintainAspectRatio: true + } + } + }), + _vm._v(" "), + _c("bar-chart", { + staticClass: "col-md-6", + attrs: { + "chart-data": + _vm.me_chart_data_r_10, + options: { + maintainAspectRatio: true + } + } + }) + ], + 1 + ), + _vm._v(" "), + _c("div", [ + _vm._v( + "\n Number of elections: " + ), + _c("i", [ + _vm._v( + _vm._s( + _vm.me_distribution_metadata + .number_of_elections + ) + ) + ]), + _vm._v(" "), + _c("br"), + _vm._v( + "\n Total time: " + ), + _c("i", [ + _vm._v( + _vm._s( + _vm.me_distribution_metadata + .total_time + ) + ) + ]), + _vm._v(" "), + _c("br"), + _vm._v( + "\n Distribution of correct choices percentage in " + + _vm._s( + _vm.me_distribution_metadata + .number_of_elections + ) + + " elections:\n " + ), + _c("br"), + _vm._v( + "\n Charts: Majority Elections correct answers distribution (grouped by 1 and 10 percent)\n " + ), + _c("br"), + _vm._v( + "\n (by 1): " + + _vm._s( + _vm.majority_elections_distribution + ) + + "\n " + ), + _c("br"), + _vm._v( + "\n (by 10): " + + _vm._s( + _vm.majority_elections_distribution_r_10 + ) + + "\n " + ) + ]) + ]) + : _vm._e() + ]) + : _c("div", [ + _c("i", [ + _vm._v("N/A (fetch distribution first)") + ]) + ]) ]) + ]) + ]) ]) - ]) - ]) - : _vm._e(), - _vm._v(" "), - _c("div", { staticClass: "row mt-1" }, [ - _c("div", { staticClass: "col-md-12 col-lg-12" }, [ - _c("div", { staticClass: "card" }, [ - _c("div", { staticClass: "card-header" }, [ - _vm._v("Majority elections distribution") - ]), - _vm._v(" "), - _c("div", { staticClass: "card-body" }, [ - _c("div", [ - _c("label", { staticClass: "text-info" }, [ - _vm._v("Auto update ME distribution after elections") - ]), - _vm._v(" "), - _c("input", { - directives: [ - { - name: "model", - rawName: "v-model", - value: _vm.auto_fetch_distribution, - expression: "auto_fetch_distribution" - } - ], - attrs: { type: "checkbox" }, - domProps: { - checked: Array.isArray(_vm.auto_fetch_distribution) - ? _vm._i(_vm.auto_fetch_distribution, null) > -1 - : _vm.auto_fetch_distribution - }, - on: { - change: function($event) { - var $$a = _vm.auto_fetch_distribution, - $$el = $event.target, - $$c = $$el.checked ? true : false - if (Array.isArray($$a)) { - var $$v = null, - $$i = _vm._i($$a, $$v) - if ($$el.checked) { - $$i < 0 && - (_vm.auto_fetch_distribution = $$a.concat([ - $$v - ])) - } else { - $$i > -1 && - (_vm.auto_fetch_distribution = $$a - .slice(0, $$i) - .concat($$a.slice($$i + 1))) - } - } else { - _vm.auto_fetch_distribution = $$c - } - } - } - }) - ]), - _vm._v(" "), - _vm.me_distribution_metadata - ? _c("div", [ - _vm.majority_elections_distribution - ? _c("div", [ - _c( + : _vm._e() + ]) + : _vm._e() + ]), + _vm._v(" "), + _c("div", { staticClass: "row mt-1" }, [ + _vm.show_last_election_chart + ? _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _vm.population_stats + ? _c("div", { staticClass: "row mt-1" }, [ + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c("div", { staticClass: "card" }, [ + _c("div", { staticClass: "card-header" }, [ + _vm._v("Last elections status") + ]), + _vm._v(" "), + _c("div", { staticClass: "card-body" }, [ + _vm.last_elections_data + ? _c( "div", - { staticClass: "row" }, [ - _c("bar-chart", { - staticClass: "col-md-6", - attrs: { - "chart-data": _vm.me_chart_data, - options: { maintainAspectRatio: true } - } - }), + _c("div", [ + _vm._v( + "\n Election type: " + ), + _c("i", [ + _vm._v( + _vm._s( + _vm.last_elections_data + .elections_type + ) + ) + ]), + _vm._v( + "\n Number of elections: " + ), + _c("i", [ + _vm._v( + _vm._s( + _vm.last_elections_data + .number_of_elections + ) + ) + ]), + _vm._v(" "), + _c("br"), + _vm._v( + "\n Total time: " + ), + _c("i", [ + _vm._v( + _vm._s( + _vm.last_elections_data.total_time + ) + ) + ]) + ]), _vm._v(" "), - _c("bar-chart", { - staticClass: "col-md-6", - attrs: { - "chart-data": _vm.me_chart_data_r_10, - options: { maintainAspectRatio: true } - } - }) + _vm.show_last_election_chart + ? _c("bar-chart", { + attrs: { + "chart-data": + _vm.last_elections_chart_data, + options: { + maintainAspectRatio: false, + scales: { + yAxes: [ + { + id: "left-y-axis", + type: "linear", + position: "left", + ticks: { min: 0 } + } + ] + } + }, + styles: { height: 200 } + } + }) + : _vm._e() ], 1 - ), - _vm._v(" "), - _c("div", [ - _vm._v( - "\n Number of elections: " - ), - _c("i", [ - _vm._v( - _vm._s( - _vm.me_distribution_metadata - .number_of_elections - ) - ) - ]), - _vm._v(" "), - _c("br"), - _vm._v( - "\n Total time: " - ), - _c("i", [ - _vm._v( - _vm._s( - _vm.me_distribution_metadata.total_time - ) - ) - ]), - _vm._v(" "), - _c("br"), - _vm._v( - "\n Distribution of correct choices percentage in " + - _vm._s( - _vm.me_distribution_metadata - .number_of_elections - ) + - " elections:\n " - ), - _c("br"), - _vm._v( - "\n Charts: Majority Elections correct answers distribution (grouped by 1 and 10 percent)\n " - ), - _c("br"), - _vm._v( - "\n (by 1): " + - _vm._s( - _vm.majority_elections_distribution - ) + - "\n " - ), - _c("br"), - _vm._v( - "\n (by 10): " + - _vm._s( - _vm.majority_elections_distribution_r_10 - ) + - "\n " - ) + ) + : _c("div", [ + _c("i", [_vm._v("N/A (run elections first)")]) ]) - ]) - : _vm._e() - ]) - : _c("div", [ - _c("i", [_vm._v("N/A (fetch distribution first)")]) + ]) ]) - ]) - ]) - ]) - ]) - ]), - _vm._v(" "), - _c("div", { staticClass: "col-md-6 col-lg-6" }, [ - _vm.population_stats - ? _c("div", { staticClass: "row mt-1" }, [ - _c("div", { staticClass: "col-md-12 col-lg-12" }, [ - _c("div", { staticClass: "card" }, [ - _c("div", { staticClass: "card-header" }, [ - _vm._v("Last elections status") - ]), - _vm._v(" "), - _c("div", { staticClass: "card-body" }, [ - _vm.last_elections_data - ? _c( - "div", - [ - _c("div", [ - _vm._v( - "\n Election type: " - ), - _c("i", [ - _vm._v( - _vm._s( - _vm.last_elections_data.elections_type - ) - ) - ]), - _vm._v( - "\n Number of elections: " - ), - _c("i", [ - _vm._v( - _vm._s( - _vm.last_elections_data - .number_of_elections - ) - ) - ]), - _vm._v(" "), - _c("br"), - _vm._v( - "\n Total time: " - ), - _c("i", [ - _vm._v( - _vm._s(_vm.last_elections_data.total_time) - ) - ]) - ]), - _vm._v(" "), - _c("label", { staticClass: "text-info" }, [ - _vm._v("Show last elections chart") - ]), - _vm._v(" "), - _c("input", { - directives: [ - { - name: "model", - rawName: "v-model", - value: _vm.show_last_election_chart, - expression: "show_last_election_chart" - } - ], - attrs: { type: "checkbox" }, - domProps: { - checked: Array.isArray( - _vm.show_last_election_chart - ) - ? _vm._i( - _vm.show_last_election_chart, - null - ) > -1 - : _vm.show_last_election_chart - }, - on: { - change: function($event) { - var $$a = _vm.show_last_election_chart, - $$el = $event.target, - $$c = $$el.checked ? true : false - if (Array.isArray($$a)) { - var $$v = null, - $$i = _vm._i($$a, $$v) - if ($$el.checked) { - $$i < 0 && - (_vm.show_last_election_chart = $$a.concat( - [$$v] - )) - } else { - $$i > -1 && - (_vm.show_last_election_chart = $$a - .slice(0, $$i) - .concat($$a.slice($$i + 1))) - } - } else { - _vm.show_last_election_chart = $$c - } - } - } - }), - _vm._v(" "), - _vm.show_last_election_chart - ? _c("bar-chart", { - attrs: { - "chart-data": - _vm.last_elections_chart_data, - options: { - maintainAspectRatio: false, - scales: { - yAxes: [ - { - id: "left-y-axis", - type: "linear", - position: "left", - ticks: { min: 0 } - } - ] - } - }, - styles: { height: 200 } - } - }) - : _vm._e() - ], - 1 - ) - : _vm._e() ]) ]) - ]) - ]) - : _vm._e() - ]) - ]), - _vm._v(" "), - _c("div", { staticClass: "row mt-2" }) + : _vm._e() + ]) + : _vm._e() + ]) ]) ]) ]) diff --git a/resources/js/components/population-show.vue b/resources/js/components/population-show.vue index ca752afd0ae20fb69ea3b3e82120fa601859efc6..f675b8b403729a4cb17cc69e37ab11e2a1e2585c 100644 --- a/resources/js/components/population-show.vue +++ b/resources/js/components/population-show.vue @@ -7,67 +7,160 @@ <div class="card-header">{{population_name}} Actions</div> <div class="card-body" v-if="stage_name"> <div v-if="population_stats.stage === 'l'"> - <h5>Learning stage</h5> - <button v-if="population_stats.stage === 'l'" @click.prevent="switchToPerformanceStage()"> - Finish Learning stage - </button> - <h5>{{election_name}}:</h5> - <div> + <h5>Learning stage ({{election_name}})</h5> + <div class="col-md-12 col-lg-12"> + <button v-if="population_stats.stage === 'l'" @click.prevent="switchToPerformanceStage()"> + Finish Learning stage + </button> + </div> + <h5>Reputation modifiers:</h5> + <div class="col-md-12 col-lg-12"> + <ul> + <li class="text-info">Forgetting percent: {{population_stats.forgetting_percent}}</li> + <li class="text-info">Follower multiplier: {{population_stats.follower_factor}}</li> + </ul> + </div> + <h5>Elections</h5> + <div class="col-md-12 col-lg-12"> <label class="text-info">Number of elections: </label> <input type="number" min="1" max="100" step="0" v-model="custom_number_elections" style="width:70px"> + <button :disabled="running_elections_lock" class="btn btn-sm btn-outline-info" @click.prevent="runElections(population_stats.election_type, custom_number_elections)"> + Run {{custom_number_elections}} election<span v-if="custom_number_elections > 1">s</span> + </button> </div> - <button :disabled="running_elections_lock" class="btn btn-sm btn-outline-info" @click.prevent="runElections(population_stats.election_type, custom_number_elections)"> - Run {{custom_number_elections}} election<span v-if="custom_number_elections > 1">s</span> <i>({{population_stats.election_type}})</i> - </button> - <hr> </div> <div v-else-if="population_stats.stage === 'p'"> - <h5>Performance stage</h5> - <h5>{{election_name}}:</h5> + <h5>Performance stage ({{election_name}})</h5> + <h5>Elections</h5> <div> <label class="text-info">Number of elections: </label> <input type="number" min="1" max="100" step="0" v-model="custom_number_elections" style="width:70px"> + <button :disabled="running_elections_lock" class="btn btn-sm btn-outline-info" @click.prevent="runElections('d1', custom_number_elections)"> + Run {{custom_number_elections}} election<span v-if="custom_number_elections > 1">s</span> + </button> </div> - <button :disabled="running_elections_lock" class="btn btn-sm btn-outline-info" @click.prevent="runElections('d1', custom_number_elections)"> - Run {{custom_number_elections}} election<span v-if="custom_number_elections > 1">s</span> <i>(type d1)</i> - </button> - <hr> </div> <div v-else> <i class="text-warning">Unrecognized stage code.</i> </div> + <h5>Chart display options</h5> + <div class="col-md-12 col-lg-12"> + <input type="checkbox" v-model="show_population_stats"> + <label class="text-info">Show population stats</label> + </div> + + <div class="col-md-12 col-lg-12"> + <input type="checkbox" v-model="show_last_election_chart"> + <label class="text-info">Show last elections chart</label> + </div> + + <div class="col-md-12 col-lg-12"> + <input type="checkbox" v-model="show_voters_graph"> + <label class="text-info">Show voters graph</label> + </div> + + <div class="col-md-12 col-lg-12"> + <input type="checkbox" v-model="show_timeline_graph"> + <label class="text-info">Show timeline graph (results)</label> + </div> + + <div class="col-md-12 col-lg-12"> + <input type="checkbox" v-model="show_weights_timeline_graph"> + <label class="text-info">Show timeline graph (weights)</label> + </div> + </div> <div v-else> <i>Population stage not defined. Cannot run elections.</i> </div> </div> + <div class="card"> + <div class="card-header">Voters' attributes charts</div> + <div class="card-body"> + <div class="row"> + <div class="col-md-12 col-lg-12"> + <input type="checkbox" v-model="auto_fetch_voters"> + <label class="text-info">Auto update voters' details after election</label> + </div> + <div class="col-md-12 col-lg-12"> + <button class="btn btn-sm btn-outline-info" @click.prevent="fetchPopulationDetails">Fetch Voters Data</button> + </div> + </div> + </div> + </div> + <div class="card"> + <div class="card-header">Elections timeline (type selector)</div> + <div class="card-body"> + <div class="row"> + <div class="col-md-12 col-lg-12"> + <v-select :options="election_timeline_selector" + id="election_timeline_selector" + v-model="current_election_timeline_key" + placeholder="Choose election type" + label="text"> + </v-select> + </div> + </div> + </div> + </div> + <div class="card"> + <div class="card-header">Elections timeline (results)</div> + <div class="card-body"> + <div class="row"> + <div class="col-md-12 col-lg-12"> + <label class="text-info">Moving average</label> + <input type="number" min="0" step="1" v-model="moving_average" style="width:70px"> + </div> + <div class="col-md-12 col-lg-12"> + <input type="checkbox" v-model="auto_fetch_elections_timeline"> + <label class="text-info">Auto update timeline after election</label> + </div> + <div class="col-md-12 col-lg-12"> + <button :disabled="!current_election_timeline_key" + v-on:click.prevent="fetchElectionsTimeline" + v-bind:class="{'btn-primary' : current_election_timeline_key }" + class="btn-xs"> + <i v-if="current_election_timeline_key">Fetch {{current_election_timeline_key.text}} results timeline</i> + <i v-else>Select election type</i> + </button> + </div> + </div> + </div> + </div> + <div class="card"> + <div class="card-header">Elections timeline (weights)</div> + <div class="card-body"> + <div class="row"> + <div class="col-md-12 col-lg-12"> + <input type="checkbox" v-model="auto_fetch_weights_timeline"> + <label class="text-info">Auto update weights timeline after election</label> + </div> + <div class="col-md-12 col-lg-12"> + <button :disabled="!current_election_timeline_key" + v-on:click.prevent="fetchWeightsTimeline" + v-bind:class="{'btn-primary' : current_election_timeline_key }" + class="btn-xs"> + <i v-if="current_election_timeline_key">Fetch {{current_election_timeline_key.text}} weights timeline</i> + <i v-else>Select election type</i> + </button> + </div> + </div> + </div> + </div> </div> </div> <div class="col-md-9 col-lg-9"> - <div class="row"> + <div class="row mt-1"> <div class="alert alert-info col-md-12 col-lg-12" v-if="feedback"> + <button class="btn btn-sm btn-outline-info" @click.prevent="resetFeedback">x</button> INFO: {{feedback}} - <button class="float-right btn btn-sm btn-outline-info" @click.prevent="resetFeedback">x</button> </div> </div> - <div class="row mt-1"> + <div v-if="population_stats" class="row mt-1"> <div class="col-md-12"> - <div class="card"> + <div class="card" v-if="show_voters_graph"> <div class="card-header">Voters' attributes charts</div> <div class="card-body"> - <div class="row"> - <div class="col-md-4"> - <button class="btn btn-sm btn-outline-info" @click.prevent="fetchPopulationDetails">Fetch Voters Data</button> - </div> - <div class="col-md-4"> - <label class="text-info">Auto update voters' details after election</label> - <input type="checkbox" v-model="auto_fetch_voters"> - </div> - <div class="col-md-4"> - <label class="text-info">Show voters graph</label> - <input type="checkbox" v-model="show_voters_graph"> - </div> - </div> <div v-if="voters_fetched"> <div v-if="show_voters_graph"> <line-chart :chart-data="voters_chart_data" :options="voters_chart_options" :styles="h_300_chart_styles"></line-chart> @@ -77,75 +170,72 @@ <div v-else> <i>N/A</i> </div> - </div> </div> </div> </div> <div v-if="population_stats" class="row mt-1"> <div class="col-md-12 col-lg-12"> - <div class="card"> - <div class="card-header">Elections timeline</div> + <div class="card" v-if="show_timeline_graph"> + <div class="card-header">Elections timeline (results)</div> <div class="card-body"> - <div> - <div class="row"> - <div class="col-md-4"> - <v-select :options="election_timeline_selector" - id="election_timeline_selector" - v-model="current_election_timeline_key" - placeholder="Choose election type" - label="text"> - </v-select> - <br> - <button :disabled="!current_election_timeline_key" - v-on:click.prevent="fetchElectionsTimeline" - v-bind:class="{'btn-primary' : current_election_timeline_key }" - class="btn-xs"> - <i v-if="current_election_timeline_key">Fetch {{current_election_timeline_key.text}} timeline</i> - <i v-else>Select election type</i> - </button> - </div> - <div class="col-md-4"> - <label class="text-info">Auto update timeline after election</label> - <input type="checkbox" v-model="auto_fetch_elections_timeline"> - <br> - <label class="text-info">Moving average</label> - <input type="number" min="0" step="1" v-model="moving_average" style="width:70px"> - </div> - <div class="col-md-4"> - <label class="text-info">Show timeline graph</label> - <input type="checkbox" v-model="show_timeline_graph"> - </div> - </div> + <div v-if="elections_timeline" > <hr> - <div v-if="elections_timeline" > - Election type: <i>{{elections_timeline.elections_type}}</i>, - Number of elections: <i>{{elections_timeline.no_of_elections}}</i>, - Number of voters: <i>{{elections_timeline.no_of_voters}}</i> - <div v-if="show_timeline_graph"> - <line-chart :chart-data="election_timeline_chart_data" - :options="{ + Election type: <i>{{elections_timeline.elections_type}}</i>, + Number of elections: <i>{{elections_timeline.no_of_elections}}</i>, + Number of voters: <i>{{elections_timeline.no_of_voters}}</i> + <div v-if="show_timeline_graph"> + <line-chart :chart-data="election_timeline_chart_data" + :options="{ maintainAspectRatio: false, scales: { yAxes: [{id: 'left-y-axis',type: 'linear',position: 'left',ticks: {min: 0, max:100}}] } }" - :styles="h_500_chart_styles" - ></line-chart> - </div> - <div v-else> - <i>select show graph</i> - </div> + :styles="h_500_chart_styles" + ></line-chart> + </div> + <div v-else> + <i>select show graph</i> + </div> + </div> + <div v-else><i>N/A</i></div> + </div> + </div> + <div class="card" v-if="show_weights_timeline_graph"> + <div class="card-header">Elections timeline (weights)</div> + <div class="card-body"> + <div v-if="weights_timeline" > + <hr> + Election type: <i>{{weights_timeline.elections_type}}</i>, + Number of elections: <i>{{weights_timeline.no_of_elections}}</i>, + Number of voters: <i>{{weights_timeline.no_of_voters}} (A:{{weights_timeline.no_of_voters_a}}, B:{{weights_timeline.no_of_voters_b}})</i> + <div v-if="show_weights_timeline_graph"> + <h5>Timeline for delegation weights</h5> + <line-chart :chart-data="weights_timeline_chart_data" + :options="{ + maintainAspectRatio: false, + scales: { + yAxes: [ + {id: 'left-y-axis',type: 'linear',position: 'left'}, + {id: 'right-y-axis',type: 'linear',position: 'right',ticks: {min: 0, max:100}} + ] + } + }" + :styles="h_500_chart_styles" + ></line-chart> + </div> + <div v-else> + <i>select show graph</i> </div> - <div v-else><i>N/A</i></div> </div> + <div v-else><i>N/A</i></div> </div> </div> </div> </div> - <div class="row mt-2"> - <div class="col-md-6 col-lg-6 col-sm-6"> - + <div class="row mt-1"> + <div class="col-md-6 col-lg-6 col-sm-6" v-if="show_population_stats"> <div v-if="population_stats" class="row mt-1"> <div class="col-md-6 col-lg-6"> <div class="card"> @@ -177,7 +267,7 @@ </div> </div> </div> - <div class="row mt-1"> + <div class="row mt-1" v-if="show_majority_distribution"> <div class="col-md-12 col-lg-12"> <div class="card"> <div class="card-header">Majority elections distribution</div> @@ -213,8 +303,9 @@ </div> </div> </div> - - <div class="col-md-6 col-lg-6"> + </div> + <div class="row mt-1"> + <div class="col-md-12 col-lg-12" v-if="show_last_election_chart"> <div v-if="population_stats" class="row mt-1"> <div class="col-md-12 col-lg-12"> <div class="card"> @@ -227,10 +318,8 @@ <br> Total time: <i>{{last_elections_data.total_time}}</i> </div> - <label class="text-info">Show last elections chart</label> - <input type="checkbox" v-model="show_last_election_chart"> <bar-chart v-if="show_last_election_chart" - :chart-data="last_elections_chart_data" + :chart-data="last_elections_chart_data" :options="{ maintainAspectRatio: false, scales: { @@ -240,14 +329,13 @@ :styles="{height: 200}" ></bar-chart> </div> + <div v-else><i>N/A (run elections first)</i></div> </div> </div> </div> </div> </div> </div> - <div class="row mt-2"> - </div> </div> </div> @@ -265,6 +353,12 @@ components: {LineChart, BarChart, vSelect}, data() { return { + show_population_stats: true, + show_majority_distribution: false, + show_last_election_chart: false, + show_voters_graph: false, + show_timeline_graph: false, + show_weights_timeline_graph: false, custom_number_elections: 1, current_election_timeline_key: null, election_timeline_selector : [ @@ -288,11 +382,10 @@ elections_timeline: null, moving_average: 0, auto_fetch_elections_timeline: false, - show_timeline_graph: true, + weights_timeline: null, + auto_fetch_weights_timeline: false, running_elections_lock: false, auto_fetch_voters: false, - show_voters_graph: false, - show_last_election_chart: false, auto_fetch_distribution: false, feedback : null, population_id: route().params.population_id, @@ -677,9 +770,9 @@ let expertise = []; let avg_expertise = this.population_stats.voters_stats.expertise_average; this.elections_timeline.elections.forEach((value,idx) => { - labels.push(idx); - percent_correct.push(value); - expertise.push(avg_expertise); + labels.push(idx); + percent_correct.push(value); + expertise.push(avg_expertise); }); return { labels: labels, @@ -701,6 +794,68 @@ } ] } + }, + weights_timeline_chart_data() { + console.log('computing weights chart data'); + let labels = []; + let avg_weight_a = []; + let avg_weight_b = []; + let reputation_a = []; + let reputation_b = []; + let weight_share_b = []; + this.weights_timeline.weights.forEach((value,idx) => { + labels.push(idx); + avg_weight_a.push(value.avg_weight_a); + avg_weight_b.push(value.avg_weight_b); + reputation_a.push(value.reputation_a); + reputation_b.push(value.reputation_b); + weight_share_b.push(value.weight_share_b); + }); + return { + labels: labels, + datasets: [ + { + label: 'Group A (avg Weight per voter)', + borderColor: '#6b9c3a', + fill: false, + data: avg_weight_a, + yAxisID: 'left-y-axis' + }, + + { + label: 'Group B (avg Weight per voter)', + borderColor: '#01439b', + fill: false, + data: avg_weight_b, + yAxisID: 'left-y-axis' + }, + + { + label: 'Group A - Reputation sum', + borderColor: '#929c84', + fill: false, + data: reputation_a, + yAxisID: 'left-y-axis' + }, + + { + label: 'Group B - Reputation sum', + borderColor: '#6c739b', + fill: false, + data: reputation_b, + yAxisID: 'left-y-axis' + }, + + { + label: 'Group B - Weight share: wB/(wA+wB)', + borderColor: '#b77959', + backgroundColor: '#b77959', + fill: true, + data: weight_share_b, + yAxisID: 'right-y-axis' + } + ] + } } }, methods: { @@ -744,6 +899,9 @@ if (this.auto_fetch_elections_timeline) { this.fetchElectionsTimeline(); } + if (this.auto_fetch_weights_timeline) { + this.fetchWeightsTimeline(); + } }).catch((err) => { this.feedback = 'population stats fetching error'; }); @@ -767,8 +925,8 @@ number:multi }).then((response) => { this.feedback = 'voting done, fetching updated population stats..'; + console.log(this); this.fetchPopulationStats(); - console.log(response.data); this.last_elections_data = response.data; this.running_elections_lock = false; }).catch((err) => { @@ -819,16 +977,37 @@ "population":this.population_id } ), { - params: { - 'type': this.current_election_timeline_key.value, - 'moving_average': this.moving_average - } - }).then((response) => { + params: { + 'type': this.current_election_timeline_key.value, + 'moving_average': this.moving_average + } + }).then((response) => { this.elections_timeline = response.data; this.feedback = 'election timeline fetched'; }).catch((err) => { this.feedback = 'election timeline fetching error'; }); + }, + fetchWeightsTimeline() { + console.log(this.current_election_timeline_key); + axios.get( + route( + 'internal.api.population.get.weights.timeline', + { + "template":this.template_id, + "population":this.population_id + } + ), { + params: { + 'type': this.current_election_timeline_key.value, + 'moving_average': this.moving_average + } + }).then((response) => { + this.weights_timeline = response.data; + this.feedback = 'weights timeline fetched'; + }).catch((err) => { + this.feedback = 'weights timeline fetching error'; + }); } } } diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 9d57af9cdbdf6b0db766faa8ca66279b8cdfb0af..a676f11671cfaa29863dbb00ce42446a5a83eebb 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -21,7 +21,7 @@ <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm"> <div class="container"> <a class="navbar-brand" href="{{ route('home') }}"> - {{ config('app.name', 'Laravel') }} + {{ config('app.name', 'LD sim') }} </a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}"> <span class="navbar-toggler-icon"></span>