![JAR search and dependency download from the Maven repository](/logo.png)
com.jongsoft.highchart.render.ImageRenderer Maven / Gradle / Ivy
/*
* The MIT License
*
* Copyright 2016 Jong Soft.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.jongsoft.highchart.render;
import com.jongsoft.Renderer;
import com.jongsoft.highchart.AbstractHighchart;
import com.jongsoft.highchart.HeatmapChart;
import com.jongsoft.highchart.Highchart;
import com.jongsoft.highchart.PolarHighchart;
import com.jongsoft.highchart.monitoring.Monitoring;
import com.jongsoft.highchart.phantomjs.DriverPoolFactory;
import com.jongsoft.highchart.phantomjs.PhantomCommandBuilder;
import com.jongsoft.highchart.phantomjs.TimedPhantomJsDriver;
import com.jongsoft.highchart.serializer.JsonUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebDriverException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import static com.jongsoft.highchart.monitoring.Monitoring.Level.TRACE;
public class ImageRenderer implements Renderer> {
private static final Logger LOG = LoggerFactory.getLogger(ImageRenderer.class);
private AbstractHighchart, ?> globalOptions;
private AbstractHighchart, ?> chartOptions;
private OutputStream outStream;
@Override
@Monitoring(level = TRACE)
public void render() {
TimedPhantomJsDriver phantomJSDriver;
if (globalOptions == null) {
LOG.trace("No global options provided, instantiate default settings.");
globalOptions = new Highchart();
}
if (outStream == null) {
throw new RenderException("Cannot render highcharts when no outputstream is set");
}
if (chartOptions == null) {
throw new RenderException("Cannot render when no highcharts graph is provided");
}
try {
LOG.trace("Attempting to obtain a phantom js driver for rendering.");
phantomJSDriver = DriverPoolFactory.getDriverPool(false).borrowObject();
} catch (Exception e) {
throw new RenderException("Unable to borrow phantom js driver from driver pool", e);
}
globalOptions.getChart().setRenderTo("svg-chart");
try {
LOG.trace("Executing a phantom js script for the render.");
PhantomCommandBuilder phantomCommand = new PhantomCommandBuilder()
.libraryPath(DriverPoolFactory.getExpansionDir());
LOG.trace("Injecting jQuey and Highchart.js");
phantomCommand.injectJs("highchart.js");
// Append any additional libraries based upon the type of Highchart instance being rendered
if (chartOptions instanceof HeatmapChart) {
LOG.trace("Injecting Highcharts Map.js");
phantomCommand.injectJs("highchart-map.js");
}
if (chartOptions instanceof PolarHighchart) {
phantomCommand.injectJs("highcharts-more.js");
}
// Set the global options for Highcharts
chartOptions.getChart().setRenderTo("svg-chart");
phantomCommand.appendScript("page.evaluate(function() {")
.appendScript(" Highcharts.setOptions(").appendScript(globalOptions.toJson()).appendScript(");")
.appendScript("});");
// Append the provided chart by the client
phantomCommand.appendScript("page.evaluate(function() {")
.appendScript(" document.write('');")
.appendScript(" new Highcharts.Chart(").appendScript(chartOptions.toJson()).appendScript(");")
.appendScript("});")
.build();
Object response = phantomJSDriver.executePhantomJS(phantomCommand.build());
if (response instanceof Map) {
Map realResponse = (Map) response;
if (realResponse.containsKey("exitCode")) {
long exitCode = (long) realResponse.get("exitCode");
List exceptions = (List) realResponse.get("exception");
if (exitCode == 0 && exceptions.isEmpty()) {
outStream.write(phantomJSDriver.getScreenshotAs(OutputType.BYTES));
outStream.flush();
} else {
LOG.trace("Failed to execute command " + phantomCommand.build());
throw new RenderException(String.format("Failed to process script exit code %s exceptions %s ",
exitCode, JsonUtils.serialize(exceptions)));
}
} else {
throw new RenderException("Failed to process script, exception: " + JsonUtils.serialize(response));
}
}
} catch (IOException | WebDriverException e) {
LOG.error("Unable to save image to provided output stream", e);
throw new RenderException("Unable to save image to output stream");
} finally {
DriverPoolFactory.getDriverPool(false).returnObject(phantomJSDriver);
}
}
@Override
public Renderer> setRenderObject(AbstractHighchart, ?> chartOptions) {
this.chartOptions = chartOptions;
return this;
}
@Override
public Renderer> setGlobalOptions(AbstractHighchart, ?> chartOptions) {
this.globalOptions = chartOptions;
return this;
}
@Override
public Renderer> setOutputStream(OutputStream outputStream) {
this.outStream = outputStream;
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy