| /** |
| * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation |
| * |
| * |
| * This copyright notice shows up in the generated Java code |
| */ |
| package org.eclipse.osbp.xtext.chart.jvmmodel; |
| |
| import com.ejt.vaadin.sizereporter.ComponentResizeEvent; |
| import com.ejt.vaadin.sizereporter.ComponentResizeListener; |
| import com.ejt.vaadin.sizereporter.SizeReporter; |
| import com.vaadin.data.Property; |
| import com.vaadin.server.FileDownloader; |
| import com.vaadin.server.Page; |
| import com.vaadin.server.StreamResource; |
| import com.vaadin.ui.Button; |
| import com.vaadin.ui.HorizontalLayout; |
| import com.vaadin.ui.JavaScriptFunction; |
| import com.vaadin.ui.Label; |
| import com.vaadin.ui.Panel; |
| import com.vaadin.ui.TabSheet; |
| import com.vaadin.ui.UI; |
| import elemental.json.JsonArray; |
| import elemental.json.JsonException; |
| import elemental.json.JsonObject; |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.ResourceBundle; |
| import java.util.UUID; |
| import java.util.concurrent.Executors; |
| import javax.imageio.ImageIO; |
| import javax.inject.Inject; |
| import mondrian.olap.Member; |
| import org.dussan.vaadin.dcharts.DCharts; |
| import org.dussan.vaadin.dcharts.DownloadButtonLocation; |
| import org.dussan.vaadin.dcharts.base.elements.Trendline; |
| import org.dussan.vaadin.dcharts.base.elements.XYaxis; |
| import org.dussan.vaadin.dcharts.base.elements.XYseries; |
| import org.dussan.vaadin.dcharts.data.DataSeries; |
| import org.dussan.vaadin.dcharts.data.Ticks; |
| import org.dussan.vaadin.dcharts.metadata.LegendPlacements; |
| import org.dussan.vaadin.dcharts.metadata.PyramidSides; |
| import org.dussan.vaadin.dcharts.metadata.SeriesToggles; |
| import org.dussan.vaadin.dcharts.metadata.TooltipAxes; |
| import org.dussan.vaadin.dcharts.metadata.XYaxes; |
| import org.dussan.vaadin.dcharts.metadata.Xaxes; |
| import org.dussan.vaadin.dcharts.metadata.Yaxes; |
| import org.dussan.vaadin.dcharts.metadata.directions.BarDirections; |
| import org.dussan.vaadin.dcharts.metadata.locations.TooltipLocations; |
| import org.dussan.vaadin.dcharts.metadata.renderers.AxisRenderers; |
| import org.dussan.vaadin.dcharts.metadata.renderers.SeriesRenderers; |
| import org.dussan.vaadin.dcharts.options.Axes; |
| import org.dussan.vaadin.dcharts.options.AxesDefaults; |
| import org.dussan.vaadin.dcharts.options.Cursor; |
| import org.dussan.vaadin.dcharts.options.Highlighter; |
| import org.dussan.vaadin.dcharts.options.Legend; |
| import org.dussan.vaadin.dcharts.options.Options; |
| import org.dussan.vaadin.dcharts.options.Series; |
| import org.dussan.vaadin.dcharts.options.SeriesDefaults; |
| import org.dussan.vaadin.dcharts.options.Title; |
| import org.dussan.vaadin.dcharts.renderers.axis.LinearAxisRenderer; |
| import org.dussan.vaadin.dcharts.renderers.legend.EnhancedLegendRenderer; |
| import org.dussan.vaadin.dcharts.renderers.series.BarRenderer; |
| import org.dussan.vaadin.dcharts.renderers.series.BubbleRenderer; |
| import org.dussan.vaadin.dcharts.renderers.series.DonutRenderer; |
| import org.dussan.vaadin.dcharts.renderers.series.MeterGaugeRenderer; |
| import org.dussan.vaadin.dcharts.renderers.series.PieRenderer; |
| import org.dussan.vaadin.dcharts.renderers.series.PyramidRenderer; |
| import org.dussan.vaadin.dcharts.renderers.tick.AxisTickRenderer; |
| import org.dussan.vaadin.dcharts.renderers.tick.CanvasAxisTickRenderer; |
| import org.eclipse.e4.core.di.extensions.EventUtils; |
| import org.eclipse.e4.ui.model.application.ui.MUIElement; |
| import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; |
| import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; |
| import org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl; |
| import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl; |
| import org.eclipse.e4.ui.model.application.ui.menu.MToolBarElement; |
| import org.eclipse.emf.common.notify.Adapter; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.osbp.eventbroker.EventBrokerMsg; |
| import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent; |
| import org.eclipse.osbp.ui.api.datamart.DatamartFilter; |
| import org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator; |
| import org.eclipse.osbp.utils.vaadin.ViewLayoutManager; |
| import org.eclipse.osbp.xtext.action.ChartActionEnum; |
| import org.eclipse.osbp.xtext.basic.generator.BasicDslGeneratorUtils; |
| import org.eclipse.osbp.xtext.chart.Chart; |
| import org.eclipse.osbp.xtext.chart.ChartModel; |
| import org.eclipse.osbp.xtext.chart.ChartOption; |
| import org.eclipse.osbp.xtext.chart.ChartPackage; |
| import org.eclipse.osbp.xtext.chart.ChartTree; |
| import org.eclipse.osbp.xtext.chart.jvmmodel.D3JsJavaUtil; |
| import org.eclipse.osbp.xtext.datamart.common.DatamartFilterGenerator; |
| import org.eclipse.osbp.xtext.datamart.common.olap.CellSetToD3JsonConverter; |
| import org.eclipse.osbp.xtext.datamart.common.olap.DerivedAxis; |
| import org.eclipse.osbp.xtext.datamart.common.olap.DerivedCell; |
| import org.eclipse.osbp.xtext.datamart.common.olap.DerivedHierarchy; |
| import org.eclipse.osbp.xtext.datamart.common.olap.DerivedLevel; |
| import org.eclipse.osbp.xtext.datamart.common.olap.DerivedMember; |
| import org.eclipse.osbp.xtext.datamart.common.olap.DerivedPosition; |
| import org.eclipse.osbp.xtext.i18n.I18NModelGenerator; |
| import org.eclipse.xtend2.lib.StringConcatenation; |
| import org.eclipse.xtext.common.types.JvmDeclaredType; |
| import org.eclipse.xtext.generator.IFileSystemAccess; |
| import org.eclipse.xtext.naming.IQualifiedNameProvider; |
| import org.eclipse.xtext.xbase.compiler.GeneratorConfig; |
| import org.eclipse.xtext.xbase.compiler.ImportManager; |
| import org.eclipse.xtext.xbase.compiler.output.TreeAppendable; |
| import org.eclipse.xtext.xbase.lib.Extension; |
| import org.osgi.service.event.Event; |
| import org.osgi.service.event.EventHandler; |
| |
| @SuppressWarnings("all") |
| public class ChartModelGenerator extends I18NModelGenerator { |
| @Inject |
| @Extension |
| private IQualifiedNameProvider _iQualifiedNameProvider; |
| |
| @Inject |
| @Extension |
| private D3JsJavaUtil _d3JsJavaUtil; |
| |
| @Inject |
| @Extension |
| private BasicDslGeneratorUtils _basicDslGeneratorUtils; |
| |
| @Override |
| public TreeAppendable createAppendable(final EObject context, final ImportManager importManager, final GeneratorConfig config) { |
| TreeAppendable _xblockexpression = null; |
| { |
| this.setBuilder(context.eResource()); |
| importManager.addImportFor(this._typeReferenceBuilder.typeRef(HashMap.class, this._typeReferenceBuilder.typeRef(String.class), this._typeReferenceBuilder.typeRef(String.class)).getType()); |
| importManager.addImportFor(this._typeReferenceBuilder.typeRef(Map.class, this._typeReferenceBuilder.typeRef(String.class), this._typeReferenceBuilder.typeRef(String.class)).getType()); |
| importManager.addImportFor(this._typeReferenceBuilder.typeRef(Collection.class, this._typeReferenceBuilder.typeRef(String.class)).getType()); |
| this._basicDslGeneratorUtils.addImportFor(this, importManager, this._typeReferenceBuilder, Property.ValueChangeListener.class, DCharts.class, Label.class, List.class, ArrayList.class, Page.class, Page.Styles.class, DerivedAxis.class, DerivedCell.class, DerivedPosition.class, DerivedMember.class, HorizontalLayout.class, TabSheet.class, Series.class, XYseries.class, Ticks.class, DataSeries.class, SeriesDefaults.class, SeriesRenderers.class, CanvasAxisTickRenderer.class, DonutRenderer.class, PieRenderer.class, BubbleRenderer.class, BarRenderer.class, BarDirections.class, MeterGaugeRenderer.class, PyramidRenderer.class, PyramidSides.class, Trendline.class, Cursor.class, Legend.class, LegendPlacements.class, EnhancedLegendRenderer.class, SeriesToggles.class, Highlighter.class, Title.class, TooltipLocations.class, TooltipAxes.class, Axes.class, XYaxes.class, XYaxis.class, Xaxes.class, Yaxes.class, AxisTickRenderer.class, AxisRenderers.class, LinearAxisRenderer.class, AxesDefaults.class, DownloadButtonLocation.class, Options.class, DerivedHierarchy.class, DerivedLevel.class, CellSetToD3JsonConverter.class, Date.class, JavaScriptFunction.class, JsonArray.class, JsonObject.class, JsonException.class, EventHandler.class, Event.class, EventUtils.class, EventBrokerMsg.class, Executors.class, Notification.class, EObject.class, UIElementImpl.class, UiPackageImpl.class, MUIElement.class, MPartStack.class, UI.class, ResourceBundle.class, Locale.class, DatamartFilterGenerator.class, ViewLayoutManager.class, IDatamartFilterGenerator.FilterChangeListener.class, EventDispatcherEvent.class, EventDispatcherEvent.EventDispatcherDataTag.class, EventDispatcherEvent.EventDispatcherCommand.class, DatamartFilter.class, Member.MemberType.class, Panel.class, MPerspective.class, ChartActionEnum.class, UUID.class, StreamResource.class, MToolBarElement.class, Button.class, FileDownloader.class, StreamResource.StreamSource.class, ByteArrayOutputStream.class, ImageIO.class, ByteArrayInputStream.class, InputStream.class, Adapter.class, AdapterImpl.class, SizeReporter.class, ComponentResizeListener.class, ComponentResizeEvent.class); |
| _xblockexpression = super.createAppendable(context, importManager, config); |
| } |
| return _xblockexpression; |
| } |
| |
| @Override |
| public void doGenerate(final Resource input, final IFileSystemAccess fsa) { |
| super.addTranslatables("download"); |
| super.doGenerate(input, fsa); |
| EList<EObject> _contents = input.getContents(); |
| for (final EObject obj : _contents) { |
| this.internalDoGenerate(obj, fsa); |
| } |
| } |
| |
| protected void _internalDoGenerate(final ChartModel chartModel, final IFileSystemAccess fsa) { |
| EList<ChartPackage> _packages = chartModel.getPackages(); |
| for (final ChartPackage pkg : _packages) { |
| EList<Chart> _charts = pkg.getCharts(); |
| for (final Chart chart : _charts) { |
| ChartOption _charttype = chart.getCharttype(); |
| if ((_charttype instanceof ChartTree)) { |
| String pckgName = this._iQualifiedNameProvider.getFullyQualifiedName(pkg).toString(); |
| StringBuilder strBuilder = new StringBuilder(); |
| String pckgNamePath = pckgName.replaceAll("\\.", "/"); |
| StringConcatenation _builder = new StringConcatenation(); |
| _builder.append(pckgNamePath); |
| _builder.append("/"); |
| String _createChartJsFilename = this._d3JsJavaUtil.createChartJsFilename(chart); |
| _builder.append(_createChartJsFilename); |
| String propOutputFile = _builder.toString(); |
| this.generateJsFile(chart, strBuilder); |
| int _length = strBuilder.length(); |
| boolean _greaterThan = (_length > 0); |
| if (_greaterThan) { |
| fsa.generateFile(propOutputFile, strBuilder); |
| } |
| } |
| } |
| } |
| } |
| |
| public void generateJsFile(final Chart chart, final StringBuilder strBuilder) { |
| String chartFilePath = this._d3JsJavaUtil.createfullyQualifiedChartFilename(chart).replaceAll("\\.", "_"); |
| ChartOption _charttype = chart.getCharttype(); |
| if ((_charttype instanceof ChartTree)) { |
| ChartOption _charttype_1 = chart.getCharttype(); |
| ChartTree chartTree = ((ChartTree) _charttype_1); |
| boolean _isMap = chartTree.isMap(); |
| if (_isMap) { |
| this.generateTreeMapJsFile(strBuilder, chartFilePath); |
| } else { |
| boolean _isCollapsible = chartTree.isCollapsible(); |
| if (_isCollapsible) { |
| this.generateCollTreeJsFile(strBuilder, chartFilePath); |
| } |
| } |
| } |
| } |
| |
| public void generateTreeMapJsFile(final StringBuilder strBuilder, final String chartJavaFileName) { |
| StringConcatenation _builder = new StringConcatenation(); |
| _builder.append(chartJavaFileName); |
| _builder.append(" = function() {"); |
| _builder.newLineIfNotEmpty(); |
| _builder.append("\t"); |
| _builder.append("var margin = {"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append("top: 10,"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append("right: 10,"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append("bottom: 40,"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append("left: 10"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("};"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var width = this.getState().panelWidth;"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var height = this.getState().panelHeight;"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var color = d3.scaleOrdinal(d3.schemeCategory10);"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var divId = this.getState().htmlTagId+\"_div\";"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var inputId = this.getState().htmlTagId+\"_input\";"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var element = this.getElement();"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var data = JSON.parse(this.getState().jsonData);"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var checked = \"\";"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var connector = this;"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var dataColumn = \"\";"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var preValueLabel = \"\";"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("for (var i=0;i < this.getState().dataColumnList.length;i++) {"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("if (i == 0){"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("checked = \" checked\";"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("preValueLabel = this.getState().dataColumnList[0];"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("} else {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("checked = \"\";"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("dataColumn = dataColumn + \"\\t<label><input id=\'\"+inputId+\"\' type=\'radio\' name=\'mode\' onChange=\'update(\\\"\"+this.getState().dataColumnList[i]+\"\\\")\' value=\'\"+ this.getState().dataColumnList[i] + \"\'\" + checked + \"> \"+ this.getState().dataColumnList[i] + \"</label>\\n\";"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var treemap = d3.treemap()"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append(".size([width-margin.right-margin.left, height-margin.top-margin.bottom])"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append(".paddingInner(1)"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append(".round(true)"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append(".tile(d3.treemapSquarify);"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("element.innerHTML = \"<form>\\n\"+dataColumn+\"</form>\\n\"+\"<div id=\\\"\"+divId+\"\\\">\" + \"</div>\";"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var div = d3.select(element).select(\"#\"+divId);"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var treeDiv = div.append(\"div\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t "); |
| _builder.append(".style(\"position\", \"relative\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append(".style(\"width\", width + \"px\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append(".style(\"height\", height + \"px\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t "); |
| _builder.append(".style(\"left\", margin.left + \"px\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t "); |
| _builder.append(".style(\"top\", margin.top + \"px\");"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("update = function(valueLabel) {"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("const newRoot = d3.hierarchy(data);"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("newRoot.sum((d) => "); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("d.children).sum((d) => "); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("eval(\"d.\" + valueLabel));"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("newRoot.sort((a,b) => "); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("eval(\"b.\" + valueLabel)-eval(\"a.\" + valueLabel));"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("const node = treeDiv.datum(newRoot).selectAll(\".node\")"); |
| _builder.newLine(); |
| _builder.append("\t \t"); |
| _builder.append(".data(treemap(newRoot).leaves())"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"class\", \"node\")"); |
| _builder.newLine(); |
| _builder.append("\t \t"); |
| _builder.append(".attr(\"title\", function(d) { return d.children ? \"\" : d.data.tooltipName + \"\\n\" + valueLabel + \": \" + eval(\"d.data.\" + valueLabel); })"); |
| _builder.newLine(); |
| _builder.append("\t \t"); |
| _builder.append(".transition()"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append(".duration(1500)"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".style(\"left\", (d) => d.x0 + \"px\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".style(\"top\", (d) => d.y0 + \"px\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".style(\"width\", (d) => Math.max(0, d.x1 - d.x0 - 1) + \"px\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".style(\"height\", (d) => Math.max(0, d.y1 - d.y0 - 1) + \"px\");"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("} "); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("render = function() {"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("const root = d3.hierarchy(data);"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("root.sum((d) => "); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("d.children).sum((d) => "); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("eval(\"d.\" + preValueLabel));"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("root.sort((a,b) => "); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("eval(\"b.\" + preValueLabel)-eval(\"a.\" + preValueLabel));"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("const node = treeDiv.datum(root).selectAll(\".node\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".data(treemap(root).leaves())"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".enter().append(\"div\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"class\", \"node\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"title\", \tfunction(d) { "); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return d.data.tooltipName + \"\\n\" + preValueLabel + \": \" + eval(\"d.data.\" + preValueLabel);"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("})"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".style(\"left\", (d) => d.x0 + \"px\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".style(\"top\", (d) => d.y0 + \"px\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".style(\"width\", (d) => Math.max(0, d.x1 - d.x0 - 1) + \"px\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".style(\"height\", (d) => Math.max(0, d.y1 - d.y0 - 1) + \"px\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".style(\"background\", (d) => { "); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("while (d.depth > 2) d = d.parent; "); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return color(d.data.name);}) "); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".text(function(d) { "); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return d.data.name;"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("});"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("render();"); |
| _builder.newLine(); |
| _builder.append("}"); |
| _builder.newLine(); |
| strBuilder.append(_builder); |
| } |
| |
| public void generateCollTreeJsFile(final StringBuilder strBuilder, final String chartJavaFileName) { |
| StringConcatenation _builder = new StringConcatenation(); |
| _builder.append(chartJavaFileName); |
| _builder.append(" = function() {"); |
| _builder.newLineIfNotEmpty(); |
| _builder.append("\t"); |
| _builder.append("var margin = {"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("top: 10, "); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("right: 10, "); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("bottom: 40, "); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("left: 10"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("};"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var width = this.getState().panelWidth;"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var height = this.getState().panelHeight;"); |
| _builder.newLine(); |
| _builder.append(" "); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var i = 0,"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append("duration = 750,"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append("root;"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var divId = this.getState().htmlTagId+\"_div\";"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var inputId = this.getState().htmlTagId+\"_input\";"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var element = this.getElement();"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var data = JSON.parse(this.getState().jsonData);"); |
| _builder.newLine(); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("function collapse(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("if (d.children) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("d._children = d.children;"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("d._children.forEach(collapse);"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("d.children = null;"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("function expand(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("if (d._children) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("d.children = d._children;"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("d.children.forEach(expand);"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("d._children = null;"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("change = function(value) {"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("//alert(\"value = \" + value);"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append("if (value === \"expand\"){"); |
| _builder.newLine(); |
| _builder.append("\t \t"); |
| _builder.append("data.children.forEach(expand);"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append("} else {"); |
| _builder.newLine(); |
| _builder.append("\t \t"); |
| _builder.append("data.children.forEach(collapse);"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append("update(data);"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("element.innerHTML = \t"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t\t"); |
| _builder.append("\"<label><input id=\\\"\"+inputId+\"\\\" type=\\\"radio\\\" name=\\\"mode\\\" onChange=\'change(\\\"expand\\\")\' value=\\\"expand\\\">Expand</label>\\n\" +"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t\t"); |
| _builder.append("\"<label><input id=\\\"\"+inputId+\"\\\" type=\\\"radio\\\" name=\\\"mode\\\" onChange=\'change(\\\"collapse\\\")\' value=\\\"collapse\\\" checked>Collapse</label>\\n\" +"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t\t"); |
| _builder.append("\"<div id=\\\"\"+divId+\"\\\">\" + \"</div>\";\t"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var div = d3.select(element).select(\"#\"+divId);"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("var svg = div.append(\"svg\")"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append(".attr(\"width\", width)"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append(".attr(\"height\", height)"); |
| _builder.newLine(); |
| _builder.append("\t \t"); |
| _builder.append(".append(\"g\")"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| _builder.append(".attr(\"transform\", \"translate(\" + margin.left + \",\" + margin.top + \")\");"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("function update(source) {"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Toggle children on click."); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("function click(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("if (d.children) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("d._children = d.children;"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("d.children = null;"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("} else {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("d.children = d._children;"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("d._children = null;"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("update(d);"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("var tree = d3.tree()"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".size([width>height?height:width, width>height?height:width]);"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("var treeData = tree(root);"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Compute the new tree layout."); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("var nodes = treeData.descendants();"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("var links = treeData.descendants().slice(1);"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Normalize for fixed-depth."); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("nodes.forEach(function(d) { "); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("d.y = d.depth * 180;"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("});"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// ****************** Nodes section ***************************"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Update the nodes"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("var node = svg.selectAll(\"g.node\").data(nodes, function(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return d.id || (d.id = ++i);"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("});"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Enter any new nodes at the parent\'s previous position."); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("var nodeEnter = node.enter().append(\"g\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"class\", \"node\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"transform\", function(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return \"translate(\" + source.y0 + \",\" + source.x0 + \")\";"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("})"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".on(\"click\", click);"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("nodeEnter.append(\"circle\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"class\", \"node\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"r\", 1e-6)"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".style(\"fill\", function(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return d._children ? \"lightsteelblue\" : \"#fff\";"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("});"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("nodeEnter.append(\"text\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"dy\", \".35em\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"x\", function(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return d.children || d._children ? -13 : 13;"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("})"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"text-anchor\", function(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return d.children || d._children ? \"end\" : \"start\";"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("})"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".text(function(d) { "); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return d.data.name;"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("});"); |
| _builder.newLine(); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// UPDATE"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("var nodeUpdate = nodeEnter.merge(node);"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Transition nodes to their new position."); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("nodeUpdate.transition()"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".duration(duration)"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"transform\", function(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return \"translate(\" + d.y + \",\" + d.x + \")\";"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("});"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("nodeUpdate.select(\"circle.node\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"r\", 4.5)"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".style(\"fill\", function(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return d._children ? \"lightsteelblue\" : \"#fff\";"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("})"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\'cursor\', \'pointer\');"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Transition exiting nodes to the parent\'s new position."); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("var nodeExit = node.exit().transition()"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".duration(duration)"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"transform\", function(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return \"translate(\" + source.y + \",\" + source.x + \")\";"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("})"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".remove();"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("nodeExit.select(\"circle\").attr(\"r\", 1e-6);"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("nodeExit.select(\"text\").style(\"fill-opacity\", 1e-6);"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// ****************** links section ***************************"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Update the links..."); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("var link = svg.selectAll(\'path.link\')"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".data(links, function(d) { return d.id; });"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Enter any new links at the parent\'s previous position."); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("var linkEnter = link.enter().insert(\'path\', \"g\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\"class\", \"link\")"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\'d\', function(d){"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("var o = {x: source.x0, y: source.y0}"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return diagonal(o, o)"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("});"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// UPDATE"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("var linkUpdate = linkEnter.merge(link);"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Transition back to the parent element position"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("linkUpdate.transition()"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".duration(duration)"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\'d\', function(d){"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return diagonal(d, d.parent)"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("});"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Remove any exiting links"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("var linkExit = link.exit().transition()"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".duration(duration)"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".attr(\'d\', function(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("var o = {x: source.x, y: source.y}"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("return diagonal(o, o)"); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t"); |
| _builder.append("})"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append(".remove();"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Store the old positions for transition."); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("nodes.forEach(function(d){"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("d.x0 = d.x;"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("d.y0 = d.y;"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("});"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("// Creates a curved (diagonal) path from parent to the child nodes"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("function diagonal(s, d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("path = `M ${s.y} ${s.x}"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("C ${(s.y + d.y) / 2} ${s.x},"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("${(s.y + d.y) / 2} ${d.x},"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("${d.y} ${d.x}`"); |
| _builder.newLine(); |
| _builder.append("\t\t\t"); |
| _builder.append("return path"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("root = d3.hierarchy(data, function(d) {"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("return d.children;"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("});"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("root.x0 = height / 2;"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("root.y0 = 0;"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("root.children.forEach(expand);"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("update(root);"); |
| _builder.newLine(); |
| _builder.append("}"); |
| _builder.newLine(); |
| strBuilder.append(_builder); |
| } |
| |
| public void internalDoGenerate(final EObject chartModel, final IFileSystemAccess fsa) { |
| if (chartModel instanceof JvmDeclaredType) { |
| _internalDoGenerate((JvmDeclaredType)chartModel, fsa); |
| return; |
| } else if (chartModel instanceof ChartModel) { |
| _internalDoGenerate((ChartModel)chartModel, fsa); |
| return; |
| } else if (chartModel != null) { |
| _internalDoGenerate(chartModel, fsa); |
| return; |
| } else { |
| throw new IllegalArgumentException("Unhandled parameter types: " + |
| Arrays.<Object>asList(chartModel, fsa).toString()); |
| } |
| } |
| } |