Export a D3 chart
It is possible to export D3-based visualizations with FusionExport. To demonstrate, we will export this chord diagram .
Let’s create a template file named
template.html
and load the d3.js
library. Write the necessary code to render the chord diagram. Now, use the --asyncCapture
CLI option to hook into D3’s rendering life-cycle and export the chart after D3 completes the rendering. template.html
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.chord {
fill-opacity: .67;
}
</style>
<body>
<script src=" https://d3js.org/d3.v3.min.js"></script >
<script>
var outerRadius = 1366 / 2,
innerRadius = outerRadius - 130;
var fill = d3.scale.category20c();
var chord = d3.layout.chord()
.padding(.04)
.sortSubgroups(d3.descending)
.sortChords(d3.descending);
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(innerRadius + 20);
var svg = d3.select("body").append("svg")
.attr("width", outerRadius 2)
.attr("height", outerRadius 2)
.append("g")
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");
d3.json(
" https://gist.githubusercontent.com/sandeep1995/141a2045ab9e4c8f450c970682b89b00/raw/7aacb8a793c2d9e0ed60ad0251e1b754b2c430f2/filename.json" ,
function(error, imports) {
if (error) throw error;
var indexByName = d3.map(),
nameByIndex = d3.map(),
matrix = [],
n = 0;
// Returns the Flare package name for the given class name.
function name(name) {
return name.substring(0, name.lastIndexOf(".")).substring(6);
}
// Compute a unique index for each package name.
imports.forEach(function(d) {
if (!indexByName.has(d = name(d.name))) {
nameByIndex.set(n, d);
indexByName.set(d, n++);
}
});
// Construct a square matrix counting package imports.
imports.forEach(function(d) {
var source = indexByName.get(name(d.name)),
row = matrix[source];
if (!row) {
row = matrix[source] = [];
for (var i = -1; ++i < n;) row[i] = 0;
}
d.imports.forEach(function(d) {
row[indexByName.get(name(d))]++;
});
});
chord.matrix(matrix);
var g = svg.selectAll(".group")
.data(chord.groups)
.enter().append("g")
.attr("class", "group");
g.append("path")
.style("fill", function(d) {
return fill(d.index);
})
.style("stroke", function(d) {
return fill(d.index);
})
.attr("d", arc);
g.append("text")
.each(function(d) {
d.angle = (d.startAngle + d.endAngle) / 2;
})
.attr("dy", ".35em")
.attr("transform", function(d) {
return "rotate(" + (d.angle 180 / Math.PI - 90) + ")" +
"translate(" + (innerRadius + 26) + ")" +
(d.angle > Math.PI ? "rotate(180)" : "");
})
.style("text-anchor", function(d) {
return d.angle > Math.PI ? "end" : null;
})
.text(function(d) {
return nameByIndex.get(d.index);
});
svg.selectAll(".chord")
.data(chord.chords)
.enter().append("path")
.attr("class", "chord")
.style("stroke", function(d) {
return d3.rgb(fill(d.source.index)).darker();
})
.style("fill", function(d) {
return fill(d.source.index);
})
.attr("d", d3.svg.chord().radius(innerRadius));
// Emitting CAPTURE_EXIT event after d3 chart render complete
FusionExport.emit('CAPTURE_EXIT');
});
d3.select(self.frameElement).style("height", outerRadius 2 + "px");
</script>
</body>
</html>
Pay special attention to FusionExport.emit('
CAPTURE_EXIT
'). You need to emit the CAPTURE_EXIT
event when the render is complete.The fusioncharts_config.json looks like as follows:
{
"template": "path/to/d3_exp/template.html",
"output-file": "./",
"type": "pdf",
"async-capture": true
}
Once done, run the following command:
$ fe -e fusioncharts_config.json
// D3 export
const path = require('path');
// Require FusionExport
const {
ExportManager,
ExportConfig
} = require('../');
// Instantiate ExportManager
const exportManager = new ExportManager();
// Instantiate ExportConfig and add the required configurations
const exportConfig = new ExportConfig();
exportConfig.set('templateFilePath', path.join(dirname, 'resources', 'template_d3.html'));
exportConfig.set('type', 'jpg');
exportConfig.set('asyncCapture', true);
// provide the export config
exportManager.export(exportConfig);
// Called when export is done
exportManager.on('exportDone', (outputFileBag) => {
outputFileBag.forEach((op) => {
console.log(DONE: ${op.realName}
);
});
ExportManager.saveExportedFiles(outputFileBag);
});
// Called on each export state change
exportManager.on('exportStateChange', (state) => {
console.log([${state.reporter}] ${state.customMsg}
);
});
// Called on erroe
exportManager.on('error', (err) => {
console.error(err);
});
import com.fusioncharts.fusionexport.client.*;
public class d3_exp {
public static void main(String[] args) throws Exception {
String rootPath = System.getProperty("user.dir") + java.io.File.separator;
String templateRelativePath = "src\test\resources\static2\resources\template_d3.html".replace("\", java.io.File.separator);
String templateAbsolutePath = rootPath + templateRelativePath;
ExportConfig config = new ExportConfig();
config.set("templateFilePath", templateAbsolutePath);
config.set("type", "pdf");
config.set("asyncCapture", true);
ExportManager manager = new ExportManager(config);
manager.export(new ExportDoneListener() {
@Override
public void exportDone(ExportDoneData result, ExportException error) {
if (error != null) {
System.out.println(error.getMessage());
} else {
ExportManager.saveExportedFiles(rootPath + "bin" + java.io.File.separator + "static2" + java.io.File.separator + "resources", result);
}
}
},
new ExportStateChangedListener() {
@Override
public void exportStateChanged(ExportState state) {
System.out.println("STATE: " + state.customMsg);
}
});
}
}
using System;
using System.IO;
using System.Linq;
using FusionCharts.FusionExport.Client; // Import sdk
namespace FusionExportTest {
public static class D3_Exp {
public static void Run(string host = Constants.DEFAULT_HOST, int port = Constants.DEFAULT_PORT) {
// Instantiate the ExportConfig class and add the required configurations
ExportConfig exportConfig = new ExportConfig();
exportConfig.Set("templateFilePath", "./resources/template_d3.html");
exportConfig.Set("type", "jpg");
exportConfig.Set("asyncCapture", true);
// Instantiate the ExportManager class
ExportManager em = new ExportManager(host: host, port: port);
// Call the Export() method with the export config and the respective callbacks
em.Export(exportConfig, OnExportDone, OnExportStateChanged);
Console.Read();
}
// Called when export is done
static void OnExportDone(ExportEvent ev, ExportException error) {
if (error != null) {
Console.WriteLine("Error: " + error);
} else {
var fileNames = ExportManager.GetExportedFileNames(ev.exportedFiles);
Console.WriteLine("Done: " + String.Join(", ", fileNames)); // export result
}
}
// Called on each export state change
static void OnExportStateChanged(ExportEvent ev) {
Console.WriteLine("State: " + ev.state.customMsg);
}
}
}
<?php
// D3 export
require DIR__ . '/../vendor/autoload.php';
// Use the sdk
use FusionExport\ExportManager;
use FusionExport\ExportConfig;
// Instantiate the ExportConfig class and add the required configurations
$exportConfig = new ExportConfig();
$exportConfig->set('templateFilePath', realpath('resources/template_d3.html'));
$exportConfig->set('type', 'jpg');
$exportConfig->set('asyncCapture', 'true');
// Called on each export state change
$onStateChange = function ($event) {
$state = $event->state;
echo('STATE: [' . $state->reporter . '] ' . $state->customMsg . "\n");
};
// Called when export is done
$onDone = function ($event, $e) {
$export = $event->export;
if ($e) {
echo('ERROR: ' . $e->getMessage());
} else {
foreach ($export as $file) {
echo('DONE: ' . $file->realName. "\n");
}
ExportManager::saveExportedFiles($export);
}
};
// Instantiate the ExportManager class
$exportManager = new ExportManager();
// Call the export() method with the export config and the respective callbacks
$exportManager->export($exportConfig, $onDone, $onStateChange);
#!/usr/bin/env python
from fusionexport import ExportManager, ExportConfig # Import sdk
def read_file(file_path):
try:
with open(file_path, "r") as f:
return f.read()
except Exception as e:
print(e)
# Called when export is done
def on_export_done(event, error):
if error:
print(error)
else:
ExportManager.save_exported_files("exported_images", event["result"])
# Called on each export state change
def on_export_state_changed(event):
print(event["state"])
# Instantiate the ExportConfig class and add the required configurations
export_config = ExportConfig()
export_config["templateFilePath"] = "template_d3.html"
export_config["type"] = "pdf"
export_config["asyncCapture"] = "true"
# Provide port and host of FusionExport Service
export_server_host = "127.0.0.1"
export_server_port = 1337
# Instantiate the ExportManager class
em = ExportManager(export_server_host, export_server_port)
# Call the export() method with the export config and the respective callbacks
em.export(export_config, on_export_done, on_export_state_changed)
// D3 export
package main
import (
"fmt"
"github.com/fusioncharts/fusionexport-go-client"
)
// Called when export is done
func onDone(outFileBag []FusionExport.OutFileBag, err error) {
check(err)
FusionExport.SaveExportedFiles(outFileBag)
}
// Called on each export state change
func onStateChange(event FusionExport.ExportEvent) {
fmt.Println("[" + event.Reporter + "] " + event.CustomMsg)
}
func main() {
// Instantiate ExportConfig and add the required configurations
exportConfig := FusionExport.NewExportConfig()
exportConfig.Set("templateFilePath", "example/resources/template_d3.html")
exportConfig.Set("type", "pdf")
exportConfig.Set("asyncCapture", true)
// Instantiate ExportManager
exportManager := FusionExport.NewExportManager()
// Call the Export() method with the export config and the respective callbacks
exportManager.Export(exportConfig, onDone, onStateChange)
}
func check(e error) {
if e != nil {
panic(e)
}
}
Related Resources
Was this article helpful to you ?