show rendered image

added loading icon
image is scaled to available space
This commit is contained in:
2016-12-21 20:06:11 +01:00
parent d1e39513f3
commit bc5d1b0b7b
19 changed files with 461 additions and 47 deletions

View File

@@ -1,6 +1,8 @@
dependencies {
compile project(':performanceDb')
compile project(':pdb-plotting')
compile("org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE")
testCompile("org.springframework.boot:spring-boot-starter-test:1.4.2.RELEASE")

View File

@@ -0,0 +1,9 @@
package org.lucares.pdbui;
public interface HardcodedValues {
/**
* The path for generated images relative to the context root.
*/
String WEB_IMAGE_OUTPUT_PATH = "img-generated";
}

View File

@@ -0,0 +1,18 @@
package org.lucares.pdbui;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR, reason = "Internal Server Error")
public class InternalServerError extends RuntimeException {
private static final long serialVersionUID = 1L;
public InternalServerError(final String message, final Throwable cause) {
super(message, cause);
}
public InternalServerError(final Throwable cause) {
super(cause);
}
}

View File

@@ -2,11 +2,12 @@ package org.lucares.pdbui;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@ComponentScan("org.lucares.pdbui")
// @PropertySource("classpath:/config.system.properties")
// @PropertySource("classpath:/config.user.properties")
@PropertySource("classpath:/config.system.properties")
@PropertySource("classpath:/config.user.properties")
public class MySpringConfiguration {
}

View File

