All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tech.tablesaw.plotly.components.Figure Maven / Gradle / Ivy

There is a newer version: 0.43.3
Show newest version
package tech.tablesaw.plotly.components;

import com.google.common.base.Preconditions;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UncheckedIOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.pebbletemplates.pebble.PebbleEngine;
import io.pebbletemplates.pebble.error.PebbleException;
import io.pebbletemplates.pebble.template.PebbleTemplate;
import tech.tablesaw.plotly.event.EventHandler;
import tech.tablesaw.plotly.traces.Trace;

/**
 * Plotly's graph description places attributes into two categories: traces (objects that describe a
 * single series of data in a graph like Scatter or Heatmap) and layout attributes that apply to the
 * rest of the chart, like the title, xaxis, or annotations).
 *
 * 

Figure combines the two parts, associating one or more traces with a layout. If the layout is * null a default layout is provided. */ public class Figure { private Trace[] data; private Layout layout; private Config config; private EventHandler[] eventHandlers; private final Map context = new HashMap<>(); private final PebbleEngine engine = TemplateUtils.getNewEngine(); public Figure(FigureBuilder builder) { this.data = builder.traces(); this.layout = builder.layout; this.config = builder.config; this.eventHandlers = builder.eventHandlers(); } public Figure(Trace... traces) { this((Layout) null, traces); } public Figure(Layout layout, Trace... traces) { this(layout, (Config) null, traces); } public Figure(Layout layout, Config config, Trace... traces) { this.data = traces; this.layout = layout; this.config = config; this.eventHandlers = null; } /** @deprecated Use the FigureBuilder instead */ @Deprecated public Figure(Layout layout, EventHandler eventHandler, Trace... traces) { this(layout, new EventHandler[] {eventHandler}, traces); } /** @deprecated Use the FigureBuilder instead */ @Deprecated public Figure(Layout layout, EventHandler[] eventHandlers, Trace... traces) { this.data = traces; this.layout = layout; this.config = null; this.eventHandlers = eventHandlers; } public String divString(String divName) { return String.format("

" + System.lineSeparator(), divName); } public Layout getLayout() { return layout; } public void setLayout(Layout layout) { this.layout = layout; } public Config getConfig() { return config; } public void setConfig(Config config) { this.config = config; } public EventHandler[] getEventHandlers() { return eventHandlers; } public void setEventHandlers(EventHandler... handlers) { eventHandlers = handlers; } public Trace[] getTraces() { return data; } public void setTraces(Trace... data) { this.data = data; } public String asJavascript(String divName) { Writer writer = new StringWriter(); PebbleTemplate compiledTemplate; buildContext(divName); try { compiledTemplate = engine.getTemplate("figure_template.html"); compiledTemplate.evaluate(writer, getContext()); } catch (PebbleException e) { throw new IllegalStateException(e); } catch (IOException e) { throw new UncheckedIOException(e); } return writer.toString(); } protected void buildContext(String divName) { String targetName = "target_" + divName; context.put("divName", divName); context.put("targetName", targetName); StringBuilder builder = new StringBuilder(); if (layout != null) { builder.append(layout.asJavascript()); } if (config != null) { builder.append(config.asJavascript()); } builder.append(System.lineSeparator()); for (int i = 0; i < data.length; i++) { Trace trace = data[i]; builder.append(trace.asJavascript(i)); builder.append(System.lineSeparator()); } builder.append(System.lineSeparator()); String figure = builder.toString(); context.put("figure", figure); context.put("plotFunction", plotFunction(targetName)); context.put("eventHandlerFunction", eventHandlerFunction(targetName, divName)); } protected String plotFunction(String divName) { StringBuilder builder = new StringBuilder(); builder.append("var data = [ "); for (int i = 0; i < data.length; i++) { builder.append("trace").append(i); if (i < data.length - 1) { builder.append(", "); } } builder.append("];").append(System.lineSeparator()); builder.append("Plotly.newPlot(").append(divName).append(", ").append("data"); if (layout != null) { builder.append(", "); builder.append("layout"); } if (config != null) { builder.append(", "); builder.append("config"); } builder.append(");"); return builder.toString(); } protected String eventHandlerFunction(String targetName, String divName) { StringBuilder builder = new StringBuilder(); if (eventHandlers != null) { builder.append(System.lineSeparator()); for (EventHandler eventHandler : eventHandlers) { builder.append(eventHandler.asJavascript(targetName, divName)); } builder.append(System.lineSeparator()); } return builder.toString(); } public Map getContext() { return context; } public static FigureBuilder builder() { return new FigureBuilder(); } public static class FigureBuilder { private Layout layout; private Config config; private List traces = new ArrayList<>(); private List eventHandlers = new ArrayList<>(); public FigureBuilder layout(Layout layout) { this.layout = layout; return this; } public FigureBuilder config(Config config) { this.config = config; return this; } public FigureBuilder addTraces(Trace... traces) { this.traces.addAll(Arrays.asList(traces)); return this; } public FigureBuilder addEventHandlers(EventHandler... handlers) { this.eventHandlers.addAll(Arrays.asList(handlers)); return this; } public Figure build() { Preconditions.checkState(!traces.isEmpty(), "A figure must have at least one trace"); return new Figure(this); } private EventHandler[] eventHandlers() { return eventHandlers.toArray(new EventHandler[0]); } private Trace[] traces() { return traces.toArray(new Trace[0]); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy