blob: 1c1c8dd36d6ab0ba095f719e0ce9ef36321721a4 [file] [log] [blame]
/**
*
* 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;
}
}
}