aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/api/api/Controllers/DatasetController.cs78
-rw-r--r--backend/api/api/Controllers/ModelController.cs69
-rw-r--r--backend/api/api/Controllers/PredictorController.cs57
-rw-r--r--backend/api/api/Models/Dataset.cs2
-rw-r--r--backend/api/api/Models/Model.cs2
-rw-r--r--backend/api/api/Models/Predictor.cs2
-rw-r--r--backend/api/api/Services/DatasetService.cs28
-rw-r--r--backend/api/api/Services/IDatasetService.cs12
-rw-r--r--backend/api/api/Services/IModelService.cs10
-rw-r--r--backend/api/api/Services/IPredictorService.cs8
-rw-r--r--backend/api/api/Services/MlConnectionService.cs2
-rw-r--r--backend/api/api/Services/ModelService.cs22
-rw-r--r--backend/api/api/Services/PredictorService.cs16
-rw-r--r--backend/api/api/Services/TempRemovalService.cs6
-rw-r--r--backend/api/api/Services/UserService.cs12
-rw-r--r--backend/microservice/api/controller.py2
-rw-r--r--backend/microservice/api/newmlservice.py85
-rw-r--r--frontend/src/app/_data/Dataset.ts2
-rw-r--r--frontend/src/app/_data/Experiment.ts13
-rw-r--r--frontend/src/app/_data/Model.ts2
-rw-r--r--frontend/src/app/_data/Notification.ts1
-rw-r--r--frontend/src/app/_data/Predictor.ts3
-rw-r--r--frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.ts2
-rw-r--r--frontend/src/app/_elements/dataset-load/dataset-load.component.ts6
-rw-r--r--frontend/src/app/_elements/item-predictor/item-predictor.component.html35
-rw-r--r--frontend/src/app/_elements/model-load/model-load.component.html38
-rw-r--r--frontend/src/app/_elements/model-load/model-load.component.ts11
-rw-r--r--frontend/src/app/_elements/notifications/notifications.component.html16
-rw-r--r--frontend/src/app/_elements/notifications/notifications.component.ts26
-rw-r--r--frontend/src/app/_pages/filter-datasets/filter-datasets.component.ts2
-rw-r--r--frontend/src/app/_pages/my-models/my-models.component.html2
-rw-r--r--frontend/src/app/_pages/my-models/my-models.component.ts8
-rw-r--r--frontend/src/app/_pages/my-predictors/my-predictors.component.html27
-rw-r--r--frontend/src/app/_pages/my-predictors/my-predictors.component.ts38
-rw-r--r--frontend/src/app/_services/datasets.service.ts4
-rw-r--r--frontend/src/app/_services/predictors.service.ts2
-rw-r--r--frontend/src/app/app-routing.module.ts2
-rw-r--r--frontend/src/app/experiment/experiment.component.html331
-rw-r--r--frontend/src/app/experiment/experiment.component.ts22
-rw-r--r--frontend/src/app/training/training.component.html2
40 files changed, 534 insertions, 474 deletions
diff --git a/backend/api/api/Controllers/DatasetController.cs b/backend/api/api/Controllers/DatasetController.cs
index add85aba..0a9fe0bd 100644
--- a/backend/api/api/Controllers/DatasetController.cs
+++ b/backend/api/api/Controllers/DatasetController.cs
@@ -25,22 +25,23 @@ namespace api.Controllers
_fileService = fileService;
jwtToken = Token;
}
- public string getUsername()
+
+ public string getUserId()
{
- string username;
+ string userId;
var header = Request.Headers[HeaderNames.Authorization];
if (AuthenticationHeaderValue.TryParse(header, out var headerValue))
{
var scheme = headerValue.Scheme;
var parameter = headerValue.Parameter;
- username = jwtToken.TokenToUsername(parameter);
- if (username == null)
+ userId = jwtToken.TokenToId(parameter);
+ if (userId == null)
return null;
}
else
return null;
- return username;
+ return userId;
}
// GET: api/<DatasetController>/mydatasets
@@ -48,17 +49,17 @@ namespace api.Controllers
[Authorize(Roles = "User,Guest")]
public ActionResult<List<Dataset>> Get()
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
- if (username == "")
+ if (userId == "")
return _datasetService.GetGuestDatasets();
//ako bude trebao ID, samo iz baze uzeti
- return _datasetService.GetMyDatasets(username);
+ return _datasetService.GetMyDatasets(userId);
}
// GET: api/<DatasetController>/datesort/{ascdsc}/{latest}
@@ -69,12 +70,12 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult<List<Dataset>> SortDatasets(bool ascdsc, int latest)
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
- List<Dataset> lista = _datasetService.SortDatasets(username, ascdsc, latest);
+ List<Dataset> lista = _datasetService.SortDatasets(userId, ascdsc, latest);
if (latest == 0)
return lista;
@@ -100,14 +101,7 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult<List<Dataset>> Search(string name)
{
- string username = getUsername();
-
- if (username == null)
- return BadRequest();
-
- //ako bude trebao ID, samo iz baze uzeti
-
- return _datasetService.SearchDatasets(name, username);
+ return _datasetService.SearchDatasets(name);
}
@@ -117,12 +111,12 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult<Dataset> Get(string name)
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
- var dataset = _datasetService.GetOneDataset(username, name);
+ var dataset = _datasetService.GetOneDataset(userId, name);
if (dataset == null)
return NotFound($"Dataset with name = {name} not found or dataset is not public or not preprocessed");
@@ -134,25 +128,15 @@ namespace api.Controllers
[Authorize(Roles = "User,Guest")]
public async Task<ActionResult<Dataset>> Post([FromBody] Dataset dataset)
{
- string uploaderId;
- var header = Request.Headers[HeaderNames.Authorization];
- if (AuthenticationHeaderValue.TryParse(header, out var headerValue))
- {
- var scheme = headerValue.Scheme;
- var parameter = headerValue.Parameter;
- uploaderId = jwtToken.TokenToId(parameter);
- if (uploaderId == null)
- return null;
- }
- else
- return BadRequest();
+ string uploaderId = getUserId();
+
//da li ce preko tokena da se ubaci username ili front salje
//dataset.username = usernameToken;
//username = "" ako je GUEST DODAO
- var existingDataset = _datasetService.GetOneDataset(dataset.username, dataset.name);
+ var existingDataset = _datasetService.GetOneDataset(dataset.uploaderId, dataset.name);
if (existingDataset != null)
- return NotFound($"Dateset with name = {dataset.name} exisits");
+ return NotFound($"Dataset with this name already exists");
else
{
FileModel fileModel = _fileService.getFile(dataset.fileId);
@@ -169,20 +153,20 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult Put(string name, [FromBody] Dataset dataset)
{
- string username = getUsername();
+ string uploaderId = getUserId();
- if (username == null)
+ if (uploaderId == null)
return BadRequest();
- var existingDataset = _datasetService.GetOneDataset(username, name);
+ var existingDataset = _datasetService.GetOneDataset(uploaderId, name);
//ne mora da se proverava
if (existingDataset == null)
- return NotFound($"Dataset with name = {name} or user with username = {username} not found");
+ return NotFound($"Dataset with name = {name} or user with ID = {uploaderId} not found");
dataset.lastUpdated = DateTime.UtcNow;
- _datasetService.Update(username, name, dataset);
+ _datasetService.Update(uploaderId, name, dataset);
return Ok($"Dataset with name = {name} updated");
}
@@ -192,17 +176,17 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult Delete(string name)
{
- string username = getUsername();
+ string uploaderId = getUserId();
- if (username == null)
+ if (uploaderId == null)
return BadRequest();
- var dataset = _datasetService.GetOneDataset(username, name);
+ var dataset = _datasetService.GetOneDataset(uploaderId, name);
if (dataset == null)
- return NotFound($"Dataset with name = {name} or user with username = {username} not found");
+ return NotFound($"Dataset with name = {name} or user with ID = {uploaderId} not found");
- _datasetService.Delete(dataset.username, dataset.name);
+ _datasetService.Delete(dataset.uploaderId, dataset.name);
return Ok($"Dataset with name = {name} deleted");
diff --git a/backend/api/api/Controllers/ModelController.cs b/backend/api/api/Controllers/ModelController.cs
index 04c072da..fe16507b 100644
--- a/backend/api/api/Controllers/ModelController.cs
+++ b/backend/api/api/Controllers/ModelController.cs
@@ -56,23 +56,6 @@ namespace api.Controllers
return uploaderId;
}
- public string getUsername()
- {
- string username;
- var header = Request.Headers[HeaderNames.Authorization];
- if (AuthenticationHeaderValue.TryParse(header, out var headerValue))
- {
- var scheme = headerValue.Scheme;
- var parameter = headerValue.Parameter;
- username = jwtToken.TokenToUsername(parameter);
- if (username == null)
- return null;
- }
- else
- return null;
-
- return username;
- }
[HttpPost("trainModel")]
[Authorize(Roles = "User,Guest")]
@@ -81,16 +64,16 @@ namespace api.Controllers
string experimentId = trainModelObject.ExperimentId;
string modelId = trainModelObject.ModelId;
- string uploaderId = getUserId();
+ string userId = getUserId();
- if (uploaderId == null)
+ if (userId == null)
return BadRequest();
var experiment=_experimentService.Get(experimentId);
var dataset = _datasetService.GetOneDataset(experiment.datasetId);
- var filepath = _fileService.GetFilePath(dataset.fileId, uploaderId);
+ var filepath = _fileService.GetFilePath(dataset.fileId, userId);
var model = _modelService.GetOneModel(modelId);
- _mlService.TrainModel(model,experiment,filepath,dataset,uploaderId);//To do Obavestiti korisnika kada se model istrenira
+ _mlService.TrainModel(model,experiment,filepath,dataset, userId);//To do Obavestiti korisnika kada se model istrenira
return Ok();
}
@@ -99,7 +82,7 @@ namespace api.Controllers
{
var model=_modelService.GetOneModel(info.ModelId);
- var user = _userService.GetUserByUsername(model.username);
+ var user = _userService.GetUserById(model.uploaderId);
if (ChatHub.CheckUser(user._id))
await _ichat.Clients.Client(ChatHub.Users[user._id]).SendAsync("NotifyEpoch",model.name,info.ModelId,info.Stat,model.epochs,info.EpochNum);
@@ -117,12 +100,12 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult<List<Model>> Get()
{
- string username = getUsername();
-
- if (username == null)
+ string uploaderId = getUserId();
+
+ if (uploaderId == null)
return BadRequest();
- return _modelService.GetMyModels(username);
+ return _modelService.GetMyModels(uploaderId);
}
// vraca svoj model prema nekom imenu
@@ -131,12 +114,12 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult<Model> Get(string name)
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
- var model = _modelService.GetOneModel(username, name);
+ var model = _modelService.GetOneModel(userId, name);
if (model == null)
return NotFound($"Model with name = {name} not found");
@@ -155,14 +138,14 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult<List<Model>> GetLatestModels(int latest)
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
//ako bude trebao ID, samo iz baze uzeti
- List<Model> lista = _modelService.GetLatestModels(username);
+ List<Model> lista = _modelService.GetLatestModels(userId);
List<Model> novaLista = new List<Model>();
@@ -185,7 +168,7 @@ namespace api.Controllers
/*if (_modelService.CheckHyperparameters(1, model.hiddenLayerNeurons, model.hiddenLayers, model.outputNeurons) == false)
return BadRequest("Bad parameters!");*/
- var existingModel = _modelService.GetOneModel(model.username, model.name);
+ var existingModel = _modelService.GetOneModel(model.uploaderId, model.name);
if (existingModel != null && !overwrite)
return NotFound($"Model with name = {model.name} exisits");
@@ -209,18 +192,18 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult Put(string name, [FromBody] Model model)
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
- var existingModel = _modelService.GetOneModel(username, name);
+ var existingModel = _modelService.GetOneModel(userId, name);
if (existingModel == null)
- return NotFound($"Model with name = {name} or user with username = {username} not found");
+ return NotFound($"Model with name = {name} or user with ID = {userId} not found");
- _modelService.Update(username, name, model);
+ _modelService.Update(userId, name, model);
return NoContent();
}
@@ -229,17 +212,17 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult Delete(string name)
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
- var model = _modelService.GetOneModel(username, name);
+ var model = _modelService.GetOneModel(userId, name);
if (model == null)
- return NotFound($"Model with name = {name} or user with username = {username} not found");
+ return NotFound($"Model with name = {name} or user with ID = {userId} not found");
- _modelService.Delete(model.username, model.name);
+ _modelService.Delete(model.uploaderId, model.name);
return Ok($"Model with name = {name} deleted");
diff --git a/backend/api/api/Controllers/PredictorController.cs b/backend/api/api/Controllers/PredictorController.cs
index 64907dac..dd5aa5fd 100644
--- a/backend/api/api/Controllers/PredictorController.cs
+++ b/backend/api/api/Controllers/PredictorController.cs
@@ -32,22 +32,22 @@ namespace api.Controllers
_modelService = modelService;
}
- public string getUsername()
+ public string getUserId()
{
- string username;
+ string uploaderId;
var header = Request.Headers[HeaderNames.Authorization];
if (AuthenticationHeaderValue.TryParse(header, out var headerValue))
{
var scheme = headerValue.Scheme;
var parameter = headerValue.Parameter;
- username = jwtToken.TokenToUsername(parameter);
- if (username == null)
+ uploaderId = jwtToken.TokenToId(parameter);
+ if (uploaderId == null)
return null;
}
else
return null;
- return username;
+ return uploaderId;
}
// GET: api/<PredictorController>/mypredictors
@@ -55,12 +55,12 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult<List<Predictor>> Get()
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
- return _predictorService.GetMyPredictors(username);
+ return _predictorService.GetMyPredictors(userId);
}
// GET: api/<PredictorController>/publicpredictors
@@ -90,12 +90,12 @@ namespace api.Controllers
[Authorize(Roles = "User,Guest")]
public ActionResult<Predictor> GetPredictor(string id)
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
- Predictor predictor = _predictorService.GetPredictor(username, id);
+ Predictor predictor = _predictorService.GetPredictor(userId, id);
if (predictor == null)
return NotFound($"Predictor with id = {id} not found");
@@ -108,11 +108,12 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult<Predictor> Get(string id)
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
+ //treba userId da se salje GetOnePredictor
var predictor = _predictorService.GetOnePredictor(id);
if (predictor == null)
@@ -130,12 +131,12 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult<List<Predictor>> SortPredictors(bool ascdsc, int latest)
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
- List<Predictor> lista = _predictorService.SortPredictors(username, ascdsc, latest);
+ List<Predictor> lista = _predictorService.SortPredictors(userId, ascdsc, latest);
if(latest == 0)
return lista;
@@ -154,7 +155,7 @@ namespace api.Controllers
[HttpPost("add")]
public async Task<ActionResult<Predictor>> Post([FromBody] Predictor predictor)
{
- var user=_userService.GetUserByUsername(predictor.username);
+ var user=_userService.GetUserById(predictor.uploaderId);
predictor.dateCreated = DateTime.Now.ToUniversalTime();
var model = _modelService.GetOneModel(predictor.modelId);
if (model == null || user==null)
@@ -171,12 +172,12 @@ namespace api.Controllers
[Authorize(Roles = "User,Guest")]
public async Task<ActionResult> UsePredictor(String id, [FromBody] PredictorColumns[] inputs)
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
- Predictor predictor = _predictorService.GetPredictor(username, id);
+ Predictor predictor = _predictorService.GetPredictor(userId, id);
Experiment e = _experimentService.Get(predictor.experimentId);
@@ -195,16 +196,16 @@ namespace api.Controllers
[Authorize(Roles = "User")]
public ActionResult Put(string id, [FromBody] Predictor predictor)
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
var existingPredictor = _predictorService.GetOnePredictor(id);
//ne mora da se proverava
if (existingPredictor == null)
- return NotFound($"Predictor with id = {id} or user with username = {username} not found");
+ return NotFound($"Predictor with id = {id} or user with ID = {userId} not found");
_predictorService.Update(id, predictor);
@@ -212,21 +213,21 @@ namespace api.Controllers
}
// DELETE api/<PredictorController>/name
- [HttpDelete("{name}")]
+ [HttpDelete("{id}")]
[Authorize(Roles = "User")]
public ActionResult Delete(string id)
{
- string username = getUsername();
+ string userId = getUserId();
- if (username == null)
+ if (userId == null)
return BadRequest();
var predictor = _predictorService.GetOnePredictor(id);
if (predictor == null)
- return NotFound($"Predictor with id = {id} or user with username = {username} not found");
+ return NotFound($"Predictor with id = {id} or user with ID = {userId} not found");
- _predictorService.Delete(id);
+ _predictorService.Delete(id, userId);
return Ok($"Predictor with id = {id} deleted");
diff --git a/backend/api/api/Models/Dataset.cs b/backend/api/api/Models/Dataset.cs
index 47814449..cc7185f0 100644
--- a/backend/api/api/Models/Dataset.cs
+++ b/backend/api/api/Models/Dataset.cs
@@ -7,7 +7,7 @@ namespace api.Models
public class Dataset
{
public Dataset() { }
- public string username { get; set; }
+ public string uploaderId { get; set; }
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]//mongo data type to .net
diff --git a/backend/api/api/Models/Model.cs b/backend/api/api/Models/Model.cs
index 72ee093b..a9dbfbdd 100644
--- a/backend/api/api/Models/Model.cs
+++ b/backend/api/api/Models/Model.cs
@@ -9,7 +9,7 @@ namespace api.Models
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]//mongo data type to .net
public string _id { get; set; }
- public string username { get; set; }
+ public string uploaderId { get; set; }
public string name { get; set; }
diff --git a/backend/api/api/Models/Predictor.cs b/backend/api/api/Models/Predictor.cs
index 26371d2a..8608d766 100644
--- a/backend/api/api/Models/Predictor.cs
+++ b/backend/api/api/Models/Predictor.cs
@@ -9,7 +9,7 @@ namespace api.Models
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]//mongo data type to .net
public string _id { get; set; }
- public string username { get; set; }
+ public string uploaderId { get; set; }
//public string name { get; set; }
//public string description { get; set; }
public string[] inputs { get; set; }
diff --git a/backend/api/api/Services/DatasetService.cs b/backend/api/api/Services/DatasetService.cs
index 176ab424..f260a1ba 100644
--- a/backend/api/api/Services/DatasetService.cs
+++ b/backend/api/api/Services/DatasetService.cs
@@ -14,7 +14,7 @@ namespace api.Services
_dataset = database.GetCollection<Dataset>(settings.DatasetCollectionName);
}
- public List<Dataset> SearchDatasets(string name, string username)
+ public List<Dataset> SearchDatasets(string name)
{
return _dataset.Find(dataset => dataset.name == name && dataset.isPublic == true && dataset.isPreProcess).ToList();
}
@@ -27,27 +27,27 @@ namespace api.Services
}
//brisanje odredjenog name-a
- public void Delete(string username, string name)
+ public void Delete(string userId, string id)
{
- _dataset.DeleteOne(dataset => (dataset.username == username && dataset.name == name));
+ _dataset.DeleteOne(dataset => (dataset.uploaderId == userId && dataset._id == id));
}
- public List<Dataset> GetMyDatasets(string username)
+ public List<Dataset> GetMyDatasets(string userId)
{
- return _dataset.Find(dataset => dataset.username == username && dataset.isPreProcess).ToList();
+ return _dataset.Find(dataset => dataset.uploaderId == userId && dataset.isPreProcess).ToList();
}
public List<Dataset> GetGuestDatasets()
{
//Join Igranonica public datasetove sa svim temp uploadanim datasetovima
- List<Dataset> datasets= _dataset.Find(dataset => dataset.username == "Igrannonica" && dataset.isPublic == true && dataset.isPreProcess).ToList();
- datasets.AddRange(_dataset.Find(dataset => dataset.username == "" && dataset.isPreProcess).ToList());
+ List<Dataset> datasets= _dataset.Find(dataset => dataset.uploaderId == "Igrannonica" && dataset.isPublic == true && dataset.isPreProcess).ToList();
+ datasets.AddRange(_dataset.Find(dataset => dataset.uploaderId == "" && dataset.isPreProcess).ToList());
return datasets;
}
//poslednji datasetovi
- public List<Dataset> SortDatasets(string username, bool ascdsc, int latest)
+ public List<Dataset> SortDatasets(string userId, bool ascdsc, int latest)
{
- List<Dataset> list = _dataset.Find(dataset => dataset.username == username && dataset.isPreProcess).ToList();
+ List<Dataset> list = _dataset.Find(dataset => dataset.uploaderId == userId && dataset.isPreProcess).ToList();
if(ascdsc)
list = list.OrderBy(dataset => dataset.lastUpdated).ToList();
@@ -62,9 +62,9 @@ namespace api.Services
return _dataset.Find(dataset => dataset.isPublic == true && dataset.isPreProcess).ToList();
}
- public Dataset GetOneDataset(string username, string name)
+ public Dataset GetOneDataset(string userId, string name)
{
- return _dataset.Find(dataset => dataset.username == username && dataset.name == name && dataset.isPreProcess).FirstOrDefault();
+ return _dataset.Find(dataset => dataset.uploaderId == userId && dataset.name == name && dataset.isPreProcess).FirstOrDefault();
}
//odraditi za pretragu getOne
@@ -74,9 +74,9 @@ namespace api.Services
}
//ako je potrebno da se zameni name ili ekstenzija
- public void Update(string username, string name, Dataset dataset )
+ public void Update(string userId, string id, Dataset dataset )
{
- _dataset.ReplaceOne(dataset => dataset.username == username && dataset.name == name, dataset);
+ _dataset.ReplaceOne(dataset => dataset.uploaderId == userId && dataset._id == id, dataset);
}
public void Update(Dataset dataset)
{
@@ -85,7 +85,7 @@ namespace api.Services
public string GetDatasetId(string fileId)
{
- Dataset dataset = _dataset.Find(dataset => dataset.fileId == fileId && dataset.username == "Igrannonica").FirstOrDefault();
+ Dataset dataset = _dataset.Find(dataset => dataset.fileId == fileId && dataset.uploaderId == "Igrannonica").FirstOrDefault();
return dataset._id;
}
diff --git a/backend/api/api/Services/IDatasetService.cs b/backend/api/api/Services/IDatasetService.cs
index c6138943..f493a2ec 100644
--- a/backend/api/api/Services/IDatasetService.cs
+++ b/backend/api/api/Services/IDatasetService.cs
@@ -5,15 +5,15 @@ namespace api.Services
{
public interface IDatasetService
{
- Dataset GetOneDataset(string username, string name);
+ Dataset GetOneDataset(string userId, string name);
Dataset GetOneDataset(string id);
- List<Dataset> SearchDatasets(string name, string username);
- List<Dataset> GetMyDatasets(string username);
- List<Dataset> SortDatasets(string username, bool ascdsc, int latest);
+ List<Dataset> SearchDatasets(string name);
+ List<Dataset> GetMyDatasets(string userId);
+ List<Dataset> SortDatasets(string userId, bool ascdsc, int latest);
List<Dataset> GetPublicDatasets();
Dataset Create(Dataset dataset);
- void Update(string username, string name, Dataset dataset);
- void Delete(string username, string name);
+ void Update(string userId, string id, Dataset dataset);
+ void Delete(string userId, string id);
public List<Dataset> GetGuestDatasets();
public void Update(Dataset dataset);
string GetDatasetId(string fileId);
diff --git a/backend/api/api/Services/IModelService.cs b/backend/api/api/Services/IModelService.cs
index e10b8f3b..bcb82e2d 100644
--- a/backend/api/api/Services/IModelService.cs
+++ b/backend/api/api/Services/IModelService.cs
@@ -5,16 +5,16 @@ namespace api.Services
{
public interface IModelService
{
- Model GetOneModel(string username, string name);
+ Model GetOneModel(string userId, string name);
Model GetOneModel(string id);
- List<Model> GetMyModels(string username);
- List<Model> GetLatestModels(string username);
+ List<Model> GetMyModels(string userId);
+ List<Model> GetLatestModels(string userId);
//List<Model> GetPublicModels();
Model Create(Model model);
Model Replace(Model model);
- void Update(string username, string name, Model model);
+ void Update(string userId, string name, Model model);
public void Update(string id, Model model);
- void Delete(string username, string name);
+ void Delete(string userId, string name);
bool CheckHyperparameters(int inputNeurons, int hiddenLayerNeurons, int hiddenLayers, int outputNeurons);
bool CheckDb();
}
diff --git a/backend/api/api/Services/IPredictorService.cs b/backend/api/api/Services/IPredictorService.cs
index 7c31215e..16f0432a 100644
--- a/backend/api/api/Services/IPredictorService.cs
+++ b/backend/api/api/Services/IPredictorService.cs
@@ -5,12 +5,12 @@ namespace api.Services
public interface IPredictorService
{
Predictor Create(Predictor predictor);
- void Delete(string id);
- List<Predictor> GetMyPredictors(string username);
+ void Delete(string id, string userId);
+ List<Predictor> GetMyPredictors(string userId);
Predictor GetOnePredictor(string id);
- Predictor GetPredictor(string username, string id);
+ Predictor GetPredictor(string userId, string id);
List<Predictor> GetPublicPredictors();
- List<Predictor> SortPredictors(string username, bool ascdsc, int latest);
+ List<Predictor> SortPredictors(string userId, bool ascdsc, int latest);
void Update(string id, Predictor predictor);
}
} \ No newline at end of file
diff --git a/backend/api/api/Services/MlConnectionService.cs b/backend/api/api/Services/MlConnectionService.cs
index 22db0aea..17c0f8b8 100644
--- a/backend/api/api/Services/MlConnectionService.cs
+++ b/backend/api/api/Services/MlConnectionService.cs
@@ -67,7 +67,7 @@ namespace api.Services
public async Task<string> Predict(Predictor predictor, Experiment experiment, PredictorColumns[] inputs)
{
- string filePath = _fileService.GetFilePath(predictor.h5FileId, predictor.username);
+ string filePath = _fileService.GetFilePath(predictor.h5FileId, predictor.uploaderId);
var request = new RestRequest("predict", Method.Post);
request.AddParameter("predictor", JsonConvert.SerializeObject(predictor));
diff --git a/backend/api/api/Services/ModelService.cs b/backend/api/api/Services/ModelService.cs
index c21844f7..d3ff9bf9 100644
--- a/backend/api/api/Services/ModelService.cs
+++ b/backend/api/api/Services/ModelService.cs
@@ -26,18 +26,18 @@ namespace api.Services
return model;
}
- public void Delete(string username, string name)
+ public void Delete(string userId, string name)
{
- _model.DeleteOne(model => (model.username == username && model.name == name));
+ _model.DeleteOne(model => (model.uploaderId == userId && model.name == name));
}
- public List<Model> GetMyModels(string username)
+ public List<Model> GetMyModels(string userId)
{
- return _model.Find(model => model.username == username).ToList();
+ return _model.Find(model => model.uploaderId == userId).ToList();
}
- public List<Model> GetLatestModels(string username)
+ public List<Model> GetLatestModels(string userId)
{
- List<Model> list = _model.Find(model => model.username == username).ToList();
+ List<Model> list = _model.Find(model => model.uploaderId == userId).ToList();
list = list.OrderByDescending(model => model.lastUpdated).ToList();
@@ -50,9 +50,9 @@ namespace api.Services
return _model.Find(model => model.isPublic == true).ToList();
}
*/
- public Model GetOneModel(string username, string name)
+ public Model GetOneModel(string userId, string name)
{
- return _model.Find(model => model.username == username && model.name == name).FirstOrDefault();
+ return _model.Find(model => model.uploaderId == userId && model.name == name).FirstOrDefault();
}
public Model GetOneModel(string id)
@@ -60,9 +60,9 @@ namespace api.Services
return _model.Find(model => model._id == id).FirstOrDefault();
}
- public void Update(string username, string name, Model model)
+ public void Update(string userId, string name, Model model)
{
- _model.ReplaceOne(model => model.username == username && model.name == name, model);
+ _model.ReplaceOne(model => model.uploaderId == userId && model.name == name, model);
}
public void Update(string id, Model model)
{
@@ -83,7 +83,7 @@ namespace api.Services
public bool CheckDb()
{
Model? model = null;
- model = _model.Find(model => model.username == "igrannonica").FirstOrDefault();
+ model = _model.Find(model => model.uploaderId == "Igrannonica").FirstOrDefault();
if (model != null)
return false;
diff --git a/backend/api/api/Services/PredictorService.cs b/backend/api/api/Services/PredictorService.cs
index 144248d4..756cc943 100644
--- a/backend/api/api/Services/PredictorService.cs
+++ b/backend/api/api/Services/PredictorService.cs
@@ -21,14 +21,14 @@ namespace api.Services
return predictor;
}
- public void Delete(string id)
+ public void Delete(string id, string userId)
{
- _predictor.DeleteOne(predictor => (predictor._id == id));
+ _predictor.DeleteOne(predictor => (predictor._id == id && predictor.uploaderId == userId));
}
- public List<Predictor> GetMyPredictors(string username)
+ public List<Predictor> GetMyPredictors(string userId)
{
- return _predictor.Find(predictor => predictor.username == username).ToList();
+ return _predictor.Find(predictor => predictor.uploaderId == userId).ToList();
}
public Predictor GetOnePredictor(string id)
@@ -36,15 +36,15 @@ namespace api.Services
return _predictor.Find(predictor => predictor._id == id).FirstOrDefault();
}
- public Predictor GetPredictor(string username, string id)
+ public Predictor GetPredictor(string userId, string id)
{
- return _predictor.Find(predictor => predictor._id == id && (predictor.username == username || predictor.isPublic == true)).FirstOrDefault();
+ return _predictor.Find(predictor => predictor._id == id && (predictor.uploaderId == userId || predictor.isPublic == true)).FirstOrDefault();
}
- public List<Predictor> SortPredictors(string username, bool ascdsc, int latest)
+ public List<Predictor> SortPredictors(string userId, bool ascdsc, int latest)
{
- List<Predictor> list = _predictor.Find(predictor => predictor.username == username).ToList();
+ List<Predictor> list = _predictor.Find(predictor => predictor.uploaderId == userId).ToList();
if (ascdsc)
list = list.OrderBy(predictor => predictor.dateCreated).ToList();
diff --git a/backend/api/api/Services/TempRemovalService.cs b/backend/api/api/Services/TempRemovalService.cs
index e7f366a3..302ca974 100644
--- a/backend/api/api/Services/TempRemovalService.cs
+++ b/backend/api/api/Services/TempRemovalService.cs
@@ -27,7 +27,7 @@ namespace api.Services
if ((DateTime.Now.ToUniversalTime() - file.date).TotalDays >= 1)
{
DeleteFile(file._id);
- List<Dataset> datasets = _dataset.Find(dataset => dataset.fileId == file._id && dataset.username=="").ToList();
+ List<Dataset> datasets = _dataset.Find(dataset => dataset.fileId == file._id && dataset.uploaderId=="").ToList();
foreach(var dataset in datasets)
{
DeleteDataset(dataset._id);
@@ -37,7 +37,7 @@ namespace api.Services
DeleteExperiment(experiment._id);
foreach(var modelId in experiment.ModelIds)
{
- var delModel=_model.Find(model=> modelId== model._id && model.username=="").FirstOrDefault();
+ var delModel=_model.Find(model=> modelId== model._id && model.uploaderId=="").FirstOrDefault();
if(delModel!= null)
DeleteModel(delModel._id);
}
@@ -48,7 +48,7 @@ namespace api.Services
}
}
//Brisanje modela ukoliko gost koristi vec postojeci dataset
- List<Model> models1= _model.Find(model =>model.username == "").ToList();
+ List<Model> models1= _model.Find(model =>model.uploaderId == "").ToList();
foreach(var model in models1)
{
if ((DateTime.Now.ToUniversalTime() - model.dateCreated.ToUniversalTime()).TotalDays >= 1)
diff --git a/backend/api/api/Services/UserService.cs b/backend/api/api/Services/UserService.cs
index 7fc4bdb1..b53f5fdc 100644
--- a/backend/api/api/Services/UserService.cs
+++ b/backend/api/api/Services/UserService.cs
@@ -51,17 +51,17 @@ namespace api.Services
using (var session = _client.StartSession())
{
if(username!=user.Username)
- if(_users.Find(u => u.Username == user.Username).FirstOrDefault()!=null)
- {
- return false;
- }
+ if(_users.Find(u => u.Username == user.Username).FirstOrDefault()!=null)
+ {
+ return false;
+ }
//Trenutan MongoDB Server ne podrzava transakcije.Omoguciti Podrsku
//session.StartTransaction();
try
{
_users.ReplaceOne(user => user.Username == username, user);
- if (username != user.Username)
+ /*if (username != user.Username)
{
var builderModel = Builders<Model>.Update;
var builderDataset = Builders<Dataset>.Update;
@@ -70,7 +70,7 @@ namespace api.Services
_datasets.UpdateMany(x => x.username == username, builderDataset.Set(x => x.username, user.Username));
_predictors.UpdateMany(x => x.username == username, builderPredictor.Set(x => x.username, user.Username));
}
-
+ */
//session.AbortTransaction();
diff --git a/backend/microservice/api/controller.py b/backend/microservice/api/controller.py
index e6515e7b..9b83b8e7 100644
--- a/backend/microservice/api/controller.py
+++ b/backend/microservice/api/controller.py
@@ -78,7 +78,7 @@ def train():
m.append({"Name" : attribute, "JsonValue" : value})
predictor = {
"_id" : "",
- "username" : paramsModel["username"],
+ "uploaderId" : paramsModel["uploaderId"],
"inputs" : paramsExperiment["inputColumns"],
"output" : paramsExperiment["outputColumn"],
"isPublic" : False,
diff --git a/backend/microservice/api/newmlservice.py b/backend/microservice/api/newmlservice.py
index a9bce3bb..9951c25f 100644
--- a/backend/microservice/api/newmlservice.py
+++ b/backend/microservice/api/newmlservice.py
@@ -156,48 +156,53 @@ def train(dataset, paramsModel,paramsExperiment,paramsDataset,callback):
#
### Enkodiranje
encoding=paramsExperiment["encoding"]
- if(encoding=='label'):
- encoder=LabelEncoder()
- for col in data.columns:
- if(data[col].dtype==np.object_):
- data[col]=encoder.fit_transform(data[col])
+ datafront=dataset.copy()
+ svekolone=datafront.columns
+ kategorijskekolone=datafront.select_dtypes(include=['object']).columns
+ for kolona in svekolone:
+ if(kolona in kategorijskekolone):
+ if(encoding=='label'):
+ encoder=LabelEncoder()
+ for col in data.columns:
+ if(data[col].dtype==np.object_):
+ data[col]=encoder.fit_transform(data[col])
- elif(encoding=='onehot'):
- category_columns=[]
- for col in data.columns:
- if(data[col].dtype==np.object_):
- category_columns.append(col)
- data=pd.get_dummies(data, columns=category_columns, prefix=category_columns)
-
- elif(encoding=='ordinal'):
- encoder = OrdinalEncoder()
- for col in data.columns:
- if(data[col].dtype==np.object_):
- data[col]=encoder.fit_transform(data[col])
-
- elif(encoding=='hashing'):
- category_columns=[]
- for col in data.columns:
- if(data[col].dtype==np.object_):
- category_columns.append(col)
- encoder=ce.HashingEncoder(cols=category_columns, n_components=len(category_columns))
- encoder.fit_transform(data)
- elif(encoding=='binary'):
- category_columns=[]
- for col in data.columns:
- if(data[col].dtype==np.object_):
- category_columns.append(col)
- encoder=ce.BinaryEncoder(cols=category_columns, return_df=True)
- encoder.fit_transform(data)
-
- elif(encoding=='baseN'):
- category_columns=[]
- for col in data.columns:
- if(data[col].dtype==np.object_):
- category_columns.append(col)
- encoder=ce.BaseNEncoder(cols=category_columns, return_df=True, base=5)
- encoder.fit_transform(data)
+ elif(encoding=='onehot'):
+ category_columns=[]
+ for col in data.columns:
+ if(data[col].dtype==np.object_):
+ category_columns.append(col)
+ data=pd.get_dummies(data, columns=category_columns, prefix=category_columns)
+
+ elif(encoding=='ordinal'):
+ encoder = OrdinalEncoder()
+ for col in data.columns:
+ if(data[col].dtype==np.object_):
+ data[col]=encoder.fit_transform(data[col])
+
+ elif(encoding=='hashing'):
+ category_columns=[]
+ for col in data.columns:
+ if(data[col].dtype==np.object_):
+ category_columns.append(col)
+ encoder=ce.HashingEncoder(cols=category_columns, n_components=len(category_columns))
+ encoder.fit_transform(data)
+ elif(encoding=='binary'):
+ category_columns=[]
+ for col in data.columns:
+ if(data[col].dtype==np.object_):
+ category_columns.append(col)
+ encoder=ce.BinaryEncoder(cols=category_columns, return_df=True)
+ encoder.fit_transform(data)
+
+ elif(encoding=='baseN'):
+ category_columns=[]
+ for col in data.columns:
+ if(data[col].dtype==np.object_):
+ category_columns.append(col)
+ encoder=ce.BaseNEncoder(cols=category_columns, return_df=True, base=5)
+ encoder.fit_transform(data)
#
# Input - output
#
diff --git a/frontend/src/app/_data/Dataset.ts b/frontend/src/app/_data/Dataset.ts
index 732d1c56..766040a3 100644
--- a/frontend/src/app/_data/Dataset.ts
+++ b/frontend/src/app/_data/Dataset.ts
@@ -10,7 +10,7 @@ export default class Dataset {
public accessibleByLink: boolean = false,
public dateCreated: Date = new Date(),
public lastUpdated: Date = new Date(),
- public username: string = '',
+ public uploaderId: string = '',
public delimiter: string = '',
public hasHeader: boolean = true,
diff --git a/frontend/src/app/_data/Experiment.ts b/frontend/src/app/_data/Experiment.ts
index 453f6ca0..95ef6e1e 100644
--- a/frontend/src/app/_data/Experiment.ts
+++ b/frontend/src/app/_data/Experiment.ts
@@ -1,3 +1,4 @@
+import { ProblemType } from "./Model";
export default class Experiment {
_id: string = '';
uploaderId: string = '';
@@ -18,8 +19,8 @@ export default class Experiment {
public randomTestSet: boolean = true,
public randomTestSetDistribution: number = 0.1, //0.1-0.9 (10% - 90%) JESTE OVDE ZAKUCANO 10, AL POSLATO JE KAO 0.1 BACK-U
- //TODO - za svaku kolonu se bira enkoding
- public encoding: Encoding = Encoding.Label
+ public encodings: ColumnEncoding[] = [],
+ public type: ProblemType = ProblemType.Regression
) { }
}
@@ -65,4 +66,12 @@ export enum Encoding {
WOE = 'woe',
Quantile = 'quantile'
*/
+}
+
+export class ColumnEncoding {
+ constructor (
+ public columnName: string,
+ public encoding: Encoding
+ )
+ {}
} \ No newline at end of file
diff --git a/frontend/src/app/_data/Model.ts b/frontend/src/app/_data/Model.ts
index 1af3fe30..b273f56a 100644
--- a/frontend/src/app/_data/Model.ts
+++ b/frontend/src/app/_data/Model.ts
@@ -19,7 +19,7 @@ export default class Model {
public batchSize: number = 5,
public hiddenLayerActivationFunctions: string[] = ['sigmoid'],
public outputLayerActivationFunction: ActivationFunction = ActivationFunction.Sigmoid,
- public username: string = '',
+ public uploaderId: string = '',
public metrics: string[] = [], // TODO add to add-model form
public epochs: number = 5 // TODO add to add-model form
) { }
diff --git a/frontend/src/app/_data/Notification.ts b/frontend/src/app/_data/Notification.ts
index c505d399..94a3be1d 100644
--- a/frontend/src/app/_data/Notification.ts
+++ b/frontend/src/app/_data/Notification.ts
@@ -1,5 +1,4 @@
export default class Notification {
- _id: string = '';
constructor(
public title: string = 'Treniranje u toku...',
public id: string = '042',
diff --git a/frontend/src/app/_data/Predictor.ts b/frontend/src/app/_data/Predictor.ts
index 7e902eae..8aa2b6cb 100644
--- a/frontend/src/app/_data/Predictor.ts
+++ b/frontend/src/app/_data/Predictor.ts
@@ -7,6 +7,7 @@ export default class Predictor {
public output: string = '',
public isPublic: boolean = false,
public accessibleByLink: boolean = false,
- public dateCreated: Date = new Date()
+ public dateCreated: Date = new Date(),
+ public uploaderId: string = ''
) { }
} \ No newline at end of file
diff --git a/frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.ts b/frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.ts
index 6ff108ce..3e1b5c73 100644
--- a/frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.ts
+++ b/frontend/src/app/_elements/add-new-dataset/add-new-dataset.component.ts
@@ -90,7 +90,7 @@ export class AddNewDatasetComponent {
this.modelsService.uploadData(this.files[0]).subscribe((file) => {
//console.log('ADD MODEL: STEP 2 - ADD DATASET WITH FILE ID ' + file._id);
this.dataset.fileId = file._id;
- this.dataset.username = shared.username;
+ this.dataset.uploaderId = shared.userId;
this.datasetsService.addDataset(this.dataset).subscribe((dataset) => {
this.newDatasetAdded.emit("added");
diff --git a/frontend/src/app/_elements/dataset-load/dataset-load.component.ts b/frontend/src/app/_elements/dataset-load/dataset-load.component.ts
index 62cca456..73dbf2d2 100644
--- a/frontend/src/app/_elements/dataset-load/dataset-load.component.ts
+++ b/frontend/src/app/_elements/dataset-load/dataset-load.component.ts
@@ -41,12 +41,14 @@ export class DatasetLoadComponent implements OnInit {
viewMyDatasetsForm() {
this.showMyDatasets = true;
- this.resetSelectedDataset();
+ if (this.selectedDataset != undefined)
+ this.resetSelectedDataset();
//this.resetCbsAndRbs(); //TREBA DA SE DESI
}
viewNewDatasetForm() {
this.showMyDatasets = false;
- this.resetSelectedDataset();
+ if (this.selectedDataset != undefined)
+ this.resetSelectedDataset();
//this.resetCbsAndRbs(); //TREBA DA SE DESI
}
diff --git a/frontend/src/app/_elements/item-predictor/item-predictor.component.html b/frontend/src/app/_elements/item-predictor/item-predictor.component.html
index 7ae26fd3..3199dcc8 100644
--- a/frontend/src/app/_elements/item-predictor/item-predictor.component.html
+++ b/frontend/src/app/_elements/item-predictor/item-predictor.component.html
@@ -1,26 +1,35 @@
<div class="card" style="min-width: 12rem;">
- <div class="card-header">
- {{predictor.name}}
+ <div class="card-header d-flex mb-2 justify-content-" style="padding: 0;margin: 0;">
+
+ <div class=" p-2 float-left "><b style="color: gray;">Prediktor</b></div>
+
</div>
- <div class="card-body">
+ <div class="card-body overflow-hidden">
+ <b style="color: gray;">Opis</b><hr style="width: 20%;">
<p class="card-text">
- {{predictor.description}}
+ {{predictor.description}}
</p>
- <div class="d-flex flex-column align-items-center">
- <table class="table table-bordered table-sm">
+
+ <b style="color: gray;">Ulazne kolone</b>
+ <div style="overflow: scroll; overflow-y: hidden;">
+
+ <table class="table table-bordered table-md" >
<thead>
- <th class="text-center" *ngFor="let column of predictor.inputs">{{column}}</th>
+ <th scope="col" *ngFor="let column of predictor.inputs" >{{column}}</th>
</thead>
</table>
- <mat-icon>arrow_downward</mat-icon>
- <p>
- {{predictor.output}}
- </p>
+ </div>
+ <b style="color: gray;">Izlazna kolona: </b><b>{{predictor.output}}</b>
+ <hr>
+ <div>
+ <table>
+ <tr><td><span class="material-icons">calendar_today</span></td><td><span style="color: grey;"> <b> Kreirano</b></span></td><td>{{predictor.dateCreated |date}}</td></tr>
+ </table>
</div>
</div>
<div class="card-footer text-center">
- <button class="btn btn-lg col-4" style="background-color:#003459; color:white;"
+ <button class="btn btn-md col-4" style="background-color:#003459; color:white;"
(click)="openPredictor();">Iskoristi</button>
- <!--<a routerLink="/predict" mat-raised-button color="primary">Iskoristi</a>-->
+
</div>
</div> \ No newline at end of file
diff --git a/frontend/src/app/_elements/model-load/model-load.component.html b/frontend/src/app/_elements/model-load/model-load.component.html
index f40ea476..dcb35c21 100644
--- a/frontend/src/app/_elements/model-load/model-load.component.html
+++ b/frontend/src/app/_elements/model-load/model-load.component.html
@@ -17,7 +17,7 @@
<div *ngIf="showMyModels" class="px-5">
<div class="overflow-auto" style="max-height: 500px;">
<ul class="list-group">
- <li class="list-group-item p-3" *ngFor="let model of myModels|filter:term"
+ <li class="list-group-item p-3" *ngFor="let model of myModels|filter:term|filter:(forExperiment ? forExperiment.type : '')"
[ngClass]="{'selectedModelClass': this.selectedModel == model}">
<app-item-model name="usersModel" [model]="model" (click)="selectThisModel(model);">
</app-item-model>
@@ -43,11 +43,7 @@
<textarea class="form-control" name="desc" rows="3" [(ngModel)]="newModel.description"></textarea>
</div>
</div>
- <div class="col-2">
- <label for="dateCreated" class="col-form-label">Datum:</label> &nbsp;&nbsp;
- <input type="text" class="form-control-plaintext" id="dateCreated" placeholder="--/--/--"
- value="{{newModel.dateCreated | date: 'dd/MM/yyyy'}}" readonly>
- </div>
+
</div>
<h2 class="mt-5 mb-4 mx-5">Parametri treniranja modela:</h2>
<div>
@@ -58,7 +54,7 @@
<label for="type" class="col-form-label">Tip problema: </label>
</div>
<div class="col-2">
- <select id=typeOptions class="form-control" name="type" [(ngModel)]="newModel.type"
+ <select id=typeOptions class="form-select" name="type" [(ngModel)]="newModel.type"
(change)="filterOptions()">
<option
*ngFor="let option of Object.keys(ProblemType); let optionName of Object.values(ProblemType)"
@@ -86,7 +82,7 @@
<label for="optimizer" class="col-form-label">Optimizacija: </label>
</div>
<div class="col-2">
- <select id=optimizerOptions class="form-control" name="optimizer" [(ngModel)]="newModel.optimizer">
+ <select id=optimizerOptions class="form-select" name="optimizer" [(ngModel)]="newModel.optimizer">
<option
*ngFor="let option of Object.keys(Optimizer); let optionName of Object.values(Optimizer)"
[value]="option">
@@ -108,10 +104,10 @@
<div class="row p-2">
<div class="col-1"></div>
<div class="col-3">
- <label for="lossFunction" class="col-form-label">Funkcija obrade gubitka: </label>
+ <label for="lossFunction" class="col-form-label">Funkcija troška: </label>
</div>
<div class="col-2">
- <select id=lossFunctionOptions class="form-control" name="lossFunction"
+ <select id=lossFunctionOptions class="form-select" name="lossFunction"
[(ngModel)]="newModel.lossFunction" aria-checked="true">
<option
*ngFor="let option of Object.keys(lossFunction); let optionName of Object.values(lossFunction)"
@@ -125,7 +121,21 @@
<label for="batchSize" class="col-form-label">Broj uzorka po iteraciji: </label>
</div>
<div class="col-1">
- <input type="number" min="1" class="form-control" name="batchSize" [(ngModel)]="newModel.batchSize">
+
+ <input type="number" min="0" step="1" max="7" class="form-control" name="batchSizePower" [(ngModel)]="batchSizePower" (click)="updateBatchSize()" >
+ {{newModel.batchSize}}
+
+ </div>
+
+ <div class="row p-2">
+ <div class="col-1"></div>
+ <div class="col-3 m-1">
+ <label for="epochs" class="col-form-label">Broj epoha: </label>
+ </div>
+ <div class="col-1">
+ <input type="number" min="1" max="1000" class="form-control" name="epochs"
+ [(ngModel)]="newModel.epochs">
+ </div>
</div>
</div>
@@ -147,8 +157,8 @@
<div class="input-group-prepend">
<span class="input-group-text">#{{i+1}}</span>
</div>
- <select [id]="'hiddenLayerActivationFunctionOption_'+i" class="form-control"
- [(ngModel)]="newModel.hiddenLayerActivationFunctions[i]">
+ <select [id]="'hiddenLayerActivationFunctionOption_'+i" class="form-select"
+ [(ngModel)]="newModel.hiddenLayerActivationFunctions[i]" >
<option
*ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)"
[value]="option">
@@ -164,7 +174,7 @@
style="text-align: center;">Funkcija aktivacije<br>izlaznog sloja:</label>
</div>
<div class="col-2 mt-2">
- <select id=outputLayerActivationFunctionOptions class="form-control"
+ <select id=outputLayerActivationFunctionOptions class="form-select"
name="outputLayerActivationFunction" [(ngModel)]="newModel.outputLayerActivationFunction">
<option
*ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)"
diff --git a/frontend/src/app/_elements/model-load/model-load.component.ts b/frontend/src/app/_elements/model-load/model-load.component.ts
index 745dc12e..dbca3d17 100644
--- a/frontend/src/app/_elements/model-load/model-load.component.ts
+++ b/frontend/src/app/_elements/model-load/model-load.component.ts
@@ -1,5 +1,6 @@
-import { Component, OnInit, ViewChild, Output, EventEmitter } from '@angular/core';
+import { Component, OnInit, ViewChild, Output, EventEmitter, Input } from '@angular/core';
import Shared from 'src/app/Shared';
+import Experiment from 'src/app/_data/Experiment';
import Model, { ActivationFunction, LossFunction, LossFunctionBinaryClassification, LossFunctionMultiClassification, LossFunctionRegression, Metrics, MetricsBinaryClassification, MetricsMultiClassification, MetricsRegression, NullValueOptions, Optimizer, ProblemType } from 'src/app/_data/Model';
import { ModelsService } from 'src/app/_services/models.service';
import { GraphComponent } from '../graph/graph.component';
@@ -13,6 +14,7 @@ import { GraphComponent } from '../graph/graph.component';
export class ModelLoadComponent implements OnInit {
@ViewChild(GraphComponent) graph!: GraphComponent;
+ @Input() forExperiment?:Experiment;
@Output() selectedModelChangeEvent = new EventEmitter<Model>();
newModel: Model = new Model();
@@ -43,6 +45,11 @@ export class ModelLoadComponent implements OnInit {
ngOnInit(): void {
}
+ batchSizePower:number=1;
+ updateBatchSize()
+ {
+ this.newModel.batchSize=2**this.batchSizePower;
+ }
updateGraph() {
this.graph.update();
@@ -62,7 +69,7 @@ export class ModelLoadComponent implements OnInit {
uploadModel() {
this.getMetrics();
- this.newModel.username = Shared.username;
+ this.newModel.uploaderId = Shared.userId;
this.modelsService.addModel(this.newModel).subscribe((response) => {
Shared.openDialog('Model dodat', 'Model je uspešno dodat u bazu.');
diff --git a/frontend/src/app/_elements/notifications/notifications.component.html b/frontend/src/app/_elements/notifications/notifications.component.html
index ef897cfc..3b2f4eaa 100644
--- a/frontend/src/app/_elements/notifications/notifications.component.html
+++ b/frontend/src/app/_elements/notifications/notifications.component.html
@@ -11,14 +11,18 @@
</button>
</h2>
- <div id="collapseNotifs" class="collapse show">
+ <div id="collapseNotifs" class="collapse show overflow-auto" style="max-height: 32rem;">
<div *ngFor="let notification of notifications" class="p-2 m-1 border rounded">
- <div class="d-flex flex-row">
- <p>{{notification.title}}</p>
- </div>
- <div *ngIf="notification.hasProgress" class="border-3 border-primary bg-dark m-1" style="height: 5px; margin-top: -10px !important;">
- <div class="bg-primary" style="height: 5px;" [style]="'width: '+(notification.progress*100)+'%;'">
+ <div class="d-flex flex-row ">
+ <div>
+ <p>{{notification.title}}</p>
+ <div *ngIf="notification.hasProgress" class="border-3 border-primary bg-dark m-1" style="height: 5px; margin-top: -10px !important; min-width: 12rem;">
+ <div class="bg-primary" style="height: 5px;" [style]="'width: '+(notification.progress*100)+'%;'">
+ </div>
+ </div>
</div>
+ <button type="button" class="btn-close ms-auto align-self-center" aria-label="Close" (click)="removeNotification(notification);"></button>
</div>
+
</div>
</div> \ No newline at end of file
diff --git a/frontend/src/app/_elements/notifications/notifications.component.ts b/frontend/src/app/_elements/notifications/notifications.component.ts
index e199f70a..9b460240 100644
--- a/frontend/src/app/_elements/notifications/notifications.component.ts
+++ b/frontend/src/app/_elements/notifications/notifications.component.ts
@@ -21,13 +21,33 @@ export class NotificationsComponent implements OnInit {
this.notifications.push(new Notification(`Obrađen izvor podataka: ${dName}`, dId, 1.0, false));
});
- this.signalRService.hubConnection.on("NotifyEpoch", (epoch: string, mName: string, mId: string, numEpochs) => {
- //todo epoch
- this.notifications.push(new Notification(`Treniranje modela: ${mName}`, mId, 0.5));
+ this.signalRService.hubConnection.on("NotifyEpoch", (mName: string, mId: string, stat: string, totalEpochs: number, currentEpoch: number) => {
+ const existingNotification = this.notifications.find(x => x.id === mId)
+ const progress = ((currentEpoch + 1) / totalEpochs);
+ console.log("Ukupno epoha", totalEpochs, "Trenutna epoha:", currentEpoch);
+ if (!existingNotification)
+ this.notifications.push(new Notification(`Treniranje modela: ${mName}`, mId, progress, true));
+ else {
+ existingNotification.progress = progress;
+ }
+ });
+
+ this.signalRService.hubConnection.on("NotifyModel", (mName: string, mId: string, stat: string, totalEpochs: number, currentEpoch: number) => {
+ const existingNotification = this.notifications.find(x => x.id === mId)
+ const progress = ((currentEpoch + 1) / totalEpochs);
+ if (!existingNotification)
+ this.notifications.push(new Notification(`Treniranje modela: ${mName}`, mId, progress, true));
+ else {
+ existingNotification.progress = progress;
+ }
});
} else {
console.warn("Notifications: No connection!");
}
}
+ removeNotification(notification: Notification) {
+ this.notifications.splice(this.notifications.indexOf(notification), 1);
+ }
+
}
diff --git a/frontend/src/app/_pages/filter-datasets/filter-datasets.component.ts b/frontend/src/app/_pages/filter-datasets/filter-datasets.component.ts
index c83bf208..66b3755e 100644
--- a/frontend/src/app/_pages/filter-datasets/filter-datasets.component.ts
+++ b/frontend/src/app/_pages/filter-datasets/filter-datasets.component.ts
@@ -33,7 +33,7 @@ export class FilterDatasetsComponent implements OnInit {
newDataset._id = "";
newDataset.isPublic = false;
newDataset.lastUpdated = new Date();
- newDataset.username = decodedToken.name;
+ newDataset.uploaderId = decodedToken.uploaderId;
let name=prompt("Unesite naziv dataset-a",newDataset.name);
newDataset.name=name as string;
if(name!=null && name!="")
diff --git a/frontend/src/app/_pages/my-models/my-models.component.html b/frontend/src/app/_pages/my-models/my-models.component.html
index b0e9c4ef..9b281239 100644
--- a/frontend/src/app/_pages/my-models/my-models.component.html
+++ b/frontend/src/app/_pages/my-models/my-models.component.html
@@ -15,7 +15,7 @@
<div class="panel-footer row"><!-- panel-footer -->
<div class="col-xs-6 text-center">
<div>
- <button type="button" class="btn btn-default btn-lg"style="min-width: 7rem;float: left;" (click)="deleteThisModel(model)" mat-raised-button color="primary">Koristi
+ <button type="button" class="btn btn-default btn-lg"style="min-width: 7rem;float: left;" (click)="useThisModel(model)" mat-raised-button color="primary">Koristi
<span class="glyphicon glyphicon-search"></span>
</button>
<button (click)="deleteThisModel(model)" mat-raised-button color="warn" style="min-width: 7rem;float: right" ><mat-icon>delete</mat-icon></button>
diff --git a/frontend/src/app/_pages/my-models/my-models.component.ts b/frontend/src/app/_pages/my-models/my-models.component.ts
index 92d3fbaa..d379fa69 100644
--- a/frontend/src/app/_pages/my-models/my-models.component.ts
+++ b/frontend/src/app/_pages/my-models/my-models.component.ts
@@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
import shared from 'src/app/Shared';
import Model from 'src/app/_data/Model';
import { ModelsService } from 'src/app/_services/models.service';
@@ -12,7 +13,7 @@ export class MyModelsComponent implements OnInit {
myModels: Model[] = [];
//myModel: Model;
- constructor(private modelsS : ModelsService) {
+ constructor(private modelsS : ModelsService, private router : Router) {
@@ -44,6 +45,11 @@ deleteThisModel(model: Model): void{
}
+useThisModel(model: Model): void{
+
+ this.router.navigate(['/training'])
+
+}
getAllMyModels(): void{
this.modelsS.getMyModels().subscribe(m => {
this.myModels = m;
diff --git a/frontend/src/app/_pages/my-predictors/my-predictors.component.html b/frontend/src/app/_pages/my-predictors/my-predictors.component.html
index d38f93e4..31fa786c 100644
--- a/frontend/src/app/_pages/my-predictors/my-predictors.component.html
+++ b/frontend/src/app/_pages/my-predictors/my-predictors.component.html
@@ -1,16 +1,23 @@
<div id="header">
<h1>Trenirani modeli</h1>
</div>
-<div id="container" style="background-color:rgba(255, 255, 255, 0.8);">
-<div class="row" *ngFor="let predictor of predictors">
- <div class="left">
- <app-item-predictor [predictor]="predictor"></app-item-predictor>
- </div>
- <div>
- <button (click)="delete(predictor)" mat-raised-button color="warn" style="min-width: 15rem;float: right" ><mat-icon>delete</mat-icon></button>
- </div>
-
+<div id="wrapper">
+<div id="container" class="container p-5" style="background-color:rgba(255, 255, 255, 0.8); min-height: 100%;">
+ <div class="row mt-3 mb-2 d-flex justify-content-center">
+
+ <div class="col-sm-6" style="margin-bottom: 10px;">
+ </div>
+ <div class="row">
+ <div class="col-sm-4" style="margin-bottom: 10px;" *ngFor="let predictor of predictors">
+ <app-item-predictor [predictor]="predictor"></app-item-predictor>
+ <div>
+ <button (click)="deleteThisPredictor(predictor)" mat-raised-button color="warn" style="min-width: 10rem;float: right" ><mat-icon>delete</mat-icon></button>
+ </div>
+ </div>
+ </div>
+</div>
</div>
-
</div>
+
+
diff --git a/frontend/src/app/_pages/my-predictors/my-predictors.component.ts b/frontend/src/app/_pages/my-predictors/my-predictors.component.ts
index 17c496fd..4dc5300d 100644
--- a/frontend/src/app/_pages/my-predictors/my-predictors.component.ts
+++ b/frontend/src/app/_pages/my-predictors/my-predictors.component.ts
@@ -1,7 +1,7 @@
import { Component, OnInit } from '@angular/core';
import Predictor from 'src/app/_data/Predictor';
import { PredictorsService } from 'src/app/_services/predictors.service';
-
+import shared from 'src/app/Shared';
@Component({
selector: 'app-my-predictors',
templateUrl: './my-predictors.component.html',
@@ -12,28 +12,30 @@ export class MyPredictorsComponent implements OnInit {
constructor(private predictorsS : PredictorsService) {
}
ngOnInit(): void {
- this.getAllMyPredictors();
-
+ this.predictorsS.getMyPredictors().subscribe((response) => {
+ this.predictors = response;
+ }, (error) => {
+ if (error.error == "Predictor with...") {
+ shared.openDialog("Greska", "Greska");
+ }
+ });
}
- delete(predictor: Predictor){
- if(window.confirm("IZABRANI MODEL ĆE BITI IZBRISAN"))
- {
- this.predictorsS.deletePredictor(predictor).subscribe((response) => {
- this.getAllMyPredictors();
- }, (error) =>{
- if (error.error == "Predictor with name = {name} deleted") {
- alert("Greška pri brisanju modela!");
- }
- });
- }
-
-
+ deleteThisPredictor(predictor: Predictor): void{
+ shared.openYesNoDialog('Brisanje prediktora','Da li ste sigurni da želite da obrišete prediktor?',() => {
+ this.predictorsS.deletePredictor(predictor).subscribe((response) => {
+ this.getAllMyPredictors();
+ }, (error) =>{
+ if (error.error == "Predictor with name = {name} deleted") {
+ shared.openDialog("Obaveštenje", "Greška prilikom brisanja prediktora.");
+ }
+ });
+ });
}
getAllMyPredictors(): void{
- this.predictorsS.getMyPredictors().subscribe(m => {
- this.predictors = m;
+ this.predictorsS.getMyPredictors().subscribe(p => {
+ this.predictors = p;
});
}
diff --git a/frontend/src/app/_services/datasets.service.ts b/frontend/src/app/_services/datasets.service.ts
index c3281be6..b2272f0a 100644
--- a/frontend/src/app/_services/datasets.service.ts
+++ b/frontend/src/app/_services/datasets.service.ts
@@ -29,10 +29,10 @@ export class DatasetsService {
}
editDataset(dataset: Dataset): Observable<Dataset> {
- return this.http.put<Dataset>(`${Configuration.settings.apiURL}/dataset/`, dataset, { headers: this.authService.authHeader() });
+ return this.http.put<Dataset>(`${Configuration.settings.apiURL}/dataset/` + dataset._id, dataset, { headers: this.authService.authHeader() });
}
deleteDataset(dataset: Dataset) {
- return this.http.delete(`${Configuration.settings.apiURL}/dataset/` + dataset.name, { headers: this.authService.authHeader(), responseType: "text" });
+ return this.http.delete(`${Configuration.settings.apiURL}/dataset/` + dataset._id, { headers: this.authService.authHeader(), responseType: "text" });
}
}
diff --git a/frontend/src/app/_services/predictors.service.ts b/frontend/src/app/_services/predictors.service.ts
index 9e8383aa..a24ee708 100644
--- a/frontend/src/app/_services/predictors.service.ts
+++ b/frontend/src/app/_services/predictors.service.ts
@@ -24,7 +24,7 @@ export class PredictorsService {
}
deletePredictor(predictor: Predictor) {
- return this.http.delete(`${Configuration.settings.apiURL}/predictor/` + predictor.name, { headers: this.authService.authHeader(), responseType: "text" });
+ return this.http.delete(`${Configuration.settings.apiURL}/predictor/` + predictor._id, { headers: this.authService.authHeader(), responseType: "text" });
}
getMyPredictors(): Observable<Predictor[]> {
diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts
index e22f7a88..238668d9 100644
--- a/frontend/src/app/app-routing.module.ts
+++ b/frontend/src/app/app-routing.module.ts
@@ -20,6 +20,7 @@ const routes: Routes = [
/*{ path: 'add-model', component: AddModelComponent, data: { title: 'Dodaj model' } },*/
{ path: 'experiment', component: ExperimentComponent, data: { title: 'Dodaj eksperiment' } },
{ path: 'training', component: TrainingComponent, data: { title: 'Treniraj model' } },
+ { path: 'training/:id', component: TrainingComponent, data: { title: 'Treniraj model' } },
{ path: 'my-datasets', component: MyDatasetsComponent, canActivate: [AuthGuardService], data: { title: 'Moji izvori podataka' } },
{ path: 'my-models', component: MyModelsComponent, canActivate: [AuthGuardService], data: { title: 'Moji modeli' } },
{ path: 'my-predictors', component: MyPredictorsComponent, canActivate: [AuthGuardService], data: { title: 'Moji trenirani modeli' } },
@@ -28,6 +29,7 @@ const routes: Routes = [
{ path: 'browse-datasets', component: FilterDatasetsComponent, data: { title: 'Javni izvori podataka' } },
{ path: 'browse-predictors', component: BrowsePredictorsComponent, data: { title: 'Javni trenirani modeli' } },
{ path: 'predict/:id', component: PredictComponent, data: { title: 'Predvidi vrednosti' } },
+
];
@NgModule({
diff --git a/frontend/src/app/experiment/experiment.component.html b/frontend/src/app/experiment/experiment.component.html
index e46f5bd9..62236cce 100644
--- a/frontend/src/app/experiment/experiment.component.html
+++ b/frontend/src/app/experiment/experiment.component.html
@@ -13,150 +13,132 @@
</div>
<div id="carouselExampleControls" class="carousel slide px-5 mt-5" data-bs-wrap="false" data-bs-ride="carousel" data-bs-interval="false">
- <div class="carousel-inner">
- <div class="carousel-item active mt-2">
- <h2 class="mb-5">1. Izvor podataka</h2>
- <app-dataset-load (selectedDatasetChangeEvent)="updateDataset($event)"></app-dataset-load>
- </div>
+ <div class="carousel-inner">
+ <div class="carousel-item active mt-2">
+ <h2 class="mb-5">1. Izvor podataka</h2>
+ <app-dataset-load (selectedDatasetChangeEvent)="updateDataset($event)"></app-dataset-load>
+ </div>
- <div class="carousel-item mt-2">
- <h2 class="mb-4">2. Preprocesiranje</h2>
+ <div class="carousel-item mt-2">
+ <h2 class="mb-4">2. Preprocesiranje</h2>
- <div class="px-5">
- <h3>Biranje ulaznih i izlaznih kolona:</h3>
- <div *ngIf="selectedDataset">
- <div class="row">
- <div class="col d-flex justify-content-center">
- <h3>Izaberite ulazne kolone:</h3>
- <div id="divInputs" class="form-check mt-2">
- <br>
- <div *ngFor="let item of selectedDataset.columnInfo; let i = index">
- <input class="form-check-input" type="checkbox" value="{{item.columnName}}"
- id="cb_{{item.columnName}}" name="cbsNew"
- [checked]="experiment.outputColumn != item.columnName"
- [disabled]="experiment.outputColumn == item.columnName"
- (click)="checkedColumnsChanged(item, 0)">&nbsp;
- <label class="form-check-label" for="cb_{{item.columnName}}">
+ <div class="px-5">
+ <h3>Biranje ulaznih i izlaznih kolona:</h3>
+ <div *ngIf="selectedDataset">
+ <div class="row">
+ <div class="col d-flex justify-content-center">
+ <h3>Izaberite ulazne kolone:</h3>
+ <div id="divInputs" class="form-check mt-2">
+ <br>
+ <div *ngFor="let item of selectedDataset.columnInfo; let i = index">
+ <input class="form-check-input" type="checkbox" value="{{item.columnName}}" id="cb_{{item.columnName}}" name="cbsNew" [checked]="experiment.outputColumn != item.columnName" [disabled]="experiment.outputColumn == item.columnName" (change)="checkedColumnsChanged(item, 0); resetColumnEncodings();">&nbsp;
+ <label class="form-check-label" for="cb_{{item.columnName}}">
{{item.columnName}}
</label>
+ </div>
</div>
</div>
- </div>
- <div class="col d-flex justify-content-left">
- <h3>Izaberite izlaznu kolonu:</h3>
- <div id="divOutputs" class="form-check mt-2">
- <br>
- <div *ngFor="let item of selectedDataset.columnInfo; let i = index">
- <input class="form-check-input" type="radio" value="{{item.columnName}}"
- id="rb_{{item.columnName}}" name="rbsNew"
- [(ngModel)]="this.experiment.outputColumn"
- (change)="experiment.outputColumn = item.columnName"
- (click)="checkedColumnsChanged(item, 1);">&nbsp;
- <label class="form-check-label" for="rb_{{item.columnName}}">
+ <div class="col d-flex justify-content-left">
+ <h3>Izaberite izlaznu kolonu:</h3>
+ <div id="divOutputs" class="form-check mt-2">
+ <br>
+ <div *ngFor="let item of selectedDataset.columnInfo; let i = index">
+ <input class="form-check-input" type="radio" value="{{item.columnName}}" id="rb_{{item.columnName}}" name="rbsNew" [(ngModel)]="this.experiment.outputColumn" (change)="experiment.outputColumn = item.columnName; checkedColumnsChanged(item, 1); resetColumnEncodings();"
+ checked>&nbsp;
+ <label class="form-check-label" for="rb_{{item.columnName}}">
{{item.columnName}}
</label>
+ </div>
</div>
</div>
</div>
</div>
- </div>
-
- <h3 class="mt-5">Popunjavanje nedostajućih vrednosti:</h3>
- <div class="form-check" *ngIf="selectedDataset">
- <input type="radio" [(ngModel)]="experiment.nullValues" [value]="NullValueOptions.DeleteRows"
- class="form-check-input" value="deleteRows" name="fillMissing" id="delRows" checked
- data-bs-toggle="collapse" data-bs-target="#fillMissingCustom.show">
- <label for="delRows" class="form-check-label">Obriši sve
+
+
+ <div class="mt-5 mb-3 mx-3" *ngIf="countSelectedNullCols() == 0">
+ <h3 class="border p-2 text-center"><i>Izabrane kolone nemaju nedostajuće vrednosti koje možete popuniti.</i></h3>
+ </div>
+
+ <div *ngIf="countSelectedNullCols() != 0">
+ <h3 class="mt-5">Popunjavanje nedostajućih vrednosti:</h3>
+ <div class="form-check" *ngIf="selectedDataset">
+ <input type="radio" [(ngModel)]="experiment.nullValues " [value]="NullValueOptions.DeleteRows " class="form-check-input" value="deleteRows" name="fillMissing " id="delRows" checked data-bs-toggle="collapse" data-bs-target="#fillMissingCustom.show">
+ <label for="delRows" class="form-check-label ">Obriši sve
redove sa nedostajućim vrednostima ({{selectedDataset.nullRows}} od {{selectedDataset.rowCount}})</label><br>
- <input type="radio" [(ngModel)]="experiment.nullValues" [value]="NullValueOptions.DeleteColumns"
- class="form-check-input" value="deleteCols" name="fillMissing" id="delCols" data-bs-toggle="collapse"
- data-bs-target="#fillMissingCustom.show">
- <label for="delCols" class="form-check-label">Obriši sve
+ <input type="radio" [(ngModel)]="experiment.nullValues " [value]="NullValueOptions.DeleteColumns " class="form-check-input" value="deleteCols" name="fillMissing " id="delCols" data-bs-toggle="collapse" data-bs-target="#fillMissingCustom.show">
+ <label for="delCols" class="form-check-label ">Obriši sve
kolone sa nedostajućim vrednostima ({{countSelectedNullCols()}} od {{selectedDataset.columnInfo.length}})</label><br>
- <input type="radio" [(ngModel)]="experiment.nullValues" [value]="NullValueOptions.Replace"
- class="form-check-input" name="fillMissing" id="replace" data-bs-toggle="collapse"
- data-bs-target="#fillMissingCustom:not(.show)">
- <label for="replace" class="form-check-label">Izabraću
+ <input type="radio" [(ngModel)]="experiment.nullValues " [value]="NullValueOptions.Replace " class="form-check-input" name="fillMissing" id="replace" data-bs-toggle="collapse" data-bs-target="#fillMissingCustom:not(.show)">
+ <label for="replace" class="form-check-label">Izabraću
vrednosti koje će da zamene nedostajuće vrednosti za svaku kolonu...</label><br><br>
- <div class="collapse" id="fillMissingCustom">
- <div>
- <label for="columnReplacers" class="form-label">Unesite zamenu za svaku kolonu:</label>
- <div class="my-3" *ngIf="getSelectedColumnsArrayWithoutNullVals().length > 0" >
- <label class="text-center form-control mx-3 text-secondary">
+ <div class="collapse" id="fillMissingCustom">
+ <div>
+ <label for="columnReplacers" class="form-label">Unesite zamenu za svaku kolonu:</label>
+ <div class="my-3 " *ngIf="getSelectedColumnsArrayWithoutNullVals().length> 0">
+ <label class="text-center form-control mx-3 text-secondary">
Kolone <span style="font-style: italic;" *ngFor="let colname of getSelectedColumnsArrayWithoutNullVals(); let i = index">
<span *ngIf="i != getSelectedColumnsArrayWithoutNullVals().length - 1">{{colname}}, </span>
<span *ngIf="i == getSelectedColumnsArrayWithoutNullVals().length - 1">{{colname}} </span>
</span>
nemaju nedostajućih vrednosti za popunjavanje.
</label>
- </div>
- <div id="columnReplacers">
- <div *ngFor="let column of selectedColumnsInfoArray; let i = index" class="my-3">
- <div *ngIf="column.numNulls > 0">
- <span class="w-20 mx-3">
- {{column.columnName}}&nbsp;<span class="small" style="color:gray;">({{column.numNulls}} null)
- </span>
- </span>
-
- <label *ngIf="column.numNulls <= 0"
- class="text-center form-control mx-3 text-secondary">
- Ova kolona nema
- nedostajućih
- vrednosti.
- </label>
-
- <div *ngIf="column.numNulls > 0" class="d-flex flex-row justify-content-end">
- <div class="flex-grow-3 mx-3 me-auto">
- <div class="input-group">
- <div class="input-group-prepend">
- <label [for]="'fillCol_'+column.columnName" class="form-control">
+ </div>
+ <div id="columnReplacers">
+ <div *ngFor="let column of selectedColumnsInfoArray; let i = index" class="my-3">
+ <div *ngIf="column.numNulls > 0">
+ <span class="w-20 mx-3">
+ {{column.columnName}}&nbsp;
+ <span class="small" style="color:gray;">({{column.numNulls}} null)</span>
+ </span>
+
+ <div class="d-flex flex-row justify-content-end">
+ <div class="flex-grow-3 mx-3 me-auto">
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <label [for]="'fillCol_'+column.columnName" class="form-control">
Zameni
<input type="radio" [id]="'fillCol_'+column.columnName"
[name]="'delOp_'+column.columnName">
</label>
- </div>
- <input type="text" class="form-control" [id]="'fillText_'+column.columnName"
- (keyup)="checkFillColRadio(column.columnName)"
- placeholder="Unesi vrednost...">
-
- <div class="input-group-append">
- <select [id]="'replaceOptions'+i" class="form-control btn-primary"
- *ngIf="column.isNumber" (change)="replace($event, column); checkFillColRadio(column.columnName);">
+ </div>
+ <input type="text" class="form-control" [id]="'fillText_'+column.columnName" (keyup)="checkFillColRadio(column.columnName)" placeholder="Unesi vrednost...">
+
+ <div class="input-group-append">
+ <select [id]="'replaceOptions'+i" class="form-control btn-primary" *ngIf="column.isNumber" (change)="replace($event, column); checkFillColRadio(column.columnName);">
<option
*ngFor="let option of Object.keys(ReplaceWith); let optionName of Object.values(ReplaceWith)"
[value]="option">
{{ optionName }}
</option>
</select>
- <select [id]="'replaceOptions'+i"
- class="form-control btn-outline-primary"
- *ngIf="!column.isNumber && column.numNulls > 0"
- (change)="replace($event, column); checkFillColRadio(column.columnName);">
+ <select [id]="'replaceOptions'+i" class="form-control btn-outline-primary" *ngIf="!column.isNumber && column.numNulls > 0" (change)="replace($event, column); checkFillColRadio(column.columnName);">
<option *ngFor="let option of column.uniqueValues" [value]="option">
{{ option }}
</option>
</select>
+ </div>
+ </div>
</div>
- </div>
- </div>
-
- <div class="flex-shrink-1 mx-3">
- <div class="input-group">
- <label class="form-control" [for]="'delCol_'+column.columnName">Izbriši
+
+ <div class="flex-shrink-1 mx-3">
+ <div class="input-group">
+ <label class="form-control" [for]="'delCol_'+column.columnName">Izbriši
kolonu
<input type="radio" [id]="'delCol_'+column.columnName"
[name]="'delOp_'+column.columnName"
(change)="emptyFillTextInput(column.columnName)"></label>
- </div>
- </div>
-
- <div class="flex-shrink-1 mx-3">
- <div class="input-group">
- <label class="form-control" [for]="'delRows_'+column.columnName">Izbriši
+ </div>
+ </div>
+
+ <div class="flex-shrink-1 mx-3">
+ <div class="input-group">
+ <label class="form-control" [for]="'delRows_'+column.columnName">Izbriši
redove
<input type="radio" [id]="'delRows_'+column.columnName"
[name]="'delOp_'+column.columnName" checked
(change)="emptyFillTextInput(column.columnName)"></label>
+ </div>
+ </div>
</div>
</div>
</div>
@@ -165,96 +147,109 @@
</div>
</div>
</div>
- </div>
-
- <div id="randomOptions" class="mt-5">
- <div class="p-2 m-2">
- <label for="type" class="form-check-label">Želite li da redosled podataka bude nasumičan?</label>
- <input class="mx-3 form-check-input" type="checkbox" [(ngModel)]="experiment.randomOrder"
- type="checkbox" value="" checked>
- </div>
- <div class="border m-3">
- <div class="row p-2 m-2">
- <div class="col-4">
- <label for="splitYesNo" class="form-check-label">
+
+ <div id="randomOptions" class="mt-5">
+ <div class="p-2 m-2">
+ <label for="type" class="form-check-label">Želite li da redosled podataka bude nasumičan?</label>
+ <input class="mx-3 form-check-input" type="checkbox" [(ngModel)]="experiment.randomOrder" type="checkbox" value="" checked>
+ </div>
+ <div class="border m-3">
+ <div class="row p-2 m-2">
+ <div class="col-4">
+ <label for="splitYesNo" class="form-check-label">
<h3>Podela test skupa:&nbsp;&nbsp;
<input id="splitYesNo" class="form-check-input" type="checkbox"
[checked]="experiment.randomTestSet"
(change)="experiment.randomTestSet = !experiment.randomTestSet">
</h3>
</label>
+ </div>
+ <div class="col-8">
+ trening
+ <mat-slider style="width: 85%;" min="10" max="90" step="10" value="10" name="randomTestSetDistribution" thumbLabel [disabled]="!experiment.randomTestSet" [(ngModel)]="tempTestSetDistribution">
+ </mat-slider>
+ test
+ </div>
</div>
- <div class="col-8">
- trening
- <mat-slider style="width: 85%;" min="10" max="90" step="10" value="10"
- name="randomTestSetDistribution" thumbLabel [disabled]="!experiment.randomTestSet"
- [(ngModel)]="tempTestSetDistribution">
- </mat-slider>
- test
- </div>
- </div>
-
- <div class="row p-2 m-2">
- <label for="percentage" class="form-label">Procenat podataka koji se uzima za trening
+
+ <div class="row p-2 m-2">
+ <label for="percentage" class="form-label">Procenat podataka koji se uzima za trening
skup:</label>
- <input id="percentage" type="number" class="form-control mx-3" style=" max-width: 15%" min="10" max="90" step="10" value="90"
- [(ngModel)]="tempTestSetDistribution" [disabled]="!experiment.randomTestSet">
+ <input id="percentage" type="number" class="form-control mx-3" style=" max-width: 15%" min="10" max="90" step="10" value="90" [(ngModel)]="tempTestSetDistribution" [disabled]="!experiment.randomTestSet">
+ </div>
</div>
</div>
- </div>
-
- <div id="encodingForColumns" class="row px-3 my-5">
- <div class="col-1">
- <label for="encoding" class="col-form-label">Enkoding: </label>
- </div>
- <div class="col-2">
- <select id=encodingOptions class="form-control" name="encoding" [(ngModel)]="experiment.encoding">
- <option *ngFor="let option of Object.keys(Encoding); let optionName of Object.values(Encoding)"
- [value]="option">
- {{ optionName }}
- </option>
- </select>
+
+ <div id="encodingsForColumns" class="px-3 my-5">
+ <label for="encoding" class="col-form-label mb-2">Enkoding za izabrane kolone:</label>
+
+ <div class="row d-flex flex-row justify-content-between align-items-center">
+ <div class="col-5" *ngFor="let item of [].constructor(selectedColumnsInfoArray.length); let i = index">
+ <div class="input-group mb-2">
+ <div class="input-group-prepend">
+ <span class="input-group-text">{{selectedColumnsInfoArray[i].columnName}}</span>
+ </div>
+ <select [id]="'encodingOption_'+i" class="form-select" [(ngModel)]="experiment.encodings[i].encoding">
+ <option
+ *ngFor="let option of Object.keys(Encoding); let optionName of Object.values(Encoding)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ </div>
+ </div>
</div>
+
</div>
-
- </div>
- </div>
+ </div>
- <div class="carousel-item mt-2">
- <h2 class="mb-4">3. Dodaj eskperiment</h2>
+ <div class="carousel-item mt-2">
+ <h2 class="mb-4">3. Dodaj eskperiment</h2>
- <div class="row">
- <div class="col"></div>
- <div class="col-8">
- <label for="name" class="col-form-label">Naziv eksperimenta:</label>
- <input type="text" class="form-control mb-3" name="name" placeholder="Naziv..." [(ngModel)]="experiment.name">
-
- <label for="desc" class="col-sm-2 col-form-label">Opis:</label>
- <div>
- <textarea class="form-control" name="desc" rows="3" [(ngModel)]="experiment.description"></textarea>
- </div>
- <div class="form-group row mt-5 mb-3">
- <div class="col"></div>
- <button class="btn btn-lg col-4" style="background-color:#003459; color:white;" (click)="saveExperiment();">Sačuvaj
+ <div class="row">
+ <div class="col"></div>
+ <div class="col-8">
+ <label for="name" class="col-form-label">Naziv eksperimenta:</label>
+ <input type="text" class="form-control mb-3" name="name" placeholder="Naziv..." [(ngModel)]="experiment.name">
+
+ <label for="desc" class="col-sm-2 col-form-label">Opis:</label>
+ <div>
+ <textarea class="form-control" name="desc" rows="3" [(ngModel)]="experiment.description"></textarea>
+ </div>
+ <label for="desc" class="col-sm-2 col-form-label mt-3">Tip problema:</label>
+ <div class="col-4">
+ <select id="typeOptions" class="form-select" name="type" [(ngModel)]="experiment.type">
+ <option
+ *ngFor="let option of Object.keys(ProblemType); let optionName of Object.values(ProblemType)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ <div class="form-group row mt-5 mb-3">
+ <div class="col"></div>
+ <button class="btn btn-lg col-4" style="background-color:#003459; color:white;" (click)="saveExperiment();">Sačuvaj
eksperiment</button>
- <div class="col"></div>
+ <div class="col"></div>
+ </div>
</div>
+ <div class="col"></div>
</div>
- <div class="col"></div>
</div>
+
</div>
- </div>
- <div class="m-3 d-flex flex-row justify-content-between align-items-center" style=" margin-left: auto;">
- <button mat-fab color="primary" data-bs-target="#carouselExampleControls" data-bs-slide="prev">
- <mat-icon>arrow_backward</mat-icon>
- </button>
- <button mat-fab color="primary" data-bs-target="#carouselExampleControls" data-bs-slide="next">
- <mat-icon>arrow_forward</mat-icon>
- </button>
- </div>
+ <div class="m-3 d-flex flex-row justify-content-between align-items-center" style=" margin-left: auto;">
+ <button mat-fab color="primary" data-bs-target="#carouselExampleControls" data-bs-slide="prev">
+ <mat-icon>arrow_backward</mat-icon>
+ </button>
+ <button mat-fab color="primary" data-bs-target="#carouselExampleControls" data-bs-slide="next">
+ <mat-icon>arrow_forward</mat-icon>
+ </button>
+ </div>
</div>
</div>
</div> \ No newline at end of file
diff --git a/frontend/src/app/experiment/experiment.component.ts b/frontend/src/app/experiment/experiment.component.ts
index b5e1d1f4..2d0f6ec5 100644
--- a/frontend/src/app/experiment/experiment.component.ts
+++ b/frontend/src/app/experiment/experiment.component.ts
@@ -1,10 +1,11 @@
import { Component, OnInit } from '@angular/core';
import Experiment, { NullValReplacer, NullValueOptions, ReplaceWith, Encoding } from '../_data/Experiment';
-import Model from '../_data/Model';
+import Model,{ProblemType} from '../_data/Model';
import Dataset, { ColumnInfo } from '../_data/Dataset';
import { ModelsService } from '../_services/models.service';
import Shared from '../Shared';
import { ExperimentsService } from '../_services/experiments.service';
+import { ColumnEncoding } from '../_data/Experiment';
@Component({
selector: 'app-experiment',
@@ -21,8 +22,9 @@ export class ExperimentComponent implements OnInit {
NullValueOptions = NullValueOptions;
ReplaceWith = ReplaceWith;
Encoding = Encoding;
+ ColumnEncoding = ColumnEncoding;
Object = Object;
-
+ ProblemType=ProblemType;
selectedColumnsInfoArray: ColumnInfo[] = [];
selectedNotNullColumnsArray: string[] = [];
@@ -38,6 +40,17 @@ export class ExperimentComponent implements OnInit {
this.selectedDataset = dataset;
this.selectedColumnsInfoArray = this.selectedDataset.columnInfo;
this.selectedNotNullColumnsArray = [];
+ this.experiment.outputColumn = this.selectedDataset.columnInfo[this.selectedDataset.columnInfo.length - 1].columnName;
+
+ this.resetColumnEncodings();
+ console.log(this.experiment.encodings);
+ }
+
+ resetColumnEncodings() {
+ this.experiment.encodings = [];
+ for (let i = 0; i < this.selectedColumnsInfoArray.length; i++) {
+ this.experiment.encodings.push(new ColumnEncoding(this.selectedColumnsInfoArray[i].columnName, Encoding.Label));
+ }
}
getInputById(id: string): HTMLInputElement {
@@ -179,13 +192,14 @@ export class ExperimentComponent implements OnInit {
this.experiment.randomTestSetDistribution = 1 - Math.round(this.tempTestSetDistribution / 100 * 10) / 10;
- //console.log("Eksperiment:", this.experiment);
+ console.log("Eksperiment:", this.experiment);
this.experimentsService.addExperiment(this.experiment).subscribe((response) => {
this.experiment = response;
- this.selectedColumnsInfoArray = [];
+ this.selectedColumnsInfoArray = [];
this.selectedNotNullColumnsArray = [];
+ this.experiment.encodings = [];
Shared.openDialog("Obaveštenje", "Eksperiment je uspešno kreiran.");
}, (error) => {
diff --git a/frontend/src/app/training/training.component.html b/frontend/src/app/training/training.component.html
index 0ce4cc89..672e75fb 100644
--- a/frontend/src/app/training/training.component.html
+++ b/frontend/src/app/training/training.component.html
@@ -23,7 +23,7 @@
</div>
<h2 class="mt-5 mb-2">2. Izaberite model</h2>
- <app-model-load (selectedModelChangeEvent)="selectModel($event)"></app-model-load>
+ <app-model-load (selectedModelChangeEvent)="selectModel($event)" [forExperiment]="selectedExperiment"></app-model-load>
<h2 class="my-5">3. Treniranje modela</h2>