| /** |
| * |
| * 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.ComponentResizeListener |
| import com.ejt.vaadin.sizereporter.SizeReporter |
| import com.vaadin.server.StreamResource |
| import com.vaadin.shared.ui.JavaScriptComponentState |
| import com.vaadin.ui.AbstractJavaScriptComponent |
| import com.vaadin.ui.Component |
| import com.vaadin.ui.VerticalLayout |
| import elemental.json.JsonException |
| import java.util.ArrayList |
| import java.util.HashMap |
| import java.util.HashSet |
| import java.util.List |
| import java.util.Locale |
| import java.util.Set |
| import javax.annotation.PostConstruct |
| import javax.annotation.PreDestroy |
| import javax.inject.Inject |
| import org.dussan.vaadin.dcharts.DCharts |
| import org.eclipse.e4.core.contexts.IEclipseContext |
| import org.eclipse.e4.ui.di.Focus |
| import org.eclipse.e4.ui.model.application.MApplication |
| import org.eclipse.e4.ui.workbench.IPresentationEngine |
| import org.eclipse.emf.common.notify.Adapter |
| import org.eclipse.osbp.dsl.semantic.common.types.LAttribute |
| import org.eclipse.osbp.dsl.semantic.entity.LEntity |
| import org.eclipse.osbp.osgi.hybrid.api.AbstractHybridVaaclipseView |
| import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent |
| import org.eclipse.osbp.runtime.common.event.IEventDispatcher |
| import org.eclipse.osbp.ui.api.datamart.DatamartFilter |
| import org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator |
| import org.eclipse.osbp.ui.api.e4.IE4Focusable |
| import org.eclipse.osbp.ui.api.layout.IViewLayoutManager |
| import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService |
| import org.eclipse.osbp.ui.api.themes.EnumCssClass |
| import org.eclipse.osbp.ui.api.themes.IThemeResourceService |
| import org.eclipse.osbp.ui.api.user.IUser |
| import org.eclipse.osbp.xtext.action.ActionPackage |
| import org.eclipse.osbp.xtext.chart.Chart |
| import org.eclipse.osbp.xtext.chart.ChartAxis |
| import org.eclipse.osbp.xtext.chart.ChartBar |
| import org.eclipse.osbp.xtext.chart.ChartBubble |
| import org.eclipse.osbp.xtext.chart.ChartDatamart |
| import org.eclipse.osbp.xtext.chart.ChartDonut |
| import org.eclipse.osbp.xtext.chart.ChartGauge |
| import org.eclipse.osbp.xtext.chart.ChartHighlighter |
| import org.eclipse.osbp.xtext.chart.ChartLegend |
| import org.eclipse.osbp.xtext.chart.ChartLine |
| import org.eclipse.osbp.xtext.chart.ChartNumberInterval |
| import org.eclipse.osbp.xtext.chart.ChartPackage |
| import org.eclipse.osbp.xtext.chart.ChartPie |
| import org.eclipse.osbp.xtext.chart.ChartSegmentColor |
| import org.eclipse.osbp.xtext.chart.ChartTree |
| import org.eclipse.osbp.xtext.cubedsl.CubeLevel |
| import org.eclipse.osbp.xtext.datamart.common.olap.DerivedCellSet |
| import org.eclipse.osbp.xtext.datamartdsl.DatamartAttribute |
| import org.eclipse.osbp.xtext.datamartdsl.DatamartCube |
| import org.eclipse.osbp.xtext.datamartdsl.DatamartCubeAxis |
| import org.eclipse.osbp.xtext.datamartdsl.DatamartDerivedMeasure |
| import org.eclipse.osbp.xtext.datamartdsl.DatamartEntity |
| import org.eclipse.osbp.xtext.datamartdsl.DatamartMeasure |
| import org.eclipse.osbp.xtext.datamartdsl.DatamartMember |
| import org.eclipse.osbp.xtext.datamartdsl.DatamartOwner |
| import org.eclipse.osbp.xtext.datamartdsl.DatamartPackage |
| import org.eclipse.osbp.xtext.datamartdsl.ValueScaleEnum |
| import org.eclipse.osbp.xtext.datamartdsl.jvmmodel.DatamartDSLJvmModelInferrer |
| import org.eclipse.osbp.xtext.table.common.PropertyLookup |
| import org.eclipse.xtext.common.types.JvmAnnotationReference |
| import org.eclipse.xtext.common.types.JvmConstructor |
| import org.eclipse.xtext.common.types.JvmDeclaredType |
| import org.eclipse.xtext.common.types.JvmField |
| import org.eclipse.xtext.common.types.JvmOperation |
| import org.eclipse.xtext.common.types.JvmStringAnnotationValue |
| import org.eclipse.xtext.common.types.JvmVisibility |
| import org.eclipse.xtext.common.types.TypesFactory |
| import org.eclipse.xtext.naming.IQualifiedNameProvider |
| import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer |
| import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor |
| import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder |
| import org.osgi.service.event.EventHandler |
| import org.slf4j.Logger |
| import com.vaadin.annotations.JavaScript |
| |
| /** |
| * <p> |
| * This inferrer infers models of extension .chart and generates code to be used by a e4 application as view. Underlying components |
| * are from the vaadin component repository and especially the vaadin addon dChart. |
| * </p> |
| * |
| * @author Joerg Riegel |
| */ |
| |
| /** |
| * <p>Infers a JVM model from the source model.</p> |
| * |
| * <p>The JVM model should contain all elements that would appear in the Java code |
| * which is generated from the source model. Other models link against the JVM model rather than the source model.</p> |
| */ |
| class ChartDSLJvmModelInferrer extends AbstractModelInferrer { |
| |
| @Inject extension JvmTypesBuilder |
| @Inject extension IQualifiedNameProvider |
| @Inject extension DatamartDSLJvmModelInferrer datamartInferrer |
| @Inject extension D3JsJavaUtil |
| @Inject private TypesFactory typesFactory |
| |
| /** |
| * <p>infer method dispatches the necessary routines to build fields, setter, getter, constructors and methods of the generated code.</p> |
| * |
| */ |
| def dispatch void infer(ChartPackage pckg, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) { |
| for (chart:pckg.charts) { |
| var cls = chart.toClass(pckg.fullyQualifiedName+"."+chart.name+"Chart") |
| cls.superTypes.add(_typeReferenceBuilder.typeRef(AbstractHybridVaaclipseView)) |
| cls.superTypes.add(_typeReferenceBuilder.typeRef(IUser.UserLocaleListener)) |
| cls.superTypes.add(_typeReferenceBuilder.typeRef(IDatamartFilterGenerator.FilterChangeListener)) |
| cls.superTypes.add(_typeReferenceBuilder.typeRef(IEventDispatcher.Receiver)) |
| cls.superTypes.add(_typeReferenceBuilder.typeRef(IE4Focusable)) |
| acceptor.accept(cls, |
| [ |
| it.fileHeader = pckg.documentation |
| it.toFields(chart) |
| it.toConstructor(chart) |
| it.toGetterSetter(chart) |
| it.toOperations(chart) |
| ]) |
| if ((chart.charttype instanceof ChartTree)) { |
| chart.createJsJavaComponent(acceptor) |
| } |
| } |
| } |
| |
| /** |
| * <p>build the constructors to be used by an e4 application.</p> |
| * |
| */ |
| def void toConstructor(JvmDeclaredType type, Chart chart) { |
| type.members += chart.toConstructor([ |
| annotations += _annotationTypesBuilder.annotationRef(Inject) |
| parameters += chart.toParameter("parent", _typeReferenceBuilder.typeRef(VerticalLayout)) |
| parameters += chart.toParameter("context", _typeReferenceBuilder.typeRef(IEclipseContext)) |
| parameters += chart.toParameter("app", _typeReferenceBuilder.typeRef(MApplication)) |
| body = [ append( |
| ''' |
| super(parent,context,app);''')] |
| ]) |
| } |
| |
| /** |
| * <p>build the class variables.</p> |
| * |
| */ |
| def void toFields(JvmDeclaredType type, Chart chart) { |
| var JvmField field = null |
| // create logger |
| field = chart.toField("log", _typeReferenceBuilder.typeRef(Logger))[setInitializer([append('''org.slf4j.LoggerFactory.getLogger("charts")''')])] |
| field.static = true |
| field.visibility = JvmVisibility::PRIVATE |
| type.members += field |
| field = chart.toField("user", _typeReferenceBuilder.typeRef(IUser)) [annotations += _annotationTypesBuilder.annotationRef(Inject)] |
| type.members += field |
| field = chart.toField("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext)) [annotations += _annotationTypesBuilder.annotationRef(Inject)] |
| type.members += field |
| field = chart.toField("coordinateSystem", _typeReferenceBuilder.typeRef(ArrayList, _typeReferenceBuilder.typeRef(Integer))) |
| type.members += field |
| field = chart.toField("filterGenerator", _typeReferenceBuilder.typeRef(IDatamartFilterGenerator)) |
| type.members += field |
| field = chart.toField("layoutManager", _typeReferenceBuilder.typeRef(IViewLayoutManager)) |
| type.members += field |
| // the package name of the referenced datamart |
| if (getSourceDataMartRefName(chart) !== null) { |
| var packageName = (chart.source.datamartRef.eContainer as DatamartPackage).fullyQualifiedName.toString |
| field = chart.toField("datamartInstance", _typeReferenceBuilder.typeRef('''«packageName».«chart.source.datamartRef.name.toString»Datamart''')) |
| type.members += field |
| } |
| field = chart.toField("dataComponent", _typeReferenceBuilder.typeRef(Component)) |
| type.members += field |
| field = chart.toField("attributeLookupMap", _typeReferenceBuilder.typeRef(HashMap, _typeReferenceBuilder.typeRef(String), _typeReferenceBuilder.typeRef(PropertyLookup))) |
| type.members += field |
| field = chart.toField("charts", _typeReferenceBuilder.typeRef(ArrayList, _typeReferenceBuilder.typeRef(DCharts))) |
| type.members += field |
| field = chart.toField("refreshView", _typeReferenceBuilder.typeRef(EventHandler)) |
| type.members += field |
| field = chart.toField("dslMetadataService", _typeReferenceBuilder.typeRef(IDSLMetadataService)) [annotations += _annotationTypesBuilder.annotationRef(Inject)] |
| type.members += field |
| field = chart.toField("eventDispatcher", _typeReferenceBuilder.typeRef(IEventDispatcher))[annotations += _annotationTypesBuilder.annotationRef(Inject)] |
| type.members += field |
| field = chart.toField("renderingEngine", _typeReferenceBuilder.typeRef(IPresentationEngine))[annotations += _annotationTypesBuilder.annotationRef(Inject)] |
| type.members += field |
| field = chart.toField("themeResourceService", _typeReferenceBuilder.typeRef(IThemeResourceService))[annotations += _annotationTypesBuilder.annotationRef(Inject)] |
| type.members += field |
| if (chart.toolbar !== null && chart.toolbar.eContainer !== null) { |
| var packageName = (chart.toolbar.eContainer as ActionPackage).fullyQualifiedName.toString |
| field = chart.toField("toolbarUUID", _typeReferenceBuilder.typeRef(String)) |
| type.members += field |
| field = chart.toField("toolbarClass", _typeReferenceBuilder.typeRef('''«packageName».«chart.toolbar.name.toString.toFirstUpper»Toolbar''')) |
| type.members += field |
| } |
| field = chart.toField("panelWidth", _typeReferenceBuilder.typeRef(int)) |
| type.members += field |
| field = chart.toField("panelHeight", _typeReferenceBuilder.typeRef(int)) |
| type.members += field |
| field = chart.toField("splitAdapter", _typeReferenceBuilder.typeRef(Adapter.Internal)) |
| type.members += field |
| field = chart.toField("resizeListener", _typeReferenceBuilder.typeRef(ComponentResizeListener)) |
| type.members += field |
| field = chart.toField("sizeReporter", _typeReferenceBuilder.typeRef(SizeReporter)); |
| type.members += field |
| } |
| |
| /** |
| * <p>build the getters and setters from class variables.</p> |
| * |
| */ |
| def void toGetterSetter(JvmDeclaredType type, Chart chart) { |
| var JvmOperation operation = null |
| operation = chart.toGetter("coordinateSystem", _typeReferenceBuilder.typeRef(ArrayList, _typeReferenceBuilder.typeRef(Integer))) |
| operation.visibility = JvmVisibility::PUBLIC |
| type.members += operation |
| } |
| |
| /** |
| * <p>build the methods.</p> |
| * |
| */ |
| def void toOperations(JvmDeclaredType type, Chart chart) { |
| // activate |
| type.members += chart.toMethod("activate", _typeReferenceBuilder.typeRef(Void::TYPE), |
| [ |
| annotations += _annotationTypesBuilder.annotationRef(PostConstruct) |
| body = [append( |
| ''' |
| super.initView(); |
| user.addUserLocaleListener(this); |
| filterGenerator.addFilterChangeListener(this); |
| // to resize the chart according to split positions of partsashcontainer - setContainerData is tracked |
| ((EObject)getPart()).eAdapters().add(splitAdapter); |
| sizeReporter.addResizeListener(resizeListener); |
| eventDispatcher.addEventReceiver(this);''')] |
| ]) |
| |
| // deactivate |
| type.members += chart.toMethod("deactivate", _typeReferenceBuilder.typeRef(Void::TYPE), |
| [ |
| annotations += _annotationTypesBuilder.annotationRef(PreDestroy) |
| body = [append( |
| ''' |
| user.removeUserLocaleListener(this); |
| filterGenerator.removeFilterChangeListener(this); |
| ((EObject)getPart()).eAdapters().remove(splitAdapter); |
| sizeReporter.removeResizeListener(resizeListener); |
| eventDispatcher.removeEventReceiver(this); |
| super.destroyView();''')] |
| ]) |
| // create view |
| type.members += chart.toMethod("createView", _typeReferenceBuilder.typeRef(Void::TYPE), [ |
| parameters += chart.toParameter("parent", _typeReferenceBuilder.typeRef(VerticalLayout)) |
| body = [ append('''«chart.createView»''')] |
| ]) |
| // create components |
| type.members += chart.toMethod("createComponents", _typeReferenceBuilder.typeRef(Void::TYPE), [ |
| body = [ append('''«chart.createComponents»''')] |
| ]) |
| // create tab |
| type.members += chart.toMethod("createTabSheet", _typeReferenceBuilder.typeRef(Component), [ |
| parameters += chart.toParameter("cellSet", _typeReferenceBuilder.typeRef(DerivedCellSet)) |
| parameters += chart.toParameter("axisNo", _typeReferenceBuilder.typeRef(Integer)) |
| body = [ append('''«chart.createTabSheet»''')] |
| ]) |
| // create chart |
| if (!((chart.charttype instanceof ChartTree))) { |
| type.members += chart.toMethod("createChart", _typeReferenceBuilder.typeRef(Component), [ |
| parameters += chart.toParameter("cellSet", _typeReferenceBuilder.typeRef(DerivedCellSet)) |
| body = [ append('''«chart.createChart»''')] |
| ]) |
| } |
| // create D3 chart |
| if ((chart.charttype instanceof ChartTree)) { |
| type.members += chart.toMethod("createD3Chart", _typeReferenceBuilder.typeRef(Component), [ |
| exceptions += _typeReferenceBuilder.typeRef(JsonException) |
| parameters += chart.toParameter("cxCellSet", _typeReferenceBuilder.typeRef(DerivedCellSet)) |
| body = [ append('''«chart.createD3Chart»''')] |
| ]) |
| } |
| // focus |
| type.members += chart.toMethod("setFocus", _typeReferenceBuilder.typeRef(Void::TYPE), |
| [ |
| annotations += _annotationTypesBuilder.annotationRef(Focus) |
| body = [append( |
| ''' |
| Component parent = getParent(); |
| while(!(parent instanceof Panel) && parent != null) { |
| parent = parent.getParent(); |
| } |
| if(parent != null) { |
| ((Panel)parent).focus(); |
| }''')] |
| |
| ]) |
| // locale notification |
| type.members += chart.toMethod("localeChanged", _typeReferenceBuilder.typeRef(Void::TYPE), [ |
| visibility = JvmVisibility.PUBLIC |
| annotations += _annotationTypesBuilder.annotationRef(Override) |
| parameters += chart.toParameter("locale", _typeReferenceBuilder.typeRef(Locale)) |
| body = [append('''«chart.localeChanged»''')] |
| ]) |
| // filter notification |
| type.members += chart.toMethod("filterChanged", _typeReferenceBuilder.typeRef(Void::TYPE), |
| [ |
| parameters += chart.toParameter("changedFilter", _typeReferenceBuilder.typeRef(DatamartFilter)) |
| visibility = JvmVisibility.PUBLIC |
| annotations += _annotationTypesBuilder.annotationRef(Override) |
| body = [append('''renderData();''')] |
| ]) |
| // event notification |
| type.members += chart.toMethod("receiveEvent", _typeReferenceBuilder.typeRef(Void::TYPE), |
| [ |
| visibility = JvmVisibility.PUBLIC |
| annotations += _annotationTypesBuilder.annotationRef(Override) |
| parameters += chart.toParameter("event", _typeReferenceBuilder.typeRef(EventDispatcherEvent)) |
| body = [append('''«chart.receiveEvent»''')] |
| ]) |
| // getChartResource |
| type.members += chart.toMethod("getChartResource", _typeReferenceBuilder.typeRef(StreamResource), |
| [ |
| visibility = JvmVisibility.PRIVATE |
| parameters += chart.toParameter("chart", _typeReferenceBuilder.typeRef(DCharts)) |
| parameters += chart.toParameter("layoutManager", _typeReferenceBuilder.typeRef(IViewLayoutManager)) |
| body = [append('''«chart.chartResource»''')] |
| ]) |
| } |
| |
| def String getSourceDataMartRefName(Chart chart) { |
| if (chart.source !== null && chart.source.datamartRef !== null && chart.source.datamartRef.name !== null) { |
| return chart.source.datamartRef.name.toString |
| } |
| else { |
| return null; |
| } |
| } |
| |
| /** |
| * <p>build the main method to be called from e4.</p> |
| * |
| */ |
| def String createView(Chart chart) { |
| var body = |
| ''' |
| eclipseContext.set(IE4Focusable.class, this); |
| charts = new ArrayList<DCharts>(); |
| coordinateSystem = new ArrayList<Integer>(); |
| parent.setPrimaryStyleName("osbp"); // <== is THIS necessary any more??? |
| parent.addStyleName("«EnumCssClass.VIEW.styleName»"); |
| parent.addStyleName("«EnumCssClass.CHART_VIEW.styleName»"); |
| parent.setSizeFull(); |
| layoutManager = new ViewLayoutManager(); |
| layoutManager.init(parent); |
| splitAdapter = new AdapterImpl() { |
| @Override |
| public void notifyChanged(Notification notification) { |
| if (notification.getEventType()==Notification.SET && |
| notification.getFeatureID(UIElementImpl.class) == UiPackageImpl.UI_ELEMENT__CONTAINER_DATA) |
| { |
| log.debug("render due to split position changed"); |
| renderData(); |
| } |
| } |
| }; |
| sizeReporter = new SizeReporter(layoutManager.getDataArea()); |
| resizeListener = new ComponentResizeListener() { |
| @Override |
| public void sizeChanged(ComponentResizeEvent event) { |
| boolean changed = false; |
| if (panelWidth != event.getWidth()) { |
| changed = true; |
| panelWidth = event.getWidth(); |
| } |
| if (panelHeight != event.getHeight()) { |
| changed = true; |
| panelHeight = event.getHeight(); |
| } |
| if (changed) { |
| log.debug("Panel size changed : " + event.getWidth() + " x " + event.getHeight()); |
| renderData(); |
| } |
| } |
| }; |
| datamartInstance = new «getSourceDataMartRefName(chart)»Datamart(); |
| datamartInstance.setUser(user); |
| filterGenerator = new DatamartFilterGenerator(datamartInstance, eclipseContext, «chart.source.datamartRef.showCaption.booleanValue», «Integer.max(10,chart.source.datamartRef.numMultiRows)»); |
| filterGenerator.createUIFilters(layoutManager); |
| attributeLookupMap = new HashMap<String,PropertyLookup>(); |
| ''' |
| if (chart.toolbar !== null) { |
| body = ''' |
| «body» |
| toolbarUUID = UUID.randomUUID().toString(); |
| toolbarClass = new «chart.toolbar.name.toString.toFirstUpper»Toolbar(); |
| toolbarClass.createToolbar(eclipseContext, renderingEngine, themeResourceService, toolbarUUID);''' |
| } |
| body = ''' |
| «body» |
| refreshView = «chart.refreshView» |
| ''' |
| return body |
| } |
| |
| /** |
| * <p>create a handler for external triggered refresh requests.</p> |
| * |
| */ |
| def String refreshView(Chart chart) { |
| var body = "" |
| body = ''' |
| «body» |
| new EventHandler() { |
| @Override |
| public void handleEvent(Event event) { |
| renderData(); |
| } |
| }; |
| ''' |
| return body |
| } |
| |
| /** |
| * <p>build the data components.</p> |
| * |
| */ |
| def String createComponents(Chart chart) { |
| var body = "" |
| if (chart.source !== null) { |
| var isCube = ((chart.source as ChartDatamart).datamartRef.source instanceof DatamartCube) |
| body = ''' |
| «body»// get the results |
| if (panelWidth == 0 && panelHeight == 0) { |
| return; |
| } |
| final DerivedCellSet cellSet = datamartInstance.getResults(«IF !isCube»false, getTaskOperativeDtoClass(), getTaskInitialOperativeDtos()«ENDIF»); |
| getCoordinateSystem().clear(); |
| charts.clear(); |
| if (cellSet == null) { |
| promptSecurityMessage(dslMetadataService.translate(user.getLocale().toLanguageTag(), "securityMessage"), layoutManager.getDataArea()); |
| return; |
| } else { |
| layoutManager.getDataArea().removeAllComponents(); |
| } |
| // generate a new result component |
| if (cellSet != null) { |
| // create a multidimensional coordinate system against the cellSet |
| for (int axis = 0; axis < cellSet.getAxes().size(); axis++) { |
| getCoordinateSystem().add(0); |
| } |
| // remove any previous component |
| if (dataComponent != null) { |
| layoutManager.getDataArea().removeComponent(dataComponent); |
| dataComponent = null; |
| } |
| if (cellSet.getAxes().size() < 2) { |
| log.error("at least 2 axes from referenced datamart «chart.source.datamartRef.name» are needed to render «chart.name»"); |
| } else { |
| dataComponent = createTabSheet(cellSet, cellSet.getAxes().size()); |
| if(dataComponent != null) { |
| dataComponent.setSizeFull(); |
| dataComponent.setId("dataComponent"); |
| dataComponent.addStyleName("«EnumCssClass.DATA_COMPONENT.styleName»"); |
| layoutManager.getDataArea().addComponent(dataComponent); |
| layoutManager.getDataArea().setExpandRatio(dataComponent, 1); |
| } |
| } |
| getParent().markAsDirtyRecursive(); |
| } |
| else { |
| log.error("referenced datamart «chart.source.datamartRef.name» generates no results"); |
| } |
| ''' |
| } else { |
| body = ''' |
| «body» |
| // generate a new result component |
| try { |
| // remove any previous component |
| if (dataComponent != null) { |
| layoutManager.getDataArea().removeComponent(dataComponent); |
| dataComponent = null; |
| } |
| dataComponent = createTabSheet(null, 2); |
| dataComponent.setSizeFull(); |
| dataComponent.setId("dataComponent"); |
| dataComponent.addStyleName("«EnumCssClass.DATA_COMPONENT.styleName»"); |
| layoutManager.getDataArea().addComponent(dataComponent); |
| layoutManager.getDataArea().setExpandRatio(dataComponent, 1); |
| } catch (DerivedOlapException e) { |
| log.error(e.getLocalizedMessage()); |
| } |
| ''' |
| } |
| return body |
| } |
| |
| /** |
| * <p>if more than 2 axes (dimensions) are found in the cellSet, build recursive tabsheets as long as the remaining axes are more than 2.</p> |
| * |
| */ |
| def String createTabSheet(Chart chart) { |
| var body = |
| ''' |
| // either create a recursive tabsheet or a chart |
| Component component = null; |
| if (axisNo == 2) { |
| ''' |
| if ((chart.charttype instanceof ChartTree)) { |
| body = ''' |
| «body» |
| try { |
| component = createD3Chart(cellSet); |
| } catch (JsonException e) { |
| log.error(e.getLocalizedMessage()); |
| } |
| ''' |
| } |
| else { |
| body = ''' |
| «body» |
| component = createChart(cellSet); |
| ''' |
| } |
| body = ''' |
| «body» |
| } |
| else { |
| Integer axis = axisNo-1; |
| TabSheet tabsheet = new TabSheet(); |
| tabsheet.setSizeFull(); |
| DerivedAxis tabAxis = cellSet.getAxes().get(axis); |
| // create a tab page for all tab axis members |
| int tabNo = 0; |
| for (DerivedPosition column : tabAxis.getPositions()) { |
| // create the title for the axis |
| String title = null; |
| for (DerivedMember member : column.getMembers()) { |
| if (title == null) { |
| title = dslMetadataService.translate(user.getLocale().toLanguageTag(), member.getCaption()); |
| } |
| else { |
| title += " / "+dslMetadataService.translate(user.getLocale().toLanguageTag(), member.getCaption()); |
| } |
| } |
| // position the data to this coordinate |
| getCoordinateSystem().set(axis, tabNo); |
| component = createTabSheet(cellSet, axis); |
| // set the caption |
| if (component != null) { |
| component.setCaption(title); |
| // add the component as a tab page |
| tabsheet.addComponent(component); |
| } |
| tabNo++; |
| } |
| component = tabsheet; |
| } |
| return component;''' |
| return body |
| } |
| |
| /** |
| * <p>build the chart components.</p> |
| * |
| */ |
| def String createChart(Chart chart) { |
| var body = "" |
| var postfix = "" |
| var chartType = "" |
| var hasAxis = true |
| var multipleAxes = <String, String>newHashMap |
| var ChartAxis category_axis = null |
| var ChartAxis data_axis = null |
| var ChartAxis inner_axis = null |
| var ChartAxis outer_axis = null |
| var axisSwitch = false; |
| var axisPrefix = 'XY' |
| if (chart.charttype instanceof ChartBar) { |
| if ((chart.charttype as ChartBar).swapped) { |
| axisPrefix = 'YX' |
| axisSwitch = true; |
| } |
| } |
| for (element : chart.source.elements) { |
| if (element instanceof ChartAxis) { |
| var axis = element as ChartAxis |
| if (axis.axis.name.getName.equals('COLUMNS') || axis.axis.name.getName.equals('ROWS')) { |
| if ((axis.renderType.getName.equals("LOG") || axis.renderType.getName.equals("LINEAR") || axis.renderType.getName.equals("PYRAMID"))) { |
| data_axis = axis |
| } |
| if ((axis.renderType.getName.equals("CATEGORY") || axis.renderType.getName.equals("DATE"))) { |
| category_axis = axis |
| } |
| } |
| } |
| } |
| if (chart.charttype instanceof ChartBar) { |
| chartType = "BAR" |
| postfix = '''_«chartType»''' |
| inner_axis = category_axis |
| outer_axis = data_axis |
| } |
| else if (chart.charttype instanceof ChartBubble) { |
| chartType = "BUBBLE" |
| postfix = '''_«chartType»''' |
| hasAxis = true |
| inner_axis = data_axis |
| outer_axis = category_axis |
| } |
| else if (chart.charttype instanceof ChartDonut) { |
| chartType = "DONUT" |
| hasAxis = false |
| inner_axis = category_axis |
| outer_axis = data_axis |
| } |
| else if (chart.charttype instanceof ChartLine) { |
| chartType = "LINE" |
| inner_axis = category_axis |
| outer_axis = data_axis |
| } |
| else if (chart.charttype instanceof ChartPie) { |
| chartType = "PIE" |
| hasAxis = false |
| inner_axis = data_axis |
| outer_axis = category_axis |
| } |
| else if (chart.charttype instanceof ChartGauge) { |
| chartType = "METER_GAUGE" |
| hasAxis = false |
| inner_axis = data_axis |
| outer_axis = category_axis |
| } |
| |
| body = |
| ''' |
| List<Integer> coordinate = new ArrayList<Integer>(getCoordinateSystem()); |
| ''' |
| body = ''' |
| «body»// create a label series |
| List<String> «data_axis.axis.name.literal»TitlesArray = new ArrayList<String>(); |
| for (DerivedPosition pos : cellSet.getAxes().get(«data_axis.axis.name.value»).getPositions()) { |
| ''' |
| body = ''' |
| «body» |
| String title = null; |
| for (DerivedMember member : pos.getMembers()) { |
| if(member.getType() == MemberType.MEASURE) { |
| if (title == null) { |
| title = dslMetadataService.translate(user.getLocale().toLanguageTag(), member.getCaption()); |
| } |
| else { |
| title += " "+dslMetadataService.translate(user.getLocale().toLanguageTag(), member.getCaption()); |
| } |
| } |
| } |
| if(title != null) { |
| «data_axis.axis.name.literal»TitlesArray.add(title); |
| } |
| } |
| ''' |
| if (hasAxis) { |
| body = ''' |
| «body»Series «data_axis.axis.name.literal»Series = new Series(); |
| ''' |
| body = ''' |
| «body»if («data_axis.axis.name.literal»TitlesArray.size() > 0) { |
| ''' |
| // evaluate multiple scales |
| var showMarker = false |
| if (chart.charttype instanceof ChartLine) { |
| showMarker = (chart.charttype as ChartLine).showMarker |
| } |
| body = '''«body»«chart.createLabelSeries(data_axis, multipleAxes, axisPrefix, showMarker)»''' |
| body = ''' |
| «body»} |
| ''' |
| } |
| body = ''' |
| «body»// create the data series ticks |
| String «category_axis.axis.name.literal»AxisLabel = ""; |
| Boolean «category_axis.axis.name.literal»AxisLabelSet = false; |
| List<String> «category_axis.axis.name.literal»TitlesArray = new ArrayList<String>(); |
| for (DerivedPosition pos : cellSet.getAxes().get(«category_axis.axis.name.value»).getPositions()) { |
| String title = ""; |
| for (DerivedMember member : pos.getMembers()) { |
| if(member.getType() == MemberType.REGULAR) { |
| String[] tokens = member.getUniqueName().split("\\]\\.\\["); |
| if (!«category_axis.axis.name.literal»AxisLabelSet) { |
| if («category_axis.axis.name.literal»AxisLabel.length() > 0) { |
| «category_axis.axis.name.literal»AxisLabel += " / "; |
| } |
| «category_axis.axis.name.literal»AxisLabel += dslMetadataService.translate(user.getLocale().toLanguageTag(), member.getLevel().getName()); |
| } |
| int start = 1; |
| // if shortlabel is configured, use only last level name |
| if («category_axis.shortLabel.booleanValue») { |
| start = tokens.length-1; |
| } |
| for (int token = start; token < tokens.length; token++) { |
| title += dslMetadataService.translate(user.getLocale().toLanguageTag(), tokens[token])+" "; |
| } |
| } |
| } |
| if(title != null) { |
| «category_axis.axis.name.literal»AxisLabelSet = true; |
| «category_axis.axis.name.literal»TitlesArray.add(title.trim().replace("[", "").replace("]", "")); |
| } |
| } |
| ''' |
| if (hasAxis) { |
| body = ''' |
| «body»Ticks «category_axis.axis.name.literal»Ticks = new Ticks(); |
| «category_axis.axis.name.literal»Ticks.add(«category_axis.axis.name.literal»TitlesArray.toArray()); |
| ''' |
| } |
| |
| body = ''' |
| «body» |
| if(«category_axis.axis.name.literal»TitlesArray.isEmpty()) { |
| return null; |
| } |
| // copy cellset data to data series |
| DataSeries dataSeries = new DataSeries(); |
| ''' |
| if (chart.charttype instanceof ChartBubble) { |
| body = ''' |
| «body»dataSeries.newSeries(); |
| ''' |
| } |
| body = ''' |
| «body»int «outer_axis.axis.name.literal»No = 0; |
| ''' |
| body = ''' |
| «body»for (DerivedPosition «outer_axis.axis.name.literal»Pos : cellSet.getAxes().get(«outer_axis.axis.name.value»).getPositions()) { |
| ''' |
| body = ''' |
| «body» coordinate.set(«outer_axis.axis.name.value», «outer_axis.axis.name.literal»No); |
| ''' |
| if (chart.charttype instanceof ChartDonut) { |
| body = ''' |
| «body» dataSeries.newSeries(); |
| ''' |
| } |
| if (!(chart.charttype instanceof ChartPie) && !(chart.charttype instanceof ChartDonut)) { |
| body = ''' |
| «body» ArrayList<Object> «inner_axis.axis.name.literal»DataSeries = new ArrayList<Object>(); |
| ''' |
| } |
| body = ''' |
| «body» if(«outer_axis.axis.name.literal»Pos.getMembers().get(0).getType() == MemberType.«IF outer_axis==data_axis»MEASURE«ELSE»REGULAR«ENDIF») { |
| ''' |
| body = ''' |
| «body» int «inner_axis.axis.name.literal»No = 0; |
| ''' |
| body = ''' |
| «body» for (DerivedPosition «inner_axis.axis.name.literal»Pos : cellSet.getAxes().get(«inner_axis.axis.name.value»).getPositions()) { |
| ''' |
| body = ''' |
| «body» if(«inner_axis.axis.name.literal»Pos.getMembers().get(0).getType() == MemberType.«IF inner_axis==data_axis»MEASURE«ELSE»REGULAR«ENDIF») { |
| ''' |
| if (chart.charttype instanceof ChartPie) { |
| body = ''' |
| «body» dataSeries.newSeries(); |
| ''' |
| } |
| body = ''' |
| «body» coordinate.set(«inner_axis.axis.name.value», «inner_axis.axis.name.literal»No); |
| ''' |
| body = ''' |
| «body» |
| Object value = null; |
| DerivedCell cell = cellSet.getCell(coordinate); |
| if (cell != null) { |
| value = cell.getValue(); |
| } |
| ''' |
| if (chart.charttype instanceof ChartPie || chart.charttype instanceof ChartDonut) { |
| body = ''' |
| «body» dataSeries.add(«outer_axis.axis.name.literal»TitlesArray.get(«outer_axis.axis.name.literal»No)+" "+«inner_axis.axis.name.literal»TitlesArray.get(«inner_axis.axis.name.literal»No),(value == null ? 0.0 : value)); |
| ''' |
| } |
| else { |
| body = ''' |
| «body» «inner_axis.axis.name.literal»DataSeries.add(value == null ? 0.0 : value); |
| ''' |
| } |
| body = ''' |
| «body» «inner_axis.axis.name.literal»No ++; |
| } |
| } |
| ''' |
| if (!(chart.charttype instanceof ChartPie) && !(chart.charttype instanceof ChartDonut)) { |
| if (chart.charttype instanceof ChartBubble) { |
| body = ''' |
| «body» «inner_axis.axis.name.literal»DataSeries.add(«outer_axis.axis.name.literal»TitlesArray.get(«outer_axis.axis.name.literal»No)); |
| ''' |
| } |
| body = ''' |
| «body» dataSeries.add(«inner_axis.axis.name.literal»DataSeries.toArray()); |
| ''' |
| } |
| body = ''' |
| «body» } |
| «outer_axis.axis.name.literal»No ++; |
| } |
| ''' |
| body = ''' |
| «body»SeriesDefaults seriesDefaults = new SeriesDefaults() |
| .setRenderer(SeriesRenderers.«chartType»); |
| ''' |
| if (chart.charttype instanceof ChartLine) { |
| body = ''' |
| «body»seriesDefaults.setFillToZero(«(chart.charttype as ChartLine).fillToZero.booleanValue.toString»).setFill(«(chart.charttype as ChartLine).fillArea.toString»); |
| ''' |
| if ((chart.charttype as ChartLine).trendLine) { |
| body = ''' |
| «body»seriesDefaults.setTrendline( |
| new Trendline().setShow(true).setLineWidth(1)); |
| ''' |
| } |
| } |
| // options |
| body = ''' |
| «body»Options options = new Options() |
| .setSeriesDefaults(seriesDefaults); |
| ''' |
| if (chart.charttype instanceof ChartPie) { |
| body = ''' |
| «body»seriesDefaults.setRendererOptions(new PieRenderer() |
| .setShowDataLabels(true).setFill(«(!(chart.charttype as ChartPie).empty).toString»)); |
| ''' |
| } |
| else if (chart.charttype instanceof ChartDonut) { |
| body = ''' |
| «body»seriesDefaults.setRendererOptions(new DonutRenderer() |
| .setShowDataLabels(true) |
| .setStartAngle(-90) |
| .setSliceMargin(3)); |
| ''' |
| } |
| else if (chart.charttype instanceof ChartBubble) { |
| body = ''' |
| «body»seriesDefaults.setRendererOptions(new BubbleRenderer() |
| .setVaryBubbleColors(true) |
| «IF (chart.charttype as ChartBubble).multiplier».setAutoscaleMultiplier(«(chart.charttype as ChartBubble).multiplierValue»f)«ENDIF» |
| «IF (chart.charttype as ChartBubble).transparent».setHighlightAlpha(0.8f).setBubbleAlpha(0.6f)«ENDIF» |
| «IF (chart.charttype as ChartBubble).gradient».setBubbleGradients(true)«ENDIF» |
| .setShowLabels(false) |
| .setAutoscaleBubbles(true)); |
| ''' |
| } |
| else if (chart.charttype instanceof ChartGauge) { |
| var intervalValues = "" |
| var intervalColors = "" |
| if ((chart.charttype as ChartGauge).hasIntervals) { |
| for (interval : (chart.charttype as ChartGauge).intervals) { |
| if (interval instanceof ChartNumberInterval) { |
| intervalValues = '''«intervalValues»«IF intervalValues.length>0»,«ENDIF»«(interval as ChartNumberInterval).numberIntervalValue»f''' |
| if ((interval as ChartNumberInterval).numberRange instanceof ChartSegmentColor) { |
| intervalColors = '''«intervalColors»«IF intervalColors.length>0»,«ENDIF»"«((interval as ChartNumberInterval).numberRange as ChartSegmentColor).rgb.toHex»"''' |
| } |
| } |
| } |
| } |
| body = ''' |
| «body»seriesDefaults.setRendererOptions(new MeterGaugeRenderer() |
| .setShowTickLabels(«(chart.charttype as ChartGauge).hasTicks.toString») |
| «IF (chart.charttype as ChartGauge).labeled».setLabel("«(chart.charttype as ChartGauge).labelValue»")«ENDIF» |
| «IF (chart.charttype as ChartGauge).hasIntervals».setIntervals(«intervalValues»)«ENDIF» |
| «IF (chart.charttype as ChartGauge).hasIntervals».setIntervalColors(«intervalColors»)«ENDIF»); |
| ''' |
| } |
| else if (chart.charttype instanceof ChartBar) { |
| body = ''' |
| «body»seriesDefaults.setFillToZero(true); |
| seriesDefaults.setRendererOptions(new BarRenderer() |
| «IF axisSwitch».setBarDirection(BarDirections.HOTIZONTAL));«ELSE».setBarDirection(BarDirections.VERTICAL));«ENDIF» |
| ''' |
| if ((chart.charttype as ChartBar).stacked) { |
| body = ''' |
| «body»options.setStackSeries(true); |
| ''' |
| } |
| if ((chart.charttype as ChartBar).shadow) { |
| body = ''' |
| «body»seriesDefaults.setShadow(true).setShadowAlpha(0.05f); |
| ''' |
| } |
| if ((chart.charttype as ChartBar).animated) { |
| body = ''' |
| «body»options.setAnimate(true); |
| ''' |
| } |
| } |
| body = ''' |
| «body» |
| String[] seriesColors = {"#98E958","#3090F0","#EC6464","#F9DD51","#24DCD4","#EC64A5","#685CB0","#FF7D42","#AA514D","#7FB053","#BBA85B","#247981"}; |
| ««« String[] seriesColors = {"#0000FF","#FF0000","#00FF00","#FFFF00","#FF00FF","#00FFFF","#FF4500","#008000","#00BFFF","#FF69B4","#FFD700","#000080"}; |
| options.setSeriesColors(seriesColors); |
| ''' |
| if (hasAxis) { |
| // axes |
| body = ''' |
| «body»Axes axes = new Axes(); |
| ''' |
| if (chart.charttype instanceof ChartBubble) { |
| // x |
| body = ''' |
| «body»CanvasAxisTickRenderer axisTickRenderer = new CanvasAxisTickRenderer(); |
| axisTickRenderer.setTextColor("#202020"); |
| if («data_axis.axis.name.literal»TitlesArray.size() > 0) { |
| axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(0)»).setLabel(«data_axis.axis.name.literal»TitlesArray.get(0)).setTickOptions(axisTickRenderer«IF category_axis.angle!=0».setAngle(«data_axis.angle»)«ENDIF»)); |
| axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(1)»).setLabel(«data_axis.axis.name.literal»TitlesArray.get(1)).setTickOptions(axisTickRenderer«IF category_axis.angle!=0».setAngle(«data_axis.angle»)«ENDIF»)); |
| axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(1)»2).setLabel(«data_axis.axis.name.literal»TitlesArray.get(2)).setTickOptions(axisTickRenderer«IF category_axis.angle!=0».setAngle(«data_axis.angle»)«ENDIF»)); |
| } |
| ''' |
| } |
| else { |
| // x |
| body = ''' |
| «body»CanvasAxisTickRenderer tickRenderer = new CanvasAxisTickRenderer(); |
| tickRenderer.setTextColor("#202020"); |
| axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(0)») |
| .setRenderer(AxisRenderers.«category_axis.renderType.name().toString») |
| .setLabel(«category_axis.axis.name.literal»AxisLabel) |
| .setTicks(«category_axis.axis.name.literal»Ticks) |
| .setTickOptions(tickRenderer«IF category_axis.angle!=0».setAngle(«category_axis.angle»)«ENDIF»)); |
| ''' |
| // y .. y9 |
| body = ''' |
| «body»CanvasAxisTickRenderer axisTickRenderer = new CanvasAxisTickRenderer(); |
| axisTickRenderer.setTextColor("#202020"); |
| axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(1)») |
| .setPad(1.05f) |
| .setTickOptions(axisTickRenderer«IF data_axis.angle!=0».setAngle(«data_axis.angle»)«ENDIF»)); |
| ''' |
| // additional axes |
| for (axisKey : multipleAxes.keySet) { |
| if (!axisKey.equals("1")) { |
| body = '''«body»«multipleAxes.get(axisKey)»''' |
| } |
| } |
| if (multipleAxes.keySet.size > 0) { |
| body = ''' |
| «body»LinearAxisRenderer linearAxisRenderer = new LinearAxisRenderer(); |
| linearAxisRenderer.setAlignTicks(true); |
| AxesDefaults axesDefaults = new AxesDefaults() |
| .setUseSeriesColor(true) |
| .setBorderWidth(3) |
| .setRendererOptions(linearAxisRenderer); |
| options.setAxesDefaults(axesDefaults); |
| ''' |
| } |
| } |
| body = ''' |
| «body»options.setAxes(axes); |
| ''' |
| } |
| // legend |
| for (element : chart.source.elements) { |
| if (element instanceof ChartLegend) { |
| var legend = element as ChartLegend |
| body = ''' |
| «body»Legend legend = new Legend().setShow(«(legend !== null).booleanValue.toString»); |
| ''' |
| body = ''' |
| «body»legend.setPlacement(LegendPlacements.«legend.placement.name()»); |
| ''' |
| if (legend.toggle) { |
| body = ''' |
| «body»EnhancedLegendRenderer renderer = new EnhancedLegendRenderer(); |
| renderer.setSeriesToggle(SeriesToggles.«legend.toggleType.getName»); |
| renderer.setSeriesToggleReplot(«legend.replot.booleanValue.toString»); |
| legend.setRendererOptions(renderer); |
| ''' |
| } |
| body = ''' |
| «body»options.setLegend(legend); |
| ''' |
| } |
| } |
| |
| // highlighter |
| for (element : chart.source.elements) { |
| if (element instanceof ChartHighlighter) { |
| var highlighter = element as ChartHighlighter |
| body = ''' |
| «body»Highlighter highlighter = new Highlighter().setShow(«(highlighter !== null).booleanValue.toString»); |
| ''' |
| body = ''' |
| «body»highlighter.setShowTooltip(true) |
| .setTooltipAlwaysVisible(«highlighter.tooltipAlways.booleanValue.toString») |
| .setKeepTooltipInsideChart(«highlighter.insideChart.booleanValue.toString») |
| .setTooltipLocation(TooltipLocations.«highlighter.location.name()») |
| .setBringSeriesToFront(true) |
| .setFadeTooltip(true) |
| .setShowMarker(true); |
| ''' |
| body = ''' |
| «body»highlighter.setTooltipAxes(TooltipAxes.«axisPrefix»«postfix»); |
| ''' |
| body = ''' |
| «body»options.setHighlighter(highlighter); |
| ''' |
| } |
| } |
| |
| // cursor |
| if (chart.charttype instanceof ChartLine) { |
| if ((chart.charttype as ChartLine).cursor) { |
| body = ''' |
| «body»Cursor cursor = new Cursor() |
| .setShow(true) |
| .setZoom(«(chart.charttype as ChartLine).zoom.toString») |
| .setShowTooltip(«(chart.charttype as ChartLine).tooltip.toString»); |
| options.setCursor(cursor); |
| ''' |
| } |
| if ((chart.charttype as ChartLine).animated) { |
| body = ''' |
| «body»options.setAnimate(true); |
| ''' |
| } |
| } |
| if (hasAxis) { |
| // series |
| body = ''' |
| «body»options.setSeries(«data_axis.axis.name.literal»Series); |
| ''' |
| } |
| body = ''' |
| «body»DCharts chart = new DCharts(); |
| chart.setDataSeries(dataSeries); |
| chart.setOptions(options); |
| ««« chart.setEnableDownload(true); |
| ««« chart.setDownloadButtonCaption(dslMetadataService.translate(user.getLocale().toLanguageTag(), "download")); |
| ««« chart.setDownloadFilename("«chart.name»"); |
| ««« chart.setDownloadButtonLocation(DownloadButtonLocation.TOP_RIGHT); |
| chart.setEnableChartImageChangeEvent(true); |
| ''' |
| body = ''' |
| «body»chart.setId("chart"); |
| chart.setImmediate(true); |
| chart.show(); |
| charts.add(chart); |
| ''' |
| if (chart.toolbar !== null && chart.toolbar.eContainer !== null) { |
| body = ''' |
| «body» |
| for (MToolBarElement element : toolbarClass.getToolBar().getChildren()) { |
| Object widget = element.getWidget(); |
| if (widget instanceof Button) { |
| List<String> tags = element.getTags(); |
| if (tags.contains(ChartActionEnum.CHART_ACTION_DOWNLOAD.getLiteral())) { |
| FileDownloader fileDownloader = new FileDownloader(getChartResource(chart, layoutManager)); |
| fileDownloader.extend((Button) widget); |
| } |
| } |
| }''' |
| } |
| body = ''' |
| «body»return chart;''' |
| return body |
| } |
| |
| /** |
| * <p>helper method to convert a rgb string to a hex string.</p> |
| * |
| */ |
| def String toHex(String rgb) { |
| var colorHex = "#" |
| for (color : rgb.split(",")) { |
| var i = new Integer(color); |
| colorHex = '''«colorHex»«String::format("%02x", i)»''' |
| } |
| return colorHex |
| } |
| |
| /** |
| * <p>build the label series. Create multiple y-axes when the underlying datamart presents different scales.</p> |
| * |
| * <p>scales are used to display line charts together for comparison reason but they are of different scalings.</p> |
| */ |
| def String createLabelSeries(Chart chart, ChartAxis data_axis, HashMap<String,String>multipleAxes, String axisPrefix, boolean showMarker) { |
| var body = "" |
| var msrCnt = 0 |
| // find multiple axes defined in datamart |
| if ((chart.source as ChartDatamart).datamartRef.source instanceof DatamartCube) { |
| for (axisOrSlicer : ((chart.source as ChartDatamart).datamartRef.source as DatamartCube).axisslicer) { |
| if (axisOrSlicer instanceof DatamartCubeAxis) { |
| for (element : (axisOrSlicer as DatamartCubeAxis).elements) { |
| if (element instanceof DatamartDerivedMeasure) { |
| if ((element as DatamartDerivedMeasure).scaled) { |
| body = '''«body»«(element as DatamartDerivedMeasure).scale.createScale(data_axis, multipleAxes, msrCnt, axisPrefix, showMarker)»''' |
| msrCnt = msrCnt + 1 |
| } |
| } |
| if (element instanceof DatamartMeasure) { |
| if ((element as DatamartMeasure).scaled) { |
| body = '''«body»«(element as DatamartMeasure).scale.createScale(data_axis, multipleAxes, msrCnt, axisPrefix, showMarker)»''' |
| msrCnt = msrCnt + 1 |
| } |
| } |
| } |
| } |
| } |
| } |
| else if ((chart.source as ChartDatamart).datamartRef.source instanceof DatamartEntity) { |
| var entity = ((chart.source as ChartDatamart).datamartRef.source as DatamartEntity) |
| body = '''«body»«entity.entityScale(data_axis, multipleAxes, msrCnt, axisPrefix, showMarker)»''' |
| } |
| // no multiple axes defined in datamart |
| if (multipleAxes.keySet.size == 0) { |
| body = ''' |
| «body» for (String title : «data_axis.axis.name.literal»TitlesArray) { |
| «data_axis.axis.name.literal»Series.addSeries(new XYseries().setLabel(title).setShowMarker(«showMarker.toString»)); |
| } |
| ''' |
| } |
| return body |
| } |
| |
| /** |
| * <p>helper method for scales coming from datamart entities not from cubes.</p> |
| * |
| */ |
| def String entityScale(DatamartEntity entity, ChartAxis data_axis, HashMap<String,String> multipleAxes, int msrCnt, String axisPrefix, boolean showMarker) { |
| var counter = msrCnt |
| var body = "" |
| for (attribute : entity.attributes) { |
| if (attribute instanceof DatamartAttribute) { |
| if (attribute.scaled) { |
| body = '''«body»«attribute.scale.createScale(data_axis, multipleAxes, counter, axisPrefix, showMarker)»''' |
| counter = counter + 1 |
| } |
| } |
| } |
| for (navigation : entity.navigations) { |
| if (navigation instanceof DatamartMember) { |
| body = '''«body»«(navigation as DatamartMember).datamartEntity.entityScale(data_axis, multipleAxes, counter, axisPrefix, showMarker)»''' |
| } |
| if (navigation instanceof DatamartOwner) { |
| body = '''«body»«(navigation as DatamartOwner).datamartEntity.entityScale(data_axis, multipleAxes, counter, axisPrefix, showMarker)»''' |
| } |
| } |
| return body |
| } |
| |
| /** |
| * <p>helper method for scales.</p> |
| * |
| */ |
| def String createScale(ValueScaleEnum scale, ChartAxis data_axis, HashMap<String,String> multipleAxes, int msrCnt, String axisPrefix, boolean showMarker) { |
| var multipleBody = "" |
| var body = "" |
| var scaleOrdinal = scale.ordinal |
| var scaleName = scale.toString |
| body = ''' |
| «body» |
| «data_axis.axis.name.literal»Series.addSeries(new XYseries(«axisPrefix.charAt(1)»axes.«axisPrefix.charAt(1)»«IF scaleOrdinal != 0»«(scaleOrdinal+1)»«ENDIF»).setLabel(«data_axis.axis.name.literal»TitlesArray.get(«msrCnt»)).setShowMarker(«showMarker.toString»)); |
| ''' |
| if (!multipleAxes.keySet.contains(scaleName)) { |
| // axis 1 is never expressed, but 2..9 |
| multipleBody = |
| '''axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(1)»«IF scaleOrdinal != 0»«(scaleOrdinal+1)»«ENDIF»).setTickOptions(axisTickRenderer«IF data_axis.angle!=0».setAngle(«data_axis.angle»)«ENDIF»)); |
| ''' |
| multipleAxes.put(scaleName, multipleBody) |
| } |
| return body |
| } |
| |
| /** |
| * <p>helper method to get a attribute name or its alias if present of a entity's attribute object.</p> |
| * |
| */ |
| def String getAttributeName(DatamartAttribute attribute) { |
| return (attribute.attributeRef as LAttribute).name.toUpperCase |
| } |
| |
| /** |
| * <p>helper method to get a level name of a hierarchy's level object.</p> |
| * |
| */ |
| def String getLevelName(CubeLevel level) { |
| return level.name |
| } |
| |
| def String filterChanged(Chart chart) { |
| var body = "" |
| body = ''' |
| «body» |
| if(changedFilter != null) { |
| MPerspective perspective = getContext().get(MPerspective.class); |
| EventDispatcherEvent evnt = new EventDispatcherEvent(perspective, EventDispatcherCommand.SELECT, changedFilter.getName(), "«chart.name»"); |
| evnt.addData(changedFilter.getSelectedData()); |
| eventDispatcher.sendEvent(evnt); |
| } |
| renderData(); |
| ''' |
| return body |
| } |
| |
| def Set<LEntity> findRequestedEntities(Chart chart) { |
| var entities = new HashSet<LEntity>() |
| entities.addAll((chart.source as ChartDatamart).datamartRef.findAllEntities()) |
| return entities |
| } |
| |
| def String receiveEvent(Chart chart) { |
| var body = "" |
| body = ''' |
| «body» |
| switch(event.getCommand()) { |
| case SELECT: |
| MPerspective perspective = getContext().get(MPerspective.class); |
| if(event.getPerspective() == null || (perspective != null && event.getPerspective().equals(perspective))){ |
| if(!event.getSender().equals("«chart.fullyQualifiedName»")) { |
| if(filterGenerator.selectItem(event, «chart.selectById.booleanValue»)) { |
| renderData(); |
| } |
| } |
| } |
| break; |
| case SAVE: |
| case DELETE: |
| if(!event.getSender().equals("«chart.fullyQualifiedName»")) { |
| «FOR e:findRequestedEntities(chart)» |
| if(event.getTopic().equals("«e.fullyQualifiedName»")){ |
| datamartInstance.clearCache(); |
| renderData(); |
| } |
| «ENDFOR» |
| } |
| break; |
| case REFRESH: |
| if(!event.getSender().equals("«chart.fullyQualifiedName»")) { |
| «FOR e:findRequestedEntities(chart)» |
| if(event.getTopic().equals("«e.fullyQualifiedName»")){ |
| datamartInstance.clearCache(); |
| renderData(); |
| } |
| «ENDFOR» |
| } |
| /* must be activated if sure that the filter is to be refreshed |
| if (filterGenerator != null) { |
| filterGenerator.updateFilter(); |
| }*/ |
| break; |
| } |
| ''' |
| return body |
| } |
| |
| def localeChanged(Chart chart) |
| ''' |
| if(charts != null) { |
| for(DCharts chart:charts) { |
| chart.setLocale(locale); |
| «IF chart.source.datamartRef.description && |
| chart.source.datamartRef.descriptionValue !== null» |
| chart.setDescription(dslMetadataService.translate(locale.toLanguageTag(), "«chart.source.datamartRef.descriptionValue»")); |
| ««« chart.setDownloadButtonCaption(dslMetadataService.translate(locale.toLanguageTag(), "download")); |
| «ENDIF» |
| } |
| } |
| if(layoutManager != null) { |
| layoutManager.setLabelValue(dslMetadataService.translate(locale.toLanguageTag(), "«chart.name»")); |
| } |
| ''' |
| |
| def chartResource(Chart chart) |
| ''' |
| return new StreamResource(new StreamSource() { |
| private static final long serialVersionUID = -6463786579404065302L; |
| @Override |
| public InputStream getStream() { |
| try { |
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
| ImageIO.write(chart.getChartImage(), chart.getChartImageFormat() |
| .getFormat(), bos); |
| return new ByteArrayInputStream(bos.toByteArray()); |
| } catch (Exception e) { |
| return new ByteArrayInputStream("".getBytes()); |
| } |
| } |
| }, layoutManager.getCaption() + chart.getChartImageFormat().getFormatExtension()); |
| ''' |
| |
| def void createJsJavaComponent(Chart chart, IJvmDeclaredTypeAcceptor acceptor){ |
| val stateClassName = chart.createStateFilename |
| var chart_cls = chart.toClass(chart.createfullyQualifiedChartFilename) |
| // JavaScript-Java-State-Component creation |
| var state_cls = chart.toClass(chart.createfullyQualifiedStateFilename) |
| if (chart.charttype instanceof ChartTree){ |
| val ChartTree chartTree = chart.charttype as ChartTree |
| // JavaScript-Java-Component creation |
| acceptor.accept(chart_cls) |
| .initializeLater([ |
| superTypes += _typeReferenceBuilder.typeRef(AbstractJavaScriptComponent) |
| var JvmAnnotationReference jsAnnotationRef = chartTree.toAnnotation(typeof(JavaScript)) |
| var jsAnnotationList = newArrayList( |
| "theme://plugin/org.eclipse.osbp.utils.js/org/eclipse/osbp/utils/js/d3.js", |
| "theme://plugin/org.eclipse.osbp.utils.js/org/eclipse/osbp/utils/js/d3-scale-chromatic.js", |
| chart.createChartJsFilename |
| ) |
| jsAnnotationRef.addStringValuesToAnnotation(jsAnnotationList) |
| annotations += jsAnnotationRef |
| if (chartTree.map){ |
| it.toTreeMapConstructor(chart) |
| } else if (chartTree.collapsible) { |
| it.toChartConstructor(chart) |
| } |
| it.toChartOperations(chart, stateClassName) |
| ]) |
| // JavaScript-Java-State-Component creation |
| acceptor.accept(state_cls) |
| .initializeLater([ |
| superTypes += _typeReferenceBuilder.typeRef(JavaScriptComponentState) |
| if (chartTree.map){ |
| it.toTreeMapStateFields(chart) |
| } else if (chartTree.collapsible) { |
| it.toChartStateFields(chart) |
| } |
| ]) |
| } |
| } |
| |
| def void toChartOperations(JvmDeclaredType type, Chart chart, String stateClassName){ |
| // create view |
| type.members += chart.toMethod("getState", _typeReferenceBuilder.typeRef(stateClassName), [ |
| body = [ append('''return («stateClassName») super.getState();''')] |
| ]) |
| |
| } |
| |
| def getD3StateVars() |
| ''' |
| getState().jsonData = _jsonData; |
| getState().htmlTagId=_htmlTagId; |
| getState().panelWidth = new Integer(width).toString(); |
| getState().panelHeight = new Integer(height).toString(); |
| ''' |
| |
| def JvmConstructor getChartConstructor(JvmDeclaredType type, Chart chart) { |
| return chart.toConstructor([ |
| parameters += chart.toParameter("_htmlTagId", _typeReferenceBuilder.typeRef(String)) |
| parameters += chart.toParameter("_jsonData", _typeReferenceBuilder.typeRef(String)) |
| parameters += chart.toParameter("width", _typeReferenceBuilder.typeRef(int)) |
| parameters += chart.toParameter("height", _typeReferenceBuilder.typeRef(int)) |
| body = [ append(getD3StateVars)] |
| ]) |
| } |
| |
| def void toTreeMapConstructor(JvmDeclaredType type, Chart chart) { |
| var JvmConstructor constructor = type.getChartConstructor(chart) |
| constructor.parameters += chart.toParameter("dataColumns", _typeReferenceBuilder.typeRef(List, _typeReferenceBuilder.typeRef(String))) |
| constructor.body = [ append( |
| ''' |
| «d3StateVars» |
| getState().dataColumnList = dataColumns;''')] |
| type.members += constructor |
| } |
| |
| def void toChartConstructor(JvmDeclaredType type, Chart chart) { |
| var JvmConstructor constructor = type.getChartConstructor(chart) |
| type.members += constructor |
| } |
| |
| def void addStringValuesToAnnotation(JvmAnnotationReference annotationRef, ArrayList<String> annotationStringList){ |
| var JvmStringAnnotationValue value = typesFactory.createJvmStringAnnotationValue |
| for (annotationString : annotationStringList){ |
| value.values += annotationString |
| } |
| annotationRef.explicitValues += value |
| } |
| |
| def void toTreeMapStateFields(JvmDeclaredType type, Chart chart){ |
| type.toChartStateFields(chart) |
| type.members += chart.toField("dataColumnList", _typeReferenceBuilder.typeRef(List, _typeReferenceBuilder.typeRef(String)))[ |
| visibility = JvmVisibility::PUBLIC |
| setInitializer([append('''new ArrayList<String>()''')])] |
| } |
| |
| def void toChartStateFields(JvmDeclaredType type, Chart chart){ |
| type.members += chart.toField("jsonData", _typeReferenceBuilder.typeRef(String))[ |
| visibility = JvmVisibility::PUBLIC |
| setInitializer([append('''""''')])] |
| type.members += chart.toField("htmlTagId", _typeReferenceBuilder.typeRef(String))[ |
| visibility = JvmVisibility::PUBLIC |
| setInitializer([append('''""''')])] |
| type.members += chart.toField("panelWidth", _typeReferenceBuilder.typeRef(String)) [ |
| visibility = JvmVisibility::PUBLIC |
| setInitializer([append('''""''')]) |
| ] |
| type.members += chart.toField("panelHeight", _typeReferenceBuilder.typeRef(String)) [ |
| visibility = JvmVisibility::PUBLIC |
| setInitializer([append('''""''')]) |
| ] |
| type.members += chart.toField("inputValue", _typeReferenceBuilder.typeRef(String))[ |
| visibility = JvmVisibility::PUBLIC |
| setInitializer([append('''""''')])] |
| } |
| |
| def createD3Chart(Chart chart) |
| ''' |
| CellSetToD3JsonConverter jsonConverter = new CellSetToD3JsonConverter(); |
| return new «val d3ChartFileName = chart.createChartFilename»«d3ChartFileName»("«d3ChartFileName»", jsonConverter.getD3JsonString(cxCellSet, «IF chart.charttype instanceof ChartTree && (chart.charttype as ChartTree).collapsible»true«ELSE»false«ENDIF»), panelWidth, panelHeight«IF chart.treeMap», jsonConverter.getDataColumnNameList(cxCellSet)«ENDIF»);''' |
| } |