@@ -1,13 +1,9 @@
package org.lucares.pdbui;
import java.nio.file.Paths;
import org.springframework.boot.SpringApplication;
public class MyWebapp {
public static final String IMAGE_DIR = Paths.get("/tmp/images").toFile().getAbsolutePath() + "/";
public static void main(final String[] args) throws Exception {
SpringApplication.run(MySpringConfiguration.class, args);
}

View File

@@ -1,7 +1,12 @@
package org.lucares.pdbui;
import java.io.File;
import java.nio.file.Path;
import org.lucares.pdbui.domain.PlotRequest;
import org.lucares.pdbui.domain.PlotResponse;
import org.lucares.recommind.logs.InternalPlottingException;
import org.lucares.recommind.logs.Plotter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
@@ -12,12 +17,12 @@ import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@EnableAutoConfiguration
public class PdbController {
public class PdbController implements HardcodedValues {
private final PdbRepository pdbRepository;
private final Plotter plotter;
public PdbController(final PdbRepository pdbRepository) {
this.pdbRepository = pdbRepository;
public PdbController(final Plotter plotter) {
this.plotter = plotter;
}
@RequestMapping(path = "/plots", //
@@ -27,8 +32,17 @@ public class PdbController {
)
@ResponseBody
PlotResponse createPlot(@RequestBody final PlotRequest request) {
System.out.println(request.getQuery());
return new PlotResponse("img/abc.png");
try {
System.out.println(request.getQuery());
final File image = plotter.plot(request.getQuery(), request.getHeight(), request.getWidth());
final Path relativeImagePath = plotter.getOutputDir().relativize(image.toPath());
return new PlotResponse(WEB_IMAGE_OUTPUT_PATH + "/" + relativeImagePath.toString());
} catch (final InternalPlottingException e) {
throw new InternalServerError(e);
}
}
}

View File

@@ -1,15 +1,24 @@
package org.lucares.pdbui;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.lucares.performance.db.PerformanceDb;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
@Repository
public class PdbRepository implements DisposableBean {
private final PerformanceDb db;
public PdbRepository(final PerformanceDb db) {
this.db = db;
public PdbRepository(@Value("${db.base}") final String dbBaseDir) {
final Path dataDirectory = Paths.get(dbBaseDir);
this.db = new PerformanceDb(dataDirectory);
}
public PerformanceDb getDb() {
return db;
}
@Override

View File

@@ -0,0 +1,42 @@
package org.lucares.pdbui;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.lucares.performance.db.PerformanceDb;
import org.lucares.recommind.logs.Plotter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.stereotype.Component;
@Component
public class PlotterBeanFactory extends AbstractFactoryBean<Plotter> implements PropertyKeys {
private final PerformanceDb db;
private final Path tmpDir;
private final Path outputDir;
@Autowired
public PlotterBeanFactory(final PdbRepository dbRepository, @Value("${" + TMP_DIR + "}") final String tmpDir,
@Value("${" + PATH_GENERATED_IMAGES + "}") final String outputDir) {
this.db = dbRepository.getDb();
this.tmpDir = Paths.get(tmpDir);
this.outputDir = Paths.get(outputDir);
}
@Override
public Class<?> getObjectType() {
return Plotter.class;
}
@Override
protected Plotter createInstance() throws Exception {
Files.createDirectories(tmpDir);
Files.createDirectories(outputDir);
return new Plotter(db, tmpDir, outputDir);
}
}

View File

@@ -0,0 +1,14 @@
package org.lucares.pdbui;
public interface PropertyKeys {
/**
* The path for generated images
*/
String PATH_GENERATED_IMAGES = "path.output";
/**
* Path for temporary files
*/
String TMP_DIR = "path.tmp";
}

View File

@@ -1,14 +1,27 @@
package org.lucares.pdbui;
import java.nio.file.Paths;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter {
public class WebConfiguration extends WebMvcConfigurerAdapter implements HardcodedValues, PropertyKeys {
private final String outputDir;
public WebConfiguration(@Value("${" + PATH_GENERATED_IMAGES + "}") final String outputDir) {
this.outputDir = outputDir;
}
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/img/**").addResourceLocations("file:" + MyWebapp.IMAGE_DIR);
final String pathPattern = "/" + WEB_IMAGE_OUTPUT_PATH + "/**";
final String resourceLocation = "file:" + Paths.get(outputDir).toAbsolutePath() + "/";
registry.addResourceHandler(pathPattern).addResourceLocations(resourceLocation);
}
}

View File

@@ -3,6 +3,10 @@ package org.lucares.pdbui.domain;
public class PlotRequest {
private String query;
private int height;
private int width;
public String getQuery() {
return query;
}
@@ -11,8 +15,24 @@ public class PlotRequest {
this.query = query;
}
public int getWidth() {
return width;
}
public void setWidth(final int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(final int height) {
this.height = height;
}
@Override
public String toString() {
return query;
return query + ":" + height + "x" + width;
}
}

View File

@@ -1 +1,4 @@
db.base=/tmp/db
db.base=/tmp/db
path.tmp=/tmp/pdb/tmp
path.output=/tmp/pdb/out

View File

@@ -1 +1 @@
db.base=/home/andi/ws/performanceDb/db
db.base=/home/andi/ws/performanceDb/db

View File

@@ -1,4 +1,5 @@
body {
html, body {
height: 100%;
margin:0;
padding:0;
}
@@ -11,11 +12,19 @@ body {
font-style: normal;
}
#content{
display: flex;
flex-flow: column;
height: 100%;
}
#top-menu-bar {
background-color: black;
color: white;
padding: 3px;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
}
#logo {
@@ -26,6 +35,9 @@ body {
background-color: #aaa;
text-align: right;
padding-bottom:3px;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
}
#search-bar #search-query {
@@ -42,8 +54,13 @@ body {
}
#result-view {
background: red;
font-size: 32px;
background: #eee;
bottom: 0;
left:0;
right: 0;
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
}
#result-view i {
@@ -53,3 +70,10 @@ body {
line-height: 1.2em;
}
.center
{
display: flex;
justify-content: center;
align-items: center;
}

View File

@@ -0,0 +1,189 @@
.uil-cube-css {
background: none;
position: relative;
width: 200px;
height: 200px;
}
width: 100%;
@-webkit-keyframes uil-cube-css {
0% {
-ms-transform: scale(1.4);
-moz-transform: scale(1.4);
-webkit-transform: scale(1.4);
-o-transform: scale(1.4);
transform: scale(1.4);
}
100% {
-ms-transform: scale(1);
-moz-transform: scale(1);
-webkit-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
@-webkit-keyframes uil-cube-css {
0% {
-ms-transform: scale(1.4);
-moz-transform: scale(1.4);
-webkit-transform: scale(1.4);
-o-transform: scale(1.4);
transform: scale(1.4);
}
100% {
-ms-transform: scale(1);
-moz-transform: scale(1);
-webkit-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
@-moz-keyframes uil-cube-css {
0% {
-ms-transform: scale(1.4);
-moz-transform: scale(1.4);
-webkit-transform: scale(1.4);
-o-transform: scale(1.4);
transform: scale(1.4);
}
100% {
-ms-transform: scale(1);
-moz-transform: scale(1);
-webkit-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
@-ms-keyframes uil-cube-css {
0% {
-ms-transform: scale(1.4);
-moz-transform: scale(1.4);
-webkit-transform: scale(1.4);
-o-transform: scale(1.4);
transform: scale(1.4);
}
100% {
-ms-transform: scale(1);
-moz-transform: scale(1);
-webkit-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
@-moz-keyframes uil-cube-css {
0% {
-ms-transform: scale(1.4);
-moz-transform: scale(1.4);
-webkit-transform: scale(1.4);
-o-transform: scale(1.4);
transform: scale(1.4);
}
100% {
-ms-transform: scale(1);
-moz-transform: scale(1);
-webkit-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
@-webkit-keyframes uil-cube-css {
0% {
-ms-transform: scale(1.4);
-moz-transform: scale(1.4);
-webkit-transform: scale(1.4);
-o-transform: scale(1.4);
transform: scale(1.4);
}
100% {
-ms-transform: scale(1);
-moz-transform: scale(1);
-webkit-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
@-o-keyframes uil-cube-css {
0% {
-ms-transform: scale(1.4);
-moz-transform: scale(1.4);
-webkit-transform: scale(1.4);
-o-transform: scale(1.4);
transform: scale(1.4);
}
100% {
-ms-transform: scale(1);
-moz-transform: scale(1);
-webkit-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
@keyframes uil-cube-css {
0% {
-ms-transform: scale(1.4);
-moz-transform: scale(1.4);
-webkit-transform: scale(1.4);
-o-transform: scale(1.4);
transform: scale(1.4);
}
100% {
-ms-transform: scale(1);
-moz-transform: scale(1);
-webkit-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
.uil-cube-css > div {
position: absolute;
width: 80px;
height: 80px;
-ms-animation: uil-cube-css 1s cubic-bezier(0.2, 0.8, 0.2, 0.8) infinite;
-moz-animation: uil-cube-css 1s cubic-bezier(0.2, 0.8, 0.2, 0.8) infinite;
-webkit-animation: uil-cube-css 1s cubic-bezier(0.2, 0.8, 0.2, 0.8) infinite;
-o-animation: uil-cube-css 1s cubic-bezier(0.2, 0.8, 0.2, 0.8) infinite;
animation: uil-cube-css 1s cubic-bezier(0.2, 0.8, 0.2, 0.8) infinite;
}
.uil-cube-css > div:nth-of-type(1) {
top: 10px;
left: 10px;
background: #cec9c9;
opacity: 0.9;
-ms-animation-delay: 0s;
-moz-animation-delay: 0s;
-webkit-animation-delay: 0s;
-o-animation-delay: 0s;
animation-delay: 0s;
}
.uil-cube-css > div:nth-of-type(2) {
top: 10px;
left: 110px;
background: #cec9c9;
opacity: 0.8;
-ms-animation-delay: 0.1s;
-moz-animation-delay: 0.1s;
-webkit-animation-delay: 0.1s;
-o-animation-delay: 0.1s;
animation-delay: 0.1s;
}
.uil-cube-css > div:nth-of-type(3) {
top: 110px;
left: 10px;
background: #cec9c9;
opacity: 0.7;
-ms-animation-delay: 0.3s;
-moz-animation-delay: 0.3s;
-webkit-animation-delay: 0.3s;
-o-animation-delay: 0.3s;
animation-delay: 0.3s;
}
.uil-cube-css > div:nth-of-type(4) {
top: 110px;
left: 110px;
background: #cec9c9;
opacity: 0.6;
-ms-animation-delay: 0.2s;
-moz-animation-delay: 0.2s;
-webkit-animation-delay: 0.2s;
-o-animation-delay: 0.2s;
animation-delay: 0.2s;
}

View File

@@ -6,16 +6,19 @@
<link rel="stylesheet" type="text/css" href="css/typography.css">
<link rel="stylesheet" type="text/css" href="css/design.css">
<link rel="stylesheet" type="text/css" href="css/icons.css">
<link rel="stylesheet" type="text/css" href="css/loading.css">
</head>
<body>
<div id="top-menu-bar">
<div id="logo">LOGO</div>
</div>
<div id="search-bar">
<textarea id="search-query"></textarea>
<button id="search-submit"><i class="fa fa-search"> Search</i></button>
</div>
<div id="result-view">
<div id="content">
<div id="top-menu-bar">
<div id="logo">LOGO</div>
</div>
<div id="search-bar">
<textarea id="search-query">method=AuditService.logEvent</textarea>
<button id="search-submit"><i class="fa fa-search"> Search</i></button>
</div>
<div id="result-view">
</div>
</div>
</body>
</html>

View File

@@ -4,12 +4,15 @@ $(document).ready(function(){
$('#search-submit').click(function(event){
event.preventDefault(); // prevent submit of form which would reload the page
showLoadingIcon();
var request = {};
request['query'] = $('#search-query').val();
request['height'] = $('#result-view').height()-10;
request['width'] = $('#result-view').width()-10;
var success = function(response){
$('#result-view').text("SUCCESS: "+response.imageUrls);
$('#result-view').html('<img src=\"'+response.imageUrls+'" />');
};
var error = function(e) {
//var response = JSON.parse(e.responseText);
@@ -22,6 +25,11 @@ $(document).ready(function(){
});
});
function showLoadingIcon()
{
$('#result-view').html("<div class='center'><div class='uil-cube-css' style='-webkit-transform:scale(0.41)'><div /><div></div><div></div><div></div></div></div>");
}
function postJson(url, requestData, successCallback, errorCallback) {