diff --git a/modules/JPEGExporter/README.md b/modules/JPEGExporter/README.md
new file mode 100644
index 000000000..e37669894
--- /dev/null
+++ b/modules/JPEGExporter/README.md
@@ -0,0 +1,7 @@
+## JPEG Exporter
+
+Adds a Gephi image exporter for `.jpg`/`.jpeg` with configurable:
+
+- Width (px)
+- Height (px)
+- DPI metadata
diff --git a/modules/JPEGExporter/pom.xml b/modules/JPEGExporter/pom.xml
new file mode 100644
index 000000000..82bd33017
--- /dev/null
+++ b/modules/JPEGExporter/pom.xml
@@ -0,0 +1,79 @@
+
+
+ 4.0.0
+
+ gephi-plugin-parent
+ org.gephi
+ 0.10.0
+
+
+ my.self
+ jpegexporter
+ 0.0.1
+ nbm
+
+ JPEG Exporter
+
+
+
+ org.gephi
+ io-exporter-api
+
+
+ org.gephi
+ preview-api
+
+
+ org.gephi
+ project-api
+
+
+ org.gephi
+ utils-longtask
+
+
+ org.netbeans.api
+ org-openide-util
+
+
+ org.netbeans.api
+ org-openide-util-lookup
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+
+
+
+
+ org.apache.netbeans.utilities
+ nbm-maven-plugin
+
+ Apache 2.0
+ Elio Moreau
+ elio.moreau@ens.psl.eu
+
+ https://github.com/eliomor01/gephi-plugins.git
+
+
+
+
+
+
+
+
+
+
+ oss-sonatype
+ oss-sonatype
+ https://oss.sonatype.org/content/repositories/snapshots/
+
+ true
+
+
+
+
diff --git a/modules/JPEGExporter/src/main/java/org/gephi/plugins/jpegexporter/ExporterBuilderJPEG.java b/modules/JPEGExporter/src/main/java/org/gephi/plugins/jpegexporter/ExporterBuilderJPEG.java
new file mode 100644
index 000000000..329a3dd26
--- /dev/null
+++ b/modules/JPEGExporter/src/main/java/org/gephi/plugins/jpegexporter/ExporterBuilderJPEG.java
@@ -0,0 +1,29 @@
+package org.gephi.plugins.jpegexporter;
+
+import org.gephi.io.exporter.api.FileType;
+import org.gephi.io.exporter.spi.VectorExporter;
+import org.gephi.io.exporter.spi.VectorFileExporterBuilder;
+import org.openide.util.NbBundle;
+import org.openide.util.lookup.ServiceProvider;
+
+@ServiceProvider(service = VectorFileExporterBuilder.class)
+public class ExporterBuilderJPEG implements VectorFileExporterBuilder {
+
+ @Override
+ public VectorExporter buildExporter() {
+ return new JPEGExporter();
+ }
+
+ @Override
+ public FileType[] getFileTypes() {
+ return new FileType[]{
+ new FileType(".jpg", NbBundle.getMessage(ExporterBuilderJPEG.class, "fileType_JPG_Name")),
+ new FileType(".jpeg", NbBundle.getMessage(ExporterBuilderJPEG.class, "fileType_JPEG_Name"))
+ };
+ }
+
+ @Override
+ public String getName() {
+ return "jpeg";
+ }
+}
diff --git a/modules/JPEGExporter/src/main/java/org/gephi/plugins/jpegexporter/JPEGExporter.java b/modules/JPEGExporter/src/main/java/org/gephi/plugins/jpegexporter/JPEGExporter.java
new file mode 100644
index 000000000..b0bdf0eab
--- /dev/null
+++ b/modules/JPEGExporter/src/main/java/org/gephi/plugins/jpegexporter/JPEGExporter.java
@@ -0,0 +1,228 @@
+package org.gephi.plugins.jpegexporter;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataNode;
+import javax.imageio.stream.ImageOutputStream;
+import org.gephi.io.exporter.spi.ByteExporter;
+import org.gephi.io.exporter.spi.VectorExporter;
+import org.gephi.preview.api.G2DTarget;
+import org.gephi.preview.api.PreviewController;
+import org.gephi.preview.api.PreviewModel;
+import org.gephi.preview.api.PreviewProperties;
+import org.gephi.preview.api.PreviewProperty;
+import org.gephi.preview.api.RenderTarget;
+import org.gephi.project.api.Workspace;
+import org.gephi.utils.longtask.spi.LongTask;
+import org.gephi.utils.progress.Progress;
+import org.gephi.utils.progress.ProgressTicket;
+import org.openide.util.Lookup;
+
+public class JPEGExporter implements VectorExporter, ByteExporter, LongTask {
+
+ private static final float MM_PER_INCH = 25.4f;
+ private static final float CM_PER_INCH = 2.54f;
+ private static final float DEFAULT_WIDTH_CM = 16.0f;
+ private static final float DEFAULT_HEIGHT_CM = 9.0f;
+ private static final int DEFAULT_DPI = 300;
+
+ private ProgressTicket progress;
+ private boolean cancel;
+ private Workspace workspace;
+ private OutputStream stream;
+ private float widthCm = DEFAULT_WIDTH_CM;
+ private float heightCm = DEFAULT_HEIGHT_CM;
+ private int dpi = DEFAULT_DPI;
+ private int margin = 4;
+ private G2DTarget target;
+
+ @Override
+ public boolean execute() {
+ Progress.start(progress);
+
+ PreviewController controller = Lookup.getDefault().lookup(PreviewController.class);
+ PreviewModel model = controller.getModel(workspace);
+
+ setExportProperties(model);
+ controller.refreshPreview(workspace);
+
+ target = (G2DTarget) controller.getRenderTarget(RenderTarget.G2D_TARGET, workspace);
+ if (target instanceof LongTask) {
+ ((LongTask) target).setProgressTicket(progress);
+ }
+
+ try {
+ target.refresh();
+ Progress.switchToIndeterminate(progress);
+
+ int widthPx = cmToPixels(widthCm, dpi);
+ int heightPx = cmToPixels(heightCm, dpi);
+
+ Image sourceImg = target.getImage();
+ BufferedImage img = new BufferedImage(widthPx, heightPx, BufferedImage.TYPE_INT_RGB);
+ Graphics2D graphics = img.createGraphics();
+ graphics.setColor(Color.WHITE);
+ graphics.fillRect(0, 0, widthPx, heightPx);
+ graphics.drawImage(sourceImg, 0, 0, null);
+ graphics.dispose();
+
+ writeJpegWithDpi(img, stream, dpi);
+ stream.close();
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ } finally {
+ discardExportProperties(model);
+ Progress.finish(progress);
+ }
+
+ return !cancel;
+ }
+
+ @Override
+ public Workspace getWorkspace() {
+ return workspace;
+ }
+
+ @Override
+ public void setWorkspace(Workspace workspace) {
+ this.workspace = workspace;
+ }
+
+ @Override
+ public void setOutputStream(OutputStream stream) {
+ this.stream = stream;
+ }
+
+ @Override
+ public boolean cancel() {
+ cancel = true;
+ if (target instanceof LongTask) {
+ ((LongTask) target).cancel();
+ }
+ return true;
+ }
+
+ @Override
+ public void setProgressTicket(ProgressTicket progressTicket) {
+ this.progress = progressTicket;
+ }
+
+ public float getWidthCm() {
+ return widthCm;
+ }
+
+ public void setWidthCm(float widthCm) {
+ this.widthCm = widthCm;
+ }
+
+ public float getHeightCm() {
+ return heightCm;
+ }
+
+ public void setHeightCm(float heightCm) {
+ this.heightCm = heightCm;
+ }
+
+ public int getDpi() {
+ return dpi;
+ }
+
+ public void setDpi(int dpi) {
+ this.dpi = dpi;
+ }
+
+ private synchronized void setExportProperties(PreviewModel model) {
+ PreviewProperties props = model.getProperties();
+ props.putValue(PreviewProperty.VISIBILITY_RATIO, 1.0F);
+ int widthPx = cmToPixels(widthCm, dpi);
+ int heightPx = cmToPixels(heightCm, dpi);
+ props.putValue("width", widthPx);
+ props.putValue("height", heightPx);
+ props.putValue(PreviewProperty.MARGIN, (float) margin);
+ }
+
+ private synchronized void discardExportProperties(PreviewModel model) {
+ PreviewProperties props = model.getProperties();
+ props.removeSimpleValue("width");
+ props.removeSimpleValue("height");
+ props.removeSimpleValue(PreviewProperty.MARGIN);
+ }
+
+ static void writeJpegWithDpi(BufferedImage image, OutputStream output, int dpiValue) throws IOException {
+ Iterator writers = ImageIO.getImageWritersByFormatName("jpeg");
+ if (!writers.hasNext()) {
+ throw new IOException("No JPEG ImageWriter available");
+ }
+
+ ImageWriter writer = writers.next();
+ ImageWriteParam writeParam = writer.getDefaultWriteParam();
+ if (writeParam.canWriteCompressed()) {
+ writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+ writeParam.setCompressionQuality(0.95f);
+ }
+
+ ImageTypeSpecifier imageTypeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
+ IIOMetadata metadata = writer.getDefaultImageMetadata(imageTypeSpecifier, writeParam);
+ setDpiMetadata(metadata, dpiValue);
+
+ try (ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(output)) {
+ writer.setOutput(imageOutputStream);
+ writer.write(null, new IIOImage(image, null, metadata), writeParam);
+ imageOutputStream.flush();
+ } finally {
+ writer.dispose();
+ }
+ }
+
+ static int cmToPixels(float cm, int dpi) {
+ return Math.max(1, Math.round((cm / CM_PER_INCH) * dpi));
+ }
+
+ static void setDpiMetadata(IIOMetadata metadata, int dpiValue) {
+ if (metadata == null) {
+ return;
+ }
+
+ if (metadata.isStandardMetadataFormatSupported()) {
+ IIOMetadataNode root = (IIOMetadataNode) metadata.getAsTree("javax_imageio_1.0");
+ IIOMetadataNode dimension = getOrCreateChild(root, "Dimension");
+ float pixelsPerMM = MM_PER_INCH / dpiValue;
+
+ IIOMetadataNode horizontal = getOrCreateChild(dimension, "HorizontalPixelSize");
+ horizontal.setAttribute("value", Float.toString(pixelsPerMM));
+
+ IIOMetadataNode vertical = getOrCreateChild(dimension, "VerticalPixelSize");
+ vertical.setAttribute("value", Float.toString(pixelsPerMM));
+
+ try {
+ metadata.mergeTree("javax_imageio_1.0", root);
+ } catch (Exception ignored) {
+ }
+ }
+
+ // Avoid mutating native JPEG tree (`javax_imageio_jpeg_image_1.0`) as it can
+ // break marker sequencing in some writers and produce unreadable JPEG files.
+ }
+
+ private static IIOMetadataNode getOrCreateChild(IIOMetadataNode parent, String name) {
+ for (int i = 0; i < parent.getLength(); i++) {
+ if (name.equals(parent.item(i).getNodeName())) {
+ return (IIOMetadataNode) parent.item(i);
+ }
+ }
+ IIOMetadataNode child = new IIOMetadataNode(name);
+ parent.appendChild(child);
+ return child;
+ }
+}
diff --git a/modules/JPEGExporter/src/main/java/org/gephi/plugins/jpegexporter/UIExporterJPEG.java b/modules/JPEGExporter/src/main/java/org/gephi/plugins/jpegexporter/UIExporterJPEG.java
new file mode 100644
index 000000000..51f7a553c
--- /dev/null
+++ b/modules/JPEGExporter/src/main/java/org/gephi/plugins/jpegexporter/UIExporterJPEG.java
@@ -0,0 +1,61 @@
+package org.gephi.plugins.jpegexporter;
+
+import javax.swing.JPanel;
+import org.gephi.io.exporter.spi.Exporter;
+import org.gephi.io.exporter.spi.ExporterUI;
+import org.openide.util.NbBundle;
+import org.openide.util.NbPreferences;
+import org.openide.util.lookup.ServiceProvider;
+
+@ServiceProvider(service = ExporterUI.class)
+public class UIExporterJPEG implements ExporterUI {
+
+ private static final String PREF_WIDTH = "JPEG_width";
+ private static final String PREF_HEIGHT = "JPEG_height";
+ private static final String PREF_DPI = "JPEG_dpi";
+ private static final JPEGExporter DEFAULTS = new JPEGExporter();
+
+ private UIExporterJPEGPanel panel;
+ private JPEGExporter exporter;
+
+ @Override
+ public JPanel getPanel() {
+ panel = new UIExporterJPEGPanel();
+ return panel;
+ }
+
+ @Override
+ public void setup(Exporter exporter) {
+ this.exporter = (JPEGExporter) exporter;
+ this.exporter
+ .setWidthCm(NbPreferences.forModule(UIExporterJPEG.class).getFloat(PREF_WIDTH, DEFAULTS.getWidthCm()));
+ this.exporter
+ .setHeightCm(NbPreferences.forModule(UIExporterJPEG.class).getFloat(PREF_HEIGHT, DEFAULTS.getHeightCm()));
+ this.exporter.setDpi(NbPreferences.forModule(UIExporterJPEG.class).getInt(PREF_DPI, DEFAULTS.getDpi()));
+ if (panel != null) {
+ panel.setup(this.exporter);
+ }
+ }
+
+ @Override
+ public void unsetup(boolean update) {
+ if (update && panel != null && exporter != null) {
+ panel.unsetup(exporter);
+ NbPreferences.forModule(UIExporterJPEG.class).putFloat(PREF_WIDTH, exporter.getWidthCm());
+ NbPreferences.forModule(UIExporterJPEG.class).putFloat(PREF_HEIGHT, exporter.getHeightCm());
+ NbPreferences.forModule(UIExporterJPEG.class).putInt(PREF_DPI, exporter.getDpi());
+ }
+ panel = null;
+ exporter = null;
+ }
+
+ @Override
+ public boolean isUIForExporter(Exporter exporter) {
+ return exporter instanceof JPEGExporter;
+ }
+
+ @Override
+ public String getDisplayName() {
+ return NbBundle.getMessage(UIExporterJPEG.class, "UIExporterJPEG.name");
+ }
+}
diff --git a/modules/JPEGExporter/src/main/java/org/gephi/plugins/jpegexporter/UIExporterJPEGPanel.java b/modules/JPEGExporter/src/main/java/org/gephi/plugins/jpegexporter/UIExporterJPEGPanel.java
new file mode 100644
index 000000000..475b6d463
--- /dev/null
+++ b/modules/JPEGExporter/src/main/java/org/gephi/plugins/jpegexporter/UIExporterJPEGPanel.java
@@ -0,0 +1,75 @@
+package org.gephi.plugins.jpegexporter;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import javax.swing.JFormattedTextField;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSpinner;
+import javax.swing.SpinnerNumberModel;
+import org.openide.util.NbBundle;
+
+public class UIExporterJPEGPanel extends JPanel {
+
+ private final JSpinner widthSpinner = new JSpinner(new SpinnerNumberModel(16.0d, 0.1d, 1000.0d, 0.1d));
+ private final JSpinner heightSpinner = new JSpinner(new SpinnerNumberModel(9.0d, 0.1d, 1000.0d, 0.1d));
+ private final JSpinner dpiSpinner = new JSpinner(new SpinnerNumberModel(300, 1, 2400, 1));
+
+ public UIExporterJPEGPanel() {
+ initComponents();
+ JFormattedTextField widthField = ((JSpinner.NumberEditor) widthSpinner.getEditor()).getTextField();
+ widthField.setColumns(8);
+ JFormattedTextField heightField = ((JSpinner.NumberEditor) heightSpinner.getEditor()).getTextField();
+ heightField.setColumns(8);
+ }
+
+ public void setup(JPEGExporter exporter) {
+ widthSpinner.setValue((double) exporter.getWidthCm());
+ heightSpinner.setValue((double) exporter.getHeightCm());
+ dpiSpinner.setValue(exporter.getDpi());
+ }
+
+ public void unsetup(JPEGExporter exporter) {
+ exporter.setWidthCm(((Double) widthSpinner.getValue()).floatValue());
+ exporter.setHeightCm(((Double) heightSpinner.getValue()).floatValue());
+ exporter.setDpi((Integer) dpiSpinner.getValue());
+ }
+
+ private void initComponents() {
+ setLayout(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.insets = new Insets(4, 6, 4, 6);
+ gbc.anchor = GridBagConstraints.WEST;
+
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ add(new JLabel(NbBundle.getMessage(UIExporterJPEGPanel.class, "UIExporterJPEGPanel.widthLabel.text")), gbc);
+
+ gbc.gridx = 1;
+ add(widthSpinner, gbc);
+
+ gbc.gridx = 2;
+ add(new JLabel("cm"), gbc);
+
+ gbc.gridx = 0;
+ gbc.gridy = 1;
+ add(new JLabel(NbBundle.getMessage(UIExporterJPEGPanel.class, "UIExporterJPEGPanel.heightLabel.text")), gbc);
+
+ gbc.gridx = 1;
+ add(heightSpinner, gbc);
+
+ gbc.gridx = 2;
+ add(new JLabel("cm"), gbc);
+
+ gbc.gridx = 0;
+ gbc.gridy = 2;
+ add(new JLabel(NbBundle.getMessage(UIExporterJPEGPanel.class, "UIExporterJPEGPanel.dpiLabel.text")), gbc);
+
+ gbc.gridx = 1;
+ add(dpiSpinner, gbc);
+
+ gbc.gridx = 2;
+ add(new JLabel("dpi"), gbc);
+ }
+}
diff --git a/modules/JPEGExporter/src/main/nbm/manifest.mf b/modules/JPEGExporter/src/main/nbm/manifest.mf
new file mode 100644
index 000000000..e3312361e
--- /dev/null
+++ b/modules/JPEGExporter/src/main/nbm/manifest.mf
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module-Name: JPEG Exporter
+OpenIDE-Module-Short-Description: Plugin to export in jpeg format
+OpenIDE-Module-Long-Description: Plugin to export in jpeg format
+OpenIDE-Module-Display-Category: Export
diff --git a/modules/JPEGExporter/src/main/resources/org/gephi/plugins/jpegexporter/Bundle.properties b/modules/JPEGExporter/src/main/resources/org/gephi/plugins/jpegexporter/Bundle.properties
new file mode 100644
index 000000000..22dcea4b5
--- /dev/null
+++ b/modules/JPEGExporter/src/main/resources/org/gephi/plugins/jpegexporter/Bundle.properties
@@ -0,0 +1,10 @@
+OpenIDE-Module-Long-Description=Plugin to export preview graphs to JPEG with configurable dimensions and DPI
+OpenIDE-Module-Short-Description=JPEG exporter with dimensions and DPI controls
+
+fileType_JPG_Name=JPEG Files (*.jpg)
+fileType_JPEG_Name=JPEG Files (*.jpeg)
+UIExporterJPEG.name=JPEG
+
+UIExporterJPEGPanel.widthLabel.text=Width (cm):
+UIExporterJPEGPanel.heightLabel.text=Height (cm):
+UIExporterJPEGPanel.dpiLabel.text=DPI:
diff --git a/modules/JPEGExporter/src/test/java/org/gephi/plugins/jpegexporter/JPEGExporterTest.java b/modules/JPEGExporter/src/test/java/org/gephi/plugins/jpegexporter/JPEGExporterTest.java
new file mode 100644
index 000000000..c410055f6
--- /dev/null
+++ b/modules/JPEGExporter/src/test/java/org/gephi/plugins/jpegexporter/JPEGExporterTest.java
@@ -0,0 +1,82 @@
+package org.gephi.plugins.jpegexporter;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Iterator;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataNode;
+import org.junit.Assert;
+import org.junit.Test;
+import org.w3c.dom.Node;
+
+public class JPEGExporterTest {
+
+ @Test
+ public void testCmToPixels() {
+ Assert.assertEquals(300, JPEGExporter.cmToPixels(2.54f, 300));
+ Assert.assertEquals(2480, JPEGExporter.cmToPixels(21.0f, 300));
+ Assert.assertEquals(1, JPEGExporter.cmToPixels(0.001f, 72));
+ }
+
+ @Test
+ public void testWriteJpegWithDpiProducesReadableJpeg() throws Exception {
+ BufferedImage source = new BufferedImage(320, 240, BufferedImage.TYPE_INT_RGB);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ JPEGExporter.writeJpegWithDpi(source, outputStream, 300);
+
+ byte[] bytes = outputStream.toByteArray();
+ Assert.assertTrue(bytes.length > 0);
+ BufferedImage parsed = ImageIO.read(new ByteArrayInputStream(bytes));
+ Assert.assertNotNull("Written JPEG should be readable", parsed);
+ Assert.assertEquals(320, parsed.getWidth());
+ Assert.assertEquals(240, parsed.getHeight());
+ }
+
+ @Test
+ public void testSetDpiMetadataWritesStandardDimension() throws Exception {
+ IIOMetadata metadata = createJpegMetadata();
+ Assert.assertTrue(metadata.isStandardMetadataFormatSupported());
+
+ JPEGExporter.setDpiMetadata(metadata, 300);
+
+ IIOMetadataNode root = (IIOMetadataNode) metadata.getAsTree("javax_imageio_1.0");
+ IIOMetadataNode dimension = findChild(root, "Dimension");
+ Assert.assertNotNull(dimension);
+ IIOMetadataNode horizontal = findChild(dimension, "HorizontalPixelSize");
+ IIOMetadataNode vertical = findChild(dimension, "VerticalPixelSize");
+ Assert.assertNotNull(horizontal);
+ Assert.assertNotNull(vertical);
+ Assert.assertTrue(Float.parseFloat(horizontal.getAttribute("value")) > 0f);
+ Assert.assertTrue(Float.parseFloat(vertical.getAttribute("value")) > 0f);
+ }
+
+ private IIOMetadata createJpegMetadata() throws Exception {
+ Iterator writers = ImageIO.getImageWritersByFormatName("jpeg");
+ Assert.assertTrue("No JPEG writer found", writers.hasNext());
+ ImageWriter writer = writers.next();
+ try {
+ ImageWriteParam writeParam = writer.getDefaultWriteParam();
+ return writer.getDefaultImageMetadata(
+ ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB),
+ writeParam
+ );
+ } finally {
+ writer.dispose();
+ }
+ }
+
+ private IIOMetadataNode findChild(IIOMetadataNode parent, String name) {
+ for (Node node = parent.getFirstChild(); node != null; node = node.getNextSibling()) {
+ if (name.equals(node.getNodeName())) {
+ return (IIOMetadataNode) node;
+ }
+ }
+ return null;
+ }
+}
diff --git a/pom.xml b/pom.xml
index 1ca1569b0..d6d9f5b1a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,74 +12,7 @@
- modules/GeoLayout
- modules/KBraceFilter
- modules/LinkfluencePlugin
- modules/Multimode-Networks
- modules/JsonExporter
- modules/SigmaExporter
- modules/NodeColorManager
- modules/GraphvizLayout
- modules/GraphStreaming
- modules/DesktopStreaming
- modules/StreamingAPI
- modules/StreamingImpl
- modules/JettyWrapper
- modules/StreamingServer
- modules/CircularLayout
-
- modules/loxawebsiteexport
- modules/Export-To-Earth
- modules/MapOfCountries
- modules/ScriptingPlugin
- modules/TwitterStreamingImporterV2
- modules/IsometricLayout
- modules/NetworkSplitter3D
- modules/ExcelCsvImporter
- modules/OracleDriver
- modules/Lineage
- modules/MdsLayout
- modules/filterfromfile
- modules/GiveColorToNodes
- modules/GiveColorToEdges
- modules/GravityPlugin
- modules/MdsMetric
- modules/VectorCalculator
- modules/PrestigePlugin
- modules/HttpGraph
- modules/MinimumSpanningTree
- modules/SimilarityComputer
-
- modules/PolygonShapedNodes
- modules/ScalePlugin
- modules/CirclePack
-
- modules/newmangirvan
-
- modules/polinodeExporter
- modules/LeidenAlgorithm
- modules/BridgingPlugin
- modules/BoundingDiametersSuite
- modules/BoundingDiameters
- modules/BoundingDiametersUI
- modules/dbscan
- modules/ClusteringCoefficient
- modules/KleinbergGenerator
- modules/columnCalculator
- modules/GroupPartition
- modules/HairballBuster
- modules/ForceAtlas3D
- modules/InspectorTool
- modules/ErGenerator
- modules/KatzCentrality
- modules/PositionRanking
- modules/Neo4jPlugin
- modules/LinkPrediction
- modules/WebPublishPlugin
- modules/OrderedLayout
- modules/OpenSeadragonPlugin
- modules/WordCloudPlugin
- modules/BlueskyGephi
+ modules/JPEGExporter