mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-18 10:41:26 +00:00
split up read and write charts and added cache efficiency chart
(because we will add further read/write-specific stats like total number of files read/written, bytes encrypted/decrypted, etc)
This commit is contained in:
@@ -2,9 +2,12 @@ package org.cryptomator.common.vaults;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.LongProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleLongProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.concurrent.ScheduledService;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.util.Duration;
|
||||
@@ -28,6 +31,7 @@ public class VaultStats {
|
||||
private final ScheduledService<Optional<CryptoFileSystemStats>> updateService;
|
||||
private final LongProperty bytesPerSecondRead = new SimpleLongProperty();
|
||||
private final LongProperty bytesPerSecondWritten = new SimpleLongProperty();
|
||||
private final DoubleProperty cacheHitRate = new SimpleDoubleProperty();
|
||||
|
||||
@Inject
|
||||
VaultStats(AtomicReference<CryptoFileSystem> fs, ObjectProperty<VaultState> state, ExecutorService executor) {
|
||||
@@ -55,6 +59,17 @@ public class VaultStats {
|
||||
assert Platform.isFxApplicationThread();
|
||||
bytesPerSecondRead.set(stats.map(CryptoFileSystemStats::pollBytesRead).orElse(0l));
|
||||
bytesPerSecondWritten.set(stats.map(CryptoFileSystemStats::pollBytesWritten).orElse(0l));
|
||||
cacheHitRate.set(stats.map(this::getCacheHitRate).orElse(0.0));
|
||||
}
|
||||
|
||||
private double getCacheHitRate(CryptoFileSystemStats stats) {
|
||||
long accesses = stats.pollChunkCacheAccesses();
|
||||
long hits = stats.pollChunkCacheHits();
|
||||
if (accesses == 0) {
|
||||
return 0.0;
|
||||
} else {
|
||||
return hits / (double) accesses;
|
||||
}
|
||||
}
|
||||
|
||||
private class UpdateStatsService extends ScheduledService<Optional<CryptoFileSystemStats>> {
|
||||
@@ -94,4 +109,13 @@ public class VaultStats {
|
||||
public long getBytesPerSecondWritten() {
|
||||
return bytesPerSecondWritten.get();
|
||||
}
|
||||
|
||||
public DoubleProperty cacheHitRateProperty() {
|
||||
return cacheHitRate;
|
||||
}
|
||||
|
||||
public double getCacheHitRate() {
|
||||
return cacheHitRate.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public enum FxmlFile {
|
||||
UNLOCK_INVALID_MOUNT_POINT("/fxml/unlock_invalid_mount_point.fxml"), //
|
||||
UNLOCK_SUCCESS("/fxml/unlock_success.fxml"), //
|
||||
VAULT_OPTIONS("/fxml/vault_options.fxml"), //
|
||||
VAULT_STATISTICS("/fxml/vault_statistics.fxml"), //
|
||||
VAULT_STATISTICS("/fxml/stats.fxml"), //
|
||||
WRONGFILEALERT("/fxml/wrongfilealert.fxml");
|
||||
|
||||
private final String ressourcePathString;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.cryptomator.ui.common;
|
||||
|
||||
import javafx.beans.binding.DoubleBinding;
|
||||
import javafx.beans.binding.LongBinding;
|
||||
import javafx.beans.binding.StringBinding;
|
||||
import javafx.beans.value.ObservableObjectValue;
|
||||
@@ -50,4 +51,23 @@ public final class WeakBindings {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DoubleBinding that listens to changes from the given observable without being strongly referenced by it.
|
||||
*
|
||||
* @param observable The observable
|
||||
* @return a DoubleBinding weakly referenced from the given observable
|
||||
*/
|
||||
public static DoubleBinding bindDouble(ObservableValue<Number> observable) {
|
||||
return new DoubleBinding() {
|
||||
{
|
||||
bind(observable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double computeValue() {
|
||||
return observable.getValue().doubleValue();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.cryptomator.ui.common.StageFactory;
|
||||
import org.cryptomator.ui.migration.MigrationComponent;
|
||||
import org.cryptomator.ui.removevault.RemoveVaultComponent;
|
||||
import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
|
||||
import org.cryptomator.ui.vaultstatistics.VaultStatisticsComponent;
|
||||
import org.cryptomator.ui.stats.VaultStatisticsComponent;
|
||||
import org.cryptomator.ui.wrongfilealert.WrongFileAlertComponent;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
@@ -6,7 +6,7 @@ import javafx.fxml.FXML;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.VaultService;
|
||||
import org.cryptomator.ui.vaultstatistics.VaultStatisticsComponent;
|
||||
import org.cryptomator.ui.stats.VaultStatisticsComponent;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.cryptomator.ui.vaultstatistics;
|
||||
package org.cryptomator.ui.stats;
|
||||
|
||||
import dagger.BindsInstance;
|
||||
import dagger.Lazy;
|
||||
@@ -1,13 +1,17 @@
|
||||
package org.cryptomator.ui.vaultstatistics;
|
||||
package org.cryptomator.ui.stats;
|
||||
|
||||
import javafx.animation.Animation;
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.DoubleBinding;
|
||||
import javafx.beans.binding.LongBinding;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.chart.AreaChart;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import javafx.scene.chart.XYChart.Data;
|
||||
import javafx.scene.chart.XYChart.Series;
|
||||
import javafx.stage.Stage;
|
||||
@@ -18,13 +22,14 @@ import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.WeakBindings;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Arrays;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@VaultStatisticsScoped
|
||||
public class VaultStatisticsController implements FxController {
|
||||
|
||||
private static final int IO_SAMPLING_STEPS = 100;
|
||||
private static final double IO_SAMPLING_INTERVAL = 0.5;
|
||||
private static final int IO_SAMPLING_STEPS = 30;
|
||||
private static final double IO_SAMPLING_INTERVAL = 1;
|
||||
|
||||
private final VaultStats stats;
|
||||
private final Series<Number, Number> readData;
|
||||
@@ -32,19 +37,27 @@ public class VaultStatisticsController implements FxController {
|
||||
private final Timeline ioAnimation;
|
||||
private final LongBinding bpsRead;
|
||||
private final LongBinding bpsWritten;
|
||||
private final DoubleBinding cacheHitRate;
|
||||
private final DoubleBinding cacheHitDregrees;
|
||||
private final DoubleBinding cacheHitPercentage;
|
||||
|
||||
public LineChart<Number, Number> lineGraph;
|
||||
public AreaChart<Number, Number> readChart;
|
||||
public AreaChart<Number, Number> writeChart;
|
||||
public NumberAxis readChartXAxis;
|
||||
public NumberAxis readChartYAxis;
|
||||
public NumberAxis writeChartXAxis;
|
||||
public NumberAxis writeChartYAxis;
|
||||
|
||||
@Inject
|
||||
public VaultStatisticsController(@VaultStatisticsWindow Stage window, @VaultStatisticsWindow Vault vault, ResourceBundle resourceBundle) {
|
||||
this.stats = vault.getStats();
|
||||
this.readData = new Series<>();
|
||||
this.writeData = new Series<>();
|
||||
this.bpsRead = WeakBindings.bindLong(stats.bytesPerSecondReadProperty());
|
||||
this.bpsWritten = WeakBindings.bindLong(stats.bytesPerSecondWrittenProperty());
|
||||
|
||||
this.readData = new Series<>();
|
||||
readData.setName(resourceBundle.getString("vaultstatistics.readDataLabel"));
|
||||
this.writeData = new Series<>();
|
||||
writeData.setName(resourceBundle.getString("vaultstatistics.writtenDataLabel"));
|
||||
this.cacheHitRate = WeakBindings.bindDouble(stats.cacheHitRateProperty());
|
||||
this.cacheHitDregrees = cacheHitRate.multiply(-270);
|
||||
this.cacheHitPercentage = cacheHitRate.multiply(100);
|
||||
|
||||
this.ioAnimation = new Timeline(); //TODO Research better timer
|
||||
ioAnimation.getKeyFrames().add(new KeyFrame(Duration.seconds(IO_SAMPLING_INTERVAL), new IoSamplingAnimationHandler(readData, writeData)));
|
||||
@@ -60,14 +73,18 @@ public class VaultStatisticsController implements FxController {
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
lineGraph.getData().addAll(readData, writeData);
|
||||
readChart.getData().addAll(readData);
|
||||
writeChart.getData().addAll(writeData);
|
||||
}
|
||||
|
||||
private class IoSamplingAnimationHandler implements EventHandler<ActionEvent> {
|
||||
|
||||
private static final double BYTES_TO_MEGABYTES_FACTOR = 1.0 / IO_SAMPLING_INTERVAL / 1024.0 / 1024.0;
|
||||
|
||||
private long step = IO_SAMPLING_STEPS;
|
||||
private final Series<Number, Number> decryptedBytesRead;
|
||||
private final Series<Number, Number> encryptedBytesWrite;
|
||||
private final long[] maxBuf = new long[IO_SAMPLING_STEPS];
|
||||
|
||||
public IoSamplingAnimationHandler(Series<Number, Number> readData, Series<Number, Number> writeData) {
|
||||
this.decryptedBytesRead = readData;
|
||||
@@ -82,23 +99,28 @@ public class VaultStatisticsController implements FxController {
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
// move all values one step:
|
||||
for (int i = 0; i < IO_SAMPLING_STEPS - 1; i++) {
|
||||
int j = i + 1;
|
||||
Number tmp = decryptedBytesRead.getData().get(j).getYValue();
|
||||
decryptedBytesRead.getData().get(i).setYValue(tmp);
|
||||
final long currentStep = step++;
|
||||
final long decBytes = stats.bytesPerSecondReadProperty().get();
|
||||
final long encBytes = stats.bytesPerSecondWrittenProperty().get();
|
||||
|
||||
tmp = encryptedBytesWrite.getData().get(j).getYValue();
|
||||
encryptedBytesWrite.getData().get(i).setYValue(tmp);
|
||||
}
|
||||
maxBuf[(int) currentStep % IO_SAMPLING_STEPS] = Math.max(decBytes, encBytes);
|
||||
long allTimeMax = Arrays.stream(maxBuf).max().orElse(0l);
|
||||
|
||||
// remove oldest value:
|
||||
decryptedBytesRead.getData().remove(0);
|
||||
encryptedBytesWrite.getData().remove(0);
|
||||
|
||||
// add latest value:
|
||||
final long decBytes = stats.bytesPerSecondReadProperty().get();
|
||||
final double decMb = decBytes * BYTES_TO_MEGABYTES_FACTOR;
|
||||
final long encBytes = stats.bytesPerSecondWrittenProperty().get();
|
||||
final double encMb = encBytes * BYTES_TO_MEGABYTES_FACTOR;
|
||||
decryptedBytesRead.getData().get(IO_SAMPLING_STEPS - 1).setYValue(decMb);
|
||||
encryptedBytesWrite.getData().get(IO_SAMPLING_STEPS - 1).setYValue(encMb);
|
||||
decryptedBytesRead.getData().add(new Data<>(currentStep, decBytes));
|
||||
encryptedBytesWrite.getData().add(new Data<>(currentStep, encBytes));
|
||||
|
||||
// adjust ranges:
|
||||
readChartXAxis.setLowerBound(currentStep - IO_SAMPLING_STEPS);
|
||||
readChartXAxis.setUpperBound(currentStep);
|
||||
readChartYAxis.setUpperBound(allTimeMax);
|
||||
writeChartXAxis.setLowerBound(currentStep - IO_SAMPLING_STEPS);
|
||||
writeChartXAxis.setUpperBound(currentStep);
|
||||
writeChartYAxis.setUpperBound(allTimeMax);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,4 +141,20 @@ public class VaultStatisticsController implements FxController {
|
||||
public long getBpsWritten() {
|
||||
return bpsWritten.get();
|
||||
}
|
||||
|
||||
public DoubleBinding cacheHitPercentageProperty() {
|
||||
return cacheHitPercentage;
|
||||
}
|
||||
|
||||
public double getCacheHitPercentage() {
|
||||
return cacheHitPercentage.get();
|
||||
}
|
||||
|
||||
public DoubleBinding cacheHitDregreesProperty() {
|
||||
return cacheHitDregrees;
|
||||
}
|
||||
|
||||
public double getCacheHitDregrees() {
|
||||
return cacheHitDregrees.get();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.cryptomator.ui.vaultstatistics;
|
||||
package org.cryptomator.ui.stats;
|
||||
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
@@ -38,7 +38,7 @@ abstract class VaultStatisticsModule {
|
||||
@VaultStatisticsScoped
|
||||
static Stage provideStage(StageFactory factory, ResourceBundle resourceBundle, @VaultStatisticsWindow Vault vault) {
|
||||
Stage stage = factory.create();
|
||||
stage.setTitle(String.format(resourceBundle.getString("vaultstatistics.title"), vault.getDisplayableName()));
|
||||
stage.setTitle(String.format(resourceBundle.getString("stats.title"), vault.getDisplayableName()));
|
||||
stage.setResizable(false);
|
||||
var weakStage = new WeakReference<>(stage);
|
||||
vault.stateProperty().addListener(new ChangeListener<>() {
|
||||
@@ -60,7 +60,7 @@ abstract class VaultStatisticsModule {
|
||||
@FxmlScene(FxmlFile.VAULT_STATISTICS)
|
||||
@VaultStatisticsScoped
|
||||
static Scene provideVaultStatisticsScene(@VaultStatisticsWindow FXMLLoaderFactory fxmlLoaders) {
|
||||
return fxmlLoaders.createScene("/fxml/vault_statistics.fxml");
|
||||
return fxmlLoaders.createScene("/fxml/stats.fxml");
|
||||
}
|
||||
|
||||
// ------------------
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.cryptomator.ui.vaultstatistics;
|
||||
package org.cryptomator.ui.stats;
|
||||
|
||||
import javax.inject.Scope;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.cryptomator.ui.vaultstatistics;
|
||||
package org.cryptomator.ui.stats;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -874,59 +874,52 @@
|
||||
* I/O Statistics *
|
||||
* *
|
||||
******************************************************************************/
|
||||
.chart {
|
||||
|
||||
.cache-arc-background {
|
||||
-fx-fill: transparent;
|
||||
-fx-stroke: MUTED_BG;
|
||||
-fx-stroke-type: centered;
|
||||
-fx-stroke-width: 12;
|
||||
-fx-stroke-line-cap: butt;
|
||||
}
|
||||
|
||||
.cache-arc-foreground {
|
||||
-fx-fill: transparent;
|
||||
-fx-stroke: PRIMARY;
|
||||
-fx-stroke-type: centered;
|
||||
-fx-stroke-width: 12;
|
||||
-fx-stroke-line-cap: butt;
|
||||
}
|
||||
|
||||
.chart.io-stats {
|
||||
-fx-padding: 10px;
|
||||
-fx-horizontal-grid-lines-visible: false;
|
||||
-fx-horizontal-zero-line-visible: false;
|
||||
-fx-vertical-grid-lines-visible: false;
|
||||
-fx-vertical-zero-line-visible: false;
|
||||
}
|
||||
|
||||
.axis.io-stats {
|
||||
-fx-tick-mark-visible: false;
|
||||
-fx-minor-tick-visible: false;
|
||||
-fx-tick-labels-visible: false;
|
||||
}
|
||||
|
||||
.chart-plot-background {
|
||||
-fx-background-color: MAIN_BG;
|
||||
-fx-padding: 20px;
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
/* content */
|
||||
|
||||
.chart-content {
|
||||
-fx-padding: 10px;
|
||||
-fx-text-fill: TEXT_FILL;
|
||||
-fx-tick-label-fill: GRAY_3;
|
||||
-fx-minor-tick-visible: false
|
||||
}
|
||||
.chart-horizontal-grid-lines {
|
||||
-fx-stroke: PRIMARY_L2;
|
||||
}
|
||||
.chart-vertical-zero-line,
|
||||
.chart-horizontal-zero-line {
|
||||
-fx-stroke: PRIMARY_L2;
|
||||
}
|
||||
.chart-series-line {
|
||||
-fx-stroke-width: 2px;
|
||||
}
|
||||
.chart-horizontal-zero-line,
|
||||
.chart-alternative-row-fill {
|
||||
-fx-fill: GRAY_3;
|
||||
-fx-stroke: transparent;
|
||||
-fx-stroke-width: 0;
|
||||
}
|
||||
.axis {
|
||||
-fx-tick-label-fill: TEXT_FILL;
|
||||
-fx-tick-length: 20;
|
||||
-fx-minor-tick-length: 10;
|
||||
}
|
||||
.axis-label {
|
||||
-fx-text-fill: TEXT_FILL;
|
||||
}
|
||||
.default-color0.chart-series-line { -fx-stroke: PRIMARY; }
|
||||
.default-color1.chart-series-line { -fx-stroke: RED_5 ; }
|
||||
|
||||
/* legend */
|
||||
|
||||
.chart-legend {
|
||||
-fx-text-fill: TEXT_FILL;
|
||||
-fx-background-color: transparent;
|
||||
-fx-padding: 0.4em;
|
||||
.default-color0.chart-series-area-line {
|
||||
-fx-stroke: PRIMARY;
|
||||
}
|
||||
.chart-line-symbol {
|
||||
-fx-background-radius: 5px;
|
||||
-fx-padding: 5px;
|
||||
.default-color0.chart-series-area-fill {
|
||||
-fx-fill: linear-gradient(to bottom, PRIMARY, transparent);
|
||||
-fx-stroke: transparent;
|
||||
}
|
||||
.default-color0.chart-line-symbol { -fx-background-color: PRIMARY; }
|
||||
.default-color1.chart-line-symbol { -fx-background-color: RED_5; }
|
||||
|
||||
@@ -884,48 +884,52 @@
|
||||
|
||||
/* content */
|
||||
|
||||
.chart-content {
|
||||
|
||||
.cache-arc-background {
|
||||
-fx-fill: transparent;
|
||||
-fx-stroke: MUTED_BG;
|
||||
-fx-stroke-type: centered;
|
||||
-fx-stroke-width: 12;
|
||||
-fx-stroke-line-cap: butt;
|
||||
}
|
||||
|
||||
.cache-arc-foreground {
|
||||
-fx-fill: transparent;
|
||||
-fx-stroke: PRIMARY;
|
||||
-fx-stroke-type: centered;
|
||||
-fx-stroke-width: 12;
|
||||
-fx-stroke-line-cap: butt;
|
||||
}
|
||||
|
||||
.chart.io-stats {
|
||||
-fx-padding: 10px;
|
||||
-fx-text-fill: TEXT_FILL;
|
||||
-fx-tick-label-fill: GRAY_3;
|
||||
-fx-minor-tick-visible: false
|
||||
-fx-horizontal-grid-lines-visible: false;
|
||||
-fx-horizontal-zero-line-visible: false;
|
||||
-fx-vertical-grid-lines-visible: false;
|
||||
-fx-vertical-zero-line-visible: false;
|
||||
}
|
||||
.chart-horizontal-grid-lines {
|
||||
-fx-stroke: PRIMARY_D2;
|
||||
|
||||
.axis.io-stats {
|
||||
-fx-tick-mark-visible: false;
|
||||
-fx-minor-tick-visible: false;
|
||||
-fx-tick-labels-visible: false;
|
||||
}
|
||||
|
||||
.chart-plot-background {
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
.chart-vertical-zero-line,
|
||||
.chart-horizontal-zero-line {
|
||||
-fx-stroke: PRIMARY_D2;
|
||||
}
|
||||
.chart-series-line {
|
||||
-fx-stroke-width: 2px;
|
||||
}
|
||||
.chart-horizontal-zero-line,
|
||||
.chart-alternative-row-fill {
|
||||
-fx-fill: GRAY_8;
|
||||
-fx-stroke: transparent;
|
||||
-fx-stroke-width: 0;
|
||||
}
|
||||
.axis {
|
||||
-fx-tick-label-fill: TEXT_FILL;
|
||||
-fx-tick-length: 20;
|
||||
-fx-minor-tick-length: 10;
|
||||
}
|
||||
.axis-label {
|
||||
-fx-text-fill: TEXT_FILL;
|
||||
}
|
||||
.default-color0.chart-series-line { -fx-stroke: PRIMARY; }
|
||||
.default-color1.chart-series-line { -fx-stroke: RED_5 ; }
|
||||
|
||||
/* legend */
|
||||
|
||||
.chart-legend {
|
||||
-fx-text-fill: TEXT_FILL;
|
||||
-fx-background-color: transparent;
|
||||
-fx-padding: 0.4em;
|
||||
.default-color0.chart-series-area-line {
|
||||
-fx-stroke: PRIMARY;
|
||||
}
|
||||
.chart-line-symbol {
|
||||
-fx-background-radius: 5px;
|
||||
-fx-padding: 5px;
|
||||
.default-color0.chart-series-area-fill {
|
||||
-fx-fill: linear-gradient(to bottom, PRIMARY, transparent);
|
||||
-fx-stroke: transparent;
|
||||
}
|
||||
.default-color0.chart-line-symbol { -fx-background-color: PRIMARY; }
|
||||
.default-color1.chart-line-symbol { -fx-background-color: RED_5; }
|
||||
|
||||
77
main/ui/src/main/resources/fxml/stats.fxml
Normal file
77
main/ui/src/main/resources/fxml/stats.fxml
Normal file
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.chart.AreaChart?>
|
||||
<?import javafx.scene.chart.NumberAxis?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.Cursor?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.Arc?>
|
||||
<?import org.cryptomator.ui.controls.FormattedLabel?>
|
||||
<?import org.cryptomator.ui.controls.ThrougputLabel?>
|
||||
<?import javafx.scene.Group?>
|
||||
<HBox xmlns="http://javafx.com/javafx"
|
||||
xmlns:fx="http://javafx.com/fxml"
|
||||
fx:controller="org.cryptomator.ui.stats.VaultStatisticsController"
|
||||
prefWidth="600.0" spacing="12">
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="12"/>
|
||||
</padding>
|
||||
|
||||
<!-- Caching -->
|
||||
<VBox prefWidth="200" prefHeight="200">
|
||||
<StackPane>
|
||||
<Group>
|
||||
<Arc styleClass="cache-arc-background" centerX="100" centerY="100" radiusX="100" radiusY="100" startAngle="225" length="-270"/>
|
||||
<Arc styleClass="cache-arc-foreground" centerX="100" centerY="100" radiusX="100" radiusY="100" startAngle="225" length="${controller.cacheHitDregrees}"/>
|
||||
</Group>
|
||||
<VBox StackPane.alignment="CENTER" alignment="CENTER">
|
||||
<FormattedLabel styleClass="label-large" format="\%1.0f %%" arg1="${controller.cacheHitPercentage}" />
|
||||
<Label text="%stats.cacheHitRate" />
|
||||
</VBox>
|
||||
</StackPane>
|
||||
</VBox>
|
||||
|
||||
<!-- Read -->
|
||||
<VBox prefWidth="200" prefHeight="200">
|
||||
<HBox spacing="12">
|
||||
<Label text="%stats.readDataLabel"/>
|
||||
<ThrougputLabel styleClass="label-large" alignment="CENTER_RIGHT" minWidth="60" idleFormat="%main.vaultDetail.throughput.idle" kibsFormat="%main.vaultDetail.throughput.kbps"
|
||||
mibsFormat="%main.vaultDetail.throughput.mbps" bytesPerSecond="${controller.bpsRead}"/>
|
||||
</HBox>
|
||||
<AreaChart fx:id="readChart" styleClass="io-stats" createSymbols="false" animated="false">
|
||||
<xAxis>
|
||||
<NumberAxis fx:id="readChartXAxis" styleClass="io-stats" autoRanging="false" forceZeroInRange="false" side="BOTTOM"/>
|
||||
</xAxis>
|
||||
<yAxis>
|
||||
<NumberAxis fx:id="readChartYAxis" styleClass="io-stats" autoRanging="false" forceZeroInRange="true" side="LEFT" tickUnit="Infinity"/>
|
||||
</yAxis>
|
||||
<cursor>
|
||||
<Cursor fx:constant="DEFAULT"/>
|
||||
</cursor>
|
||||
</AreaChart>
|
||||
</VBox>
|
||||
|
||||
<!-- Write -->
|
||||
<VBox prefWidth="200" prefHeight="200">
|
||||
<HBox>
|
||||
<Label text="%stats.writtenDataLabel"/>
|
||||
<ThrougputLabel styleClass="label-large" alignment="CENTER_RIGHT" minWidth="60" idleFormat="%main.vaultDetail.throughput.idle" kibsFormat="%main.vaultDetail.throughput.kbps"
|
||||
mibsFormat="%main.vaultDetail.throughput.mbps" bytesPerSecond="${controller.bpsWritten}"/>
|
||||
</HBox>
|
||||
<AreaChart fx:id="writeChart" styleClass="io-stats" createSymbols="false" animated="false">
|
||||
<xAxis>
|
||||
<NumberAxis fx:id="writeChartXAxis" styleClass="io-stats" autoRanging="false" forceZeroInRange="false" side="BOTTOM"/>
|
||||
</xAxis>
|
||||
<yAxis>
|
||||
<NumberAxis fx:id="writeChartYAxis" styleClass="io-stats" autoRanging="false" forceZeroInRange="true" side="LEFT" tickUnit="Infinity"/>
|
||||
</yAxis>
|
||||
<cursor>
|
||||
<Cursor fx:constant="DEFAULT"/>
|
||||
</cursor>
|
||||
</AreaChart>
|
||||
</VBox>
|
||||
|
||||
</HBox>
|
||||
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.chart.LineChart?>
|
||||
<?import javafx.scene.chart.NumberAxis?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.Cursor?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import org.cryptomator.ui.controls.ThrougputLabel?>
|
||||
<VBox xmlns="http://javafx.com/javafx"
|
||||
xmlns:fx="http://javafx.com/fxml"
|
||||
fx:controller="org.cryptomator.ui.vaultstatistics.VaultStatisticsController"
|
||||
prefHeight="400.0" prefWidth="600.0">
|
||||
|
||||
<LineChart fx:id="lineGraph" VBox.vgrow="ALWAYS" createSymbols="false" legendVisible="true" prefHeight="372.0" prefWidth="423.0" visible="true" animated="false"
|
||||
title="%vaultstatistics.throughputTitle" verticalZeroLineVisible="true" verticalGridLinesVisible="false" horizontalGridLinesVisible="true">
|
||||
<xAxis>
|
||||
<NumberAxis autoRanging="false" lowerBound="0" side="BOTTOM" tickUnit="5" upperBound="100" label="%vaultstatistics.xAxisTimeLabel"/>
|
||||
</xAxis>
|
||||
<yAxis>
|
||||
<NumberAxis autoRanging="true" lowerBound="0" side="LEFT" tickUnit="1024" upperBound="100" label="%vaultstatistics.yAxisThroughputLabel" forceZeroInRange="true"/>
|
||||
</yAxis>
|
||||
<cursor>
|
||||
<Cursor fx:constant="DEFAULT"/>
|
||||
</cursor>
|
||||
</LineChart>
|
||||
<HBox alignment="CENTER_RIGHT" spacing="6">
|
||||
<Label styleClass="label-small,label-muted" text="%main.vaultDetail.bytesPerSecondRead"/>
|
||||
<ThrougputLabel styleClass="label-small,label-muted" alignment="CENTER_RIGHT" minWidth="60" idleFormat="%main.vaultDetail.throughput.idle" kibsFormat="%main.vaultDetail.throughput.kbps"
|
||||
mibsFormat="%main.vaultDetail.throughput.mbps" bytesPerSecond="${controller.bpsRead}"/>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER_RIGHT" spacing="6">
|
||||
<Label styleClass="label-small,label-muted" text="%main.vaultDetail.bytesPerSecondWritten"/>
|
||||
<ThrougputLabel styleClass="label-small,label-muted" alignment="CENTER_RIGHT" minWidth="60" idleFormat="%main.vaultDetail.throughput.idle" kibsFormat="%main.vaultDetail.throughput.kbps"
|
||||
mibsFormat="%main.vaultDetail.throughput.mbps" bytesPerSecond="${controller.bpsWritten}"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
@@ -161,12 +161,10 @@ preferences.donationKey.getDonationKey=Get a donation key
|
||||
preferences.about=About
|
||||
|
||||
# Vault Statistics
|
||||
vaultstatistics.title=Statistics for %s
|
||||
vaultstatistics.xAxisTimeLabel=Seconds
|
||||
vaultstatistics.yAxisThroughputLabel=Throughput in KiB/s
|
||||
vaultstatistics.throughputTitle=Read and Writes
|
||||
vaultstatistics.readDataLabel=Read Data
|
||||
vaultstatistics.writtenDataLabel=Written Data
|
||||
stats.title=Statistics for %s
|
||||
stats.readDataLabel=Read Data
|
||||
stats.writtenDataLabel=Written Data
|
||||
stats.cacheHitRate=Cache Hit Rate
|
||||
|
||||
# Main Window
|
||||
main.closeBtn.tooltip=Close
|
||||
|
||||
Reference in New Issue
Block a user