2019-08-20 10:18:01 +02:00
|
|
|
<div class="view">
|
2019-08-22 16:11:04 +02:00
|
|
|
<div id="simulationContainer">
|
|
|
|
<div class="simulationSubContainer">
|
|
|
|
<div style="height: 40%; display: flex">
|
|
|
|
<div style="width: 20%; display: flex; flex-direction: column;">
|
|
|
|
<div class="panel-container" style="display: flex; flex-direction: column; flex-grow: 1">
|
|
|
|
<div style="display: flex;">
|
|
|
|
<select id="select_model_to_simulate" onchange="modelChangeHandler(this)" style="flex-grow: 1;">
|
|
|
|
<?php foreach ($all_models as $model): ?>
|
|
|
|
<option value="<?php echo h($model['DecayingModel']['id']) ?>" <?php echo $decaying_model['DecayingModel']['id'] == $model['DecayingModel']['id'] ? 'selected' : '' ?>><?php echo h($model['DecayingModel']['name']); ?></option>
|
|
|
|
<?php endforeach; ?>
|
|
|
|
</select>
|
|
|
|
<span id="select_model_to_simulate_infobox" class="btn"><span class="fa fa-question-circle"></span></span>
|
|
|
|
</div>
|
2019-07-11 16:49:38 +02:00
|
|
|
|
2019-08-22 16:11:04 +02:00
|
|
|
<ul class="nav nav-tabs" style="margin-right: -5px; margin-bottom: 0px;" id="simulation-tabs">
|
|
|
|
<li class="<?php echo isset($attribute_id) ? '' : 'active'; ?>"><a href="#restsearch" data-toggle="tab">RestSearch</a></li>
|
|
|
|
<li class="<?php echo !isset($attribute_id) ? '' : 'active'; ?>"><a href="#specificid" data-toggle="tab">Specific ID</a></li>
|
|
|
|
</ul>
|
2019-07-09 13:43:41 +02:00
|
|
|
|
2019-08-22 16:11:04 +02:00
|
|
|
<div class="tab-content" style="padding: 5px; height: 100%;">
|
|
|
|
<div class="tab-pane <?php echo isset($attribute_id) ? '' : 'active'; ?>" id="restsearch" style="height: 100%;">
|
|
|
|
<div style="display: flex; flex-direction: column; height: 100%;">
|
|
|
|
<h3 style="">Attribute RestSearch<span style="vertical-align: top; font-size: x-small;" class="fa fa-question-circle" title="Enforced fields: returnFormat"></span></h3>
|
|
|
|
<?php
|
|
|
|
$registered_taxonomies = array_keys($decaying_model['DecayingModel']['parameters']['base_score_config']);
|
|
|
|
foreach ($registered_taxonomies as $i => &$taxonomy_name) {
|
2019-08-28 10:09:35 +02:00
|
|
|
$taxonomy_name = $taxonomy_name . '%' ;
|
2019-08-22 16:11:04 +02:00
|
|
|
}
|
|
|
|
?>
|
|
|
|
<textarea id="restSearchTextarea">
|
|
|
|
{
|
|
|
|
"includeDecayScore": 1,
|
|
|
|
"excludeDecayed": 0,
|
|
|
|
"decayingModel": [<?php echo h($decaying_model['DecayingModel']['id']); ?>],
|
|
|
|
"to_ids": 1,
|
|
|
|
"tags": <?php echo json_encode($registered_taxonomies); ?>,
|
|
|
|
"modelOverrides": {
|
|
|
|
|
|
|
|
}
|
|
|
|
}</textarea>
|
|
|
|
</br>
|
|
|
|
<span class="btn btn-primary" style="width: fit-content;" role="button" onclick="doRestSearch(this)"><?php echo __('Search'); ?></span>
|
|
|
|
</div>
|
2019-07-10 15:52:22 +02:00
|
|
|
</div>
|
2019-08-22 16:11:04 +02:00
|
|
|
<div class="tab-pane <?php echo !isset($attribute_id) ? '' : 'active'; ?>" id="specificid">
|
|
|
|
<h3 style=""><?php echo __('Specific Attribute'); ?></h3>
|
|
|
|
<div style="display: flex;">
|
|
|
|
<div style="margin-left: 4px; margin-bottom: 0px;" class="input-prepend">
|
|
|
|
<span class="add-on">ID</span>
|
|
|
|
<input type="text" value="<?php echo isset($attribute_id) ? h($attribute_id) : ''; ?>" placeholder="<?php echo __('Attribute ID or UUID') ?>" onkeypress="handle_input_key(event)" style="width: auto;">
|
|
|
|
</div>
|
|
|
|
<span id="performRestSearchButton" class="btn btn-primary" style="width: fit-content; margin-left: 4px;" role="button" onclick="doSpecificSearch(this)"><?php echo __('Simulate'); ?></span>
|
2019-07-10 15:52:22 +02:00
|
|
|
</div>
|
|
|
|
</div>
|
2019-07-09 13:43:41 +02:00
|
|
|
</div>
|
|
|
|
|
2019-08-22 16:11:04 +02:00
|
|
|
</div>
|
2019-07-09 13:43:41 +02:00
|
|
|
</div>
|
2019-08-22 16:11:04 +02:00
|
|
|
<div style="width: 80%; display: flex;">
|
|
|
|
<div class="panel-container" style="flex-grow: 1; display: flex;">
|
|
|
|
<div id="basescore-simulation-container" style="width: 30%; min-width: 400px; height: 100%; margin-right: 10px;">
|
2019-08-23 15:32:28 +02:00
|
|
|
<div>
|
|
|
|
<h5 style="display: inline-block;"><?php echo __('Base score') ?> <i id="basescore_enlarge_icon" class="fas fa-expand useCursorPointer"></i></h5>
|
|
|
|
<div id="alert-basescore-not-set" class="alert alert-warning" style="display: inline-block; margin-bottom: auto; margin-left: 5px; padding: 4px 8px;">
|
|
|
|
<strong><?php echo __('Base score configuration'); ?></strong> <?php echo __('not set. But default value sets.') ?>
|
|
|
|
</div>
|
|
|
|
<div id="alert-basescore-not-set" class="alert alert-error" style="display: inline-block; margin-bottom: auto; margin-left: 5px; padding: 4px 8px;">
|
|
|
|
<strong><?php echo __('Base score configuration'); ?></strong> <?php echo __('not set') ?>
|
|
|
|
</div>
|
2019-08-22 16:11:04 +02:00
|
|
|
</div>
|
2019-08-23 15:32:28 +02:00
|
|
|
<div style="position: relative; height: calc(100% - 75px); overflow: auto; margin-bottom: 5px;">
|
2019-08-22 16:11:04 +02:00
|
|
|
<?php echo $this->element('DecayingModels/View/basescore_computation_steps'); ?>
|
|
|
|
</div>
|
2019-08-23 15:32:28 +02:00
|
|
|
<div style="margin-bottom: 5px;">
|
|
|
|
<div style="margin-left: 4px; margin-bottom: 0px;" class="input-prepend input-append">
|
|
|
|
<span class="add-on"><?php echo __('Sighting'); ?></span>
|
|
|
|
<span id="simulation-sighting" class="add-on"></span>
|
|
|
|
</div>
|
|
|
|
<div style="margin-left: 4px; margin-bottom: 0px;" class="input-prepend input-append">
|
|
|
|
<span class="add-on"><?php echo __('Current score'); ?></span>
|
|
|
|
<span id="simulation-current-score" class="add-on"></span>
|
|
|
|
</div>
|
2019-08-22 16:11:04 +02:00
|
|
|
</div>
|
2019-07-17 16:14:24 +02:00
|
|
|
</div>
|
2019-08-22 16:11:04 +02:00
|
|
|
<div id="chart-decay-simulation-container" style="width: 70%; height: 100%; position: relative; overflow: hidden;">
|
|
|
|
<div id="simulation_chart" class="svg-container"></div>
|
2019-07-17 16:14:24 +02:00
|
|
|
</div>
|
|
|
|
</div>
|
2019-07-10 16:39:32 +02:00
|
|
|
</div>
|
2019-07-09 13:43:41 +02:00
|
|
|
</div>
|
2019-08-22 16:11:04 +02:00
|
|
|
<div style="height: 60%; overflow-y: auto; background-color: #ffffff;" class="panel-container">
|
|
|
|
<div style="height: 100%;" id="attributeTableContainer"></div>
|
|
|
|
</div>
|
2019-07-09 13:43:41 +02:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2019-08-20 10:24:03 +02:00
|
|
|
<?php echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'decayingModel', 'menuItem' => '')); ?>
|
2019-07-24 09:22:35 +02:00
|
|
|
<?php
|
|
|
|
echo $this->element('genericElements/assetLoader', array(
|
|
|
|
'css' => array('treemap', 'decayingTool'),
|
|
|
|
'js' => array('d3', 'decayingModelSimulation')
|
|
|
|
));
|
|
|
|
?>
|
2019-07-23 15:18:52 +02:00
|
|
|
|
2019-07-09 13:43:41 +02:00
|
|
|
<script>
|
2019-07-16 15:30:31 +02:00
|
|
|
var model_list = <?php echo json_encode($all_models); ?>;
|
|
|
|
var models = {};
|
2019-07-23 11:56:35 +02:00
|
|
|
$('#alert-basescore-not-set').hide();
|
|
|
|
$('#alert-basescore-not-set.alert-error').hide();
|
2019-07-09 13:43:41 +02:00
|
|
|
$(document).ready(function() {
|
2019-07-16 15:30:31 +02:00
|
|
|
model_list.forEach(function(m) {
|
|
|
|
models[m.DecayingModel.id] = m.DecayingModel;
|
|
|
|
});
|
|
|
|
$('#select_model_to_simulate_infobox').popover({
|
|
|
|
title: function() {
|
2019-08-28 12:09:32 +02:00
|
|
|
return $('<div>').text($('#select_model_to_simulate option:selected').text()).html();
|
2019-07-16 15:30:31 +02:00
|
|
|
},
|
|
|
|
content: function() {
|
|
|
|
return '<div>' + syntaxHighlightJson(models[$('#select_model_to_simulate').val()]) + '</div>';
|
|
|
|
},
|
|
|
|
html: true,
|
|
|
|
placement: 'bottom'
|
|
|
|
});
|
2019-07-24 08:59:35 +02:00
|
|
|
|
2019-08-23 15:32:28 +02:00
|
|
|
$('#basescore_enlarge_icon').click(function() {
|
|
|
|
var $table = $('#computation_help_container > table');
|
|
|
|
var css_container = 'width: 1000px; left: calc(50% - 500px); margin-left: 0;';
|
|
|
|
var css_body = 'max-height: 80%;';
|
|
|
|
openModal('<?php echo __('Basescore computation steps'); ?>', $table[0].outerHTML, '', {}, css_container, css_body);
|
|
|
|
});
|
|
|
|
|
2019-07-24 08:59:35 +02:00
|
|
|
$('body').on('click', function (e) {
|
|
|
|
if (
|
|
|
|
$(e.target).attr('id') !== 'select_model_to_simulate'
|
|
|
|
&& $(e.target).attr('id') !== 'select_model_to_simulate_infobox'
|
|
|
|
&& $(e.target).parents('#select_model_to_simulate_infobox').length === 0
|
|
|
|
&& $(e.target).parents('.popover.in').length === 0) {
|
|
|
|
$('#select_model_to_simulate_infobox').popover('hide');
|
|
|
|
}
|
|
|
|
});
|
2019-07-24 09:22:35 +02:00
|
|
|
|
2019-07-16 15:30:31 +02:00
|
|
|
<?php echo isset($attribute_id) ? '$("#performRestSearchButton").click();' : ''; ?>
|
2019-07-09 13:43:41 +02:00
|
|
|
});
|
2019-07-10 15:52:22 +02:00
|
|
|
|
2019-07-16 15:30:31 +02:00
|
|
|
|
2019-07-10 15:52:22 +02:00
|
|
|
function doRestSearch(clicked, query) {
|
|
|
|
var data = query === undefined ? $(clicked).parent().find('textarea').val() : query;
|
2019-08-14 10:48:13 +02:00
|
|
|
var json;
|
|
|
|
try {
|
|
|
|
json = JSON.parse(data);
|
|
|
|
} catch (SyntaxError) {
|
|
|
|
showMessage('fail', 'Invalid JSON syntax');
|
|
|
|
return;
|
|
|
|
}
|
2019-07-10 15:52:22 +02:00
|
|
|
fetchFormDataAjax('/decayingModel/decayingToolRestSearch/', function(formData) {
|
|
|
|
var $formData = $(formData);
|
|
|
|
url = $formData.find('form').attr('action');
|
|
|
|
$('#simulationContainer').append($formData);
|
|
|
|
$formData.find('#decayingToolRestSearchFilters').val(data);
|
|
|
|
$.ajax({
|
|
|
|
data: $formData.find('form').serialize(),
|
|
|
|
beforeSend:function() {
|
2019-07-24 08:58:45 +02:00
|
|
|
$('#attributeTableContainer').html('<div class="loading-spinner-container"><span class="fa fa-spinner fa-spin" style="font-size: xx-large;"></span></div>');
|
2019-07-10 15:52:22 +02:00
|
|
|
},
|
|
|
|
success:function (data, textStatus) {
|
|
|
|
$('#attributeTableContainer').html(data);
|
2019-07-16 15:30:31 +02:00
|
|
|
var $trs = $('#attributeTableContainer tbody > tr');
|
|
|
|
if ($trs.length == 1) {
|
|
|
|
$trs.click();
|
|
|
|
}
|
2019-08-14 10:48:13 +02:00
|
|
|
// pass potential model overrides
|
|
|
|
if (json.modelOverrides !== undefined) {
|
|
|
|
$trs.data('modelOverride', JSON.stringify(json.modelOverrides));
|
|
|
|
}
|
2019-07-10 15:52:22 +02:00
|
|
|
},
|
2019-08-28 12:09:32 +02:00
|
|
|
error:function(jqXHR, textStatus, errorThrown) {
|
|
|
|
$('#attributeTableContainer').text(textStatus + ': ' + errorThrown);
|
2019-07-10 15:52:22 +02:00
|
|
|
showMessage('fail', '<?php echo __('Failed to perform RestSearch') ?>');
|
|
|
|
},
|
|
|
|
type:'post',
|
|
|
|
cache: false,
|
|
|
|
url: url,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function doSpecificSearch(clicked) {
|
2019-07-25 15:45:33 +02:00
|
|
|
var body = {
|
|
|
|
id: $(clicked).parent().find('input').val(),
|
|
|
|
decayingModel: $('#select_model_to_simulate').val()
|
|
|
|
}
|
|
|
|
doRestSearch(clicked, JSON.stringify(body));
|
2019-07-10 15:52:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function handle_input_key(e) {
|
|
|
|
if(e.keyCode === 13){
|
|
|
|
e.preventDefault();
|
|
|
|
$('#performRestSearchButton').click();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-10 16:39:32 +02:00
|
|
|
function doSimulation(clicked, attribute_id) {
|
|
|
|
$('#attribute_div tr').removeClass('success');
|
|
|
|
$(clicked).addClass('success');
|
2019-07-11 16:49:38 +02:00
|
|
|
var model_id = $('#select_model_to_simulate').val();
|
2019-07-16 10:28:03 +02:00
|
|
|
var simulation_chart = $('#simulation_chart').data('DecayingSimulation');
|
2019-07-18 09:58:11 +02:00
|
|
|
var simulation_table = $('#basescore-simulation-container #computation_help_container_body').data('BasescoreComputationTable');
|
2019-07-16 10:28:03 +02:00
|
|
|
if (simulation_chart === undefined) {
|
|
|
|
simulation_chart = $('#simulation_chart').decayingSimulation({});
|
2019-07-19 10:50:42 +02:00
|
|
|
}
|
|
|
|
if (simulation_table === undefined) {
|
2019-07-18 09:58:11 +02:00
|
|
|
simulation_table = $('#basescore-simulation-container #computation_help_container_body').basescoreComputationTable({});
|
2019-07-16 10:28:03 +02:00
|
|
|
}
|
2019-08-14 10:48:13 +02:00
|
|
|
var url = '/decayingModel/decayingToolComputeSimulation/' + model_id + '/' + attribute_id;
|
|
|
|
var model_override = $(clicked).data('modelOverride');
|
|
|
|
if (model_override !== undefined) {
|
|
|
|
url += '/modelOverride:' + model_override;
|
|
|
|
}
|
2019-07-12 15:20:49 +02:00
|
|
|
$.ajax({
|
|
|
|
beforeSend:function() {
|
|
|
|
simulation_chart.toggleLoading(true);
|
2019-07-17 16:14:24 +02:00
|
|
|
simulation_table.toggleLoading(true);
|
2019-07-11 16:49:38 +02:00
|
|
|
},
|
2019-07-12 15:20:49 +02:00
|
|
|
success:function (data, textStatus) {
|
2019-08-14 10:48:13 +02:00
|
|
|
simulation_chart.update(data, data.Model);
|
|
|
|
simulation_table.update(data, data.Model);
|
2019-07-18 09:58:11 +02:00
|
|
|
if (Object.keys(data.base_score_config.taxonomy_effective_ratios).length > 0) { // show alert base_score not set
|
2019-07-23 11:56:35 +02:00
|
|
|
$('#alert-basescore-not-set').hide();
|
|
|
|
$('#alert-basescore-not-set.alert-error').hide();
|
|
|
|
$('#basescore-simulation-container #computation_help_container_body tr').removeClass('warning').removeClass('error');
|
2019-07-18 09:58:11 +02:00
|
|
|
} else {
|
2019-07-23 11:56:35 +02:00
|
|
|
if (data.base_score_config.default_base_score == 0) { // show alert base_score not set
|
|
|
|
$('#alert-basescore-not-set.alert-error').show('fade', {}, 250);
|
|
|
|
$('#alert-basescore-not-set').hide();
|
|
|
|
$('#basescore-simulation-container #computation_help_container_body tr').removeClass('warning').addClass('error');
|
|
|
|
} else {
|
|
|
|
$('#alert-basescore-not-set').show('fade', {}, 250);
|
|
|
|
$('#alert-basescore-not-set.alert-error').hide();
|
|
|
|
$('#basescore-simulation-container #computation_help_container_body tr').removeClass('error').addClass('warning');
|
|
|
|
}
|
2019-07-18 09:58:11 +02:00
|
|
|
}
|
2019-07-17 16:14:24 +02:00
|
|
|
$('#simulation-sighting')
|
2019-07-18 08:50:15 +02:00
|
|
|
.text(
|
2019-07-17 16:14:24 +02:00
|
|
|
d3.time.format("%c")(new Date(parseInt(data.last_sighting.Sighting.date_sighting)*1000))
|
|
|
|
);
|
|
|
|
$('#simulation-sighting').parent().tooltip({
|
2019-07-19 10:50:42 +02:00
|
|
|
title: 'From ' + (data.last_sighting.Organisation !== undefined ? data.last_sighting.Organisation.name : '?'),
|
2019-07-17 16:14:24 +02:00
|
|
|
});
|
|
|
|
$('#simulation-current-score')
|
2019-07-18 16:30:32 +02:00
|
|
|
.text(data.current_score.toFixed(2))
|
2019-07-18 08:50:15 +02:00
|
|
|
.removeClass(data.current_score > models[$('#select_model_to_simulate').val()].parameters.threshold ? 'alert-error' : 'alert-success')
|
|
|
|
.addClass(data.current_score > models[$('#select_model_to_simulate').val()].parameters.threshold ? 'alert-success' : 'alert-error');
|
|
|
|
|
2019-07-12 15:20:49 +02:00
|
|
|
},
|
|
|
|
error:function() {
|
|
|
|
showMessage('fail', '<?php echo __('Failed to perform the simulation') ?>');
|
|
|
|
},
|
|
|
|
complete:function() {
|
|
|
|
simulation_chart.toggleLoading(false);
|
2019-07-17 16:14:24 +02:00
|
|
|
simulation_table.toggleLoading(false);
|
2019-07-12 15:20:49 +02:00
|
|
|
},
|
|
|
|
type:'get',
|
|
|
|
cache: false,
|
2019-07-16 09:31:49 +02:00
|
|
|
dataType: 'json',
|
2019-08-14 10:48:13 +02:00
|
|
|
url: url,
|
2019-07-12 15:20:49 +02:00
|
|
|
});
|
2019-07-10 16:39:32 +02:00
|
|
|
}
|
2019-07-16 09:31:49 +02:00
|
|
|
|
|
|
|
function refreshSimulation() {
|
|
|
|
var $row = $('#attribute_div tr.success');
|
|
|
|
var attribute_id = $row.find('td:first').text();
|
2019-07-16 15:30:31 +02:00
|
|
|
if (attribute_id !== '') {
|
|
|
|
doSimulation($row, attribute_id);
|
|
|
|
}
|
2019-07-16 09:31:49 +02:00
|
|
|
}
|
2019-07-24 08:59:35 +02:00
|
|
|
|
|
|
|
function modelChangeHandler(clicked) {
|
|
|
|
$('#select_model_to_simulate_infobox').popover('show');
|
|
|
|
refreshSimulation();
|
|
|
|
}
|
2019-07-09 13:43:41 +02:00
|
|
|
</script>
|