Creating custom visualizer - nikonovd/megalib GitHub Wiki
The MegaL visualizer is designed to be extendible and provides several classes and interfaces that are to be used to create custom visualizer adapters. The following part describes the provided classes and additional steps to create custom components.
The project uses a self-made auto-wiring technique. Custom transformer implementations that are registered to the dispatcher are automatically provided to the executable binary interface. Please see as follows.
This is the main base class to be extended. To create a custom visualizer adapter, hence a transformer, it is obliged to extend this base class and implement all abstract methods.
Afterwards the new transformer has to be registered to the dispatcher to be provided to the outside. This is achieved using a static class initializer within the concrete implementation (see the example below). It is strictly obliged to extend the Transformer base class, otherwise the dispatcher won't be able to register its factory, because the current implementation uses class loading techniques to scan for subclasses of Transformer.
The following example provides a simple demonstration of the registration:
package your.package;
import ...
public class CustomTransformer extends Transformer<String> {
static {
Transformer.registerTransformer("custom", (VisualizerOptions options) -> new CustomTransformer(options));
FileExtensionFactory.registerFileExtension("custom", "custom");
}
// properties
public CustomTransformer(VisualizerOptions options) {
super(options);
}
@Override
public String transform(Graph g) {
// transformation of the graph domain model to target class String as defined by the generic type parameter of Transformer
}
// custom methods
}
The example above demonstrates a simple implementation extending the Transformer class. The static initializer registers the concrete implementation using the custom
identifier. The transformer factory will be provided using this identifier in the later process. It is also used as the type parameter in the binary command.
For instance, use Transformer.registerTransformer(...)
within the class initializer to register the concrete implementation to the factory.
The second line of the class inializer provides a file extension identified by the custom
identifier. Currently the FileVisualizer uses this file extension factory to derive a concrete file extension while generating the output file.
This interfaces is provided to be implemented by a custom graph processor. Its main goal is to provide a unique structure for graph transformers that adjust the graph domain model to be generalized in future releases.
A concrete implementation of this interface is the ManifestationDetacher that checks every node for a manifestsAs
relation and merges the manifestation node with its parent.
It provides an interfaces to be implemented by specific configuration builders, e.g. DOTConfigurationBuilder. The interface is to be used to create a unique structure throughout the whole project for later generalization process.
This class provides a key-value configuration class. One can specify a key and the instance will automatically index the sub-key-value pairs and provide methods that allow to store specific configuration properties for certain keys.
This interface is to be implemented by every concrete Visualizer implementation, e.g. StringVisualizer or FileVisualizer. Currently the binary uses the the FileVisualizer that delegates the transformation process to the StringVisualizer.
The StringVisualizer determines a concrete Transformer implementation by using the Transformer.getInstance(options)
method and transforming the graph model to a string representation.
The FileVisualizer takes the result and writes it into a File on the machine's file system.