14 changed files with 3777 additions and 5 deletions
@ -0,0 +1,46 @@ |
|||||||
|
package com.fr.design.chart.auto; |
||||||
|
|
||||||
|
import com.fr.data.AbstractDataModel; |
||||||
|
import com.fr.general.data.DataModel; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bjorn |
||||||
|
* @version 10.0 |
||||||
|
* Created by Bjorn on 2020-06-16 |
||||||
|
*/ |
||||||
|
public class AutoChartDataModel extends AbstractDataModel { |
||||||
|
|
||||||
|
public List<ColumnInfo> columnInfoList; |
||||||
|
|
||||||
|
public AutoChartDataModel(List<ColumnInfo> columnInfos) { |
||||||
|
this.columnInfoList = columnInfos; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getColumnCount() { |
||||||
|
return columnInfoList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getColumnName(int index) { |
||||||
|
if (index >= columnInfoList.size()) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return columnInfoList.get(index).getColumnName(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getRowCount() { |
||||||
|
return columnInfoList.get(0).getValues().size(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getValueAt(int rowIndex, int columnIndex) { |
||||||
|
if (columnIndex == DataModel.COLUMN_NAME_NOT_FOUND || columnIndex >= columnInfoList.size()) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return columnInfoList.get(columnIndex).getValues().get(rowIndex); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,142 @@ |
|||||||
|
package com.fr.design.chart.auto; |
||||||
|
|
||||||
|
import com.fr.data.TableDataSource; |
||||||
|
import com.fr.data.TableDataSourceTailor; |
||||||
|
import com.fr.data.impl.EmbeddedTableData; |
||||||
|
import com.fr.data.impl.NameTableData; |
||||||
|
import com.fr.design.chart.auto.strategy.AutoTypeStrategy; |
||||||
|
import com.fr.design.chart.auto.strategy.imp.AvaStrategy; |
||||||
|
import com.fr.design.chart.auto.strategy.imp.BubbleChartStrategy; |
||||||
|
import com.fr.design.chart.auto.strategy.imp.SingleDimensionStrategy; |
||||||
|
import com.fr.design.chart.auto.strategy.imp.SingleTargetStrategy; |
||||||
|
import com.fr.design.data.DesignTableDataManager; |
||||||
|
import com.fr.design.file.HistoryTemplateListCache; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.general.GeneralUtils; |
||||||
|
import com.fr.general.data.DataModel; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.plugin.chart.vanchart.VanChart; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bjorn |
||||||
|
* @version 10.0 |
||||||
|
* Created by Bjorn on 2020-05-08 |
||||||
|
*/ |
||||||
|
public class AutoTypeCalculate { |
||||||
|
|
||||||
|
public static List<VanChart> calculateType(String tableName, List<String> columns) { |
||||||
|
List<ColumnInfo> columnValue = calculateField(tableName, columns); |
||||||
|
if (columnValue.isEmpty()) { |
||||||
|
return new ArrayList<>(); |
||||||
|
} |
||||||
|
|
||||||
|
List<ColumnInfo> dimensions = new ArrayList<>(); |
||||||
|
List<ColumnInfo> targets = new ArrayList<>(); |
||||||
|
for (ColumnInfo field : columnValue) { |
||||||
|
if (isTarget(field.getValues())) { |
||||||
|
targets.add(field); |
||||||
|
} else { |
||||||
|
dimensions.add(field); |
||||||
|
} |
||||||
|
} |
||||||
|
AutoTypeStrategy autoTypeStrategy = chooseStrategy(dimensions.size(), targets.size()); |
||||||
|
return autoTypeStrategy.rankChart(tableName, dimensions, targets); |
||||||
|
} |
||||||
|
|
||||||
|
private static AutoTypeStrategy chooseStrategy(int dimensionSize, int targetSize) { |
||||||
|
if (dimensionSize == 0) { |
||||||
|
//没有维度,并且只有一个指标,使用单指标匹配逻辑,大于1个指标,使用气泡图(散点图)匹配逻辑
|
||||||
|
if (targetSize == 1) { |
||||||
|
return new SingleTargetStrategy(); |
||||||
|
} else { |
||||||
|
return new BubbleChartStrategy(); |
||||||
|
} |
||||||
|
} else if (dimensionSize == 1) { |
||||||
|
//1个维度,并且没有指标,使用单维度匹配,2~3个指标,使用气泡图(散点图)匹配逻辑,其余使用ava匹配
|
||||||
|
if (targetSize == 0) { |
||||||
|
return new SingleDimensionStrategy(); |
||||||
|
} else if (targetSize == 2 || targetSize == 3) { |
||||||
|
return new BubbleChartStrategy(); |
||||||
|
} else { |
||||||
|
return new AvaStrategy(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
//大与1个维度,并且没有指标,使用单维度匹配(循环),否则使用ava匹配
|
||||||
|
if (targetSize == 0) { |
||||||
|
return new SingleDimensionStrategy(); |
||||||
|
} else { |
||||||
|
return new AvaStrategy(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean isTarget(List<String> values) { |
||||||
|
for (String value : values) { |
||||||
|
if (StringUtils.isEmpty(value)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
Number number = GeneralUtils.string2Number(value); |
||||||
|
if (number == null) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private static List<ColumnInfo> calculateField(String tableName, List<String> columns) { |
||||||
|
NameTableData nameTableData = new NameTableData(tableName); |
||||||
|
TableDataSource dataSource = TableDataSourceTailor.extractTableData(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getTarget()); |
||||||
|
Calculator calculator = Calculator.createCalculator(); |
||||||
|
calculator.setAttribute(TableDataSource.KEY, dataSource); |
||||||
|
nameTableData.createTableData(calculator); |
||||||
|
|
||||||
|
EmbeddedTableData tableData; |
||||||
|
try { |
||||||
|
tableData = DesignTableDataManager.previewTableDataNeedInputParameters(dataSource, nameTableData, Integer.MAX_VALUE, false); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
return new ArrayList<>(); |
||||||
|
} |
||||||
|
|
||||||
|
List<ColumnInfo> originalData = new ArrayList<>(); |
||||||
|
for (String column : columns) { |
||||||
|
List<String> columnData = getColumnData(tableData, column); |
||||||
|
if (columnData != null && !columnData.isEmpty()) { |
||||||
|
originalData.add(new ColumnInfo(column, columnData)); |
||||||
|
} |
||||||
|
} |
||||||
|
return originalData; |
||||||
|
} |
||||||
|
|
||||||
|
private static List<String> getColumnData(EmbeddedTableData tableData, String columnName) { |
||||||
|
int colIndex = getColIndex(tableData, columnName); |
||||||
|
|
||||||
|
if (colIndex == DataModel.COLUMN_NAME_NOT_FOUND) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
int size = tableData.getRowCount(); |
||||||
|
List<String> columnData = new ArrayList<>(); |
||||||
|
for (int i = 0; i < size; i++) { |
||||||
|
Object valueAt = tableData.getValueAt(i, colIndex); |
||||||
|
columnData.add(GeneralUtils.objectToString(valueAt)); |
||||||
|
} |
||||||
|
return columnData; |
||||||
|
} |
||||||
|
|
||||||
|
private static int getColIndex(EmbeddedTableData tableData, String columnName) { |
||||||
|
int colIndex = 0; |
||||||
|
|
||||||
|
for (int count = tableData.getColumnCount(); colIndex < count; ++colIndex) { |
||||||
|
if (ComparatorUtils.tableDataColumnNameEquals(tableData.getColumnName(colIndex), columnName)) { |
||||||
|
return colIndex; |
||||||
|
} |
||||||
|
} |
||||||
|
return DataModel.COLUMN_NAME_NOT_FOUND; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,56 @@ |
|||||||
|
package com.fr.design.chart.auto; |
||||||
|
|
||||||
|
import com.fr.data.util.function.DataFunction; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bjorn |
||||||
|
* @version 10.0 |
||||||
|
* Created by Bjorn on 2020-06-16 |
||||||
|
*/ |
||||||
|
public class ColumnInfo { |
||||||
|
|
||||||
|
private String columnName; |
||||||
|
private List<String> values; |
||||||
|
private DataFunction function; |
||||||
|
private List<Object> resultValues = new ArrayList<>(); |
||||||
|
|
||||||
|
public ColumnInfo(String columnName, List<String> values) { |
||||||
|
this.columnName = columnName; |
||||||
|
this.values = values; |
||||||
|
} |
||||||
|
|
||||||
|
public String getColumnName() { |
||||||
|
return columnName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setColumnName(String columnName) { |
||||||
|
this.columnName = columnName; |
||||||
|
} |
||||||
|
|
||||||
|
public List<String> getValues() { |
||||||
|
return values; |
||||||
|
} |
||||||
|
|
||||||
|
public void setValues(List<String> values) { |
||||||
|
this.values = values; |
||||||
|
} |
||||||
|
|
||||||
|
public DataFunction getFunction() { |
||||||
|
return function; |
||||||
|
} |
||||||
|
|
||||||
|
public void setFunction(DataFunction function) { |
||||||
|
this.function = function; |
||||||
|
} |
||||||
|
|
||||||
|
public List<Object> getResultValues() { |
||||||
|
return resultValues; |
||||||
|
} |
||||||
|
|
||||||
|
public void setResultValues(List<Object> resultValues) { |
||||||
|
this.resultValues = resultValues; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,265 @@ |
|||||||
|
package com.fr.design.chart.auto.strategy; |
||||||
|
|
||||||
|
import com.fr.base.chart.chartdata.TopDefinitionProvider; |
||||||
|
import com.fr.chart.chartdata.BubbleTableDefinition; |
||||||
|
import com.fr.chart.chartdata.ChartDataUtils; |
||||||
|
import com.fr.chart.chartdata.ChartSummaryColumn; |
||||||
|
import com.fr.chart.chartdata.MoreNameCDDefinition; |
||||||
|
import com.fr.chart.chartdata.OneValueCDDefinition; |
||||||
|
import com.fr.data.impl.NameTableData; |
||||||
|
import com.fr.data.util.function.DataFunction; |
||||||
|
import com.fr.design.chart.auto.ColumnInfo; |
||||||
|
import com.fr.general.GeneralUtils; |
||||||
|
import com.fr.general.data.DataModel; |
||||||
|
import com.fr.graph.g2d.canvas.CanvasPainter; |
||||||
|
import com.fr.json.JSONArray; |
||||||
|
import com.fr.json.JSONObject; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.plugin.chart.vanchart.VanChart; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bjorn |
||||||
|
* @version 10.0 |
||||||
|
* Created by Bjorn on 2020-06-17 |
||||||
|
*/ |
||||||
|
public abstract class AbstractAutoTypeStrategy implements AutoTypeStrategy { |
||||||
|
|
||||||
|
private static CanvasPainter engine; |
||||||
|
|
||||||
|
public static final String NONE = InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Use_None"); |
||||||
|
|
||||||
|
public static final int MAX_COUNT = 3; |
||||||
|
|
||||||
|
//对维度和指标进行计算
|
||||||
|
protected void calculateColumn(List<ColumnInfo> dimensions, List<ColumnInfo> targets) { |
||||||
|
//<key,<functionFieldId,valueList>> 需要聚合计算的数据数组。eg:{a-x-:{fieldId3:[1,4],fieldId4:[5,8]},a-y-:{fieldId3:[3],fieldId4:[7]}}。
|
||||||
|
Map<String, Map<String, List<Object>>> targetFieldMap = new HashMap<>(); |
||||||
|
|
||||||
|
//关键字段可能有数据字典属性,需要拿到数据字典的映射值<key,<keyFieldId, (actualValue, displayValue)>>。eg:{a-x-:{fieldId1:(a,a1),fieldId1:(x,x1)},a-y-:{fieldId1:(a,a1),fieldId1:(y,y1)}}
|
||||||
|
Map<String, Map<String, String>> dimensionFieldMap = new LinkedHashMap<>(); |
||||||
|
|
||||||
|
int size = dimensions.get(0).getValues().size(); |
||||||
|
|
||||||
|
for (int rowIndex = 0; rowIndex < size; rowIndex++) { |
||||||
|
String key = StringUtils.EMPTY; |
||||||
|
Map<String, String> keyValueMap = new HashMap<>(); |
||||||
|
//处理维度字段
|
||||||
|
for (ColumnInfo field : dimensions) { |
||||||
|
String columnName = field.getColumnName(); |
||||||
|
String result = field.getValues().get(rowIndex); |
||||||
|
List<Object> resultList = new ArrayList<>(); |
||||||
|
key += (result + "-"); |
||||||
|
resultList.add(result); |
||||||
|
keyValueMap.put(columnName, result); |
||||||
|
} |
||||||
|
if (!dimensionFieldMap.containsKey(key)) { |
||||||
|
dimensionFieldMap.put(key, keyValueMap); |
||||||
|
} |
||||||
|
//处理指标字段
|
||||||
|
for (ColumnInfo field : targets) { |
||||||
|
String result = field.getValues().get(rowIndex); |
||||||
|
Map<String, List<Object>> map = targetFieldMap.get(key); |
||||||
|
if (map == null) { |
||||||
|
map = new HashMap<>(); |
||||||
|
targetFieldMap.put(key, map); |
||||||
|
} |
||||||
|
String columnName = field.getColumnName(); |
||||||
|
List<Object> list = map.get(columnName); |
||||||
|
if (list == null) { |
||||||
|
list = new ArrayList<>(); |
||||||
|
map.put(columnName, list); |
||||||
|
} |
||||||
|
list.add(result); |
||||||
|
} |
||||||
|
} |
||||||
|
calculateAndFill(dimensionFieldMap, targetFieldMap, dimensions, targets); |
||||||
|
} |
||||||
|
|
||||||
|
private void calculateAndFill(Map<String, Map<String, String>> dimensionFieldMap, |
||||||
|
Map<String, Map<String, List<Object>>> targetFieldMap, |
||||||
|
List<ColumnInfo> dimensions, List<ColumnInfo> targets) { |
||||||
|
for (String key : dimensionFieldMap.keySet()) { |
||||||
|
Map<String, List<Object>> targetValues = targetFieldMap.get(key); |
||||||
|
//对需要计算的字段使用dataFunction进行计算
|
||||||
|
for (ColumnInfo field : targets) { |
||||||
|
DataFunction dataFunction = field.getFunction(); |
||||||
|
dataFunction.reset(); |
||||||
|
List<Object> valueList = targetValues.get(field.getColumnName()); |
||||||
|
field.getResultValues().add(ChartDataUtils.calculateByFunction(dataFunction, valueList)); |
||||||
|
} |
||||||
|
|
||||||
|
Map<String, String> keyValue = dimensionFieldMap.get(key); |
||||||
|
for (ColumnInfo field : dimensions) { |
||||||
|
String result = keyValue.get(field.getColumnName()); |
||||||
|
field.getResultValues().add(result); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected List<RankChart> analyzeByAva(List<ColumnInfo> dimensions, List<ColumnInfo> targets) { |
||||||
|
|
||||||
|
List<RankChart> rankChartList = new ArrayList<>(); |
||||||
|
|
||||||
|
CanvasPainter engine = createEngine(); |
||||||
|
if (engine == null) { |
||||||
|
return rankChartList; |
||||||
|
} |
||||||
|
|
||||||
|
JSONArray jsonArray = new JSONArray(); |
||||||
|
int size = dimensions.isEmpty() ? targets.get(0).getResultValues().size() : dimensions.get(0).getResultValues().size(); |
||||||
|
for (int i = 0; i < size; i++) { |
||||||
|
JSONObject jsonObject = new JSONObject(); |
||||||
|
for (ColumnInfo columnInfo : dimensions) { |
||||||
|
jsonObject.put(columnInfo.getColumnName(), GeneralUtils.objectToString(columnInfo.getResultValues().get(i))); |
||||||
|
} |
||||||
|
for (ColumnInfo columnInfo : targets) { |
||||||
|
jsonObject.put(columnInfo.getColumnName(), GeneralUtils.objectToNumber(columnInfo.getResultValues().get(i))); |
||||||
|
} |
||||||
|
jsonArray.add(jsonObject); |
||||||
|
} |
||||||
|
|
||||||
|
String result = StringUtils.EMPTY; |
||||||
|
try { |
||||||
|
result = (String) engine.executeFunction("analyzeData", jsonArray.toString()); |
||||||
|
} catch (Exception ex) { |
||||||
|
FineLoggerFactory.getLogger().error(ex.getMessage(), ex); |
||||||
|
} |
||||||
|
|
||||||
|
JSONArray resultArray = new JSONArray(result); |
||||||
|
for (int i = 0; i < resultArray.length(); i++) { |
||||||
|
JSONObject jsonObject = resultArray.getJSONObject(i); |
||||||
|
AvaType type = AvaType.parse(GeneralUtils.objectToString(jsonObject.get("type"))); |
||||||
|
double score = GeneralUtils.objectToNumber(jsonObject.get("score")).doubleValue(); |
||||||
|
if (type == null || score <= 0) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
RankChart rankChart = new RankChart(); |
||||||
|
rankChart.setVanChart(type.getVanChart()); |
||||||
|
rankChart.setGrade(score); |
||||||
|
rankChart.setMainCategory(GeneralUtils.objectToString(jsonObject.get("category"))); |
||||||
|
rankChartList.add(rankChart); |
||||||
|
if (rankChartList.size() >= MAX_COUNT) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return rankChartList; |
||||||
|
} |
||||||
|
|
||||||
|
protected List<VanChart> selectHighRankChart(List<RankChart> rankChartList) { |
||||||
|
Collections.sort(rankChartList); |
||||||
|
List<VanChart> vanChartList = new ArrayList<>(); |
||||||
|
int size = Math.min(rankChartList.size(), MAX_COUNT); |
||||||
|
for (int i = 0; i < size; i++) { |
||||||
|
vanChartList.add(rankChartList.get(i).getVanChart()); |
||||||
|
} |
||||||
|
return vanChartList; |
||||||
|
} |
||||||
|
|
||||||
|
private synchronized static CanvasPainter createEngine() { |
||||||
|
if (engine != null) { |
||||||
|
return engine; |
||||||
|
} |
||||||
|
CanvasPainter.Builder builder = null; |
||||||
|
try { |
||||||
|
builder = CanvasPainter.newDefaultBuilder() |
||||||
|
.loadAndExecute("/com/fr/design/chart/auto/js/analyze.js") |
||||||
|
.loadAndExecute("/com/fr/design/chart/auto/js/ava.js"); |
||||||
|
|
||||||
|
} catch (Exception ex) { |
||||||
|
FineLoggerFactory.getLogger().error(ex.getMessage(), ex); |
||||||
|
} finally { |
||||||
|
if (builder != null) { |
||||||
|
engine = builder.build(); |
||||||
|
} |
||||||
|
} |
||||||
|
return engine; |
||||||
|
} |
||||||
|
|
||||||
|
protected TopDefinitionProvider createOneValueCDDefinition(String tableName, DataModel dataModel, String categoryName, |
||||||
|
String seriesName, String valueName, DataFunction dataFunction) { |
||||||
|
OneValueCDDefinition oneValueCDDefinition = new OneValueCDDefinition(); |
||||||
|
oneValueCDDefinition.setTableData(new NameTableData(tableName)); |
||||||
|
oneValueCDDefinition.setDataModel(dataModel); |
||||||
|
oneValueCDDefinition.setCategoryName(categoryName); |
||||||
|
oneValueCDDefinition.setSeriesColumnName(seriesName); |
||||||
|
oneValueCDDefinition.setValueColumnName(valueName); |
||||||
|
oneValueCDDefinition.setDataFunction(dataFunction); |
||||||
|
return oneValueCDDefinition; |
||||||
|
} |
||||||
|
|
||||||
|
protected TopDefinitionProvider createMoreNameCDDefinition(String tableName, DataModel dataModel, |
||||||
|
String categoryName, String seriesName, DataFunction dataFunction) { |
||||||
|
ChartSummaryColumn chartSummaryColumn = new ChartSummaryColumn(); |
||||||
|
chartSummaryColumn.setCustomName(seriesName); |
||||||
|
chartSummaryColumn.setName(seriesName); |
||||||
|
chartSummaryColumn.setFunction(dataFunction); |
||||||
|
|
||||||
|
MoreNameCDDefinition moreNameCDDefinition = new MoreNameCDDefinition(); |
||||||
|
moreNameCDDefinition.setTableData(new NameTableData(tableName)); |
||||||
|
moreNameCDDefinition.setDataModel(dataModel); |
||||||
|
moreNameCDDefinition.setCategoryName(categoryName); |
||||||
|
moreNameCDDefinition.setChartSummaryColumn(new ChartSummaryColumn[]{chartSummaryColumn}); |
||||||
|
return moreNameCDDefinition; |
||||||
|
} |
||||||
|
|
||||||
|
protected TopDefinitionProvider createBubbleTableDefinition(String tableName, DataModel dataModel, |
||||||
|
String seriesName, String x, String y, String value) { |
||||||
|
BubbleTableDefinition bubbleTableDefinition = new BubbleTableDefinition(); |
||||||
|
bubbleTableDefinition.setTableData(new NameTableData(tableName)); |
||||||
|
bubbleTableDefinition.setDataModel(dataModel); |
||||||
|
bubbleTableDefinition.setSeriesName(seriesName); |
||||||
|
bubbleTableDefinition.setBubbleX(x); |
||||||
|
bubbleTableDefinition.setBubbleY(y); |
||||||
|
bubbleTableDefinition.setBubbleSize(value); |
||||||
|
return bubbleTableDefinition; |
||||||
|
} |
||||||
|
|
||||||
|
public class RankChart implements Comparable<RankChart> { |
||||||
|
|
||||||
|
private double grade; |
||||||
|
|
||||||
|
private VanChart vanChart; |
||||||
|
|
||||||
|
private String mainCategory; |
||||||
|
|
||||||
|
public double getGrade() { |
||||||
|
return grade; |
||||||
|
} |
||||||
|
|
||||||
|
public void setGrade(double grade) { |
||||||
|
this.grade = grade; |
||||||
|
} |
||||||
|
|
||||||
|
public VanChart getVanChart() { |
||||||
|
return vanChart; |
||||||
|
} |
||||||
|
|
||||||
|
public void setVanChart(VanChart vanChart) { |
||||||
|
this.vanChart = vanChart; |
||||||
|
} |
||||||
|
|
||||||
|
public String getMainCategory() { |
||||||
|
return mainCategory; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMainCategory(String mainCategory) { |
||||||
|
this.mainCategory = mainCategory; |
||||||
|
} |
||||||
|
|
||||||
|
public int compareTo(RankChart compare) { |
||||||
|
//分数越高,排名越前
|
||||||
|
return compare.getGrade() - grade >= 0 ? 1 : -1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
package com.fr.design.chart.auto.strategy; |
||||||
|
|
||||||
|
import com.fr.design.chart.auto.ColumnInfo; |
||||||
|
import com.fr.plugin.chart.vanchart.VanChart; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bjorn |
||||||
|
* @version 10.0 |
||||||
|
* Created by Bjorn on 2020-06-16 |
||||||
|
*/ |
||||||
|
public interface AutoTypeStrategy { |
||||||
|
|
||||||
|
/** |
||||||
|
* 计算排名匹配度最高的图表 |
||||||
|
* |
||||||
|
* @param dimensions 维度 |
||||||
|
* @param targets 指标 |
||||||
|
*/ |
||||||
|
public List<VanChart> rankChart(String tableName, List<ColumnInfo> dimensions, List<ColumnInfo> targets); |
||||||
|
} |
@ -0,0 +1,79 @@ |
|||||||
|
package com.fr.design.chart.auto.strategy; |
||||||
|
|
||||||
|
import com.fr.chart.charttypes.ChartTypeManager; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.plugin.chart.PiePlot4VanChart; |
||||||
|
import com.fr.plugin.chart.area.VanChartAreaPlot; |
||||||
|
import com.fr.plugin.chart.bubble.VanChartBubblePlot; |
||||||
|
import com.fr.plugin.chart.column.VanChartColumnPlot; |
||||||
|
import com.fr.plugin.chart.line.VanChartLinePlot; |
||||||
|
import com.fr.plugin.chart.radar.VanChartRadarPlot; |
||||||
|
import com.fr.plugin.chart.scatter.VanChartScatterPlot; |
||||||
|
import com.fr.plugin.chart.vanchart.VanChart; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bjorn |
||||||
|
* @version 10.0 |
||||||
|
* Created by Bjorn on 2020-06-18 |
||||||
|
*/ |
||||||
|
public enum AvaType { |
||||||
|
|
||||||
|
//柱形图,堆积柱形图,百分比堆积柱形图
|
||||||
|
COLUMN_CHART(VanChartColumnPlot.VAN_CHART_COLUMN_PLOT_ID, 0), |
||||||
|
STACKED_COLUMN_CHART(VanChartColumnPlot.VAN_CHART_COLUMN_PLOT_ID, 1), |
||||||
|
PERCENT_STACKED_COLUMN_CHART(VanChartColumnPlot.VAN_CHART_COLUMN_PLOT_ID, 2), |
||||||
|
|
||||||
|
//条形图,堆积条形图,百分比堆积条形图
|
||||||
|
BAR_CHART(VanChartColumnPlot.VAN_CHART_BAR_PLOT_ID, 0), |
||||||
|
STACKED_BAR_CHART(VanChartColumnPlot.VAN_CHART_BAR_PLOT_ID, 1), |
||||||
|
PERCENT_STACKED_BAR_CHART(VanChartColumnPlot.VAN_CHART_BAR_PLOT_ID, 2), |
||||||
|
|
||||||
|
//雷达图
|
||||||
|
RADAR_CHART(VanChartRadarPlot.VAN_CHART_RADAR_PLOT, 0), |
||||||
|
|
||||||
|
//饼图
|
||||||
|
PIE_CHART(PiePlot4VanChart.VAN_CHART_PIE_PLOT, 0), |
||||||
|
|
||||||
|
//折线图
|
||||||
|
LINE_CHART(VanChartLinePlot.VAN_CHART_LINE_PLOT, 0), |
||||||
|
|
||||||
|
//面积图
|
||||||
|
AREA_CHART(VanChartAreaPlot.VAN_CHART_AREA_PLOT_ID, 0), |
||||||
|
STACKED_AREA_CHART(VanChartAreaPlot.VAN_CHART_AREA_PLOT_ID, 1), |
||||||
|
PERCENT_STACKED_AREA_CHART(VanChartAreaPlot.VAN_CHART_AREA_PLOT_ID, 2), |
||||||
|
|
||||||
|
//散点图
|
||||||
|
SCATTER_PLOT(VanChartScatterPlot.VAN_CHART_SCATTER_PLOT_ID, 0), |
||||||
|
|
||||||
|
//气泡图
|
||||||
|
BUBBLE_CHART(VanChartBubblePlot.VAN_CHART_BUBBLE_PLOT_ID, 0); |
||||||
|
|
||||||
|
private VanChart vanChart; |
||||||
|
|
||||||
|
AvaType(String vanChartType, int vanChartIndex) { |
||||||
|
vanChart = (VanChart) ChartTypeManager.getInstance(). |
||||||
|
getCharts(vanChartType)[vanChartIndex]; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public VanChart getVanChart() { |
||||||
|
VanChart vanChart = null; |
||||||
|
try { |
||||||
|
vanChart = (VanChart) this.vanChart.clone(); |
||||||
|
} catch (Exception ex) { |
||||||
|
FineLoggerFactory.getLogger().error(ex.getMessage(), ex); |
||||||
|
} |
||||||
|
return vanChart; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static AvaType parse(String typeName) { |
||||||
|
for (AvaType type : AvaType.values()) { |
||||||
|
if (StringUtils.equalsIgnoreCase(type.toString(), typeName)) { |
||||||
|
return type; |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,106 @@ |
|||||||
|
package com.fr.design.chart.auto.strategy.imp; |
||||||
|
|
||||||
|
import com.fr.base.chart.chartdata.TopDefinitionProvider; |
||||||
|
import com.fr.data.util.function.SumFunction; |
||||||
|
import com.fr.design.chart.auto.AutoChartDataModel; |
||||||
|
import com.fr.design.chart.auto.ColumnInfo; |
||||||
|
import com.fr.design.chart.auto.strategy.AbstractAutoTypeStrategy; |
||||||
|
import com.fr.general.data.DataModel; |
||||||
|
import com.fr.plugin.chart.area.VanChartAreaPlot; |
||||||
|
import com.fr.plugin.chart.line.VanChartLinePlot; |
||||||
|
import com.fr.plugin.chart.radar.VanChartRadarPlot; |
||||||
|
import com.fr.plugin.chart.vanchart.VanChart; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bjorn |
||||||
|
* @version 10.0 |
||||||
|
* Created by Bjorn on 2020-06-16 |
||||||
|
* 使用ava来匹配的策略 |
||||||
|
*/ |
||||||
|
public class AvaStrategy extends AbstractAutoTypeStrategy { |
||||||
|
|
||||||
|
|
||||||
|
public List<VanChart> rankChart(String tableName, List<ColumnInfo> dimensions, List<ColumnInfo> targets) { |
||||||
|
List<RankChart> rankChartList = new ArrayList<>(); |
||||||
|
|
||||||
|
for (ColumnInfo columnInfo : targets) { |
||||||
|
columnInfo.setFunction(new SumFunction()); |
||||||
|
} |
||||||
|
if (dimensions.size() == 1) { |
||||||
|
//一个维度+一个指标匹配
|
||||||
|
for (ColumnInfo target : targets) { |
||||||
|
List<ColumnInfo> newTargets = new ArrayList<>(); |
||||||
|
newTargets.add(target); |
||||||
|
rankChartList.addAll(rankChartByAva(tableName, dimensions, newTargets)); |
||||||
|
//ava匹配之后,初始化图表和分数
|
||||||
|
} |
||||||
|
} else { |
||||||
|
//两个维度+一个指标匹配
|
||||||
|
int size = dimensions.size(); |
||||||
|
for (int i = 0; i < size; i++) { |
||||||
|
for (int j = i + 1; j < size; j++) { |
||||||
|
for (ColumnInfo target : targets) { |
||||||
|
List<ColumnInfo> newDimensions = new ArrayList<>(); |
||||||
|
newDimensions.add(dimensions.get(i)); |
||||||
|
newDimensions.add(dimensions.get(j)); |
||||||
|
List<ColumnInfo> newTargets = new ArrayList<>(); |
||||||
|
newTargets.add(target); |
||||||
|
rankChartList.addAll(rankChartByAva(tableName, newDimensions, newTargets)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return selectHighRankChart(rankChartList); |
||||||
|
} |
||||||
|
|
||||||
|
private List<RankChart> rankChartByAva(String tableName, List<ColumnInfo> dimensions, List<ColumnInfo> targets) { |
||||||
|
for (ColumnInfo columnInfo : dimensions) { |
||||||
|
columnInfo.setResultValues(new ArrayList<>()); |
||||||
|
} |
||||||
|
for (ColumnInfo columnInfo : targets) { |
||||||
|
columnInfo.setResultValues(new ArrayList<>()); |
||||||
|
} |
||||||
|
calculateColumn(dimensions, targets); |
||||||
|
//调用ava
|
||||||
|
List<RankChart> rankChartList = analyzeByAva(dimensions, targets); |
||||||
|
|
||||||
|
List<ColumnInfo> modelList = new ArrayList<>(); |
||||||
|
modelList.addAll(dimensions); |
||||||
|
modelList.addAll(targets); |
||||||
|
AutoChartDataModel dataModel = new AutoChartDataModel(modelList); |
||||||
|
for (RankChart rankChart : rankChartList) { |
||||||
|
VanChart vanChart = rankChart.getVanChart(); |
||||||
|
String plotID = vanChart.getPlot().getPlotID(); |
||||||
|
vanChart.setFilterDefinition(creatDefinition(plotID, rankChart.getMainCategory(), tableName, dataModel, dimensions, targets)); |
||||||
|
} |
||||||
|
return rankChartList; |
||||||
|
} |
||||||
|
|
||||||
|
private TopDefinitionProvider creatDefinition(String plotId, String category, String tableName, DataModel dataModel, |
||||||
|
List<ColumnInfo> dimensions, List<ColumnInfo> targets) { |
||||||
|
String categoryName; |
||||||
|
String seriesName; |
||||||
|
switch (plotId) { |
||||||
|
case VanChartLinePlot.VAN_CHART_LINE_PLOT: |
||||||
|
case VanChartAreaPlot.VAN_CHART_AREA_PLOT_ID: |
||||||
|
case VanChartRadarPlot.VAN_CHART_RADAR_PLOT: |
||||||
|
if (dimensions.size() == 1) { |
||||||
|
return createMoreNameCDDefinition(tableName, dataModel, dimensions.get(0).getColumnName(), targets.get(0).getColumnName(), new SumFunction()); |
||||||
|
} else { |
||||||
|
categoryName = category; |
||||||
|
seriesName = StringUtils.equals(dimensions.get(0).getColumnName(), categoryName) ? |
||||||
|
dimensions.get(1).getColumnName() : dimensions.get(0).getColumnName(); |
||||||
|
return createOneValueCDDefinition(tableName, dataModel, categoryName, seriesName, targets.get(0).getColumnName(), new SumFunction()); |
||||||
|
} |
||||||
|
default: |
||||||
|
categoryName = dimensions.size() > 1 ? dimensions.get(0).getColumnName() : NONE; |
||||||
|
seriesName = dimensions.size() > 1 ? dimensions.get(1).getColumnName() : dimensions.get(0).getColumnName(); |
||||||
|
return createOneValueCDDefinition(tableName, dataModel, categoryName, seriesName, targets.get(0).getColumnName(), new SumFunction()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
package com.fr.design.chart.auto.strategy.imp; |
||||||
|
|
||||||
|
import com.fr.base.chart.chartdata.TopDefinitionProvider; |
||||||
|
import com.fr.design.chart.auto.AutoChartDataModel; |
||||||
|
import com.fr.design.chart.auto.ColumnInfo; |
||||||
|
import com.fr.design.chart.auto.strategy.AbstractAutoTypeStrategy; |
||||||
|
import com.fr.plugin.chart.vanchart.VanChart; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bjorn |
||||||
|
* @version 10.0 |
||||||
|
* Created by Bjorn on 2020-06-16 |
||||||
|
* 匹配气泡图和散点图的策略 |
||||||
|
*/ |
||||||
|
public class BubbleChartStrategy extends AbstractAutoTypeStrategy { |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<VanChart> rankChart(String tableName, List<ColumnInfo> dimensions, List<ColumnInfo> targets) { |
||||||
|
List<RankChart> rankChartList = new ArrayList<>(); |
||||||
|
for (ColumnInfo columnInfo : dimensions) { |
||||||
|
List<Object> resultValues = columnInfo.getResultValues(); |
||||||
|
for (String str : columnInfo.getValues()) { |
||||||
|
resultValues.add(str); |
||||||
|
} |
||||||
|
} |
||||||
|
for (ColumnInfo columnInfo : targets) { |
||||||
|
List<Object> resultValues = columnInfo.getResultValues(); |
||||||
|
for (String str : columnInfo.getValues()) { |
||||||
|
resultValues.add(str); |
||||||
|
} |
||||||
|
} |
||||||
|
int size = targets.size(); |
||||||
|
//散点图
|
||||||
|
if (size == 2) { |
||||||
|
rankChartList.addAll(rankChartByAva(tableName, dimensions, targets)); |
||||||
|
} else { |
||||||
|
//气泡图
|
||||||
|
for (int i = 0; i < size; i++) { |
||||||
|
for (int j = i + 1; j < size; j++) { |
||||||
|
for (int k = j + 1; k < size; k++) { |
||||||
|
List<ColumnInfo> newTargets = new ArrayList<>(); |
||||||
|
newTargets.add(targets.get(i)); |
||||||
|
newTargets.add(targets.get(j)); |
||||||
|
newTargets.add(targets.get(k)); |
||||||
|
rankChartList.addAll(rankChartByAva(tableName, dimensions, newTargets)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return selectHighRankChart(rankChartList); |
||||||
|
} |
||||||
|
|
||||||
|
private List<RankChart> rankChartByAva(String tableName, List<ColumnInfo> dimensions, List<ColumnInfo> targets) { |
||||||
|
//调用ava
|
||||||
|
List<RankChart> rankChartList = analyzeByAva(dimensions, targets); |
||||||
|
|
||||||
|
List<ColumnInfo> modelList = new ArrayList<>(); |
||||||
|
modelList.addAll(dimensions); |
||||||
|
modelList.addAll(targets); |
||||||
|
AutoChartDataModel dataModel = new AutoChartDataModel(modelList); |
||||||
|
|
||||||
|
String series = dimensions.size() == 0 ? NONE : dimensions.get(0).getColumnName(); |
||||||
|
String value = targets.size() == 2 ? StringUtils.EMPTY : targets.get(2).getColumnName(); |
||||||
|
TopDefinitionProvider bubbleTableDefinition = createBubbleTableDefinition(tableName, dataModel, series, |
||||||
|
targets.get(0).getColumnName(), targets.get(1).getColumnName(), value); |
||||||
|
for (RankChart rankChart : rankChartList) { |
||||||
|
VanChart vanChart = rankChart.getVanChart(); |
||||||
|
vanChart.setFilterDefinition(bubbleTableDefinition); |
||||||
|
} |
||||||
|
return rankChartList; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,68 @@ |
|||||||
|
package com.fr.design.chart.auto.strategy.imp; |
||||||
|
|
||||||
|
import com.fr.base.chart.chartdata.TopDefinitionProvider; |
||||||
|
import com.fr.data.util.function.CountFunction; |
||||||
|
import com.fr.design.chart.auto.AutoChartDataModel; |
||||||
|
import com.fr.design.chart.auto.ColumnInfo; |
||||||
|
import com.fr.design.chart.auto.strategy.AbstractAutoTypeStrategy; |
||||||
|
import com.fr.general.data.DataModel; |
||||||
|
import com.fr.plugin.chart.area.VanChartAreaPlot; |
||||||
|
import com.fr.plugin.chart.line.VanChartLinePlot; |
||||||
|
import com.fr.plugin.chart.radar.VanChartRadarPlot; |
||||||
|
import com.fr.plugin.chart.vanchart.VanChart; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bjorn |
||||||
|
* @version 10.0 |
||||||
|
* Created by Bjorn on 2020-06-16 |
||||||
|
* 匹配无指标的策略 |
||||||
|
*/ |
||||||
|
public class SingleDimensionStrategy extends AbstractAutoTypeStrategy { |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<VanChart> rankChart(String tableName, List<ColumnInfo> dimensions, List<ColumnInfo> targets) { |
||||||
|
List<RankChart> rankChartList = new ArrayList<>(); |
||||||
|
for (ColumnInfo columnInfo : dimensions) { |
||||||
|
ColumnInfo target = new ColumnInfo(columnInfo.getColumnName(), columnInfo.getValues()); |
||||||
|
target.setFunction(new CountFunction()); |
||||||
|
target.setColumnName("value"); |
||||||
|
|
||||||
|
List<ColumnInfo> newDimension = new ArrayList<>(); |
||||||
|
List<ColumnInfo> newTarget = new ArrayList<>(); |
||||||
|
newDimension.add(columnInfo); |
||||||
|
newTarget.add(target); |
||||||
|
|
||||||
|
rankChartList.addAll(rankChartByAva(tableName, newDimension, newTarget)); |
||||||
|
} |
||||||
|
return selectHighRankChart(rankChartList); |
||||||
|
} |
||||||
|
|
||||||
|
private List<RankChart> rankChartByAva(String tableName, List<ColumnInfo> dimensions, List<ColumnInfo> targets) { |
||||||
|
calculateColumn(dimensions, targets); |
||||||
|
//调用ava
|
||||||
|
List<RankChart> rankChartList = analyzeByAva(dimensions, targets); |
||||||
|
|
||||||
|
AutoChartDataModel dataModel = new AutoChartDataModel(dimensions); |
||||||
|
for (RankChart rankChart : rankChartList) { |
||||||
|
VanChart vanChart = rankChart.getVanChart(); |
||||||
|
String plotID = vanChart.getPlot().getPlotID(); |
||||||
|
vanChart.setFilterDefinition(creatDefinition(plotID, tableName, dataModel, dimensions)); |
||||||
|
} |
||||||
|
return rankChartList; |
||||||
|
} |
||||||
|
|
||||||
|
private TopDefinitionProvider creatDefinition(String plotId, String tableName, DataModel dataModel, |
||||||
|
List<ColumnInfo> dimensions) { |
||||||
|
switch (plotId) { |
||||||
|
case VanChartLinePlot.VAN_CHART_LINE_PLOT: |
||||||
|
case VanChartAreaPlot.VAN_CHART_AREA_PLOT_ID: |
||||||
|
case VanChartRadarPlot.VAN_CHART_RADAR_PLOT: |
||||||
|
return createMoreNameCDDefinition(tableName, dataModel, dimensions.get(0).getColumnName(), dimensions.get(0).getColumnName(), new CountFunction()); |
||||||
|
default: |
||||||
|
return createOneValueCDDefinition(tableName, dataModel, NONE, dimensions.get(0).getColumnName(), dimensions.get(0).getColumnName(), new CountFunction()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
package com.fr.design.chart.auto.strategy.imp; |
||||||
|
|
||||||
|
import com.fr.data.util.function.NoneFunction; |
||||||
|
import com.fr.design.chart.auto.AutoChartDataModel; |
||||||
|
import com.fr.design.chart.auto.ColumnInfo; |
||||||
|
import com.fr.design.chart.auto.strategy.AbstractAutoTypeStrategy; |
||||||
|
import com.fr.design.chart.auto.strategy.AvaType; |
||||||
|
import com.fr.plugin.chart.attr.axis.VanChartAxis; |
||||||
|
import com.fr.plugin.chart.attr.axis.VanChartValueAxis; |
||||||
|
import com.fr.plugin.chart.column.VanChartColumnPlot; |
||||||
|
import com.fr.plugin.chart.vanchart.VanChart; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bjorn |
||||||
|
* @version 10.0 |
||||||
|
* Created by Bjorn on 2020-06-16 |
||||||
|
* 匹配无维度的策略 |
||||||
|
*/ |
||||||
|
public class SingleTargetStrategy extends AbstractAutoTypeStrategy { |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<VanChart> rankChart(String tableName, List<ColumnInfo> dimensions, List<ColumnInfo> targets) { |
||||||
|
//只有一个指标,匹配直方图
|
||||||
|
VanChart vanChart = AvaType.COLUMN_CHART.getVanChart(); |
||||||
|
List<ColumnInfo> allColumn = new ArrayList<>(dimensions); |
||||||
|
allColumn.addAll(targets); |
||||||
|
|
||||||
|
AutoChartDataModel dataModel = new AutoChartDataModel(allColumn); |
||||||
|
String columnName = targets.get(0).getColumnName(); |
||||||
|
vanChart.setFilterDefinition(createMoreNameCDDefinition(tableName, dataModel, columnName, columnName, new NoneFunction())); |
||||||
|
|
||||||
|
VanChartColumnPlot plot = vanChart.getPlot(); |
||||||
|
List<VanChartAxis> xAxisList = plot.getXAxisList(); |
||||||
|
VanChartAxis vanChartAxis = xAxisList.get(0); |
||||||
|
VanChartValueAxis axis = new VanChartValueAxis(vanChartAxis.getAxisName(), vanChartAxis.getPosition()); |
||||||
|
xAxisList.set(0, axis); |
||||||
|
|
||||||
|
List<VanChart> vanChartList = new ArrayList<>(); |
||||||
|
vanChartList.add(vanChart); |
||||||
|
return vanChartList; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
var document = { |
||||||
|
|
||||||
|
body: { |
||||||
|
|
||||||
|
style: {} |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
documentElement: { |
||||||
|
style: {} |
||||||
|
}, |
||||||
|
|
||||||
|
head: { |
||||||
|
prepend: function () { |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
addEventListener: function () { |
||||||
|
}, |
||||||
|
|
||||||
|
createDocumentFragment: function () { |
||||||
|
return { |
||||||
|
appendChild: function () { |
||||||
|
return {}; |
||||||
|
} |
||||||
|
}; |
||||||
|
}, |
||||||
|
|
||||||
|
createElement: function () { |
||||||
|
return { |
||||||
|
getContext: function () { |
||||||
|
return undefined; |
||||||
|
}, |
||||||
|
|
||||||
|
setAttribute: function () { |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
getElementsByTagName: function () { |
||||||
|
return []; |
||||||
|
}, |
||||||
|
|
||||||
|
appendChild: function () { |
||||||
|
return {}; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
function analyzeData(data) { |
||||||
|
|
||||||
|
data = JSON.parse(data); |
||||||
|
|
||||||
|
var result = window.analyze(data); |
||||||
|
|
||||||
|
for (i = 0; i < result.length; i++) { |
||||||
|
var type = result[i].type; |
||||||
|
|
||||||
|
if(type == "line_chart" || type == "area_chart" |
||||||
|
|| type == "stacked_area_chart" || type == "percent_stacked_area_chart"){ |
||||||
|
result[i].category = result[i].channels.x; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return JSON.stringify(result); |
||||||
|
} |
Loading…
Reference in new issue