Code Monkey home page Code Monkey logo

binjr's Introduction

binjr

Build Status Github Release Maven Central

trailer

Contents

What is binjr?

binjr is a time series browser; it renders time series data produced by other applications as dynamically editable representations and provides advanced features to navigate the data smoothly and efficiently (drag & drop, zoom, history, detachable tabs, advanced time-range picker).

It is a standalone client application, that runs independently of the applications that produce the data; there are no server or server-side components dedicated to binjr that need to be installed on the source.

The user experience in binjr revolves around enabling users to compose a custom view by using any of the time-series exposed by the source, simply by dragging and dropping them on the view.
That view then constantly evolves as users add or remove series from different sources, while navigating through it by changing the time range, the type of chart visualization and smaller aspects such as the color or transparency for each series.
Users can then save the current state of their session at any time to a file, in order to reopen it later or to share it with someone else.

binjr also possesses the ability to visualize time series not only as charts of numeric values, but can be customized to support visualization for any data type; for instance it features out-of-the-box a source adapter for text based log files.

Log files, produced by applications to trace their lifecycle at runtime, typically contain timestamps for each event they contain; so we can think of them as time series, but with data points being textual information instead of numerical values.
In practical terms, this means that a lot of the features built into binjr to compose and navigate time series visualizations can be applied to log files with great benefits.

Behind the scene, binjr uses Apache Lucene to index data from log files; meaning users can use its powerful query language to hack through vast quantities logged events.

It also allows binjr to open log files of any size; unlike most text editors which will fail to load multi gigabytes-sized files as they try to fit it all in memory, binjr will happily index those and present a paginated view so that memory usage remains reasonable, while the backing index ensures navigating and searching is lightning fast.

With these abilities, binjr aims to become the missing link between text editors and command line tools traditionally used to analyse monitoring data locally and full-blown log analytics platforms (e.g. Elastic/Logstash/Kibana stack) that centralizes logs for entire organizations.
It provides many of the same powerful visualization and search features while still remaining a totally local solution (the data never needs to be pushed to the cloud - or anywhere else for that matter), and requiring no setup nor maintenance to speak of.

...and what it isn't

  • binjr is not a system performance collector, nor a collector of anything else for that matter. What it provides is efficient navigation and pretty presentation for time series collected elsewhere.
  • binjr is not a cloud solution. It's not even a server based solution; it's entirely a client application, albeit one that can get its data from remote servers. Think of it as a browser, only just for time series.
  • binjr is not a live system monitoring dashboard. While you can use it to connect to live sources, its feature set is not geared toward that particular task, and there are better tools for that out there. Instead, it aims to be an investigation tool, for when you don't necessarily know what you're looking for beforehand and you'll want to build and change the view of the data as you navigate through it rather than be constrained by pre-determined dashboards.

Features

Data source agnostic

  • Standalone, client-side application.
  • Can connect to any number of sources, of different types, at the same time.
  • Communicates though the APIs exposed by the source.
  • Supports for data sources is extensible via plugins.
  • Supports time-series with numeric (e.g. charts) or text (e.g. logs) values.

Designed for ad-hoc view composition

  • Drag and drop series from any sources directly on the chart view.
  • Mix series from different sources on the same view.
  • Allows charts overlay: create charts with several Y axis and a shared time line.
  • Highly customizable views; choose chart types, change series colours, transparency, legends, etc...
  • Save you work session to a file at any time, to be reopened later or shared with someone else.

Smooth navigation

  • Mouse driven zoom of both X and Y axis.
  • Drag and drop composition.
  • Browser-like, forward & backward navigation of zoom history.
  • Advanced time-range selection widget.
  • The tabs holding the chart views can be detached into separate windows.
  • Charts from different tabs/windows can be synchronized to a common time line.

Fast, responsive & aesthetically pleasing visuals

  • Built on top of JavaFX for a modern look and cross-platform, hardware accelerated graphics.
  • Three different UI themes, to better integrate with host OS and fit user preferences.

Java based application

  • Cross-platform: works great on Linux, macOS and Windows desktops!
  • Strong performances, even under heavy load (dozens of charts with dozens of series and thousands of samples).

Supported data sources

binjr can consume time series data provided by the following data sources:

Name Description Built-in[1] Source type
JRDS A performance monitoring application written in Java. Remote
Netdata Distributed, real-time performance and health monitoring for systems and applications. Remote
RRD Files Round-Robin Database files produced by RRDtool and RRD4J. Local files
CSV Files Comma Separated Values files. Local files
Log Files Text based, semi-structured log files. Local files
JDK Flight Recoder Low-overhead data collection framework for troubleshooting Java applications and the HotSpot JVM. Local files
Demo Adapter A plugin for binjr that provides data sources for demonstration purposes. Local files

[1]: Support for data sources not marked as 'Built-in' requires additional plugins.

Getting started

There are several ways to get up and running with binjr:

Download an application bundle

The simplest way to start using binjr is to download an application bundle from the download page.

These bundles contain all the dependencies required to run the app, including a copy of the Java runtime specially crafted to only include the required components and save disk space.
They are only ~75 MiB in size and there is one for each of the supported platform: Windows, Linux and macOS.

Simply download the one for your system, unpack it and run binjr to start!

Build from source

You can also build or run the application from the source code using the included Gradle wrapper.
Simply clone the repo from Github and run:

  • ./gradlew build to build the JAR for the all the modules.
  • ./gradlew run to build and start the application straight away.
  • ./gradlew clean packageDistribution to build an application bundle for the platform on which you ran the build.

Please note that it is mandatory to run the clean task in between two executions of the packageDistribution in the same environment.

Trying it out

If you'd like to experience binjr's visualization capabilities but do not have a compatible data source handy, you can use the demonstration data adapter.

It is a plugin which embeds a small, stand-alone data source that you can readily browse using binjr.

  1. Make sure binjr is installed on your system and make a note of the folder it is installed in.
  2. Download the binjr-adapter-demo-1.x.x.zip archive from https://github.com/binjr/binjr-adapter-demo/releases/latest
  3. Copy the binjr-adapter-demo-1.x.x.jar file contained in the zip file into the plugins folder of your binjr installation.
  4. Start binjr (or restart it if it was runnning when you copied the plugin) and open the demo.bjr workspace contained in the zip (from the command menu, select Workspaces > Open..., or press Ctrl+O)

Getting help

The documentation can be found here.

If you encounter an issue, or would like to suggest an enhancement or a new feature, you may do so here.

How is it licensed?

binjr is released under the Apache License version 2.0.

Contributing

This project accepts contributions via GitHub pull requests.

Certificate of Origin

By contributing to this project you agree to the Developer Certificate of Origin (DCO). This document was created by the Linux Kernel community and is a simple statement that you, as a contributor, have the legal right to make the contribution. See the DCO file for details.

binjr's People

Contributors

arkanosis avatar fthevenet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

binjr's Issues

Improve datetime boundaries handling when max < min

Currently, when a boundary is changed in a way that causes max < min, an error is displayed.

I think the UX would be much better if instead of raising an error, the other boundary was changed automatically. The main argument is that displaying the error is annoying while doing nothing to solve the issue. I the user had planned to change both the min and the max, changing the other boundary automatically would not make it any more complicated anyway.

The way I see it, the other boundary could be set so that the time frame between min and max is either:

  • the default range (ie. the same as when launching binjr) ;
  • the same as before changing the first boundary (this is how Google Calendar behaves, for example).

I've a slight preference for the latter which seems more natural to me, but as a heavy Google Calendar user, I'm probably biased.

Thanks!

Uncaught exception when entering a negative range for a chart's Y axis

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: delta must be positive
        at eu.binjr.common.javafx.charts.MetricStableTicksAxis.calculateTickSpacing(MetricStableTicksAxis.java:39)
        at eu.binjr.common.javafx.charts.StableTicksAxis.getRange(StableTicksAxis.java:224)
        at eu.binjr.common.javafx.charts.StableTicksAxis.getRange(StableTicksAxis.java:263)
        at eu.binjr.common.javafx.charts.StableTicksAxis.getRange(StableTicksAxis.java:42)
        at javafx.controls/javafx.scene.chart.Axis.layoutChildren(Unknown Source)
  ...

Because the IllegalArgumentException is not properly handled, it leaves the worksheet incapable to recover and it stops refreshing properly.
Also, the error isn't properly logged and only appears in the err out channel.

Enhancements to time interval selection

Selection of the current time interval is quite rigid at the moment.

  • Whenever one boundary is set so that the interval is negative (i.e. the start date is after the end date), consider shifting the other boundary by a fixed amount instead of throwing on error.

  • Consider adding a further navigation facilities to the interval selections panel (which would tie in with zoom and pan as proposed in #29 )

IllegalStateException: Cannot get supported actions. Drag pointer haven't entered the application window

Version:

How to reproduce:

  • reproduce #57
  • close the source
  • add a new source
  • paste its url
Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: Cannot get supported actions. Drag pointer haven't entered the application window
        at com.sun.glass.ui.gtk.GtkDnDClipboard.mimesFromSystem(Native Method)
        at com.sun.glass.ui.SystemClipboard.getMimeTypes(SystemClipboard.java:84)
        at com.sun.glass.ui.ClipboardAssistance.getMimeTypes(ClipboardAssistance.java:140)
        at com.sun.javafx.tk.quantum.QuantumClipboard.hasContent(QuantumClipboard.java:513)
        at javafx.scene.input.Clipboard.hasContent(Clipboard.java:294)
        at javafx.scene.input.Clipboard.hasString(Clipboard.java:303)
        at javafx.scene.control.TextInputControl.paste(TextInputControl.java:656)
        at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.paste(TextInputControlBehavior.java:528)
        at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.lambda$new$20(TextInputControlBehavior.java:159)
        at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.lambda$keyMapping$62(TextInputControlBehavior.java:330)
        at com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
        at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.Scene$KeyHandler.process(Scene.java:4070)
        at javafx.scene.Scene.processKeyEvent(Scene.java:2121)
        at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2597)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:217)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:149)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$1(GlassViewEventHandler.java:248)
        at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:411)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:247)
        at com.sun.glass.ui.View.handleKeyEvent(View.java:547)
        at com.sun.glass.ui.View.notifyKey(View.java:971)
        at com.sun.glass.ui.gtk.GtkApplication.enterNestedEventLoopImpl(Native Method)
        at com.sun.glass.ui.gtk.GtkApplication._enterNestedEventLoop(GtkApplication.java:347)
        at com.sun.glass.ui.Application.enterNestedEventLoop(Application.java:509)
        at com.sun.glass.ui.EventLoop.enter(EventLoop.java:107)
        at com.sun.javafx.tk.quantum.QuantumToolkit.enterNestedEventLoop(QuantumToolkit.java:634)
        at javafx.stage.Stage.showAndWait(Stage.java:465)
        at javafx.scene.control.HeavyweightDialog.showAndWait(HeavyweightDialog.java:162)
        at javafx.scene.control.Dialog.showAndWait(Dialog.java:346)
        at eu.binjr.core.controllers.MainViewController.showAdapterDialog(MainViewController.java:802)
        at eu.binjr.core.controllers.MainViewController.lambda$populateSourceMenu$24(MainViewController.java:595)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.control.MenuItem.fire(MenuItem.java:459)
        at com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1380)
        at com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.lambda$createChildren$12(ContextMenuContent.java:1333)
        at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.Scene$MouseHandler.process(Scene.java:3862)
        at javafx.scene.Scene.processMouseEvent(Scene.java:1849)
        at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2590)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:409)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:299)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:447)
        at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:411)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:446)
        at com.sun.glass.ui.View.handleMouseEvent(View.java:556)
        at com.sun.glass.ui.View.notifyMouse(View.java:942)
        at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
        at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
        at java.base/java.lang.Thread.run(Thread.java:834)

HTTP over TLS is broken

[2019-01-13 17:08:49.141] [DEBUG] [binjr-async-thread-1] [eu.binjr.common.github.GithubApi] requestUrl = https://api.github.com/repos/binjr/binjr/releases/latest
[2019-01-13 17:08:49.524] [ERROR] [JavaFX Application Thread] [eu.binjr.core.preferences.UpdateManager] Error while checking for update
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
	at sun.security.ssl.Alert.createSSLException(Unknown Source) ~[?:?]
	at sun.security.ssl.Alert.createSSLException(Unknown Source) ~[?:?]
	at sun.security.ssl.TransportContext.fatal(Unknown Source) ~[?:?]
	at sun.security.ssl.Alert$AlertConsumer.consume(Unknown Source) ~[?:?]
	at sun.security.ssl.TransportContext.dispatch(Unknown Source) ~[?:?]
	at sun.security.ssl.SSLTransport.decode(Unknown Source) ~[?:?]
	at sun.security.ssl.SSLSocketImpl.decode(Unknown Source) ~[?:?]
	at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(Unknown Source) ~[?:?]
	at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[?:?]
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:396) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:355) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:373) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:394) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:221) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:165) ~[httpclient-4.5.6.jar:4.5.6]
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:140) ~[httpclient-4.5.6.jar:4.5.6]
	at eu.binjr.common.github.GithubApi.getRelease(GithubApi.java:103) ~[binjr-core-2.2.2-SNAPSHOT.jar:2.2.2-SNAPSHOT]
	at eu.binjr.common.github.GithubApi.getLatestRelease(GithubApi.java:80) ~[binjr-core-2.2.2-SNAPSHOT.jar:2.2.2-SNAPSHOT]
	at eu.binjr.core.preferences.UpdateManager$1.call(UpdateManager.java:117) ~[binjr-core-2.2.2-SNAPSHOT.jar:2.2.2-SNAPSHOT]
	at eu.binjr.core.preferences.UpdateManager$1.call(UpdateManager.java:113) ~[binjr-core-2.2.2-SNAPSHOT.jar:2.2.2-SNAPSHOT]
	at javafx.concurrent.Task$TaskCallable.call(Unknown Source) ~[javafx.graphics:?]
	at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:?]
	at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[?:?]
	at java.lang.Thread.run(Unknown Source) [?:?]

Implement background preloading of JRDS tree

At the moment, loading the tree from a JRDS source, other that the root level, is done lazily whenever a tree node is expended from the UI.

While this is a great way to hide the latency associated with loading the whole tree (which can be huge), this make things like drag and drop of whole branch potentially cumbersome (as you cannot hide the loading of the whole branch then) and makes the "search" function unable to find things that have not been loaded yet.

A better strategy would be to keep the current mechanism (eagerly load first level and lazily load branches) while silently preloading branches in the background, so that every thing would be loaded after a short while, without the need to force the user waiting for it.

NB: Be careful though to impose limits on that preloading, as some JRDS deployments cover hundreds of machines with hundreds of individual graphs each, so loading every thing in that case is probably no a good idea.

Get rid of modal dialog boxes in binjr

In order to streamline the UX and make it more inline with the current trend sparked by mobile and web based applications, it would be good to remove the couple of modal dialog boxes that subsist in binjr.

Other than confirmation dialogs -which are not within the scope of this proposal - there are two cases where the UI will funel the user's workflow through a modal dialog boxes:

  • When adding a new worksheet.

  • When adding a new source.

With regard to the new worksheet dialog, it was there historically because not all of a worksheet properties could be edited after it was created, therefore it made sense to force users to stop and think about their choices since they'd be stuck with it. Since this hasn't been true for a while now, the removal of the dialog should be straight forward, and not missed by anyone.

As far as the new source dialog is concerned though, making the source object fully mutable/editable would not not much sense, so the process and controls for binding a new source would remains unchanged as a one shot/cancel-able action, but maybe the UI controls form the DataAdapter could be attached to the future source's TitledPane rather than being shown in a modal dialog?

Error when adding a JRDS source without protocol prefix

Using binjr 1.4.1-SNAPSHOT, afb1ca3.

When I try to add a JRDS source with URI “localhost:8080” instead of “http://localhost:8080” I get a popup with the following error message:

