| /** |
| * |
| * Copyright (c) 2011, 2019 - 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 |
| * |
| */ |
| package org.eclipse.osbp.xtext.datamart.common.olap; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| |
| import elemental.json.JsonFactory; |
| import elemental.json.impl.JreJsonArray; |
| import elemental.json.impl.JreJsonFactory; |
| import elemental.json.impl.JreJsonObject; |
| |
| public class CellSetToD3JsonConverter { |
| |
| private static final String KEY_CHILDREN="children"; |
| private static final String KEY_NAME="name"; |
| private static final String KEY_TOOLTIPNAME="tooltipName"; |
| private static JsonFactory factory = new JreJsonFactory(); |
| |
| public CellSetToD3JsonConverter() { |
| } |
| |
| public static String getD3JsonString(DerivedCellSet cxCellSet, boolean noMeasures) { |
| // generate a new result component |
| if (cxCellSet == null) { |
| return ""; |
| } |
| ArrayList<Integer> coordinateSystem = new ArrayList<>(); |
| // create a multidimensional coordinate system against the cellSet |
| for (int axis = 0; axis < cxCellSet.getAxes().size(); axis++) { |
| coordinateSystem.add(0); |
| } |
| List<Integer> coordinate = new ArrayList<>(coordinateSystem); |
| // add styles to page for the axis's custom styles |
| List<String> dataColumns = getDataColumnNameList(cxCellSet); |
| |
| Node root = new Node(); |
| // for every data row |
| for (DerivedPosition rows : cxCellSet.getAxes().get(1).getPositions()) { |
| // row Data |
| coordinate.set(1, rows.getOrdinal()); |
| // fill in the row members for the row axis |
| for (DerivedMember member : rows.getMembers()) { |
| String qualifiedName = member.getUniqueName().replace("[", "").replace("]", ""); |
| if(!noMeasures) { |
| JreJsonObject childrenListMap = new JreJsonObject(factory); |
| // create a concatenated name of all members for the data column |
| childrenListMap.put(KEY_TOOLTIPNAME, qualifiedName.replace(".", "-")); |
| childrenListMap.put(KEY_NAME, member.getCaption()); |
| for (DerivedPosition columns : cxCellSet.getAxes().get(0).getPositions()) { |
| coordinate.set(0, columns.getOrdinal()); |
| childrenListMap.put(dataColumns.get(columns.getOrdinal()), ((Double)cxCellSet.getCell(coordinate).getValue()).toString()); |
| } |
| addToHierachy(root, qualifiedName.split("\\."), childrenListMap); |
| } |
| addToHierachy(root, qualifiedName.split("\\."), null); |
| } |
| } |
| |
| JreJsonArray json = convertToJSON(root); |
| String result = json.toJson().toString(); |
| return result.substring(1, result.length()-1); |
| } |
| |
| public static List<String> getDataColumnNameList(DerivedCellSet cxCellSet) { |
| // create a table column for all data column |
| List<String> dataColumns = new LinkedList<>(); |
| for (DerivedPosition columns : cxCellSet.getAxes().get(0).getPositions()) { |
| String title = null; |
| for (DerivedMember member : columns.getMembers()) { |
| if (title == null) { |
| title = member.getCaption(); |
| } |
| else { |
| title += " "+member.getCaption(); |
| } |
| } |
| dataColumns.add(title); |
| } |
| return dataColumns; |
| } |
| |
| private static void addToHierachy(Node root, Object[] row, JreJsonObject valueMap) { |
| Node current = root; |
| |
| // Go through each column in the row |
| for(Object col : row) { |
| // this is the last row element, so add the values |
| current = current.getOrCreateChild((String) col); |
| if(valueMap != null && col.equals(row[row.length-1])) { |
| current.setValueMap(valueMap); |
| } |
| } |
| } |
| |
| private static JreJsonArray convertToJSON(Node root) { |
| // Use recursion to build the result JSON |
| JreJsonArray array = new JreJsonArray(factory); |
| |
| // Starting at this root, go through all of the child entries |
| for(Map.Entry<String, Node> child : root.getChildren().entrySet()) { |
| Node childNode = child.getValue(); |
| |
| // New object for this entry... |
| JreJsonObject object = new JreJsonObject(factory); |
| // Set the name |
| object.put(KEY_NAME, child.getKey()); |
| |
| // Set the value if it is present on this node |
| if(childNode.getValueMap() != null) { |
| JreJsonArray values = new JreJsonArray(factory); |
| values.set(0, childNode.getValueMap()); |
| object.put(KEY_CHILDREN, values); |
| } |
| |
| // Generate the child hierarchy if it has children |
| if(!childNode.getChildren().isEmpty()) { |
| JreJsonArray childHierachy = convertToJSON(childNode); |
| object.put(KEY_CHILDREN, childHierachy); |
| } |
| |
| array.set(array.length(), object); |
| } |
| |
| return array; |
| } |
| |
| // Class used to build the hierarchy |
| static class Node { |
| // The map of children, LABEL -> NODE |
| private Map<String, Node> children = new HashMap<>(); |
| private JreJsonObject valueMap; |
| |
| public Node getOrCreateChild(String key) { |
| Node node = children.get(key); |
| |
| if(node == null) { |
| node = new Node(); |
| children.put(key, node); |
| } |
| |
| return node; |
| } |
| |
| public Map<String, Node> getChildren() { |
| return children; |
| } |
| |
| public JreJsonObject getValueMap() { |
| return valueMap; |
| } |
| |
| public void setValueMap(JreJsonObject valueMap) { |
| this.valueMap = valueMap; |
| } |
| } |
| } |