From fc6a053776f14ddf68909edd1cdab83bd5d7892e Mon Sep 17 00:00:00 2001 From: tomaszrudowski <tomasz@innit.no> Date: Sat, 30 Oct 2021 11:55:50 +0200 Subject: [PATCH] Reputation factors per template --- app/Http/Controllers/APIController.php | 42 +- app/Population.php | 4 +- ..._02_18_093626_create_populations_table.php | 2 + public/js/app.js | 1387 ++++++++++------- resources/js/components/population-create.vue | 28 +- resources/js/components/population-index.vue | 11 +- resources/js/components/population-show.vue | 165 +- 7 files changed, 1002 insertions(+), 637 deletions(-) diff --git a/app/Http/Controllers/APIController.php b/app/Http/Controllers/APIController.php index ba61f55..1e14091 100644 --- a/app/Http/Controllers/APIController.php +++ b/app/Http/Controllers/APIController.php @@ -38,7 +38,9 @@ class APIController extends Controller 'init_leadership_a' => 'required|integer|min:0|max:100', 'init_leadership_b' => 'required|integer|min:0|max:100', 'spread_leadership_a' => 'required|integer|min:0|max:100', - 'spread_leadership_b' => 'required|integer|min:0|max:100' + 'spread_leadership_b' => 'required|integer|min:0|max:100', + 'forgetting_factor' => 'nullable|int|min:0|max:100', + 'follower_factor' => 'nullable|min:1' ]); } catch (ValidationException $e) { return response()->json([ @@ -49,6 +51,15 @@ class APIController extends Controller $start = microtime(true); $population = new Population(); + + $forgettingFactor = Config::get('app.forgetting_factor', 0.99); + if (isset($attributes['forgetting_factor'])) { + $forgettingFactor = 1 - 0.01 * $attributes['forgetting_factor']; + } + $population->forgetting_factor = $forgettingFactor; + + $population->follower_factor = isset($attributes['follower_factor']) ? $attributes['follower_factor'] : Config::get('app.follower_factor', 100); + $population->save(); $population->name = isset($attributes['name']) ? $attributes['name'] : 'Population Template ' . $population->id; $population->update(); @@ -214,6 +225,8 @@ class APIController extends Controller $newPopulation->election_type = $attributes['election_type']; $newPopulation->name = $newPopulationName; $newPopulation->parent_id = $template->id; + $newPopulation->forgetting_factor = $template->forgetting_factor; + $newPopulation->follower_factor = $template->follower_factor; $newPopulation->stage = $newPopulation->election_type === "d1" ? 'p' : 'l'; // 'performance'/'learning' default stage for child population $newPopulation->save(); @@ -472,11 +485,12 @@ 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); + $data->forgetting_factor = $existingPopulation->forgetting_factor; + $forgettingModifier = 1 - (0.01 * $existingPopulation->forgetting_factor); + $data->follower_factor = $existingPopulation->follower_factor; for( $i = 0; $i < $numberOfElections; $i++) { - $singleElectionStats = $this->$electionMethod($existingPopulation, $data->forgetting_factor, $data->follower_factor); + $singleElectionStats = $this->$electionMethod($existingPopulation, $forgettingModifier, $data->follower_factor); $elections[] = $singleElectionStats; } $data->number_of_elections = $numberOfElections; @@ -507,8 +521,8 @@ class APIController extends Controller * @return \stdClass * @throws \Exception */ - private function runSingleDelegationElectionVersion1(Population $population, $forgettingFactor, $followerFactor) { - return $this->runSingleDelegationElection($population, false, 'd1', false, $forgettingFactor, $followerFactor); + private function runSingleDelegationElectionVersion1(Population $population, $forgettingModifier, $followerFactor) { + return $this->runSingleDelegationElection($population, false, 'd1', false, $forgettingModifier, $followerFactor); } /** @@ -521,8 +535,8 @@ class APIController extends Controller * @return \stdClass * @throws \Exception */ - private function runSingleDelegationElectionVersion2 (Population $population, $forgettingFactor, $followerFactor) { - return $this->runSingleDelegationElection($population, true, 'd2', false, $forgettingFactor, $followerFactor); + private function runSingleDelegationElectionVersion2 (Population $population, $forgettingModifier, $followerFactor) { + return $this->runSingleDelegationElection($population, true, 'd2', false, $forgettingModifier, $followerFactor); } /** @@ -535,8 +549,8 @@ class APIController extends Controller * @return \stdClass * @throws \Exception */ - private function runSingleDelegationElectionVersion3 (Population $population, $forgettingFactor, $followerFactor) { - return $this->runSingleDelegationElection($population, true, 'd3', true, $forgettingFactor, $followerFactor); + private function runSingleDelegationElectionVersion3 (Population $population, $forgettingModifier, $followerFactor) { + return $this->runSingleDelegationElection($population, true, 'd3', true, $forgettingModifier, $followerFactor); } /* private function runSingleDelegationElectionVersion1(Population $population) { @@ -703,7 +717,7 @@ class APIController extends Controller * @param bool $modifyReputation * @param string $type * @param bool $modifyAttributes - * @param $forgettingFactor + * @param $forgettingModifier * @param $followerFactor * @return \stdClass * @throws \Exception @@ -713,7 +727,7 @@ class APIController extends Controller $modifyReputation = false, $type = 'd1', $modifyAttributes = false, - $forgettingFactor, + $forgettingModifier, $followerFactor ) { $startTime = microtime(true); @@ -876,7 +890,7 @@ class APIController extends Controller } // balance voter reputation over time between elections - $voter->reputation = round($voter->reputation * $forgettingFactor); + $voter->reputation = round($voter->reputation * $forgettingModifier); /*if ($voter->reputation < 0) { $voter->reputation++; } elseif ($voter->reputation > 0) { @@ -1102,6 +1116,4 @@ class APIController extends Controller return response()->json($data, Response::HTTP_OK); } - - } diff --git a/app/Population.php b/app/Population.php index 1073db1..2f3b627 100644 --- a/app/Population.php +++ b/app/Population.php @@ -10,7 +10,9 @@ class Population extends Model 'name', 'parent_id', 'stage', - 'election_type' + 'election_type', + 'follower_factor', + 'forgetting_factor' ]; protected $appends = [ diff --git a/database/migrations/2021_02_18_093626_create_populations_table.php b/database/migrations/2021_02_18_093626_create_populations_table.php index 7e6c5c6..3bd93ec 100644 --- a/database/migrations/2021_02_18_093626_create_populations_table.php +++ b/database/migrations/2021_02_18_093626_create_populations_table.php @@ -19,6 +19,8 @@ class CreatePopulationsTable extends Migration $table->integer('parent_id', false, true)->nullable(true)->default(null); $table->char('stage',1)->nullable(true)->default(null); $table->char('election_type')->nullable(true)->default(null); + $table->tinyInteger('follower_factor', false, true)->nullable(false)->default(100); + $table->tinyInteger('forgetting_factor', false, true)->nullable(false)->default(1); $table->timestamps(); }); diff --git a/public/js/app.js b/public/js/app.js index d4d586b..02bfd5e 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -2291,6 +2291,28 @@ __webpack_require__.r(__webpack_exports__); // // // +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// /* harmony default export */ __webpack_exports__["default"] = ({ name: "population-create", mounted: function mounted() {}, @@ -2301,6 +2323,8 @@ __webpack_require__.r(__webpack_exports__); population: { name: null, size_a: 0, + forgetting_factor: 1, + follower_factor: 100, init_expertise_a: 50, spread_expertise_a: 0, init_confidence_a: 50, @@ -2330,7 +2354,7 @@ __webpack_require__.r(__webpack_exports__); console.log('add...'); console.log(this.population); - axios.post(route('internal.api.template.post'), this.population).then(function (response) { + axios.post(route('internal.api.templates.post'), this.population).then(function (response) { console.log(response.data); Bus.$emit('TemplateCreated', true, response.data.meta); @@ -2513,6 +2537,13 @@ __webpack_require__.r(__webpack_exports__); // // // +// +// +// +// +// +// +// /* harmony default export */ __webpack_exports__["default"] = ({ @@ -3009,6 +3040,36 @@ __webpack_require__.r(__webpack_exports__); // // // +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// @@ -3022,7 +3083,7 @@ __webpack_require__.r(__webpack_exports__); }, data: function data() { return { - show_population_stats: true, + show_population_stats: false, show_majority_distribution: false, show_last_election_chart: false, show_voters_graph: false, @@ -3485,6 +3546,9 @@ __webpack_require__.r(__webpack_exports__); resetFeedback: function resetFeedback() { this.feedback = null; }, + getTemplateLink: function getTemplateLink(templateId) { + return route('template.show', templateId); + }, fetchPopulationDetails: function fetchPopulationDetails() { var _this2 = this; @@ -78183,7 +78247,7 @@ var render = function() { _c("div", { staticClass: "row form-group" }, [ _c( "div", - { staticClass: "col-md-6 form-inline" }, + { staticClass: "col-md-12 form-inline" }, [ _c( "label", @@ -78235,10 +78299,6 @@ var render = function() { ) ]), _vm._v(" "), - _c("hr"), - _vm._v(" "), - _vm._m(1), - _vm._v(" "), _c("div", { staticClass: "row form-group" }, [ _c( "div", @@ -78249,13 +78309,13 @@ var render = function() { { class: [ "col-md-6", - _vm.validationErrors["size_a"] + _vm.validationErrors["forgetting_factor"] ? "text-danger" : "" ], attrs: { for: "size_a" } }, - [_vm._v("Size A:")] + [_vm._v("Forgetting Factor (optional 1-100%):")] ), _vm._v(" "), _c("input", { @@ -78263,13 +78323,13 @@ var render = function() { { name: "model", rawName: "v-model", - value: _vm.population.size_a, - expression: "population.size_a" + value: _vm.population.forgetting_factor, + expression: "population.forgetting_factor" } ], staticClass: "form-control col-md-6", - attrs: { type: "number", id: "size_a" }, - domProps: { value: _vm.population.size_a }, + attrs: { type: "number", id: "forgetting_factor" }, + domProps: { value: _vm.population.forgetting_factor }, on: { input: function($event) { if ($event.target.composing) { @@ -78277,20 +78337,21 @@ var render = function() { } _vm.$set( _vm.population, - "size_a", + "forgetting_factor", $event.target.value ) } } }), _vm._v(" "), - _vm._l(_vm.validationErrors["size_a"], function( - val_error - ) { - return _c("span", { staticClass: "text-danger" }, [ - _vm._v(_vm._s(val_error)) - ]) - }) + _vm._l( + _vm.validationErrors["forgetting_factor"], + function(val_error) { + return _c("span", { staticClass: "text-danger" }, [ + _vm._v(_vm._s(val_error)) + ]) + } + ) ], 2 ), @@ -78304,13 +78365,17 @@ var render = function() { { class: [ "col-md-6", - _vm.validationErrors["size_b"] + _vm.validationErrors["follower_factor"] ? "text-danger" : "" ], attrs: { for: "size_a" } }, - [_vm._v("Size B:")] + [ + _vm._v( + "Follower Factor (optional inc/dec multiplier):" + ) + ] ), _vm._v(" "), _c("input", { @@ -78318,13 +78383,13 @@ var render = function() { { name: "model", rawName: "v-model", - value: _vm.population.size_b, - expression: "population.size_b" + value: _vm.population.follower_factor, + expression: "population.follower_factor" } ], staticClass: "form-control col-md-6", - attrs: { type: "number", id: "size_b" }, - domProps: { value: _vm.population.size_b }, + attrs: { type: "number", id: "follower_factor" }, + domProps: { value: _vm.population.follower_factor }, on: { input: function($event) { if ($event.target.composing) { @@ -78332,26 +78397,29 @@ var render = function() { } _vm.$set( _vm.population, - "size_b", + "follower_factor", $event.target.value ) } } }), _vm._v(" "), - _vm._l(_vm.validationErrors["size_b"], function( - val_error - ) { - return _c("span", { staticClass: "text-danger" }, [ - _vm._v(_vm._s(val_error)) - ]) - }) + _vm._l( + _vm.validationErrors["follower_factor"], + function(val_error) { + return _c("span", { staticClass: "text-danger" }, [ + _vm._v(_vm._s(val_error)) + ]) + } + ) ], 2 ) ]), _vm._v(" "), - _vm._m(2), + _c("hr"), + _vm._v(" "), + _vm._m(1), _vm._v(" "), _c("div", { staticClass: "row form-group" }, [ _c( @@ -78363,14 +78431,13 @@ var render = function() { { class: [ "col-md-6", - "col-form-label", - _vm.validationErrors["init_expertise_a"] + _vm.validationErrors["size_a"] ? "text-danger" : "" ], - attrs: { for: "init_expertise_a" } + attrs: { for: "size_a" } }, - [_vm._v("Expertise A (init):")] + [_vm._v("Size A:")] ), _vm._v(" "), _c("input", { @@ -78378,13 +78445,13 @@ var render = function() { { name: "model", rawName: "v-model", - value: _vm.population.init_expertise_a, - expression: "population.init_expertise_a" + value: _vm.population.size_a, + expression: "population.size_a" } ], staticClass: "form-control col-md-6", - attrs: { type: "number", id: "init_expertise_a" }, - domProps: { value: _vm.population.init_expertise_a }, + attrs: { type: "number", id: "size_a" }, + domProps: { value: _vm.population.size_a }, on: { input: function($event) { if ($event.target.composing) { @@ -78392,21 +78459,20 @@ var render = function() { } _vm.$set( _vm.population, - "init_expertise_a", + "size_a", $event.target.value ) } } }), _vm._v(" "), - _vm._l( - _vm.validationErrors["init_expertise_a"], - function(val_error) { - return _c("span", { staticClass: "text-danger" }, [ - _vm._v(_vm._s(val_error)) - ]) - } - ) + _vm._l(_vm.validationErrors["size_a"], function( + val_error + ) { + return _c("span", { staticClass: "text-danger" }, [ + _vm._v(_vm._s(val_error)) + ]) + }) ], 2 ), @@ -78420,14 +78486,13 @@ var render = function() { { class: [ "col-md-6", - "col-form-label", - _vm.validationErrors["init_expertise_b"] + _vm.validationErrors["size_b"] ? "text-danger" : "" ], - attrs: { for: "init_expertise_b" } + attrs: { for: "size_a" } }, - [_vm._v("Expertise B (init):")] + [_vm._v("Size B:")] ), _vm._v(" "), _c("input", { @@ -78435,13 +78500,13 @@ var render = function() { { name: "model", rawName: "v-model", - value: _vm.population.init_expertise_b, - expression: "population.init_expertise_b" + value: _vm.population.size_b, + expression: "population.size_b" } ], staticClass: "form-control col-md-6", - attrs: { type: "number", id: "init_expertise_b" }, - domProps: { value: _vm.population.init_expertise_b }, + attrs: { type: "number", id: "size_b" }, + domProps: { value: _vm.population.size_b }, on: { input: function($event) { if ($event.target.composing) { @@ -78449,26 +78514,27 @@ var render = function() { } _vm.$set( _vm.population, - "init_expertise_b", + "size_b", $event.target.value ) } } }), _vm._v(" "), - _vm._l( - _vm.validationErrors["init_expertise_b"], - function(val_error) { - return _c("span", { staticClass: "text-danger" }, [ - _vm._v(_vm._s(val_error)) - ]) - } - ) + _vm._l(_vm.validationErrors["size_b"], function( + val_error + ) { + return _c("span", { staticClass: "text-danger" }, [ + _vm._v(_vm._s(val_error)) + ]) + }) ], 2 ) ]), _vm._v(" "), + _vm._m(2), + _vm._v(" "), _c("div", { staticClass: "row form-group" }, [ _c( "div", @@ -78480,13 +78546,13 @@ var render = function() { class: [ "col-md-6", "col-form-label", - _vm.validationErrors["spread_expertise_a"] + _vm.validationErrors["init_expertise_a"] ? "text-danger" : "" ], - attrs: { for: "spread_expertise_a" } + attrs: { for: "init_expertise_a" } }, - [_vm._v("Expertise A (spread):")] + [_vm._v("Expertise A (init):")] ), _vm._v(" "), _c("input", { @@ -78494,15 +78560,13 @@ var render = function() { { name: "model", rawName: "v-model", - value: _vm.population.spread_expertise_a, - expression: "population.spread_expertise_a" + value: _vm.population.init_expertise_a, + expression: "population.init_expertise_a" } ], staticClass: "form-control col-md-6", - attrs: { type: "number", id: "spread_expertise_a" }, - domProps: { - value: _vm.population.spread_expertise_a - }, + attrs: { type: "number", id: "init_expertise_a" }, + domProps: { value: _vm.population.init_expertise_a }, on: { input: function($event) { if ($event.target.composing) { @@ -78510,7 +78574,7 @@ var render = function() { } _vm.$set( _vm.population, - "spread_expertise_a", + "init_expertise_a", $event.target.value ) } @@ -78518,7 +78582,7 @@ var render = function() { }), _vm._v(" "), _vm._l( - _vm.validationErrors["spread_expertise_a"], + _vm.validationErrors["init_expertise_a"], function(val_error) { return _c("span", { staticClass: "text-danger" }, [ _vm._v(_vm._s(val_error)) @@ -78539,13 +78603,13 @@ var render = function() { class: [ "col-md-6", "col-form-label", - _vm.validationErrors["spread_expertise_b"] + _vm.validationErrors["init_expertise_b"] ? "text-danger" : "" ], - attrs: { for: "spread_expertise_b" } + attrs: { for: "init_expertise_b" } }, - [_vm._v("Expertise B (spread):")] + [_vm._v("Expertise B (init):")] ), _vm._v(" "), _c("input", { @@ -78553,15 +78617,13 @@ var render = function() { { name: "model", rawName: "v-model", - value: _vm.population.spread_expertise_b, - expression: "population.spread_expertise_b" + value: _vm.population.init_expertise_b, + expression: "population.init_expertise_b" } ], staticClass: "form-control col-md-6", - attrs: { type: "number", id: "spread_expertise_b" }, - domProps: { - value: _vm.population.spread_expertise_b - }, + attrs: { type: "number", id: "init_expertise_b" }, + domProps: { value: _vm.population.init_expertise_b }, on: { input: function($event) { if ($event.target.composing) { @@ -78569,7 +78631,7 @@ var render = function() { } _vm.$set( _vm.population, - "spread_expertise_b", + "init_expertise_b", $event.target.value ) } @@ -78577,7 +78639,7 @@ var render = function() { }), _vm._v(" "), _vm._l( - _vm.validationErrors["spread_expertise_b"], + _vm.validationErrors["init_expertise_b"], function(val_error) { return _c("span", { staticClass: "text-danger" }, [ _vm._v(_vm._s(val_error)) @@ -78600,13 +78662,13 @@ var render = function() { class: [ "col-md-6", "col-form-label", - _vm.validationErrors["init_confidence_a"] + _vm.validationErrors["spread_expertise_a"] ? "text-danger" : "" ], - attrs: { for: "init_confidence_a" } + attrs: { for: "spread_expertise_a" } }, - [_vm._v("Confidence A (init):")] + [_vm._v("Expertise A (spread):")] ), _vm._v(" "), _c("input", { @@ -78614,13 +78676,15 @@ var render = function() { { name: "model", rawName: "v-model", - value: _vm.population.init_confidence_a, - expression: "population.init_confidence_a" + value: _vm.population.spread_expertise_a, + expression: "population.spread_expertise_a" } ], staticClass: "form-control col-md-6", - attrs: { type: "number", id: "init_confidence_a" }, - domProps: { value: _vm.population.init_confidence_a }, + attrs: { type: "number", id: "spread_expertise_a" }, + domProps: { + value: _vm.population.spread_expertise_a + }, on: { input: function($event) { if ($event.target.composing) { @@ -78628,7 +78692,7 @@ var render = function() { } _vm.$set( _vm.population, - "init_confidence_a", + "spread_expertise_a", $event.target.value ) } @@ -78636,7 +78700,7 @@ var render = function() { }), _vm._v(" "), _vm._l( - _vm.validationErrors["init_confidence_a"], + _vm.validationErrors["spread_expertise_a"], function(val_error) { return _c("span", { staticClass: "text-danger" }, [ _vm._v(_vm._s(val_error)) @@ -78657,13 +78721,13 @@ var render = function() { class: [ "col-md-6", "col-form-label", - _vm.validationErrors["init_confidence_b"] + _vm.validationErrors["spread_expertise_b"] ? "text-danger" : "" ], - attrs: { for: "init_confidence_b" } + attrs: { for: "spread_expertise_b" } }, - [_vm._v("Confidence B (init):")] + [_vm._v("Expertise B (spread):")] ), _vm._v(" "), _c("input", { @@ -78671,13 +78735,15 @@ var render = function() { { name: "model", rawName: "v-model", - value: _vm.population.init_confidence_b, - expression: "population.init_confidence_b" + value: _vm.population.spread_expertise_b, + expression: "population.spread_expertise_b" } ], staticClass: "form-control col-md-6", - attrs: { type: "number", id: "init_confidence_b" }, - domProps: { value: _vm.population.init_confidence_b }, + attrs: { type: "number", id: "spread_expertise_b" }, + domProps: { + value: _vm.population.spread_expertise_b + }, on: { input: function($event) { if ($event.target.composing) { @@ -78685,7 +78751,7 @@ var render = function() { } _vm.$set( _vm.population, - "init_confidence_b", + "spread_expertise_b", $event.target.value ) } @@ -78693,7 +78759,123 @@ var render = function() { }), _vm._v(" "), _vm._l( - _vm.validationErrors["init_confidence_b"], + _vm.validationErrors["spread_expertise_b"], + function(val_error) { + return _c("span", { staticClass: "text-danger" }, [ + _vm._v(_vm._s(val_error)) + ]) + } + ) + ], + 2 + ) + ]), + _vm._v(" "), + _c("div", { staticClass: "row form-group" }, [ + _c( + "div", + { staticClass: "col-md-6 form-inline" }, + [ + _c( + "label", + { + class: [ + "col-md-6", + "col-form-label", + _vm.validationErrors["init_confidence_a"] + ? "text-danger" + : "" + ], + attrs: { for: "init_confidence_a" } + }, + [_vm._v("Confidence A (init):")] + ), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.population.init_confidence_a, + expression: "population.init_confidence_a" + } + ], + staticClass: "form-control col-md-6", + attrs: { type: "number", id: "init_confidence_a" }, + domProps: { value: _vm.population.init_confidence_a }, + on: { + input: function($event) { + if ($event.target.composing) { + return + } + _vm.$set( + _vm.population, + "init_confidence_a", + $event.target.value + ) + } + } + }), + _vm._v(" "), + _vm._l( + _vm.validationErrors["init_confidence_a"], + function(val_error) { + return _c("span", { staticClass: "text-danger" }, [ + _vm._v(_vm._s(val_error)) + ]) + } + ) + ], + 2 + ), + _vm._v(" "), + _c( + "div", + { staticClass: "col-md-6 form-inline" }, + [ + _c( + "label", + { + class: [ + "col-md-6", + "col-form-label", + _vm.validationErrors["init_confidence_b"] + ? "text-danger" + : "" + ], + attrs: { for: "init_confidence_b" } + }, + [_vm._v("Confidence B (init):")] + ), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.population.init_confidence_b, + expression: "population.init_confidence_b" + } + ], + staticClass: "form-control col-md-6", + attrs: { type: "number", id: "init_confidence_b" }, + domProps: { value: _vm.population.init_confidence_b }, + on: { + input: function($event) { + if ($event.target.composing) { + return + } + _vm.$set( + _vm.population, + "init_confidence_b", + $event.target.value + ) + } + } + }), + _vm._v(" "), + _vm._l( + _vm.validationErrors["init_confidence_b"], function(val_error) { return _c("span", { staticClass: "text-danger" }, [ _vm._v(_vm._s(val_error)) @@ -79564,16 +79746,47 @@ var render = function() { ]), _vm._v(" "), _c("div", { staticClass: "card-body" }, [ - _vm._v( - "\n Voters' and child-populations details and new elections available in\n " - ), - _c( - "a", - { - attrs: { href: _vm.getLink(_vm.current_population.id) } - }, - [_vm._v("Population Template detail view")] - ) + _c("div", [ + _vm._v( + "\n Voters' and child-populations details and new elections available in\n " + ), + _c( + "a", + { + attrs: { + href: _vm.getLink(_vm.current_population.id) + } + }, + [_vm._v("Population Template detail view")] + ) + ]), + _vm._v(" "), + _c("div", [ + _vm._v( + "\n Reputation settings:\n " + ), + _c("li", [ + _vm._v( + "Forgetting: " + + _vm._s(_vm.current_population.forgetting_factor) + + " % " + ), + _c("i", { staticClass: "text-muted" }, [ + _vm._v("(inc/dec towards 0 after each election)") + ]) + ]), + _vm._v(" "), + _c("li", [ + _vm._v( + "Follower: " + + _vm._s(_vm.current_population.follower_factor) + + " " + ), + _c("i", { staticClass: "text-muted" }, [ + _vm._v("(inc/dec multiplier per follower)") + ]) + ]) + ]) ]) ]), _vm._v(" "), @@ -79787,439 +80000,453 @@ var render = function() { _vm._v(_vm._s(_vm.population_name) + " Actions") ]), _vm._v(" "), - _vm.stage_name - ? _c("div", { staticClass: "card-body" }, [ - _vm.population_stats.stage === "l" - ? _c("div", [ - _c("h5", [ - _vm._v( - "Learning stage (" + _vm._s(_vm.election_name) + ")" - ) - ]), - _vm._v(" "), - _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() + _c("div", { staticClass: "card-body" }, [ + _c("div", [ + _c( + "a", + { + attrs: { + href: _vm.getTemplateLink(_vm.population_stats.parent_id) + } + }, + [_vm._v("Back to template")] + ) + ]), + _vm._v(" "), + _c("hr"), + _vm._v(" "), + _vm.stage_name + ? _c("div", [ + _vm.population_stats.stage === "l" + ? _c("div", [ + _c("h5", [_vm._v("Learning stage")]), + _vm._v(" "), + _c("h5", [_vm._v(_vm._s(_vm.election_name))]), + _vm._v(" "), + _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(" "), - _c("h5", [_vm._v("Reputation modifiers:")]), - _vm._v(" "), - _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( + "\n Finish Learning stage\n " + ) + ] + ) + : _vm._e() + ]), + _vm._v(" "), + _c("h5", [_vm._v("Reputation modifiers:")]), + _vm._v(" "), + _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: ") ]), _vm._v(" "), - _c("input", { - directives: [ - { - name: "model", - rawName: "v-model", - value: _vm.custom_number_elections, - expression: "custom_number_elections" - } - ], - staticStyle: { width: "70px" }, - attrs: { - type: "number", - min: "1", - max: "100", - step: "0" - }, - domProps: { value: _vm.custom_number_elections }, - on: { - input: function($event) { - if ($event.target.composing) { - return - } - _vm.custom_number_elections = - $event.target.value - } - } - }), + _c("h5", [_vm._v("Elections")]), _vm._v(" "), - _c( - "button", - { - staticClass: "btn btn-sm btn-outline-info", - attrs: { disabled: _vm.running_elections_lock }, + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c("label", { staticClass: "text-info" }, [ + _vm._v("Number of elections: ") + ]), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.custom_number_elections, + expression: "custom_number_elections" + } + ], + staticStyle: { width: "70px" }, + attrs: { + type: "number", + min: "1", + max: "100", + step: "0" + }, + domProps: { value: _vm.custom_number_elections }, on: { - click: function($event) { - $event.preventDefault() - return _vm.runElections( - _vm.population_stats.election_type, - _vm.custom_number_elections - ) + input: function($event) { + if ($event.target.composing) { + return + } + _vm.custom_number_elections = + $event.target.value } } - }, - [ - _vm._v( - "\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 (" + - _vm._s(_vm.election_name) + - ")" - ) - ]), - _vm._v(" "), - _c("h5", [_vm._v("Elections")]), - _vm._v(" "), - _c("div", [ - _c("label", { staticClass: "text-info" }, [ - _vm._v("Number of elections: ") - ]), - _vm._v(" "), - _c("input", { - directives: [ + }), + _vm._v(" "), + _c( + "button", { - name: "model", - rawName: "v-model", - value: _vm.custom_number_elections, - expression: "custom_number_elections" - } - ], - staticStyle: { width: "70px" }, - attrs: { - type: "number", - min: "1", - max: "100", - step: "0" - }, - domProps: { value: _vm.custom_number_elections }, - on: { - input: function($event) { - if ($event.target.composing) { - return + 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.custom_number_elections = - $event.target.value - } - } - }), + }, + [ + _vm._v( + "\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")]), _vm._v(" "), - _c( - "button", - { - staticClass: "btn btn-sm btn-outline-info", - attrs: { disabled: _vm.running_elections_lock }, + _c("h5", [_vm._v(_vm._s(_vm.election_name))]), + _vm._v(" "), + _c("h5", [_vm._v("Elections")]), + _vm._v(" "), + _c("div", [ + _c("label", { staticClass: "text-info" }, [ + _vm._v("Number of elections: ") + ]), + _vm._v(" "), + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.custom_number_elections, + expression: "custom_number_elections" + } + ], + staticStyle: { width: "70px" }, + attrs: { + type: "number", + min: "1", + max: "100", + step: "0" + }, + domProps: { value: _vm.custom_number_elections }, on: { - click: function($event) { - $event.preventDefault() - return _vm.runElections( - "d1", - _vm.custom_number_elections - ) + input: function($event) { + if ($event.target.composing) { + return + } + _vm.custom_number_elections = + $event.target.value } } - }, - [ - _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.") + }), + _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("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.show_population_stats, - expression: "show_population_stats" - } - ], - attrs: { type: "checkbox" }, - domProps: { - 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.show_population_stats, - $$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_population_stats = $$a.concat([$$v])) + : _c("div", [ + _c("i", { staticClass: "text-warning" }, [ + _vm._v("Unrecognized stage code.") + ]) + ]), + _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.show_population_stats, + expression: "show_population_stats" + } + ], + attrs: { type: "checkbox" }, + domProps: { + 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.show_population_stats, + $$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_population_stats = $$a.concat([ + $$v + ])) + } else { + $$i > -1 && + (_vm.show_population_stats = $$a + .slice(0, $$i) + .concat($$a.slice($$i + 1))) + } } else { - $$i > -1 && - (_vm.show_population_stats = $$a - .slice(0, $$i) - .concat($$a.slice($$i + 1))) + _vm.show_population_stats = $$c } - } else { - _vm.show_population_stats = $$c } } - } - }), + }), + _vm._v(" "), + _c("label", { staticClass: "text-info" }, [ + _vm._v("Show population stats") + ]) + ]), _vm._v(" "), - _c("label", { staticClass: "text-info" }, [ - _vm._v("Show population stats") - ]) - ]), - _vm._v(" "), - _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 - ])) + _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 { - $$i > -1 && - (_vm.show_last_election_chart = $$a - .slice(0, $$i) - .concat($$a.slice($$i + 1))) + _vm.show_last_election_chart = $$c } - } else { - _vm.show_last_election_chart = $$c } } - } - }), + }), + _vm._v(" "), + _c("label", { staticClass: "text-info" }, [ + _vm._v("Show last elections chart") + ]) + ]), _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: [ - { - name: "model", - rawName: "v-model", - value: _vm.show_voters_graph, - expression: "show_voters_graph" - } - ], - attrs: { type: "checkbox" }, - domProps: { - checked: Array.isArray(_vm.show_voters_graph) - ? _vm._i(_vm.show_voters_graph, null) > -1 - : _vm.show_voters_graph - }, - on: { - change: function($event) { - var $$a = _vm.show_voters_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_voters_graph = $$a.concat([$$v])) + _c("div", { staticClass: "col-md-12 col-lg-12" }, [ + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.show_voters_graph, + expression: "show_voters_graph" + } + ], + attrs: { type: "checkbox" }, + domProps: { + checked: Array.isArray(_vm.show_voters_graph) + ? _vm._i(_vm.show_voters_graph, null) > -1 + : _vm.show_voters_graph + }, + on: { + change: function($event) { + var $$a = _vm.show_voters_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_voters_graph = $$a.concat([$$v])) + } else { + $$i > -1 && + (_vm.show_voters_graph = $$a + .slice(0, $$i) + .concat($$a.slice($$i + 1))) + } } else { - $$i > -1 && - (_vm.show_voters_graph = $$a - .slice(0, $$i) - .concat($$a.slice($$i + 1))) + _vm.show_voters_graph = $$c } - } else { - _vm.show_voters_graph = $$c } } - } - }), + }), + _vm._v(" "), + _c("label", { staticClass: "text-info" }, [ + _vm._v("Show voters graph") + ]) + ]), _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])) + _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 { - $$i > -1 && - (_vm.show_timeline_graph = $$a - .slice(0, $$i) - .concat($$a.slice($$i + 1))) + _vm.show_timeline_graph = $$c } - } else { - _vm.show_timeline_graph = $$c } } - } - }), + }), + _vm._v(" "), + _c("label", { staticClass: "text-info" }, [ + _vm._v("Show timeline graph (results)") + ]) + ]), _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 - ])) + _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 { - $$i > -1 && - (_vm.show_weights_timeline_graph = $$a - .slice(0, $$i) - .concat($$a.slice($$i + 1))) + _vm.show_weights_timeline_graph = $$c } - } else { - _vm.show_weights_timeline_graph = $$c } } - } - }), - _vm._v(" "), - _c("label", { staticClass: "text-info" }, [ - _vm._v("Show timeline graph (weights)") + }), + _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." - ) + : _c("div", [ + _c("i", [ + _vm._v( + "Population stage not defined. Cannot run elections." + ) + ]) ]) - ]) + ]) ]), _vm._v(" "), _c("div", { staticClass: "card" }, [ @@ -80560,6 +80787,73 @@ var render = function() { : _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("Last elections status") + ]), + _vm._v(" "), + _c("div", { staticClass: "card-body" }, [ + _vm.last_elections_data + ? _c("div", { staticClass: "row" }, [ + _c( + "div", + { staticClass: "col-md-4 col-lg-4 col-sm-4" }, + [ + _vm._v( + "\n Election type: " + ), + _c("i", [ + _vm._v( + _vm._s(_vm.last_elections_data.elections_type) + ) + ]) + ] + ), + _vm._v(" "), + _c( + "div", + { staticClass: "col-md-4 col-lg-4 col-sm-4" }, + [ + _vm._v( + "\n Number of elections: " + ), + _c("i", [ + _vm._v( + _vm._s( + _vm.last_elections_data.number_of_elections + ) + ) + ]) + ] + ), + _vm._v(" "), + _c( + "div", + { staticClass: "col-md-4 col-lg-4 col-sm-4" }, + [ + _vm._v( + "\n Total time: " + ), + _c("i", [ + _vm._v( + _vm._s(_vm.last_elections_data.total_time) + ) + ]) + ] + ) + ]) + : _c("div", [ + _c("i", [_vm._v("N/A (run elections first)")]) + ]) + ]) + ]) + ]) + ]) + : _vm._e(), + _vm._v(" "), _vm.population_stats ? _c("div", { staticClass: "row mt-1" }, [ _c("div", { staticClass: "col-md-12" }, [ @@ -80665,7 +80959,21 @@ var render = function() { _c("i", [_vm._v("select show graph")]) ]) ]) - : _c("div", [_c("i", [_vm._v("N/A")])]) + : !_vm.current_election_timeline_key + ? _c("div", [ + _c("i", [ + _vm._v( + "N/A use Election Timeline Selector to mark election type" + ) + ]) + ]) + : _c("div", [ + _c("i", [ + _vm._v( + 'N/A yet. Use "Fetch Timeline Results" or mark "Auto Update" and run elections' + ) + ]) + ]) ]) ]) : _vm._e(), @@ -80756,7 +81064,21 @@ var render = function() { _c("i", [_vm._v("select show graph")]) ]) ]) - : _c("div", [_c("i", [_vm._v("N/A")])]) + : !_vm.current_election_timeline_key + ? _c("div", [ + _c("i", [ + _vm._v( + "N/A use Election Timeline Selector to mark election type" + ) + ]) + ]) + : _c("div", [ + _c("i", [ + _vm._v( + 'N/A yet. Use "Fetch Timeline Weights" or mark "Auto Update" and run elections' + ) + ]) + ]) ]) ]) : _vm._e() @@ -81025,7 +81347,7 @@ var render = function() { _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("Last elections chart") ]), _vm._v(" "), _c("div", { staticClass: "card-body" }, [ @@ -81033,43 +81355,6 @@ var render = function() { ? _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(" "), _vm.show_last_election_chart ? _c("bar-chart", { attrs: { diff --git a/resources/js/components/population-create.vue b/resources/js/components/population-create.vue index ec061d8..3272a58 100644 --- a/resources/js/components/population-create.vue +++ b/resources/js/components/population-create.vue @@ -16,7 +16,7 @@ <form> <div class="container-fluid"> <div class="row form-group"> - <div class="col-md-6 form-inline"> + <div class="col-md-12 form-inline"> <label for="size_a" :class="['col-md-6', validationErrors['name'] ? 'text-danger' : '']" >Name (optional):</label> @@ -27,6 +27,28 @@ <span v-for="val_error in validationErrors['name']" class="text-danger">{{ val_error}}</span> </div> </div> + <div class="row form-group"> + <div class="col-md-6 form-inline"> + <label for="size_a" + :class="['col-md-6', validationErrors['forgetting_factor'] ? 'text-danger' : '']" + >Forgetting Factor (optional 1-100%):</label> + <input type="number" + class="form-control col-md-6" + id="forgetting_factor" + v-model="population.forgetting_factor"> + <span v-for="val_error in validationErrors['forgetting_factor']" class="text-danger">{{ val_error}}</span> + </div> + <div class="col-md-6 form-inline"> + <label for="size_a" + :class="['col-md-6', validationErrors['follower_factor'] ? 'text-danger' : '']" + >Follower Factor (optional inc/dec multiplier):</label> + <input type="number" + class="form-control col-md-6" + id="follower_factor" + v-model="population.follower_factor"> + <span v-for="val_error in validationErrors['follower_factor']" class="text-danger">{{ val_error}}</span> + </div> + </div> <hr> <div> <i class="text-info"> @@ -263,6 +285,8 @@ population: { name: null, size_a: 0, + forgetting_factor: 1, + follower_factor: 100, init_expertise_a: 50, spread_expertise_a: 0, init_confidence_a: 50, @@ -290,7 +314,7 @@ addNewPopulation() { console.log('add...'); console.log(this.population); - axios.post(route('internal.api.template.post'), this.population).then((response) => { + axios.post(route('internal.api.templates.post'), this.population).then((response) => { console.log(response.data); Bus.$emit('TemplateCreated', true, response.data.meta); this.clearAndClose(); diff --git a/resources/js/components/population-index.vue b/resources/js/components/population-index.vue index bdf3989..80c126e 100644 --- a/resources/js/components/population-index.vue +++ b/resources/js/components/population-index.vue @@ -55,8 +55,15 @@ <div class="card-header">{{current_population.name}}</div> <div class="card-body"> - Voters' and child-populations details and new elections available in - <a :href="getLink(current_population.id)">Population Template detail view</a> + <div> + Voters' and child-populations details and new elections available in + <a :href="getLink(current_population.id)">Population Template detail view</a> + </div> + <div> + Reputation settings: + <li>Forgetting: {{current_population.forgetting_factor}} % <i class="text-muted">(inc/dec towards 0 after each election)</i></li> + <li>Follower: {{current_population.follower_factor}} <i class="text-muted">(inc/dec multiplier per follower)</i></li> + </div> </div> </div> diff --git a/resources/js/components/population-show.vue b/resources/js/components/population-show.vue index f675b8b..cdb1ae4 100644 --- a/resources/js/components/population-show.vue +++ b/resources/js/components/population-show.vue @@ -5,73 +5,81 @@ <div class="col-md-12"> <div class="card"> <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 ({{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 class="card-body" > + <div> + <a :href="getTemplateLink(population_stats.parent_id)">Back to template</a> + </div> + <hr> + <div v-if="stage_name"> + <div v-if="population_stats.stage === 'l'"> + <h5>Learning stage</h5> + <h5>{{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> </div> - <h5>Reputation modifiers:</h5> + <div v-else-if="population_stats.stage === 'p'"> + <h5>Performance stage</h5> + <h5>{{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> + </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"> - <ul> - <li class="text-info">Forgetting percent: {{population_stats.forgetting_percent}}</li> - <li class="text-info">Follower multiplier: {{population_stats.follower_factor}}</li> - </ul> + <input type="checkbox" v-model="show_population_stats"> + <label class="text-info">Show population stats</label> </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> + <input type="checkbox" v-model="show_last_election_chart"> + <label class="text-info">Show last elections chart</label> </div> - </div> - <div v-else-if="population_stats.stage === 'p'"> - <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 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> - <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_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_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_weights_timeline_graph"> + <label class="text-info">Show timeline graph (weights)</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 v-else> + <i>Population stage not defined. Cannot run elections.</i> </div> - - </div> - <div v-else> - <i>Population stage not defined. Cannot run elections.</i> </div> </div> <div class="card"> @@ -156,6 +164,27 @@ INFO: {{feedback}} </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">Last elections status</div> + <div class="card-body"> + <div class="row" v-if="last_elections_data"> + <div class="col-md-4 col-lg-4 col-sm-4"> + Election type: <i>{{last_elections_data.elections_type}}</i> + </div> + <div class="col-md-4 col-lg-4 col-sm-4"> + Number of elections: <i>{{last_elections_data.number_of_elections}}</i> + </div> + <div class="col-md-4 col-lg-4 col-sm-4"> + Total time: <i>{{last_elections_data.total_time}}</i> + </div> + </div> + <div v-else><i>N/A (run elections first)</i></div> + </div> + </div> + </div> + </div> <div v-if="population_stats" class="row mt-1"> <div class="col-md-12"> <div class="card" v-if="show_voters_graph"> @@ -199,7 +228,10 @@ <i>select show graph</i> </div> </div> - <div v-else><i>N/A</i></div> + <div v-else-if="!current_election_timeline_key"> + <i>N/A use Election Timeline Selector to mark election type</i> + </div> + <div v-else><i>N/A yet. Use "Fetch Timeline Results" or mark "Auto Update" and run elections</i></div> </div> </div> <div class="card" v-if="show_weights_timeline_graph"> @@ -229,7 +261,11 @@ <i>select show graph</i> </div> </div> - <div v-else><i>N/A</i></div> + + <div v-else-if="!current_election_timeline_key"> + <i>N/A use Election Timeline Selector to mark election type</i> + </div> + <div v-else><i>N/A yet. Use "Fetch Timeline Weights" or mark "Auto Update" and run elections</i></div> </div> </div> </div> @@ -309,15 +345,9 @@ <div v-if="population_stats" class="row mt-1"> <div class="col-md-12 col-lg-12"> <div class="card"> - <div class="card-header">Last elections status</div> + <div class="card-header">Last elections chart</div> <div class="card-body"> <div v-if="last_elections_data"> - <div> - Election type: <i>{{last_elections_data.elections_type}}</i> - Number of elections: <i>{{last_elections_data.number_of_elections}}</i> - <br> - Total time: <i>{{last_elections_data.total_time}}</i> - </div> <bar-chart v-if="show_last_election_chart" :chart-data="last_elections_chart_data" :options="{ @@ -353,7 +383,7 @@ components: {LineChart, BarChart, vSelect}, data() { return { - show_population_stats: true, + show_population_stats: false, show_majority_distribution: false, show_last_election_chart: false, show_voters_graph: false, @@ -862,6 +892,9 @@ resetFeedback() { this.feedback = null; }, + getTemplateLink(templateId) { + return route('template.show', templateId); + }, fetchPopulationDetails() { this.feedback = 'fetching voters data..'; axios.get(route( -- GitLab