IO Error while communicating with host "null:-1"

… then the popup slowly fades out and nothing more happens.

I have two suggestions:

  • prevent error popups from fading out (IMHO, it makes it uselessly hard to read the error message and copy it in a bug report);
  • allow HOST:PORT and HOST as alternatives to a full URI (default protocol would be HTTP and default PORT would be 80, as it's what most people would expect, I guess).

Thanks!

Enhancements to chart navigation

Common navigation features that users expect to find but are not yet implemented in binjr:

  • Zoom in and out using mouse wheel: e.g. Shift+Wheel to zoom on Y axis, Ctrl+Wheel to zoom on X axis

  • Pan charts by dragging with the mouse, e.g. Shift+ Right button to pan up and down, Crtl + Right button to pan left or right.

Inapropriate warning messages because of unset variables

[WARN ] [JavaFX Application Thread] [eu.fthevenet.binjr.data.adapters.DataAdapterFactory] Plugins location none does not exist.
[WARN ] [JavaFX Application Thread] [eu.fthevenet.binjr.controllers.MainViewController] Cannot reopen workspace Untitled: file does not exists

I think it'd be appropriate display no warning in these cases:

  • plugin location has never been set (eg. first launch);
  • there's no previous workspace (eg. first launch).

Connecting an to invalid source, but valid http address fails silently

If you try to connect to a URL that is not a valid source but points to an accessible http server, nothing seems to happen.
Quite obviously, querying the data adapter to obtain the list of available series fails and if properly logged, but no error dialog box is presented to the end user

The application appears to hang when attempting to close it while it is minimized.

The application appear to hang under the following circumstances (tested on Windows, may also affect other platforms):

  • The current workspace needs saving
  • The application is minimized to the task bar
  • User right-click "Close window" on the icon in the task bar
  • Nothing seems to happen
  • User restore the app to the desktop.
  • The main windows appears but appears to be totally unresponsive.

What happens is that the modal popup asking to confirm closing the app is invoked, which is quite normal, but when the app is made visible again, the modal window is displayed behind the main window, and is therefore inaccessible. And because this popup is modal, the whole app is blocked until is is dismissed (which you can't easily do , because it doesn't show, etc...).
Pressing "Esc" dismisses the popup and solve the issue, but since there's no indication of what is really going on, it'll look to most users as the application is hanged.

NPE when drag-and-dropping a folded tree

Version:

How to reproduce:

  • start binjr;
  • add source (eg. CV perf-ui);
  • unfold “System”
  • unfold “Load”
  • drag “CPU usage” to the view panel.
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
        at eu.binjr.core.controllers.MainViewController.lambda$buildTreeViewForTarget$50(MainViewController.java:1013)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.Scene$DnDGesture.fireEvent(Scene.java:3029)
        at javafx.scene.Scene$DnDGesture.process(Scene.java:3108)
        at javafx.scene.Scene$MouseHandler.process(Scene.java:3878)
        at javafx.scene.Scene.processMouseEvent(Scene.java:1849)
        at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2590)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:409)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:299)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:447)
        at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:411)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:446)
        at com.sun.glass.ui.View.handleMouseEvent(View.java:556)
        at com.sun.glass.ui.View.notifyMouse(View.java:942)
        at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
        at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
        at java.base/java.lang.Thread.run(Thread.java:834)

This seems to have no impact on the application's behavior, though.

Make zoom on click the default behavior

TODO: allow the cross hair markers icons to be checked by defaut or remember last state from previous sessions.
Behavior to be controllable in preferences.

Detect missing JavaFX

Spotted by @rgroux: launching binjr without JavaFX results in an unhelpful error message: “Error: Could not find or load main class eu.fthevenet.binjr.Main”.

I guess that could be improved by detecting whether JavaFX is available or not, and by asking the user to install JavaFX in the latter case.

Report the use of an unsupported version of Java

If the user is using, say, Java 10, they should be told that they have to use Java 8 instead — the same way they are told they need JavaFX, if it's absent.

Please disregard this issue if it's made irrelevant with the move to Java 11.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.