#1 -- add choosing method on page

This commit is contained in:
Anton Romanov 2022-04-18 12:59:32 +04:00
parent d5c99caeb3
commit c96c3978c6
5 changed files with 213 additions and 5 deletions

View File

@ -50,15 +50,44 @@ public class IndexController {
if (chartForm.getTimeSeriesMeta() != null if (chartForm.getTimeSeriesMeta() != null
&& chartForm.getTimeSeriesMeta().getKey() != null && chartForm.getTimeSeriesMeta().getKey() != null
&& !chartForm.getTimeSeriesMeta().getKey().isEmpty()) { && !chartForm.getTimeSeriesMeta().getKey().isEmpty()) {
addChartToModel(dbService.getTimeSeries(chartForm.getSet(), chartForm.getTimeSeriesMeta().getKey()), model); addChartToModel(dbService.getTimeSeries(chartForm.getSet(), chartForm.getTimeSeriesMeta().getKey()), null, model);
} }
return "index"; return "index";
} }
private void addChartToModel(TimeSeries timeSeries, Model model) throws ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, ModelingException { @GetMapping("/method")
public String method(Model model) throws IOException {
model.addAttribute("sets", dbService.getSets());
model.addAttribute("methods", timeSeriesService.getAvailableMethods());
model.addAttribute("chartForm", new ChartForm());
return "method";
}
@GetMapping("chartMethod")
public String chartMethod(@ModelAttribute ChartForm chartForm, Model model) throws IOException, ModelingException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
model.addAttribute("sets", dbService.getSets());
model.addAttribute("methods", timeSeriesService.getAvailableMethods());
if (chartForm.getSet() != null && !chartForm.getSet().getKey().equals("")) {
model.addAttribute("listTimeSeries", dbService.getTimeSeriesMeta(chartForm.getSet()));
}
if (chartForm.getTimeSeriesMeta() != null
&& chartForm.getTimeSeriesMeta().getKey() != null
&& !chartForm.getTimeSeriesMeta().getKey().isEmpty()
&& chartForm.getMethodClassName() != null) {
addChartToModel(dbService.getTimeSeries(chartForm.getSet(), chartForm.getTimeSeriesMeta().getKey()), chartForm.getMethodClassName(), model);
}
return "method";
}
private void addChartToModel(TimeSeries timeSeries, String method, Model model) throws ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, ModelingException {
int countForecastPoints = timeSeries.getLength() > 20 ? 10 : timeSeries.getLength() / 3; int countForecastPoints = timeSeries.getLength() > 20 ? 10 : timeSeries.getLength() / 3;
TimeSeries timeSeriesModel = timeSeriesService.smoothTimeSeries(timeSeries).getTimeSeries(); TimeSeries timeSeriesModel = timeSeriesService.smoothTimeSeries(timeSeries).getTimeSeries();
ModelingResult modelingResult = timeSeriesService.getForecast(timeSeries, countForecastPoints); ModelingResult modelingResult;
if (method == null) {
modelingResult = timeSeriesService.getForecast(timeSeries, countForecastPoints);
} else {
modelingResult = timeSeriesService.getForecast(timeSeries, method, countForecastPoints);
}
TimeSeries forecast = modelingResult.getTimeSeries(); TimeSeries forecast = modelingResult.getTimeSeries();
TimeSeries testForecast = modelingResult.getTestForecast(); TimeSeries testForecast = modelingResult.getTestForecast();
model.addAttribute("dates", getDatesForChart(timeSeries, forecast)); model.addAttribute("dates", getDatesForChart(timeSeries, forecast));

View File

@ -6,6 +6,7 @@ import ru.ulstu.db.model.TimeSeriesSet;
public class ChartForm { public class ChartForm {
private TimeSeriesSet set; private TimeSeriesSet set;
private TimeSeriesMeta timeSeriesMeta; private TimeSeriesMeta timeSeriesMeta;
private String methodClassName = null;
public TimeSeriesSet getSet() { public TimeSeriesSet getSet() {
return set; return set;
@ -22,4 +23,12 @@ public class ChartForm {
public void setTimeSeriesMeta(TimeSeriesMeta timeSeriesMeta) { public void setTimeSeriesMeta(TimeSeriesMeta timeSeriesMeta) {
this.timeSeriesMeta = timeSeriesMeta; this.timeSeriesMeta = timeSeriesMeta;
} }
public String getMethodClassName() {
return methodClassName;
}
public void setMethodClassName(String methodClassName) {
this.methodClassName = methodClassName;
}
} }

View File

@ -116,7 +116,7 @@ public abstract class Method {
return getName(); return getName();
} }
public String getId() { public String getKey() {
return getClass().getSimpleName(); return getClass().getSimpleName();
} }

View File

@ -13,10 +13,24 @@
<link rel="stylesheet" href="/webjars/font-awesome/4.7.0/css/font-awesome.min.css"/> <link rel="stylesheet" href="/webjars/font-awesome/4.7.0/css/font-awesome.min.css"/>
</head> </head>
<body> <body>
<nav class="navbar navbar-light bg-light"> <nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="/"> <a class="navbar-brand" href="/">
<img src="img/logo.png" width="180" height="60" alt=""> <img src="img/logo.png" width="180" height="60" alt="">
</a> </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>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/">Главная <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="/method">Выбрать метод</a>
</li>
</ul>
</div>
</nav> </nav>
<div class="wrapper"> <div class="wrapper">
<div id="sidebar" class="collapse navbar-collapse sidebar-mobile"> <div id="sidebar" class="collapse navbar-collapse sidebar-mobile">

View File

@ -0,0 +1,156 @@
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml"
layout:decorate="~{default}">
<head>
<title>Time series smoothing</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
</head>
<div class="container" layout:fragment="content">
<script src="/webjars/highcharts/7.0.0/highcharts.js"></script>
<script th:inline="javascript" th:if="${timeSeries != null}">
$(document).ready(function () {
var chart = {
renderTo: 'container',
style: {
fontFamily: 'arial'
}
};
var title = {
text: [[#{messages.time_series_forecast}]]
};
var xAxis = {
categories: [[${dates}]],
title: {
enabled: true,
text: [[#{messages.date}]]
},
startOnTick: true,
endOnTick: true,
showLastLabel: true
};
var yAxis = {
title: {
text: [[#{messages.value}]]
}
};
var plotOptions = {
scatter: {
marker: {
radius: 5,
states: {
hover: {
enabled: true,
lineColor: 'rgb(100,100,100)'
}
}
},
states: {
hover: {
marker: {
enabled: true
}
}
},
tooltip: {
headerFormat: '<b>{series.name}</b><br>',
pointFormat: '{point.y}'
}
}
};
var series = [
{
name: [[#{messages.time_series}]],
color: 'rgba(119,152,191,0.5)',
data: [[${timeSeries}]]
},
{
name: [[#{messages.time_series_model}]],
color: 'rgba(255,200,0,0.5)',
data: [[${model}]]
},
{
name: [[#{messages.time_series_test_forecast}]],
color: 'rgba(255,0,0,0.5)',
data: [[${testForecast}]]
},
{
name: [[#{messages.time_series_forecast_short}]],
color: 'rgba(255,0,0,0.5)',
data: [[${forecast}]]
}
];
var json = {};
json.chart = chart;
json.title = title;
json.xAxis = xAxis;
json.yAxis = yAxis;
json.series = series;
json.plotOptions = plotOptions;
$('#chart').highcharts(json);
});
</script>
<form action="#" th:action="chartMethod" th:object="${chartForm}">
<div class="row">
<div class="col-3">
<select id="select-set" class="selectpicker" data-live-search="true" th:field="*{set}"
data-width="90%" onchange="$('#select-ts').val(''); form.submit();">
<option value="">Набор временных рядов</option>
<option th:each="set : ${sets}"
th:value="${set.key}"
th:utext="${set.key}">
</option>
</select>
<script th:inline="javascript" th:if="*{set != null}">
$('#select-set').val([[*{set.key}]]);
$('#select-set').selectpicker('refresh');
</script>
<select id="select-ts" class="selectpicker" data-live-search="true" th:field="*{timeSeriesMeta}"
data-width="90%" onchange="form.submit();">
<option value="">Временной ряд</option>
<option th:each="ts : ${listTimeSeries}"
th:value="${ts.key}"
th:utext="${ts.key}">
</option>
</select>
<script th:inline="javascript" th:if="*{timeSeriesMeta != null}">
$('#select-ts').val([[*{timeSeriesMeta.key}]]);
$('#select-ts').selectpicker('refresh');
</script>
<select id="select-method" class="selectpicker" data-live-search="true" th:field="*{methodClassName}"
data-width="90%" onchange="form.submit();">
<option value="">Метод прогнозирования</option>
<option th:each="method : ${methods}"
th:value="${method.key}"
th:utext="${method.name}">
</option>
</select>
<script th:inline="javascript" th:if="*{methodClassName != null && methodClassName != ''}">
$('#select-method').val([[*{methodClassName}]]);
$('#select-method').selectpicker('refresh');
</script>
<div th:if="${forecastDescription != null && forecastDescription.timeSeriesMethod != null}">
<p> Метод прогнозирования: <span th:text="${forecastDescription.timeSeriesMethod}"> </span>
<p> Оценка: <span th:text="${forecastDescription.score.value}"> </span>
</div>
</div>
<div class="col-9">
<div id="chart" style="width: 550px; height: 400px; margin: 0 auto"></div>
</div>
</div>
</form>
</div>
</html>