- found attribute is calculated at reading time from file, to avoid lazy loading of all the log entries from database
- kind of batch writing to database for better performance
This commit is contained in:
@@ -14,7 +14,7 @@ class BasicListStatisticsPlugin implements Plugin {
|
|||||||
private difficultyTerrainValues = ['1', '1.5', '2', '2.5', '3', '3.5', '4', '4.5', '5']
|
private difficultyTerrainValues = ['1', '1.5', '2', '2.5', '3', '3.5', '4', '4.5', '5']
|
||||||
|
|
||||||
final String name = "Basic List Statistic"
|
final String name = "Basic List Statistic"
|
||||||
final String version = "0.0.1"
|
final String version = "0.0.2"
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void run(final Map context) {
|
void run(final Map context) {
|
||||||
@@ -56,27 +56,27 @@ class BasicListStatisticsPlugin implements Plugin {
|
|||||||
|
|
||||||
// create javafx chart
|
// create javafx chart
|
||||||
def typeData = FXCollections.observableArrayList()
|
def typeData = FXCollections.observableArrayList()
|
||||||
typeStats.each() { key, value -> typeData.add(new Data(key as String, value as double)) }
|
typeStats.each() { key, value -> typeData.add(new Data(key.toString() + ' (' + value + ')', value as double)) }
|
||||||
def typeChart = new PieChart(typeData);
|
def typeChart = new PieChart(typeData);
|
||||||
typeChart.setTitle("Number of cache types in list.");
|
typeChart.setTitle("Spreading of cache types in list.");
|
||||||
|
|
||||||
// create javafx chart
|
// create javafx chart
|
||||||
def difficultyData = FXCollections.observableArrayList()
|
def difficultyData = FXCollections.observableArrayList()
|
||||||
difficultyTerrainValues.each {
|
difficultyTerrainValues.each {
|
||||||
def value = difficultyStats[it]
|
def value = difficultyStats[it]
|
||||||
if (value) difficultyData.add(new Data(it, value))
|
if (value) difficultyData.add(new Data(it+ ' (' + value + ')', value))
|
||||||
}
|
}
|
||||||
def difficultyChart = new PieChart(difficultyData);
|
def difficultyChart = new PieChart(difficultyData);
|
||||||
difficultyChart.setTitle("Number of difficulties in list.");
|
difficultyChart.setTitle("Spreading of difficulties in list.");
|
||||||
|
|
||||||
// create javafx chart
|
// create javafx chart
|
||||||
def terrainData = FXCollections.observableArrayList()
|
def terrainData = FXCollections.observableArrayList()
|
||||||
difficultyTerrainValues.each {
|
difficultyTerrainValues.each {
|
||||||
def value = terrainStats[it]
|
def value = terrainStats[it]
|
||||||
if (value) terrainData.add(new Data(it, value))
|
if (value) terrainData.add(new Data(it+ ' (' + value + ')', value))
|
||||||
}
|
}
|
||||||
def terrainChart = new PieChart(terrainData);
|
def terrainChart = new PieChart(terrainData);
|
||||||
terrainChart.setTitle("Number of terrain in list.");
|
terrainChart.setTitle("Spreading of terrain in list.");
|
||||||
|
|
||||||
// add charts to layout container
|
// add charts to layout container
|
||||||
contenPane.children.addAll(typeChart, difficultyChart, terrainChart)
|
contenPane.children.addAll(typeChart, difficultyChart, terrainChart)
|
||||||
@@ -84,8 +84,6 @@ class BasicListStatisticsPlugin implements Plugin {
|
|||||||
// return the layout container
|
// return the layout container
|
||||||
def scrollPane = new ScrollPane(contenPane)
|
def scrollPane = new ScrollPane(contenPane)
|
||||||
scrollPane.minWidth = 600
|
scrollPane.minWidth = 600
|
||||||
scrollPane.prefWidth = 600
|
|
||||||
scrollPane.maxWidth = 600
|
|
||||||
scrollPane.minHeight = 450
|
scrollPane.minHeight = 450
|
||||||
scrollPane
|
scrollPane
|
||||||
}
|
}
|
||||||
@@ -95,7 +93,7 @@ class BasicListStatisticsPlugin implements Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void showDialog(header, content) {
|
private void showDialog(header, content) {
|
||||||
Dialog dialog = new Dialog(null, name+" ("+version+")")
|
Dialog dialog = new Dialog(null, name+" ("+version+")", true)
|
||||||
dialog.setMasthead(header)
|
dialog.setMasthead(header)
|
||||||
dialog.setContent(content)
|
dialog.setContent(content)
|
||||||
dialog.show()
|
dialog.show()
|
||||||
|
|||||||
113
plugins/OwnStatisticsPlugin.groovy
Normal file
113
plugins/OwnStatisticsPlugin.groovy
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import de.frosch95.geofrogger.plugins.Plugin
|
||||||
|
import javafx.collections.FXCollections
|
||||||
|
import javafx.geometry.Insets
|
||||||
|
import javafx.scene.chart.PieChart
|
||||||
|
import javafx.scene.control.Label
|
||||||
|
import javafx.scene.control.ScrollPane
|
||||||
|
import javafx.scene.layout.Pane
|
||||||
|
import javafx.scene.layout.Priority
|
||||||
|
import javafx.scene.layout.VBox
|
||||||
|
import org.controlsfx.dialog.Dialog
|
||||||
|
|
||||||
|
import static javafx.scene.chart.PieChart.Data
|
||||||
|
|
||||||
|
class OwnStatisticsPlugin implements Plugin {
|
||||||
|
|
||||||
|
private difficultyTerrainValues = ['1', '1.5', '2', '2.5', '3', '3.5', '4', '4.5', '5']
|
||||||
|
|
||||||
|
final String name = "Own Statistic"
|
||||||
|
final String version = "0.0.1"
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void run(final Map context) {
|
||||||
|
showDialog(createHeader(context.sessionContext), createContent(context.sessionContext))
|
||||||
|
}
|
||||||
|
|
||||||
|
private javafx.scene.Node createHeader(sessionContext) {
|
||||||
|
def pane = new Pane()
|
||||||
|
def Label label = new Label()
|
||||||
|
label.text = "This example plugin shows some stats based on the current list.\nThese statistics are found statistics, based on all found caches in the list."
|
||||||
|
pane.children.add(label)
|
||||||
|
pane
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates the statistic charts to show
|
||||||
|
* @param sessionContext context with the cache list in it
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private javafx.scene.Node createContent(sessionContext) {
|
||||||
|
|
||||||
|
// get the cache list out of the context
|
||||||
|
def cacheList = sessionContext.getData("cache-list")
|
||||||
|
|
||||||
|
// create a vbox as layout container
|
||||||
|
VBox contenPane = new VBox()
|
||||||
|
contenPane.prefWidth = 600
|
||||||
|
VBox.setVgrow(contenPane, Priority.ALWAYS);
|
||||||
|
|
||||||
|
|
||||||
|
// groovy maps for selecting the statistic numbers
|
||||||
|
def typeStats = [:]
|
||||||
|
def difficultyStats = [:]
|
||||||
|
def terrainStats = [:]
|
||||||
|
|
||||||
|
def foundCount = 0
|
||||||
|
|
||||||
|
println cacheList.size()
|
||||||
|
|
||||||
|
// iterate over all the caches and count the data
|
||||||
|
for (def cache in cacheList) {
|
||||||
|
if (cache.found) {
|
||||||
|
foundCount++
|
||||||
|
incrementStats(typeStats, cache.type)
|
||||||
|
incrementStats(difficultyStats, cache.difficulty)
|
||||||
|
incrementStats(terrainStats, cache.terrain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create javafx chart
|
||||||
|
def typeData = FXCollections.observableArrayList()
|
||||||
|
typeStats.each() { key, value -> typeData.add(new Data(key.toString() + ' (' + value + ')', value as double)) }
|
||||||
|
def typeChart = new PieChart(typeData);
|
||||||
|
typeChart.setTitle("Spreading of cache types found (${foundCount}).");
|
||||||
|
|
||||||
|
// create javafx chart
|
||||||
|
def difficultyData = FXCollections.observableArrayList()
|
||||||
|
difficultyTerrainValues.each {
|
||||||
|
def value = difficultyStats[it]
|
||||||
|
if (value) difficultyData.add(new Data(it+ ' (' + value + ')', value))
|
||||||
|
}
|
||||||
|
def difficultyChart = new PieChart(difficultyData);
|
||||||
|
difficultyChart.setTitle("Spreading of difficulties found (${foundCount}).");
|
||||||
|
|
||||||
|
// create javafx chart
|
||||||
|
def terrainData = FXCollections.observableArrayList()
|
||||||
|
difficultyTerrainValues.each {
|
||||||
|
def value = terrainStats[it]
|
||||||
|
if (value) terrainData.add(new Data(it+ ' (' + value + ')', value))
|
||||||
|
}
|
||||||
|
def terrainChart = new PieChart(terrainData);
|
||||||
|
terrainChart.setTitle("Spreeading of terrain found (${foundCount}).");
|
||||||
|
|
||||||
|
// add charts to layout container
|
||||||
|
contenPane.children.addAll(typeChart, difficultyChart, terrainChart)
|
||||||
|
|
||||||
|
// return the layout container
|
||||||
|
def scrollPane = new ScrollPane(contenPane)
|
||||||
|
scrollPane.minWidth = 640
|
||||||
|
scrollPane.minHeight = 450
|
||||||
|
scrollPane
|
||||||
|
}
|
||||||
|
|
||||||
|
private void incrementStats(map, key) {
|
||||||
|
map[key] = map[key] ? map[key] + 1 : 1
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDialog(header, content) {
|
||||||
|
Dialog dialog = new Dialog(null, name+" ("+version+")", true)
|
||||||
|
dialog.setMasthead(header)
|
||||||
|
dialog.setContent(content)
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -118,7 +118,7 @@ public class CacheListCell extends ListCell<Cache> {
|
|||||||
name.setText(cache.getName());
|
name.setText(cache.getName());
|
||||||
dt.setText("D: " + cache.getDifficulty() + " / T:" + cache.getTerrain());
|
dt.setText("D: " + cache.getDifficulty() + " / T:" + cache.getTerrain());
|
||||||
|
|
||||||
if (CacheUtils.hasUserFoundCache(cache, new Long(3906456))) {
|
if (cache.isFound()) {
|
||||||
foundIcon.setImage(IconManager.getIcon("/icons/iconmonstr-check-mark-11-icon.png", IconManager.IconSize.SMALL));
|
foundIcon.setImage(IconManager.getIcon("/icons/iconmonstr-check-mark-11-icon.png", IconManager.IconSize.SMALL));
|
||||||
} else {
|
} else {
|
||||||
foundIcon.setImage(null);
|
foundIcon.setImage(null);
|
||||||
@@ -129,7 +129,7 @@ public class CacheListCell extends ListCell<Cache> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setStyleClassDependingOnFoundState(Cache cache) {
|
private void setStyleClassDependingOnFoundState(Cache cache) {
|
||||||
if (CacheUtils.hasUserFoundCache(cache, new Long(3906456))) {
|
if (cache.isFound()) {
|
||||||
addClasses(this, CACHE_LIST_FOUND_CLASS);
|
addClasses(this, CACHE_LIST_FOUND_CLASS);
|
||||||
removeClasses(this, CACHE_LIST_NOT_FOUND_CLASS);
|
removeClasses(this, CACHE_LIST_NOT_FOUND_CLASS);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ public class GroundspeakGPXReader implements GPXReader {
|
|||||||
|
|
||||||
private void parseContent() {
|
private void parseContent() {
|
||||||
modelList = new ArrayList<>();
|
modelList = new ArrayList<>();
|
||||||
|
try {
|
||||||
final Element root = content.getRootElement();
|
final Element root = content.getRootElement();
|
||||||
final List<Element> waypoints = root.getChildren(WPT, defaultNamespace);
|
final List<Element> waypoints = root.getChildren(WPT, defaultNamespace);
|
||||||
|
|
||||||
@@ -177,8 +178,12 @@ public class GroundspeakGPXReader implements GPXReader {
|
|||||||
"Parse " + currentNumber + " of " + totalNumberOfCaches + " caches.",
|
"Parse " + currentNumber + " of " + totalNumberOfCaches + " caches.",
|
||||||
(double) currentNumber / (double) totalNumberOfCaches));
|
(double) currentNumber / (double) totalNumberOfCaches));
|
||||||
final Cache cache = parseWaypointElement(waypointElement);
|
final Cache cache = parseWaypointElement(waypointElement);
|
||||||
|
cache.setFound(CacheUtils.hasUserFoundCache(cache, 3906456l));
|
||||||
modelList.add(cache);
|
modelList.add(cache);
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Cache parseWaypointElement(Element waypointElement) {
|
private Cache parseWaypointElement(Element waypointElement) {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class Cache {
|
|||||||
private Long id;
|
private Long id;
|
||||||
private boolean available;
|
private boolean available;
|
||||||
private boolean archived;
|
private boolean archived;
|
||||||
|
private boolean found;
|
||||||
private String name;
|
private String name;
|
||||||
private String placedBy;
|
private String placedBy;
|
||||||
private User owner;
|
private User owner;
|
||||||
@@ -231,6 +232,14 @@ public class Cache {
|
|||||||
this.travelBugs = travelBugs;
|
this.travelBugs = travelBugs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isFound() {
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFound(final boolean found) {
|
||||||
|
this.found = found;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Cache{"
|
return "Cache{"
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ import java.util.List;
|
|||||||
public class CacheUtils {
|
public class CacheUtils {
|
||||||
|
|
||||||
public static final String FOUND_IT = "Found it";
|
public static final String FOUND_IT = "Found it";
|
||||||
|
public static final String ATTENDED = "Attended";
|
||||||
|
public static final String WEBCAM_PHOTO = "Webcam Photo Taken";
|
||||||
|
|
||||||
public static boolean hasUserFoundCache(Cache cache, Long currentUser) {
|
public static boolean hasUserFoundCache(Cache cache, Long currentUser) {
|
||||||
boolean foundIt = false;
|
boolean foundIt = false;
|
||||||
@@ -55,7 +57,7 @@ public class CacheUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isLogTypeFoundIt(Log log) {
|
private static boolean isLogTypeFoundIt(Log log) {
|
||||||
return log.getType().equals(FOUND_IT);
|
return log.getType().equals(FOUND_IT) || log.getType().equals(ATTENDED) || log.getType().equals(WEBCAM_PHOTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class CacheServiceImpl implements CacheService {
|
public class CacheServiceImpl implements CacheService {
|
||||||
|
|
||||||
|
private static final int TRANSACTION_SIZE = 100;
|
||||||
private final DatabaseService dbService = ServiceManager.getInstance().getDatabaseService();
|
private final DatabaseService dbService = ServiceManager.getInstance().getDatabaseService();
|
||||||
|
|
||||||
private final List<ProgressListener> listeners = new ArrayList<>();
|
private final List<ProgressListener> listeners = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -38,6 +38,8 @@ public class CacheServiceImpl implements CacheService {
|
|||||||
public void storeCaches(List<Cache> caches) {
|
public void storeCaches(List<Cache> caches) {
|
||||||
EntityManager em = dbService.getEntityManager();
|
EntityManager em = dbService.getEntityManager();
|
||||||
|
|
||||||
|
try {
|
||||||
|
int transactionNumber = 0;
|
||||||
int currentCacheNumber = 0;
|
int currentCacheNumber = 0;
|
||||||
int numberOfCaches = caches.size();
|
int numberOfCaches = caches.size();
|
||||||
for (Cache cache : caches) {
|
for (Cache cache : caches) {
|
||||||
@@ -47,7 +49,10 @@ public class CacheServiceImpl implements CacheService {
|
|||||||
"Save caches to Database " + currentCacheNumber + " / " + numberOfCaches,
|
"Save caches to Database " + currentCacheNumber + " / " + numberOfCaches,
|
||||||
(double) currentCacheNumber / (double) numberOfCaches));
|
(double) currentCacheNumber / (double) numberOfCaches));
|
||||||
|
|
||||||
em.getTransaction().begin();
|
// begin transaction if the transaction counter is set to zero
|
||||||
|
if (transactionNumber == 0) { em.getTransaction().begin(); };
|
||||||
|
transactionNumber++;
|
||||||
|
|
||||||
em.merge(cache.getOwner());
|
em.merge(cache.getOwner());
|
||||||
em.merge(cache.getMainWayPoint());
|
em.merge(cache.getMainWayPoint());
|
||||||
|
|
||||||
@@ -65,7 +70,21 @@ public class CacheServiceImpl implements CacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
em.merge(cache);
|
em.merge(cache);
|
||||||
|
|
||||||
|
// comit every X caches
|
||||||
|
if (transactionNumber == TRANSACTION_SIZE) {
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
|
transactionNumber = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there wasn?t a commit right before, commit the rest
|
||||||
|
if (transactionNumber != 0) {
|
||||||
|
em.getTransaction().commit();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
em.getTransaction().rollback();
|
||||||
}
|
}
|
||||||
|
|
||||||
fireEvent(new ProgressEvent("Database",
|
fireEvent(new ProgressEvent("Database",
|
||||||
|
|||||||
Reference in New Issue
Block a user