From d8233ad43e3f64457a6372e10ca379ae12c8e9d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=B2=B3?= <445798420@qq.com> Date: Mon, 22 Jun 2020 10:01:26 +0800 Subject: [PATCH 1/3] =?UTF-8?q?CHART-13666=20=E8=87=AA=E5=8A=A8=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=8E=A8=E8=8D=90=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/chart/AutoChartIcon.java | 2 +- .../fr/design/chart/AutoChartTypePane.java | 80 +- .../design/chart/auto/AutoChartDataModel.java | 46 + .../design/chart/auto/AutoTypeCalculate.java | 142 + .../com/fr/design/chart/auto/ColumnInfo.java | 56 + .../strategy/AbstractAutoTypeStrategy.java | 265 ++ .../chart/auto/strategy/AutoTypeStrategy.java | 22 + .../design/chart/auto/strategy/AvaType.java | 79 + .../chart/auto/strategy/imp/AvaStrategy.java | 106 + .../strategy/imp/BubbleChartStrategy.java | 76 + .../strategy/imp/SingleDimensionStrategy.java | 68 + .../strategy/imp/SingleTargetStrategy.java | 45 + .../com/fr/design/chart/auto/js/analyze.js | 66 + .../com/fr/design/chart/auto/js/ava.js | 2729 +++++++++++++++++ 14 files changed, 3777 insertions(+), 5 deletions(-) create mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/AutoChartDataModel.java create mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/AutoTypeCalculate.java create mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/ColumnInfo.java create mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AbstractAutoTypeStrategy.java create mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AutoTypeStrategy.java create mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AvaType.java create mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/AvaStrategy.java create mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/BubbleChartStrategy.java create mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleDimensionStrategy.java create mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleTargetStrategy.java create mode 100644 designer-chart/src/main/resources/com/fr/design/chart/auto/js/analyze.js create mode 100644 designer-chart/src/main/resources/com/fr/design/chart/auto/js/ava.js diff --git a/designer-chart/src/main/java/com/fr/design/chart/AutoChartIcon.java b/designer-chart/src/main/java/com/fr/design/chart/AutoChartIcon.java index b85e2194c..6e347d34b 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/AutoChartIcon.java +++ b/designer-chart/src/main/java/com/fr/design/chart/AutoChartIcon.java @@ -66,7 +66,7 @@ public class AutoChartIcon implements Icon { public void paintIcon(Component c, Graphics g, int x, int y) { BaseChartPainter painter = chartCollection.createResultChartPainterWithOutDealFormula(Calculator.createCalculator(), - WebChartIDInfo.createEmptyDesignerInfo(), getIconWidth(), getIconHeight()); + WebChartIDInfo.createAutoTypeInfo(), getIconWidth(), getIconHeight()); int resolution = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getJTemplateResolution(); diff --git a/designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java b/designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java index b546a330b..a7ad368fb 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java +++ b/designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java @@ -3,27 +3,41 @@ package com.fr.design.chart; import com.fr.base.chart.chartdata.CallbackEvent; import com.fr.chart.chartattr.ChartCollection; import com.fr.chartx.attr.ChartProvider; +import com.fr.design.chart.auto.AutoTypeCalculate; import com.fr.design.data.DesignTableDataManager; import com.fr.design.data.datapane.TableDataComboBox; import com.fr.design.data.tabledata.wrapper.TableDataWrapper; +import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icombocheckbox.UIComboCheckBox; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.iprogressbar.AutoProgressBar; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.GeneralUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.chart.vanchart.VanChart; import javax.swing.BorderFactory; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.JList; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.ListCellRenderer; +import javax.swing.SwingWorker; +import javax.swing.UIManager; +import javax.swing.plaf.SplitPaneUI; +import javax.swing.plaf.basic.BasicSplitPaneUI; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CancellationException; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; @@ -46,6 +60,9 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent private TableDataComboBox tableNameComboBox; private UIComboCheckBox dataFieldBox; + private AutoProgressBar connectionBar; + private SwingWorker worker; + public AutoChartTypePane() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); initButtonGroup(); @@ -62,10 +79,15 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent chartViewList.setCellRenderer(iconCellRenderer); JScrollPane subListPane = new JScrollPane(chartViewList); + subListPane.setBorder(BorderFactory.createTitledBorder(Toolkit.i18nText("Fine-Design_Chart_Recommended_Chart"))); + + JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, false, contentPane, subListPane); - JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, contentPane, subListPane); + SplitPaneUI ui = splitPane.getUI(); + if (ui instanceof BasicSplitPaneUI) { + ((BasicSplitPaneUI) ui).getDivider().setBorder(null); + } splitPane.setDividerLocation(60); - splitPane.setBorder(BorderFactory.createTitledBorder(Toolkit.i18nText("Fine-Design_Chart_M_Popup_Auto_Chart_Type"))); this.add(splitPane); } @@ -94,7 +116,7 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent JPanel tableDataPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); panel.add(tableDataPane); tableDataPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Chart_Table_Data") + ":")); - tableNameComboBox.setPreferredSize(new Dimension(96, 20)); + tableNameComboBox.setPreferredSize(new Dimension(126, 20)); tableDataPane.add(tableNameComboBox); JPanel areaNamePane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); @@ -102,6 +124,7 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent areaNamePane.add(new UILabel(Toolkit.i18nText("Fine-Design_Chart_Data_Field") + ":")); areaNamePane.add(dataFieldBox); panel.add(refreshButton); + panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); return panel; } @@ -154,6 +177,7 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent refreshButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { + refreshButton.setEnabled(false); calculateAutoChart(); } }); @@ -161,7 +185,55 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent } private void calculateAutoChart() { - chartResultModel.clear(); + connectionBar = new AutoProgressBar(this, Toolkit.i18nText("Fine-Design_Chart_Generate_Recommended_Chart"), "", 0, 100) { + public void doMonitorCanceled() { + refreshButton.setEnabled(true); + worker.cancel(true); + } + }; + setWorker(); + worker.execute(); + } + + private void setWorker() { + + worker = new SwingWorker, Void>() { + protected List doInBackground() { + connectionBar.start(); + chartResultModel.clear(); + List columnList = new ArrayList<>(); + Object[] selectedValues = dataFieldBox.getSelectedValues(); + for (Object value : selectedValues) { + columnList.add(GeneralUtils.objectToString(value)); + } + List vanChartList = AutoTypeCalculate.calculateType(tableNameComboBox.getSelectedItem().getTableDataName(), columnList); + connectionBar.close(); + return vanChartList; + } + + public void done() { + try { + List vanChartList = get(); + if (vanChartList != null && !vanChartList.isEmpty()) { + for (VanChart vanChart : vanChartList) { + ChartCollection chartCollection = new ChartCollection(vanChart); + AutoChartIcon autoChartIcon = new AutoChartIcon(chartCollection); + autoChartIcon.registerCallBackEvent(AutoChartTypePane.this); + chartResultModel.addElement(autoChartIcon); + } + chartViewList.setSelectedIndex(0); + } + } catch (Exception e) { + if (!(e instanceof CancellationException)) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), e.getMessage(), + Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + } + } finally { + refreshButton.setEnabled(true); + } + } + }; } @Override diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/AutoChartDataModel.java b/designer-chart/src/main/java/com/fr/design/chart/auto/AutoChartDataModel.java new file mode 100644 index 000000000..76889dcd2 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chart/auto/AutoChartDataModel.java @@ -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 columnInfoList; + + public AutoChartDataModel(List 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); + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/AutoTypeCalculate.java b/designer-chart/src/main/java/com/fr/design/chart/auto/AutoTypeCalculate.java new file mode 100644 index 000000000..73c23bd1c --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chart/auto/AutoTypeCalculate.java @@ -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 calculateType(String tableName, List columns) { + List columnValue = calculateField(tableName, columns); + if (columnValue.isEmpty()) { + return new ArrayList<>(); + } + + List dimensions = new ArrayList<>(); + List 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 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 calculateField(String tableName, List 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 originalData = new ArrayList<>(); + for (String column : columns) { + List columnData = getColumnData(tableData, column); + if (columnData != null && !columnData.isEmpty()) { + originalData.add(new ColumnInfo(column, columnData)); + } + } + return originalData; + } + + private static List getColumnData(EmbeddedTableData tableData, String columnName) { + int colIndex = getColIndex(tableData, columnName); + + if (colIndex == DataModel.COLUMN_NAME_NOT_FOUND) { + return null; + } + + int size = tableData.getRowCount(); + List 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; + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/ColumnInfo.java b/designer-chart/src/main/java/com/fr/design/chart/auto/ColumnInfo.java new file mode 100644 index 000000000..9d27925df --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chart/auto/ColumnInfo.java @@ -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 values; + private DataFunction function; + private List resultValues = new ArrayList<>(); + + public ColumnInfo(String columnName, List values) { + this.columnName = columnName; + this.values = values; + } + + public String getColumnName() { + return columnName; + } + + public void setColumnName(String columnName) { + this.columnName = columnName; + } + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + + public DataFunction getFunction() { + return function; + } + + public void setFunction(DataFunction function) { + this.function = function; + } + + public List getResultValues() { + return resultValues; + } + + public void setResultValues(List resultValues) { + this.resultValues = resultValues; + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AbstractAutoTypeStrategy.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AbstractAutoTypeStrategy.java new file mode 100644 index 000000000..417cd036c --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AbstractAutoTypeStrategy.java @@ -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 dimensions, List targets) { + //> 需要聚合计算的数据数组。eg:{a-x-:{fieldId3:[1,4],fieldId4:[5,8]},a-y-:{fieldId3:[3],fieldId4:[7]}}。 + Map>> targetFieldMap = new HashMap<>(); + + //关键字段可能有数据字典属性,需要拿到数据字典的映射值>。eg:{a-x-:{fieldId1:(a,a1),fieldId1:(x,x1)},a-y-:{fieldId1:(a,a1),fieldId1:(y,y1)}} + Map> dimensionFieldMap = new LinkedHashMap<>(); + + int size = dimensions.get(0).getValues().size(); + + for (int rowIndex = 0; rowIndex < size; rowIndex++) { + String key = StringUtils.EMPTY; + Map keyValueMap = new HashMap<>(); + //处理维度字段 + for (ColumnInfo field : dimensions) { + String columnName = field.getColumnName(); + String result = field.getValues().get(rowIndex); + List 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> map = targetFieldMap.get(key); + if (map == null) { + map = new HashMap<>(); + targetFieldMap.put(key, map); + } + String columnName = field.getColumnName(); + List 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> dimensionFieldMap, + Map>> targetFieldMap, + List dimensions, List targets) { + for (String key : dimensionFieldMap.keySet()) { + Map> targetValues = targetFieldMap.get(key); + //对需要计算的字段使用dataFunction进行计算 + for (ColumnInfo field : targets) { + DataFunction dataFunction = field.getFunction(); + dataFunction.reset(); + List valueList = targetValues.get(field.getColumnName()); + field.getResultValues().add(ChartDataUtils.calculateByFunction(dataFunction, valueList)); + } + + Map keyValue = dimensionFieldMap.get(key); + for (ColumnInfo field : dimensions) { + String result = keyValue.get(field.getColumnName()); + field.getResultValues().add(result); + } + } + } + + protected List analyzeByAva(List dimensions, List targets) { + + List 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 selectHighRankChart(List rankChartList) { + Collections.sort(rankChartList); + List 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 { + + 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; + } + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AutoTypeStrategy.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AutoTypeStrategy.java new file mode 100644 index 000000000..12c794568 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AutoTypeStrategy.java @@ -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 rankChart(String tableName, List dimensions, List targets); +} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AvaType.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AvaType.java new file mode 100644 index 000000000..29f242279 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AvaType.java @@ -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; + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/AvaStrategy.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/AvaStrategy.java new file mode 100644 index 000000000..aef4999f0 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/AvaStrategy.java @@ -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 rankChart(String tableName, List dimensions, List targets) { + List rankChartList = new ArrayList<>(); + + for (ColumnInfo columnInfo : targets) { + columnInfo.setFunction(new SumFunction()); + } + if (dimensions.size() == 1) { + //一个维度+一个指标匹配 + for (ColumnInfo target : targets) { + List 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 newDimensions = new ArrayList<>(); + newDimensions.add(dimensions.get(i)); + newDimensions.add(dimensions.get(j)); + List newTargets = new ArrayList<>(); + newTargets.add(target); + rankChartList.addAll(rankChartByAva(tableName, newDimensions, newTargets)); + } + } + } + } + + return selectHighRankChart(rankChartList); + } + + private List rankChartByAva(String tableName, List dimensions, List targets) { + for (ColumnInfo columnInfo : dimensions) { + columnInfo.setResultValues(new ArrayList<>()); + } + for (ColumnInfo columnInfo : targets) { + columnInfo.setResultValues(new ArrayList<>()); + } + calculateColumn(dimensions, targets); + //调用ava + List rankChartList = analyzeByAva(dimensions, targets); + + List 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 dimensions, List 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()); + } + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/BubbleChartStrategy.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/BubbleChartStrategy.java new file mode 100644 index 000000000..6f10f561b --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/BubbleChartStrategy.java @@ -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 rankChart(String tableName, List dimensions, List targets) { + List rankChartList = new ArrayList<>(); + for (ColumnInfo columnInfo : dimensions) { + List resultValues = columnInfo.getResultValues(); + for (String str : columnInfo.getValues()) { + resultValues.add(str); + } + } + for (ColumnInfo columnInfo : targets) { + List 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 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 rankChartByAva(String tableName, List dimensions, List targets) { + //调用ava + List rankChartList = analyzeByAva(dimensions, targets); + + List 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; + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleDimensionStrategy.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleDimensionStrategy.java new file mode 100644 index 000000000..4d7ad03f4 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleDimensionStrategy.java @@ -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 rankChart(String tableName, List dimensions, List targets) { + List rankChartList = new ArrayList<>(); + for (ColumnInfo columnInfo : dimensions) { + ColumnInfo target = new ColumnInfo(columnInfo.getColumnName(), columnInfo.getValues()); + target.setFunction(new CountFunction()); + target.setColumnName("value"); + + List newDimension = new ArrayList<>(); + List newTarget = new ArrayList<>(); + newDimension.add(columnInfo); + newTarget.add(target); + + rankChartList.addAll(rankChartByAva(tableName, newDimension, newTarget)); + } + return selectHighRankChart(rankChartList); + } + + private List rankChartByAva(String tableName, List dimensions, List targets) { + calculateColumn(dimensions, targets); + //调用ava + List 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 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()); + } + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleTargetStrategy.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleTargetStrategy.java new file mode 100644 index 000000000..5679b6125 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleTargetStrategy.java @@ -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 rankChart(String tableName, List dimensions, List targets) { + //只有一个指标,匹配直方图 + VanChart vanChart = AvaType.COLUMN_CHART.getVanChart(); + List 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 xAxisList = plot.getXAxisList(); + VanChartAxis vanChartAxis = xAxisList.get(0); + VanChartValueAxis axis = new VanChartValueAxis(vanChartAxis.getAxisName(), vanChartAxis.getPosition()); + xAxisList.set(0, axis); + + List vanChartList = new ArrayList<>(); + vanChartList.add(vanChart); + return vanChartList; + } +} diff --git a/designer-chart/src/main/resources/com/fr/design/chart/auto/js/analyze.js b/designer-chart/src/main/resources/com/fr/design/chart/auto/js/analyze.js new file mode 100644 index 000000000..c181cd20e --- /dev/null +++ b/designer-chart/src/main/resources/com/fr/design/chart/auto/js/analyze.js @@ -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); +} \ No newline at end of file diff --git a/designer-chart/src/main/resources/com/fr/design/chart/auto/js/ava.js b/designer-chart/src/main/resources/com/fr/design/chart/auto/js/ava.js new file mode 100644 index 000000000..07965c88f --- /dev/null +++ b/designer-chart/src/main/resources/com/fr/design/chart/auto/js/ava.js @@ -0,0 +1,2729 @@ +!function(e, a) { + 'object' == typeof exports && 'object' == typeof module ? module.exports = a() : 'function' == typeof define && define.amd ? define([], a) : 'object' == typeof exports ? exports.Advisor = a() : e.Advisor = a(); +}(window, (function() { + return function(e) { + var a = {}; + + function t(r) { + if (a[r]) return a[r].exports; + var n = a[r] = { i: r, l: !1, exports: {} }; + return e[r].call(n.exports, n, n.exports, t), n.l = !0, n.exports; + } + + return t.m = e, t.c = a, t.d = function(e, a, r) { + t.o(e, a) || Object.defineProperty(e, a, { enumerable: !0, get: r }); + }, t.r = function(e) { + 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: 'Module' }), Object.defineProperty(e, '__esModule', { value: !0 }); + }, t.t = function(e, a) { + if (1 & a && (e = t(e)), 8 & a) return e; + if (4 & a && 'object' == typeof e && e && e.__esModule) return e; + var r = Object.create(null); + if (t.r(r), Object.defineProperty(r, 'default', { + enumerable: !0, + value: e, + }), 2 & a && 'string' != typeof e) for (var n in e) t.d(r, n, function(a) { + return e[a]; + }.bind(null, n)); + return r; + }, t.n = function(e) { + var a = e && e.__esModule ? function() { + return e.default; + } : function() { + return e; + }; + return t.d(a, 'a', a), a; + }, t.o = function(e, a) { + return Object.prototype.hasOwnProperty.call(e, a); + }, t.p = '', t(t.s = 3); + }([function(e, a, t) { + 'use strict'; + t.d(a, 'a', (function() { + return r; + })), t.d(a, 'd', (function() { + return n; + })), t.d(a, 'b', (function() { + return i; + })), t.d(a, 'c', (function() { + return o; + })); + var r = function() { + return (r = Object.assign || function(e) { + for (var a, t = 1, r = arguments.length; t < r; t++) for (var n in a = arguments[t]) Object.prototype.hasOwnProperty.call(a, n) && (e[n] = a[n]); + return e; + }).apply(this, arguments); + }; + + function n(e) { + var a = 'function' == typeof Symbol && Symbol.iterator, t = a && e[a], r = 0; + if (t) return t.call(e); + if (e && 'number' == typeof e.length) return { + next: function() { + return e && r >= e.length && (e = void 0), { value: e && e[r++], done: !e }; + }, + }; + throw new TypeError(a ? 'Object is not iterable.' : 'Symbol.iterator is not defined.'); + } + + function i(e, a) { + var t = 'function' == typeof Symbol && e[Symbol.iterator]; + if (!t) return e; + var r, n, i = t.call(e), o = []; + try { + for (; (void 0 === a || a-- > 0) && !(r = i.next()).done;) o.push(r.value); + } catch (e) { + n = { error: e }; + } finally { + try { + r && !r.done && (t = i.return) && t.call(i); + } finally { + if (n) throw n.error; + } + } + return o; + } + + function o() { + for (var e = [], a = 0; a < arguments.length; a++) e = e.concat(i(arguments[a])); + return e; + } + }, function(e, a, t) { + 'use strict'; + + function r(e, a) { + for (var t = 0; t < a.length; t++) { + var r = a[t]; + r.enumerable = r.enumerable || !1, r.configurable = !0, 'value' in r && (r.writable = !0), Object.defineProperty(e, r.key, r); + } + } + + function n(e, a, t) { + return a in e ? Object.defineProperty(e, a, { + value: t, + enumerable: !0, + configurable: !0, + writable: !0, + }) : e[a] = t, e; + } + + Object.defineProperty(a, '__esModule', { value: !0 }), a.default = void 0; + var i = function() { + function e(a, t, r, i, o) { + !function(e, a) { + if (!(e instanceof a)) throw new TypeError('Cannot call a class as a function'); + }(this, e), n(this, '_id', void 0), n(this, '_hardOrSoft', void 0), n(this, '_specChartTypes', void 0), n(this, '_weight', void 0), n(this, 'validator', void 0), this._id = a, this._hardOrSoft = t, this._specChartTypes = r, this._weight = i, this.validator = o; + } + + var a, t, i; + return a = e, (t = [{ + key: 'toString', value: function() { + return 'RULE: '.concat(this._id, '^').concat(this._hardOrSoft, '^').concat(this._specChartTypes.toString(), '^*').concat(this.weight); + }, + }, { + key: 'check', value: function(e) { + return this.validator(e) * this._weight; + }, + }, { + key: 'id', get: function() { + return this._id; + }, + }, { + key: 'hardOrSoft', get: function() { + return this._hardOrSoft; + }, + }, { + key: 'specChartTypes', get: function() { + return this._specChartTypes; + }, + }, { + key: 'weight', get: function() { + return this._weight; + }, + }]) && r(a.prototype, t), i && r(a, i), e; + }(); + a.default = i; + }, function(e, a, t) { + 'use strict'; + t.r(a), t.d(a, 'CKBJson', (function() { + return o; + })), t.d(a, 'addChart', (function() { + return c; + })), t.d(a, 'CKBOptions', (function() { + return _; + })), t.d(a, 'FAMILY_OPTIONS', (function() { + return l; + })), t.d(a, 'PURPOSE_OPTIONS', (function() { + return d; + })), t.d(a, 'COORD_TYPE_OPTIONS', (function() { + return u; + })), t.d(a, 'GRAPHIC_CATEGORY_OPTIONS', (function() { + return m; + })), t.d(a, 'SHAPE_OPTIONS', (function() { + return h; + })), t.d(a, 'LOM_OPTIONS', (function() { + return p; + })), t.d(a, 'CHANNEL_OPTIONS', (function() { + return f; + })), t.d(a, 'RECOMMEND_RATING_OPTIONS', (function() { + return y; + })), t.d(a, 'CHART_ID_OPTIONS', (function() { + return g; + })); + var r = { + 'en-US': null, 'zh-CN': { + concepts: { + family: { + LineCharts: '折线图类', + ColumnCharts: '柱状图类', + BarCharts: '条形图类', + PieCharts: '饼图类', + AreaCharts: '面积图类', + ScatterCharts: '散点图类', + FunnelCharts: '漏斗图类', + HeatmapCharts: '热力图类', + RadarCharts: '雷达图类', + TreeGraph: '树形关系类', + GeneralGraph: '关系图类', + PointLayer: '点图层类', + LineLayer: '线图层类', + PolygonLayer: '面图层类', + HeatmapLayer: '地图热力图类', + Others: '其他类', + }, + category: { Statistic: '统计图表', Diagram: '示意图', Graph: '关系图', Map: '地图' }, + purpose: { + Comparison: '比较', + Trend: '趋势', + Distribution: '分布', + Rank: '排名', + Proportion: '占比', + Composition: '组成', + Relation: '关系', + Hierarchy: '层级', + Flow: '流向', + Spatial: '空间', + }, + coord: { + NumberLine: '数轴', + Cartesian2D: '二维直角坐标系', + SymmetricCartesian: '对称直角坐标系', + Cartesian3D: '三维直角坐标系', + Polar: '极坐标系', + NodeLink: '点线关系网络', + Radar: '雷达型坐标系', + Geo: '地理坐标系', + Other: '其他', + }, + shape: { + Lines: '线形', + Bars: '条形', + Round: '圆形', + Square: '方形', + Area: '面形', + Scatter: '散点形', + Symmetric: '对称形', + Network: '网络形', + Map: '地图', + }, + channel: { + Position: '位置', + Length: '长度', + Color: '颜色', + Area: '面积', + Angle: '角度', + ArcLength: '弧长', + Direction: '方向', + Size: '大小', + Opacity: '透明度', + Stroke: '线色', + LineWidth: '线粗', + Lightness: '亮度', + }, + lom: { Continuous: '连续', Discrete: '离散', Interval: '数值', Nominal: '无序名词', Ordinal: '有序名词', Time: '时间' }, + recRate: { Recommended: '推荐', 'Use with Caution': '慎用', 'Not Recommended': '不推荐' }, + }, chartTypes: { + line_chart: { name: '折线图', alias: ['折线图', '线图'], def: '使用折线的线段显示数据在一个具有顺序性的维度上的变化。' }, + step_line_chart: { + name: '阶梯图', + alias: ['阶梯线'], + def: '折线根据分类字段分为多根在 x 方向(时间)的信息是完全一致、颜色及 y 方向(变量)信息不一致的折线,通常用作同一时间区间内多个变量发展趋势的对比。', + }, + area_chart: { name: '面积图', alias: [], def: '使用带填充区域的线段显示数据在一个具有顺序性的维度上的变化。' }, + stacked_area_chart: { + name: '堆叠面积图', + alias: [], + def: '使用带不同样式的填充区域的层叠线段来显示多组数据在同一个具有顺序性的维度上的变化,线段在同一维度值上的端点高度按照数值累加。', + }, + percent_stacked_area_chart: { + name: '百分比堆叠面积图', + alias: ['%堆叠面积图', '100%堆叠面积图'], + def: '一种特殊的堆叠面积图,线段在同一维度值上的端点高度代表值在其中的占比,占比总和为百分之百。', + }, + interval_area_chart: { name: '', alias: [], def: 'TBD' }, + stream_chart: { name: '', alias: [], def: 'TBD' }, + column_chart: { name: '柱状图', alias: ['柱形图'], def: '使用柱形显示维度的数值。横轴显示分类维度,纵轴显示相应的值。' }, + grouped_column_chart: { + name: '分组柱状图', + alias: ['簇状柱状图'], + def: '使用颜色不同的柱形并排组成小组来显示各维度的数值。横轴标示出分组,颜色标示出分类,纵轴显示相应的值。', + }, + stacked_column_chart: { + name: '堆叠柱状图', + alias: [], + def: '使用颜色不同的堆叠的柱形来显示各维度的数值。横轴标示出第一个分类维度,颜色标示出第二个分类维度,纵轴显示相应的值。', + }, + percent_stacked_column_chart: { + name: '百分比堆叠柱状图', + alias: ['%堆叠柱状图', '100%堆叠柱状图'], + def: '使用颜色不同的堆叠的柱形来显示各维度的数值。横轴标示出第一个分类维度,颜色标示出第二个分类维度,纵轴显示相应分类所占的百分比。', + }, + interval_column_chart: { name: '', alias: [], def: 'TBD' }, + range_column_chart: { name: '区间柱状图', alias: [], def: '区间柱状图是一种特殊的柱状图,柱子不一定要从 0 开始,而是用柱子长度表示一个从起始值到终止值的区间。' }, + waterfall_chart: { name: '瀑布图', alias: ['桥图'], def: '瀑布图形似瀑布流水,采用绝对值与相对值结合的方式,适用于表达数个特定数值之间的数量变化关系。' }, + histogram: { name: '直方图', alias: [], def: '直方图是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。' }, + bar_chart: { name: '条形图', alias: ['条状图'], def: '使用条形显示维度的数值。纵轴显示分类维度,横轴显示相应的值。' }, + grouped_bar_chart: { + name: '分组条形图', + alias: ['簇状条形图'], + def: '使用颜色不同的条形并排组成小组来显示维度的数值。纵轴标示出分组,颜色标示出分类,横轴显示相应的值。', + }, + stacked_bar_chart: { + name: '堆叠条形图', + alias: [], + def: '使用颜色不同的堆叠的条形来显示各维度的数值。纵轴标示出第一个分类维度,颜色标示出第二个分类维度,横轴显示相应的值。', + }, + percent_stacked_bar_chart: { + name: '百分比堆叠条形图', + alias: ['%堆叠条形图', '100%堆叠条形图'], + def: '使用颜色不同的堆叠的条形来显示各维度的数值。纵轴标示出第一个分类维度,颜色标示出第二个分类维度,横轴显示相应分类所占的百分比。', + }, + interval_bar_chart: { name: '', alias: [], def: 'TBD' }, + range_bar_chart: { name: '区间条形图', alias: [], def: '区间条形图是一种特殊的条形图,条不一定要从 0 开始,而是用长度表示一个从起始值到终止值的区间。' }, + radial_bar_chart: { name: '', alias: [], def: 'TBD' }, + mirror_bar_chart: { name: '', alias: [], def: 'TBD' }, + bullet_chart: { name: '子弹图', alias: ['靶心图', '标靶图'], def: '子弹图可用于将度量的绩效可视化并与目标值和定性刻度。' }, + pie_chart: { name: '饼图', alias: [], def: '通过扇形区块的颜色和弧长(角度、面积)来展现数据的分类和占比情况。' }, + donut_chart: { name: '环图', alias: ['甜甜圈图'], def: '通过弧形区块的颜色和弧长来展现数据的分类和占比情况。' }, + nested_pie_chart: { name: '', alias: [], def: 'TBD' }, + rose_chart: { + name: '玫瑰图', + alias: ['南丁格尔图', '鸡冠花图', '极坐标面积图'], + def: '统计学家和医学改革家佛罗伦萨‧南丁格尔在克里米亚战争期间创造了这种图表。尽管外形很像饼图,但本质上来说,南丁格尔玫瑰图更像在极坐标下绘制的柱状图或堆叠柱状图。只不过,它用半径来反映数值。', + }, + scatter_plot: { name: '散点图', alias: [], def: '散点图是将所有的数据以不同颜色的点的形式展现在平面直角坐标系上的统计图表。' }, + bubble_chart: { name: '气泡图', alias: [], def: '气泡图是一种多变量的统计图表,由笛卡尔坐标系(直角坐标系)和大小不一、颜色不同的圆组成,可以看作是散点图的变形。' }, + non_ribbon_chord_diagram: { name: '', alias: [], def: 'TBD' }, + arc_diagram: { name: '弧形图', alias: [], def: '弧形图是一种关系图的特殊布局,节点被排列在同一水平线上,关系由节点间的圆弧线表示。' }, + chord_diagram: { name: '', alias: [], def: 'TBD' }, + treemap: { name: '', alias: [], def: 'TBD' }, + sankey_diagram: { name: '桑基图', alias: ['桑吉图'], def: '桑基图,是一种表现流程的示意图,用于描述一组值到另一组值的流向。分支的宽度对应了数据流量的大小。' }, + funnel_chart: { name: '漏斗图', alias: [], def: '漏斗图,形如“漏斗”,用于单流程分析,在开始和结束之间由N个流程环节组成。' }, + overlapping_funnel_chart: { name: '', alias: [], def: 'TBD' }, + mirror_funnel_chart: { name: '对比漏斗图', alias: ['对称漏斗图', '镜像漏斗图'], def: '对比漏斗图是两个独立的漏斗图以一根中轴线对称展开的图表形式。' }, + boxplot: { name: '', alias: [], def: 'TBD' }, + heatmap: { name: '热力图', alias: ['区块热力图'], def: '热力图,是一种通过对色块着色来显示数据的统计图表。' }, + density_heatmap: { name: '密度热力图', alias: ['热力图'], def: '密度热力图是一种用在连续坐标系上用色点展现密度分布的统计图表。' }, + gauge_chart: { name: '', alias: [], def: 'TBD' }, + radar_chart: { + name: '雷达图', + alias: ['蛛网图'], + def: '将不同系列的多个维度的数据量映射到坐标轴上,这些坐标轴起始于同一个圆心点,通常结束于圆周边缘,将同一组的点使用线连接起来,用颜色区分系列。', + }, + wordcloud: { name: '', alias: [], def: 'TBD' }, + candlestick_chart: { name: '', alias: [], def: 'TBD' }, + compact_box_tree: { name: '紧凑树', alias: [], def: '紧凑树是一种树图布局,从根节点开始,同一深度的节点在同一层,并且布局时会将节点大小考虑进去。' }, + dendrogram: { name: '生态树', alias: [], def: '生态树是一种树图布局,不管数据的深度多少,总是叶节点对齐。不考虑节点大小,布局时将节点视为 1 个像素点。' }, + indented_tree: { name: '缩进树', alias: [], def: '缩进树是一种树图布局,缩进树布局。每个元素会占一行/一列。' }, + radial_tree: { name: '辐射树', alias: [], def: '辐射树是一种树图布局,跟节点位于辐射树中心,其他分支辐射式展开。' }, + flow_diagram: { name: '流程图', alias: [], def: '流程图是一种图解,可视表示在过程或功能内部诸如事件、步骤等之间的顺序关系。' }, + fruchterman_layout_graph: { name: 'Fruchterman 布局力导向图', alias: [], def: '一种使用 Fruchterman 布局算法的力导向图。' }, + force_directed_layout_graph: { + name: '力导向图', + alias: [], + def: '力导向图布局作为较早被发明的一种实际应用布局算法,经过研究者多年改进、扩展,已发展成为一类算法的集合。该类算法的特点是模拟物理世界中的作用力,施加在节点上,并迭代计算以达到合理放置节点、美观布局的一类算法。', + }, + circular_layout_graph: { name: '环形布局关系图', alias: [], def: '环形布局根据参数指定的排序方式对节点进行排序后,将节点排列在圆环上。' }, + spiral_layout_graph: { name: '螺旋布局关系图', alias: [], def: '螺旋布局图的节点排列在一根螺旋线上。' }, + radial_layout_graph: { + name: '辐射布局关系图', + alias: [], + def: '辐射布局根据指定的中心点,根据其他节点与中心点的拓扑距离(最短路径长度)将其余节点放置在以中心点为圆心的同心圆上。', + }, + concentric_layout_graph: { name: '同心圆布局关系图', alias: [], def: '同心圆布局关系图将所有节点放置在同心圆上。' }, + grid_layout_graph: { name: '网格布局关系图', alias: [], def: '网格布局根据参数指定的排序方式对节点进行排序后,将节点排列在网格上。' }, + symbol_map: { + name: '符号地图', + alias: [], + def: '散点地图的变体,用具象的图标指代抽象的圆点,无需图例就能直观看出数据点代表的内容,常用于地图上重要地标的显示或数据量较少时的信息表达。', + }, + chart_map: { name: '复合图表地图', alias: [], def: '是定点地图的变体,使用二维统计图表代替点状符号的一种特殊复合形式。' }, + column_map_3d: { name: '3D 柱状图', alias: [], def: '用形状大小相同的柱状体代替点状符号,高度与数值大小映射共同表达离散现象分布特征的地图' }, + scatter_map: { name: '散点地图', alias: [], def: '指地图上可用一个形状大小相同的圆点来定位,用表达离散现象分布特征的地图,如人口、农作物、动植物等的分布' }, + path_map: { + name: '路径地图', + alias: [], + def: '指需要用一连串首尾不闭合的点坐标对(xi,yi)来定位的一类图层。属于半依比例图层,线端点依附地图比例缩放,但线的粗细不会变化。', + }, + isoline_map: { name: '等值线地图', alias: [], def: 'TBD' }, + arc_map_3d: { + name: '3D 弧线地图', + alias: [], + def: '将两个点的连线绘制成弧形,绘制的弧线可以是贝塞尔曲线,大圆航线,通常用来表示两种地理事物关系和联系,或者人口迁移,物流起点目的地等。', + }, + choropleth_map: { name: '填充地图', alias: [], def: '填充图,也叫分级统计图,可在地图上不同领土区域进行着色,查看区域间的分布对比情况' }, + choropleth_map_3d: { name: '3D 填充地图', alias: [], def: '填充地图的增强实现,通过三维视角中的高度模拟真实地物的高度。' }, + hexagonal_heat_map: { + name: '蜂窝热力地图', + alias: [], + def: '使用六边形将地图区域进行分割,计算每个区域中点数或其他累加值,将离散的点转换为数值。然后将数值映射到每个区域的色值、高度或其他参数', + }, + hexagonal_heat_map_3d: { + name: '3D 蜂窝热力地图', + alias: [], + def: '使用3D 六边形将地图区域进行分割,计算每个区域中点数或其他累加值,将离散的点转换为数值。然后将数值映射到每个区域的色值、高度或其他参数', + }, + classical_heat_map: { name: '热力地图', alias: [], def: '密度热力图是一种用在连续坐标系上用色点展现密度分布的统计地图。' }, + grid_heat_map: { + name: '网格热力地图', + alias: [], + def: '使用网格区域进行分割,计算每个区域中点数或其他累加值,将离散的点转换为数值。然后将数值映射到每个区域的色值、高度或其他参数', + }, + bubble_map: { name: '气泡地图', alias: [], def: '指地图上用一个形状相同、面积大小和数值成正比的圆点来定位的地图,是散点图的扩展,用于表达离散现象分布特征的地图。' }, + bubble_light_map: { + name: '亮点地图', + alias: [], + def: '散点图的变形,指用一个点代表一个值,连续渐进颜色代表数值大小,并通过色彩的叠加的达到效果增强,专为海量散点数据运用而生,解决远视角下,点颜色无法区分问题', + }, + packed_circles: { name: '', alias: [], def: 'TBD' }, + polar_treemap: { name: '', alias: [], def: 'TBD' }, + sunburst_diagram: { name: '', alias: [], def: 'TBD' }, + liquid_chart: { name: '水波图', alias: ['进度球'], def: '一种用来表示进度的拟物化示意图' }, + }, + }, + }; + + function n(e) { + return e && Object.keys(r).includes(e) ? r[e] : null; + } + + var i = { + line_chart: { + id: 'line_chart', + name: 'Line Chart', + alias: ['Lines'], + family: ['LineCharts'], + def: 'A line chart uses lines with segments to show changes in data in a ordinal dimension.', + purpose: ['Comparison', 'Trend'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Lines'], + dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Time', 'Ordinal'] }, { + minQty: 0, + maxQty: 1, + fieldConditions: ['Nominal'], + }, { minQty: 1, maxQty: 1, fieldConditions: ['Interval'] }], + channel: ['Position', 'Direction'], + recRate: 'Recommended', + }, + step_line_chart: { + id: 'step_line_chart', + name: 'Step Line Chart', + alias: ['Step Lines'], + family: ['LineCharts'], + def: 'A step line chart is a line chart in which points of each line are connected by horizontal and vertical line segments, looking like steps of a staircase.', + purpose: ['Comparison', 'Trend'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Lines'], + dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Time', 'Ordinal'] }, { + minQty: 0, + maxQty: 1, + fieldConditions: ['Nominal'], + }, { minQty: 1, maxQty: 1, fieldConditions: ['Interval'] }], + channel: ['Position', 'Direction'], + recRate: 'Recommended', + }, + area_chart: { + id: 'area_chart', + name: 'Area Chart', + alias: [], + family: ['AreaCharts'], + def: 'An area chart uses series of line segments with overlapped areas to show the change in data in a ordinal dimension.', + purpose: ['Comparison', 'Trend'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Area'], + dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Time', 'Ordinal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }, { minQty: 0, maxQty: 1, fieldConditions: ['Nominal'] }], + channel: ['Color', 'Position'], + recRate: 'Recommended', + }, + stacked_area_chart: { + id: 'stacked_area_chart', + name: 'Stacked Area Chart', + alias: [], + family: ['AreaCharts'], + def: 'A stacked area chart uses layered line segments with different styles of padding regions to display how multiple sets of data change in the same ordinal dimension, and the endpoint heights of the segments on the same dimension tick are accumulated by value.', + purpose: ['Comparison', 'Composition', 'Trend'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Area'], + dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Time', 'Ordinal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }, { minQty: 1, maxQty: 1, fieldConditions: ['Nominal'] }], + channel: ['Color', 'Length'], + recRate: 'Recommended', + }, + percent_stacked_area_chart: { + id: 'percent_stacked_area_chart', + name: 'Percent Stacked Area Chart', + alias: ['Percent Stacked Area', '% Stacked Area', '100% Stacked Area'], + family: ['AreaCharts'], + def: 'A percent stacked area chart is an extented stacked area chart in which the height of the endpoints of the line segment on the same dimension tick is the accumulated proportion of the ratio, which is 100% of the total.', + purpose: ['Comparison', 'Composition', 'Proportion', 'Trend'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Area'], + dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Time', 'Ordinal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }, { minQty: 1, maxQty: 1, fieldConditions: ['Nominal'] }], + channel: ['Color', 'Length'], + recRate: 'Recommended', + }, + interval_area_chart: { + id: 'interval_area_chart', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + stream_chart: { + id: 'stream_chart', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + column_chart: { + id: 'column_chart', + name: 'Column Chart', + alias: ['Columns'], + family: ['ColumnCharts'], + def: 'A column chart uses series of columns to display the value of the dimension. The horizontal axis shows the classification dimension and the vertical axis shows the corresponding value.', + purpose: ['Comparison', 'Distribution', 'Rank'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 1, maxQty: 2, fieldConditions: ['Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Position', 'Color'], + recRate: 'Recommended', + }, + grouped_column_chart: { + id: 'grouped_column_chart', + name: 'Grouped Column Chart', + alias: ['Grouped Column'], + family: ['ColumnCharts'], + def: 'A grouped column chart uses columns of different colors to form a group to display the values ​​of dimensions. The horizontal axis indicates the grouping of categories, the color indicates the categories, and the vertical axis shows the corresponding value.', + purpose: ['Comparison', 'Distribution', 'Rank'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Color', 'Position'], + recRate: 'Recommended', + }, + stacked_column_chart: { + id: 'stacked_column_chart', + name: 'Stacked Column Chart', + alias: ['Stacked Column'], + family: ['ColumnCharts'], + def: 'A stacked column chart uses stacked bars of different colors to display the values ​​for each dimension. The horizontal axis indicates the first classification dimension, the color indicates the second classification dimension, and the vertical axis shows the corresponding value.', + purpose: ['Comparison', 'Composition', 'Distribution', 'Rank'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Color', 'Length', 'Position'], + recRate: 'Recommended', + }, + percent_stacked_column_chart: { + id: 'percent_stacked_column_chart', + name: 'Percent Stacked Column Chart', + alias: ['Percent Stacked Column', '% Stacked Column', '100% Stacked Column'], + family: ['ColumnCharts'], + def: 'A percent stacked column chart uses stacked bars of different colors to display the values ​​for each dimension. The horizontal axis indicates the first classification dimension, the color indicates the second classification dimension, and the vertical axis shows the percentage of the corresponding classification.', + purpose: ['Comparison', 'Composition', 'Distribution', 'Proportion'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Color', 'Length'], + recRate: 'Recommended', + }, + interval_column_chart: { + id: 'interval_column_chart', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + range_column_chart: { + id: 'range_column_chart', + name: 'Range Column Chart', + alias: [], + family: ['ColumnCharts'], + def: 'A column chart that does not have to start from zero axis.', + purpose: ['Comparison'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Interval'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Nominal'], + }], + channel: ['Length'], + recRate: 'Recommended', + }, + waterfall_chart: { + id: 'waterfall_chart', + name: 'Waterfall Chart', + alias: ['Flying Bricks Chart', 'Mario Chart', 'Bridge Chart', 'Cascade Chart'], + family: ['ColumnCharts'], + def: 'A waterfall chart is used to portray how an initial value is affected by a series of intermediate positive or negative values', + purpose: ['Comparison', 'Trend'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Ordinal', 'Time', 'Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Color', 'Length', 'Position'], + recRate: 'Recommended', + }, + histogram: { + id: 'histogram', + name: 'Histogram', + alias: [], + family: ['ColumnCharts'], + def: 'A histogram is an accurate representation of the distribution of numerical data.', + purpose: ['Distribution'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Interval'] }], + channel: ['Position'], + recRate: 'Recommended', + }, + bar_chart: { + id: 'bar_chart', + name: 'Bar Chart', + alias: ['Bars'], + family: ['BarCharts'], + def: 'A bar chart uses series of bars to display the value of the dimension. The vertical axis shows the classification dimension and the horizontal axis shows the corresponding value.', + purpose: ['Comparison', 'Distribution', 'Rank'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 1, maxQty: 2, fieldConditions: ['Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Position', 'Color'], + recRate: 'Recommended', + }, + grouped_bar_chart: { + id: 'grouped_bar_chart', + name: 'Grouped Bar Chart', + alias: ['Grouped Bar'], + family: ['BarCharts'], + def: 'A grouped bar chart uses bars of different colors to form a group to display the values of the dimensions. The vertical axis indicates the grouping of categories, the color indicates the categories, and the horizontal axis shows the corresponding value.', + purpose: ['Comparison', 'Distribution', 'Rank'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Color', 'Position'], + recRate: 'Recommended', + }, + stacked_bar_chart: { + id: 'stacked_bar_chart', + name: 'Stacked Bar Chart', + alias: ['Stacked Bar'], + family: ['BarCharts'], + def: 'A stacked bar chart uses stacked bars of different colors to display the values ​​for each dimension. The vertical axis indicates the first classification dimension, the color indicates the second classification dimension, and the horizontal axis shows the corresponding value.', + purpose: ['Comparison', 'Composition', 'Distribution', 'Rank'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Color', 'Length', 'Position'], + recRate: 'Recommended', + }, + percent_stacked_bar_chart: { + id: 'percent_stacked_bar_chart', + name: 'Percent Stacked Bar Chart', + alias: ['Percent Stacked Bar', '% Stacked Bar', '100% Stacked Bar'], + family: ['BarCharts'], + def: 'A percent stacked column chart uses stacked bars of different colors to display the values ​​for each dimension. The vertical axis indicates the first classification dimension, the color indicates the second classification dimension, and the horizontal axis shows the percentage of the corresponding classification.', + purpose: ['Comparison', 'Composition', 'Distribution', 'Proportion'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Color', 'Length'], + recRate: 'Recommended', + }, + interval_bar_chart: { + id: 'interval_bar_chart', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + range_bar_chart: { + id: 'range_bar_chart', + name: 'Range Bar Chart', + alias: [], + family: ['BarCharts'], + def: 'A bar chart that does not have to start from zero axis.', + purpose: ['Comparison'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Interval'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Nominal'], + }], + channel: ['Length'], + recRate: 'Recommended', + }, + radial_bar_chart: { + id: 'radial_bar_chart', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + mirror_bar_chart: { + id: 'mirror_bar_chart', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + bullet_chart: { + id: 'bullet_chart', + name: 'Bullet Chart', + alias: [], + family: ['BarCharts'], + def: 'A bullet graph is a variation of a bar graph developed by Stephen Few. Seemingly inspired by the traditional thermometer charts and progress bars found in many dashboards, the bullet graph serves as a replacement for dashboard gauges and meters.', + purpose: ['Proportion'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Bars'], + dataPres: [{ minQty: 3, maxQty: 3, fieldConditions: ['Interval'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Nominal'], + }], + channel: ['Position', 'Color'], + recRate: 'Recommended', + }, + pie_chart: { + id: 'pie_chart', + name: 'Pie Chart', + alias: ['Circle Chart', 'Pie'], + family: ['PieCharts'], + def: 'A pie chart is a chart that the classification and proportion of data are represented by the color and arc length (angle, area) of the sector.', + purpose: ['Comparison', 'Composition', 'Proportion'], + coord: ['Polar'], + category: ['Statistic'], + shape: ['Round'], + dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Angle', 'Area', 'Color'], + recRate: 'Use with Caution', + }, + donut_chart: { + id: 'donut_chart', + name: 'Donut Chart', + alias: ['Donut', 'Doughnut', 'Doughnut Chart', 'Ring Chart'], + family: ['PieCharts'], + def: 'A donut chart is a variation on a Pie chart except it has a round hole in the center which makes it look like a donut.', + purpose: ['Comparison', 'Composition', 'Proportion'], + coord: ['Polar'], + category: ['Statistic'], + shape: ['Round'], + dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['ArcLength'], + recRate: 'Recommended', + }, + nested_pie_chart: { + id: 'nested_pie_chart', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + rose_chart: { + id: 'rose_chart', + name: 'Rose Chart', + alias: ['Nightingale Chart', 'Polar Area Chart', 'Coxcomb Chart'], + family: ['PieCharts'], + def: 'Nightingale Rose Chart is a peculiar combination of the Radar Chart and Stacked Column Chart types of data visualization.', + purpose: ['Comparison', 'Composition', 'Proportion'], + coord: ['Polar'], + category: ['Statistic'], + shape: ['Round'], + dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Angle', 'Color', 'Length'], + recRate: 'Use with Caution', + }, + scatter_plot: { + id: 'scatter_plot', + name: 'Scatter Plot', + alias: ['Scatter Chart', 'Scatterplot'], + family: ['ScatterCharts'], + def: 'A scatter plot is a type of plot or mathematical diagram using Cartesian coordinates to display values for typically two variables for series of data.', + purpose: ['Comparison', 'Distribution'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Scatter'], + dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Interval'] }, { + minQty: 0, + maxQty: 1, + fieldConditions: ['Nominal'], + }], + channel: ['Color', 'Position'], + recRate: 'Recommended', + }, + bubble_chart: { + id: 'bubble_chart', + name: 'Bubble Chart', + alias: ['Bubble Chart'], + family: ['ScatterCharts'], + def: 'A bubble chart is a type of chart that displays four dimensions of data with x, y positions, circle size and circle color.', + purpose: ['Comparison', 'Distribution'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Scatter'], + dataPres: [{ minQty: 3, maxQty: 3, fieldConditions: ['Interval'] }, { + minQty: 0, + maxQty: 1, + fieldConditions: ['Nominal'], + }], + channel: ['Color', 'Position', 'Size'], + recRate: 'Recommended', + }, + non_ribbon_chord_diagram: { + id: 'non_ribbon_chord_diagram', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + arc_diagram: { + id: 'arc_diagram', + name: 'Arc Diagram', + alias: [], + family: ['GeneralGraph'], + def: 'A graph where the edges are represented as arcs.', + purpose: ['Relation'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + chord_diagram: { + id: 'chord_diagram', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + treemap: { + id: 'treemap', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + sankey_diagram: { + id: 'sankey_diagram', + name: 'Sankey Diagram', + alias: [], + family: ['GeneralGraph'], + def: 'A graph shows the flows with weights between objects.', + purpose: ['Flow', 'Trend', 'Relation'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + funnel_chart: { + id: 'funnel_chart', + name: 'Funnel Chart', + alias: [], + family: ['FunnelCharts'], + def: 'A funnel chart is often used to represent stages in a sales process and show the amount of potential revenue for each stage.', + purpose: ['Trend'], + coord: ['SymmetricCartesian'], + category: ['Statistic'], + shape: ['Symmetric'], + dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Ordinal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Color', 'Length'], + recRate: 'Recommended', + }, + overlapping_funnel_chart: { + id: 'overlapping_funnel_chart', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + mirror_funnel_chart: { + id: 'mirror_funnel_chart', + name: 'Mirror Funnel Chart', + alias: ['Contrast Funnel Chart'], + family: ['FunnelCharts'], + def: 'A mirror funnel chart is a funnel chart divided into two series by a central axis.', + purpose: ['Comparison', 'Trend'], + coord: ['SymmetricCartesian'], + category: ['Statistic'], + shape: ['Symmetric'], + dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Ordinal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }, { minQty: 1, maxQty: 1, fieldConditions: ['Nominal'] }], + channel: ['Color', 'Length', 'Direction'], + recRate: 'Recommended', + }, + boxplot: { + id: 'boxplot', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + heatmap: { + id: 'heatmap', + name: 'Heatmap', + alias: [], + family: ['HeatmapCharts'], + def: 'A heatmap is a graphical representation of data where the individual values contained in a matrix are represented as colors.', + purpose: ['Distribution'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Square'], + dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal', 'Ordinal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Color', 'Position'], + recRate: 'Recommended', + }, + density_heatmap: { + id: 'density_heatmap', + name: 'Density Heatmap', + alias: ['Heatmap'], + family: ['HeatmapCharts'], + def: 'A density heatmap is a heatmap for representing the density of dots.', + purpose: ['Distribution'], + coord: ['Cartesian2D'], + category: ['Statistic'], + shape: ['Area'], + dataPres: [{ minQty: 3, maxQty: 3, fieldConditions: ['Interval'] }], + channel: ['Color', 'Position', 'Area'], + recRate: 'Recommended', + }, + gauge_chart: { + id: 'gauge_chart', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + radar_chart: { + id: 'radar_chart', + name: 'Radar Chart', + alias: ['Web Chart', 'Spider Chart', 'Star Chart', 'Cobweb Chart', 'Irregular Polygon', 'Kiviat diagram'], + family: ['RadarCharts'], + def: 'A radar chart maps series of data volume of multiple dimensions onto the axes. Starting at the same center point, usually ending at the edge of the circle, connecting the same set of points using lines.', + purpose: ['Comparison'], + coord: ['Radar'], + category: ['Statistic'], + shape: ['Round'], + dataPres: [{ minQty: 1, maxQty: 2, fieldConditions: ['Nominal'] }, { + minQty: 1, + maxQty: 1, + fieldConditions: ['Interval'], + }], + channel: ['Color', 'Position'], + recRate: 'Recommended', + }, + wordcloud: { + id: 'wordcloud', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + candlestick_chart: { + id: 'candlestick_chart', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + compact_box_tree: { + id: 'compact_box_tree', + name: 'CompactBox Tree', + alias: [], + family: ['TreeGraph'], + def: 'A type of tree graph layout which arranges the nodes with same depth on the same level.', + purpose: ['Relation', 'Hierarchy'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + dendrogram: { + id: 'dendrogram', + name: 'Dendrogram', + alias: [], + family: ['TreeGraph'], + def: 'A type of tree graph layout which arranges the leaves on the same level and ignores the node size.', + purpose: ['Relation', 'Hierarchy'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + indented_tree: { + id: 'indented_tree', + name: 'Indented Tree Layout', + alias: [], + family: ['TreeGraph'], + def: 'A type of tree graph layout where each node takes a row or a column.', + purpose: ['Relation', 'Hierarchy'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + radial_tree: { + id: 'radial_tree', + name: 'Radial Tree Layout', + alias: [], + family: ['TreeGraph'], + def: 'A type of tree graph layout which places the root at the center, and the branches around the root radially.', + purpose: ['Relation', 'Hierarchy'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + flow_diagram: { + id: 'flow_diagram', + name: 'Flow Diagram', + alias: ['Dagre Graph Layout', 'Dagre', 'Flow Chart'], + family: ['GeneralGraph'], + def: 'Directed flow graph.', + purpose: ['Relation', 'Flow'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + fruchterman_layout_graph: { + id: 'fruchterman_layout_graph', + name: 'Fruchterman Graph Layout', + alias: [], + family: ['GeneralGraph'], + def: 'A type of force directed graph layout.', + purpose: ['Relation'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + force_directed_layout_graph: { + id: 'force_directed_layout_graph', + name: 'Force Directed Graph Layout', + alias: [], + family: ['GeneralGraph'], + def: 'The classical force directed graph layout.', + purpose: ['Relation'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + circular_layout_graph: { + id: 'circular_layout_graph', + name: 'Circular Graph Layout', + alias: [], + family: ['GeneralGraph'], + def: 'A type of graph layout which arranges all the nodes on a circle.', + purpose: ['Relation'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + spiral_layout_graph: { + id: 'spiral_layout_graph', + name: 'Spiral Graph Layout', + alias: [], + family: ['GeneralGraph'], + def: 'A type of graph layout which arranges all the nodes along a spiral line.', + purpose: ['Relation'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + radial_layout_graph: { + id: 'radial_layout_graph', + name: 'Radial Graph Layout', + alias: [], + family: ['GeneralGraph'], + def: 'A type of graph layout which places a focus node on the center and the others on the concentrics centered at the focus node according to the shortest path length to the it.', + purpose: ['Relation'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + concentric_layout_graph: { + id: 'concentric_layout_graph', + name: 'Concentric Graph Layout', + alias: [], + family: ['GeneralGraph'], + def: 'A type of graph layout which arranges the nodes on concentrics.', + purpose: ['Relation'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + grid_layout_graph: { + id: 'grid_layout_graph', + name: 'Grid Graph Layout', + alias: [], + family: ['GeneralGraph'], + def: 'A type of graph layout arranges the nodes on grids.', + purpose: ['Relation'], + coord: ['Cartesian2D'], + category: ['Graph'], + shape: ['Network'], + dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], + channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + symbol_map: { + id: 'symbol_map', + name: 'Symbol Map', + alias: [], + family: ['PointLayer'], + def: 'Overlay symbols on the map as glyphs.', + purpose: ['Distribution', 'Comparison', 'Spatial'], + coord: ['Geo'], + category: ['Map'], + shape: ['Scatter', 'Map'], + dataPres: [], + channel: ['Position'], + recRate: 'Recommended', + }, + chart_map: { + id: 'chart_map', + name: 'Chart Map', + alias: [], + family: ['PointLayer'], + def: 'Overlay charts on the map as glyphs.', + purpose: ['Composition', 'Distribution', 'Comparison', 'Spatial'], + coord: ['Geo'], + category: ['Map'], + shape: ['Map'], + dataPres: [], + channel: ['Position'], + recRate: 'Recommended', + }, + column_map_3d: { + id: 'column_map_3d', + name: '3D Column Map', + alias: [], + family: ['PointLayer'], + def: 'Maps that use height of 3D columns to represent distribution.', + purpose: ['Distribution', 'Comparison', 'Spatial'], + coord: [], + category: ['Map'], + shape: ['Map'], + dataPres: [], + channel: ['Position', 'Length'], + recRate: 'Recommended', + }, + scatter_map: { + id: 'scatter_map', + name: 'Scatter Map', + alias: [], + family: ['PointLayer'], + def: 'Overlay dots with same size on the map as glyphs.', + purpose: ['Distribution', 'Spatial'], + coord: ['Geo'], + category: ['Map'], + shape: ['Scatter', 'Map'], + dataPres: [], + channel: ['Size', 'Color', 'Position', 'Opacity'], + recRate: 'Recommended', + }, + path_map: { + id: 'path_map', + name: 'Path Map', + alias: [], + family: ['LineLayer'], + def: 'Overlay paths on the map as glyphs.', + purpose: ['Spatial'], + coord: ['Geo'], + category: ['Map'], + shape: ['Lines'], + dataPres: [], + channel: ['Size', 'Color', 'Position', 'Opacity'], + recRate: 'Recommended', + }, + isoline_map: { + id: 'isoline_map', + name: 'Isoline Map', + alias: [], + family: ['LineLayer'], + def: '', + purpose: ['Comparison'], + coord: ['Geo'], + category: ['Map'], + shape: ['Lines'], + dataPres: [], + channel: ['Size', 'Color', 'Position', 'Opacity'], + recRate: 'Recommended', + }, + arc_map_3d: { + id: 'arc_map_3d', + name: '3D Arc Map', + alias: [], + family: ['LineLayer'], + def: '', + purpose: ['Relation', 'Spatial'], + coord: ['Geo'], + category: ['Map'], + shape: ['Lines'], + dataPres: [], + channel: ['Size', 'Color', 'Position', 'Opacity'], + recRate: 'Recommended', + }, + choropleth_map: { + id: 'choropleth_map', + name: 'Choropleth Map', + alias: [], + family: ['PolygonLayer'], + def: 'A choropleth map is a type of thematic map in which areas are shaded or patterned in proportion to a statistical variable that represents an aggregate summary of a geographic characteristic within each area, such as population density or per-capita income.', + purpose: ['Comparison', 'Spatial'], + coord: ['Geo'], + category: ['Map'], + shape: ['Area', 'Map'], + dataPres: [], + channel: ['Color', 'Position', 'Opacity', 'Stroke', 'LineWidth'], + recRate: 'Recommended', + }, + choropleth_map_3d: { + id: 'choropleth_map_3d', + name: '3D Choropleth Map', + alias: ['Extrude Map'], + family: ['PolygonLayer'], + def: '', + purpose: ['Comparison'], + coord: ['Geo'], + category: ['Map'], + shape: ['Area', 'Map'], + dataPres: [], + channel: ['Size', 'Color', 'Position', 'Opacity'], + recRate: 'Recommended', + }, + hexagonal_heat_map: { + id: 'hexagonal_heat_map', + name: 'Hexagonal Heat Map', + alias: [], + family: [], + def: 'Dividing the map area using hexagons.', + purpose: ['Distribution', 'Spatial'], + coord: ['Geo'], + category: ['Map'], + shape: ['Area', 'Map'], + dataPres: [], + channel: ['Size', 'Color', 'Position', 'Opacity'], + recRate: 'Recommended', + }, + hexagonal_heat_map_3d: { + id: 'hexagonal_heat_map_3d', + name: '3D Hexagonal Heat Map', + alias: [], + family: [], + def: 'Dividing the 3D map area using hexagons.', + purpose: ['Distribution'], + coord: ['Geo'], + category: ['Map'], + shape: ['Map'], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + classical_heat_map: { + id: 'classical_heat_map', + name: 'Classical Heat Map', + alias: [], + family: [], + def: '', + purpose: ['Distribution'], + coord: ['Geo'], + category: ['Map'], + shape: ['Map'], + dataPres: [], + channel: ['Color', 'Position', 'Opacity'], + recRate: 'Recommended', + }, + grid_heat_map: { + id: 'grid_heat_map', + name: 'Gird Heat Map', + alias: [], + family: [], + def: '', + purpose: ['Distribution'], + coord: [], + category: ['Map'], + shape: ['Map'], + dataPres: [], + channel: ['Color', 'Position', 'Opacity'], + recRate: 'Recommended', + }, + bubble_map: { + id: 'bubble_map', + name: 'Bubble Map', + alias: [], + family: ['PointLayer'], + def: 'Overlay bubbles on the map as glyphs.', + purpose: ['Distribution', 'Spatial'], + coord: ['Geo'], + category: ['Map'], + shape: ['Scatter', 'Map'], + dataPres: [], + channel: ['Position', 'Color', 'Size'], + recRate: 'Recommended', + }, + bubble_light_map: { + id: 'bubble_light_map', + name: 'Bubble Light Map', + alias: [], + family: ['PointLayer'], + def: 'Overlay bubbles with different lightness on the map as glyphs.', + purpose: ['Distribution', 'Spatial'], + coord: ['Geo'], + category: ['Map'], + shape: ['Scatter', 'Map'], + dataPres: [], + channel: ['Position', 'Color', 'Size', 'Opacity'], + recRate: 'Recommended', + }, + packed_circles: { + id: 'packed_circles', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + polar_treemap: { + id: 'polar_treemap', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + sunburst_diagram: { + id: 'sunburst_diagram', + name: '', + alias: [], + family: [], + def: '', + purpose: [], + coord: [], + category: [], + shape: [], + dataPres: [], + channel: [], + recRate: 'Recommended', + }, + liquid_chart: { + id: 'liquid_chart', + name: 'Liquid Chart', + alias: ['Liquid Ball', 'Progress Ball'], + family: ['Others'], + def: 'Liquid chart is a diagram to represent progress.', + purpose: ['Composition'], + coord: ['Other'], + category: ['Diagram'], + shape: ['Round'], + dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Interval'] }], + channel: ['Position'], + recRate: 'Not Recommended', + }, + }; + + function o(e, a) { + void 0 === e && (e = 'en-US'), void 0 === a && (a = !1); + var t = JSON.parse(JSON.stringify(i)), r = {}; + Object.keys(t).forEach((function(e) { + var n = t[e], i = !0; + if (a) for (var o = Object.keys(n), c = 0; c < o.length; c++) { + var s = o[c], l = n[s]; + if ('alias' !== s && 'boolean' != typeof l && (Array.isArray(l) && 0 === l.length || !l)) { + i = !1; + break; + } + } + i && (r[e] = n); + })); + var o = {}; + if (e && 'en-US' != e) { + var c = n(e), s = Object.keys(r); + c && s.forEach((function(e) { + o[e] = {}, o[e].id = e, o[e].name = c.chartTypes[e].name, o[e].alias = c.chartTypes[e].alias, o[e].def = c.chartTypes[e].def, o[e].family = r[e].family.map((function(e) { + return c.concepts.family[e]; + })), o[e].purpose = r[e].purpose.map((function(e) { + return c.concepts.purpose[e]; + })), o[e].coord = r[e].coord.map((function(e) { + return c.concepts.coord[e]; + })), o[e].category = r[e].category.map((function(e) { + return c.concepts.category[e]; + })), o[e].shape = r[e].shape.map((function(e) { + return c.concepts.shape[e]; + })), o[e].channel = r[e].channel.map((function(e) { + return c.concepts.channel[e]; + })), o[e].dataPres = r[e].dataPres.map((function(e) { + var a = {}; + return a.minQty = e.minQty, a.maxQty = e.maxQty, a.fieldConditions = e.fieldConditions.map((function(e) { + return c.concepts.lom[e]; + })), a; + })); + })); + } else o = r; + return o; + } + + function c(e, a) { + var t = e.id; + i[t] = e, Object.keys(a).forEach((function(e) { + var n = r[e]; + n && (n.chartTypes[t] = a[e]); + })); + } + + var s = t(0), + l = ['LineCharts', 'ColumnCharts', 'BarCharts', 'PieCharts', 'AreaCharts', 'ScatterCharts', 'FunnelCharts', 'HeatmapCharts', 'RadarCharts', 'TreeGraph', 'GeneralGraph', 'PolygonLayer', 'LineLayer', 'PointLayer', 'HeatmapLayer', 'Others'], + d = ['Comparison', 'Trend', 'Distribution', 'Rank', 'Proportion', 'Composition', 'Relation', 'Hierarchy', 'Flow', 'Spatial'], + u = ['NumberLine', 'Cartesian2D', 'SymmetricCartesian', 'Cartesian3D', 'Polar', 'NodeLink', 'Radar', 'Geo', 'Other'], + m = ['Statistic', 'Diagram', 'Graph', 'Map'], + h = ['Lines', 'Bars', 'Round', 'Square', 'Area', 'Scatter', 'Symmetric', 'Network', 'Map'], + p = ['Nominal', 'Ordinal', 'Interval', 'Discrete', 'Continuous', 'Time'], + f = ['Position', 'Length', 'Color', 'Area', 'Angle', 'ArcLength', 'Direction', 'Size', 'Opacity', 'Stroke', 'LineWidth', 'Lightness'], + y = ['Recommended', 'Use with Caution', 'Not Recommended']; + + function _(e) { + if (void 0 === e && (e = 'en-US'), e && 'en-US' != e) { + var a = n(e); + if (a && a.concepts) { + var t = a.concepts; + return { + family: Object.values(t.family), + category: Object.values(t.category), + purpose: Object.values(t.purpose), + coord: Object.values(t.coord), + shape: Object.values(t.shape), + channel: Object.values(t.channel), + lom: Object.values(t.lom), + recRate: Object.values(t.recRate), + }; + } + } + return { + family: Object(s.c)(l), + category: Object(s.c)(m), + purpose: Object(s.c)(d), + coord: Object(s.c)(u), + shape: Object(s.c)(h), + channel: Object(s.c)(f), + lom: Object(s.c)(p), + recRate: Object(s.c)(y), + }; + } + + var g = ['line_chart', 'step_line_chart', 'area_chart', 'stacked_area_chart', 'percent_stacked_area_chart', 'interval_area_chart', 'stream_chart', 'column_chart', 'grouped_column_chart', 'stacked_column_chart', 'percent_stacked_column_chart', 'interval_column_chart', 'range_column_chart', 'waterfall_chart', 'histogram', 'bar_chart', 'stacked_bar_chart', 'percent_stacked_bar_chart', 'grouped_bar_chart', 'interval_bar_chart', 'range_bar_chart', 'radial_bar_chart', 'mirror_bar_chart', 'bullet_chart', 'pie_chart', 'donut_chart', 'nested_pie_chart', 'rose_chart', 'scatter_plot', 'bubble_chart', 'non_ribbon_chord_diagram', 'arc_diagram', 'chord_diagram', 'treemap', 'sankey_diagram', 'funnel_chart', 'overlapping_funnel_chart', 'mirror_funnel_chart', 'boxplot', 'heatmap', 'density_heatmap', 'gauge_chart', 'radar_chart', 'wordcloud', 'candlestick_chart', 'compact_box_tree', 'dendrogram', 'indented_tree', 'radial_tree', 'flow_diagram', 'fruchterman_layout_graph', 'force_directed_layout_graph', 'circular_layout_graph', 'spiral_layout_graph', 'radial_layout_graph', 'concentric_layout_graph', 'grid_layout_graph', 'symbol_map', 'chart_map', 'column_map_3d', 'scatter_map', 'path_map', 'isoline_map', 'arc_map_3d', 'choropleth_map', 'choropleth_map_3d', 'hexagonal_heat_map', 'hexagonal_heat_map_3d', 'classical_heat_map', 'grid_heat_map', 'bubble_map', 'bubble_light_map', 'packed_circles', 'polar_treemap', 'sunburst_diagram', 'liquid_chart']; + }, function(e, a, t) { + 'use strict'; + var r = t(4); + window.analyze = r.analyze; + }, function(e, a, t) { + 'use strict'; + + function r(e) { + return (r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && 'function' == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? 'symbol' : typeof e; + })(e); + } + + Object.defineProperty(a, '__esModule', { value: !0 }), a.dataToDataProps = C, a.dataPropsToSpecs = x, a.analyze = function(e, a) { + console.log('💠💠💠💠💠💠 data 💠💠💠💠💠💠'), console.log(e), console.log('🍯🍯🍯🍯🍯🍯 options 🍯🍯🍯🍯🍯🍯'), console.log(a); + var t = C(e); + return console.log('🔶🔶🔶🔶🔶🔶 dataset analysis 🔶🔶🔶🔶🔶🔶'), console.log(t), x(t, a); + }, a.specToLibConfig = function(e, a) { + var t = (0, l.getMappingForLib)(a), r = t.typeMapping, n = t.configMapping, i = e.type, o = e.channels, c = {}; + i && r[i] && (c.type = r[i]); + for (var s = {}, d = 0, u = Object.entries(o); d < u.length; d++) { + var h = (g = u[d], b = 2, function(e) { + if (Array.isArray(e)) return e; + }(g) || function(e, a) { + if ('undefined' == typeof Symbol || !(Symbol.iterator in Object(e))) return; + var t = [], r = !0, n = !1, i = void 0; + try { + for (var o, c = e[Symbol.iterator](); !(r = (o = c.next()).done) && (t.push(o.value), !a || t.length !== a); r = !0) ; + } catch (e) { + n = !0, i = e; + } finally { + try { + r || null == c.return || c.return(); + } finally { + if (n) throw i; + } + } + return t; + }(g, b) || m(g, b) || function() { + throw new TypeError('Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.'); + }()), p = h[0], f = h[1], y = n[i]; + if (y) { + var _ = y[p]; + _ && (s[_] = f); + } + } + var g, b; + return c.configs = s, c; + }; + var n, i = t(2), o = (n = t(5)) && n.__esModule ? n : { default: n }, c = function(e) { + if (e && e.__esModule) return e; + if (null === e || 'object' !== r(e) && 'function' != typeof e) return { default: e }; + var a = d(); + if (a && a.has(e)) return a.get(e); + var t = {}, n = Object.defineProperty && Object.getOwnPropertyDescriptor; + for (var i in e) if (Object.prototype.hasOwnProperty.call(e, i)) { + var o = n ? Object.getOwnPropertyDescriptor(e, i) : null; + o && (o.get || o.set) ? Object.defineProperty(t, i, o) : t[i] = e[i]; + } + t.default = e, a && a.set(e, t); + return t; + }(t(11)), s = t(7), l = t(9); + + function d() { + if ('function' != typeof WeakMap) return null; + var e = new WeakMap; + return d = function() { + return e; + }, e; + } + + function u(e) { + return function(e) { + if (Array.isArray(e)) return h(e); + }(e) || function(e) { + if ('undefined' != typeof Symbol && Symbol.iterator in Object(e)) return Array.from(e); + }(e) || m(e) || function() { + throw new TypeError('Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.'); + }(); + } + + function m(e, a) { + if (e) { + if ('string' == typeof e) return h(e, a); + var t = Object.prototype.toString.call(e).slice(8, -1); + return 'Object' === t && e.constructor && (t = e.constructor.name), 'Map' === t || 'Set' === t ? Array.from(e) : 'Arguments' === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? h(e, a) : void 0; + } + } + + function h(e, a) { + (null == a || a > e.length) && (a = e.length); + for (var t = 0, r = new Array(a); t < a; t++) r[t] = e[t]; + return r; + } + + function p(e, a) { + var t = Object.keys(e); + if (Object.getOwnPropertySymbols) { + var r = Object.getOwnPropertySymbols(e); + a && (r = r.filter((function(a) { + return Object.getOwnPropertyDescriptor(e, a).enumerable; + }))), t.push.apply(t, r); + } + return t; + } + + function f(e) { + for (var a = 1; a < arguments.length; a++) { + var t = null != arguments[a] ? arguments[a] : {}; + a % 2 ? p(Object(t), !0).forEach((function(a) { + y(e, a, t[a]); + })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : p(Object(t)).forEach((function(a) { + Object.defineProperty(e, a, Object.getOwnPropertyDescriptor(t, a)); + })); + } + return e; + } + + function y(e, a, t) { + return a in e ? Object.defineProperty(e, a, { + value: t, + enumerable: !0, + configurable: !0, + writable: !0, + }) : e[a] = t, e; + } + + var _ = (0, i.CKBJson)('en-US', !0); + + function g(e, a) { + return e.distinct < a.distinct ? 1 : e.distinct > a.distinct ? -1 : 0; + } + + function b(e, a) { + return a.every((function(a) { + return e.includes(a); + })); + } + + function v(e, a) { + return a.some((function(a) { + return e.includes(a); + })); + } + + function C(e) { + var a = c.typeAll(e), t = []; + return a.forEach((function(e) { + var a = []; + c.isNominal(e) && a.push('Nominal'), c.isOrdinal(e) && a.push('Ordinal'), c.isInterval(e) && a.push('Interval'), c.isDiscrete(e) && a.push('Discrete'), c.isContinuous(e) && a.push('Continuous'), c.isTime(e) && a.push('Time'); + var r = f(f({}, e), {}, { levelOfMeasurements: a }); + t.push(r); + })), t; + } + + function x(e, a) { + var t = a ? a.purpose : '', r = a ? a.preferences : void 0; + var n = Object.keys(_).map((function(a) { + var n = 0, i = {}, s = 1; + o.default.filter((function(e) { + return 'HARD' === e.hardOrSoft && e.specChartTypes.includes(a); + })).forEach((function(n) { + var o = n.check({ dataProps: e, chartType: a, purpose: t, preferences: r }); + s *= o, i[n.id] = o; + })); + var l = 0; + o.default.filter((function(e) { + return 'SOFT' === e.hardOrSoft && e.specChartTypes.includes(a); + })).forEach((function(n) { + var o = n.check({ dataProps: e, chartType: a, purpose: t, preferences: r }); + l += o, i[n.id] = o; + })), n = s * (1 + l), console.log('💯score: ', n, '=', s, '* (1 +', l, ') ;charttype: ', a), console.log(i); + var d = {}; + if ('pie_chart' === a || 'donut_chart' === a) { + var m = e.find((function(e) { + return b(e.levelOfMeasurements, ['Nominal']); + })), h = e.find((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })); + h && m ? (d.color = m.name, d.angle = h.name) : n = 0; + } + if ('line_chart' === a || 'step_line_chart' == a) { + var p = e.find((function(e) { + return v(e.levelOfMeasurements, ['Time', 'Ordinal']); + })), f = e.find((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })), y = e.find((function(e) { + return b(e.levelOfMeasurements, ['Nominal']); + })); + y && (d.color = y.name), p && f ? (d.x = p.name, d.y = f.name) : n = 0; + } + if ('area_chart' === a) { + var _ = e.find((function(e) { + return v(e.levelOfMeasurements, ['Time', 'Ordinal']); + })), C = e.find((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })); + _ && C ? (d.x = _.name, d.y = C.name) : n = 0; + } + if ('bar_chart' === a) { + var x = e.filter((function(e) { + return b(e.levelOfMeasurements, ['Nominal']); + })).sort(g), P = x[0], O = x[1], S = e.find((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })); + S && P ? (d.y = P.name, d.x = S.name, O && (d.color = O.name)) : n = 0; + } + if ('column_chart' === a) { + var R = e.filter((function(e) { + return b(e.levelOfMeasurements, ['Nominal']); + })).sort(g), k = R[0], w = R[1], Q = e.find((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })); + k && Q ? (d.y = Q.name, d.x = k.name, w && (d.color = w.name)) : n = 0; + } + if ('grouped_bar_chart' === a || 'stacked_bar_chart' === a || 'percent_stacked_bar_chart' === a) { + var D = e.filter((function(e) { + return b(e.levelOfMeasurements, ['Nominal']); + })).sort(g), M = D[0], T = D[1], A = e.find((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })); + M && T && A ? (d.y = M.name, d.y2 = T.name, d.x = A.name) : n = 0; + } + if ('grouped_column_chart' === a || 'stacked_column_chart' === a || 'percent_stacked_column_chart' === a) { + var N = e.filter((function(e) { + return b(e.levelOfMeasurements, ['Nominal']); + })).sort(g), L = N[0], F = N[1], G = e.find((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })); + L && F && G ? (d.x = L.name, d.x2 = F.name, d.y = G.name) : n = 0; + } + if ('stacked_area_chart' === a || 'percent_stacked_area_chart' === a) { + var j = e.find((function(e) { + return v(e.levelOfMeasurements, ['Time', 'Ordinal']); + })), I = e.find((function(e) { + return b(e.levelOfMeasurements, ['Nominal']); + })), B = e.find((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })); + j && I && B ? (d.x = j.name, d.x2 = I.name, d.y = B.name) : n = 0; + } + if ('radar_chart' === a) { + var z = e.filter((function(e) { + return b(e.levelOfMeasurements, ['Nominal']); + })).sort(g), E = z[0], H = z[1], W = e.find((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })); + E && H && W ? (d.angle = E.name, d.series = H.name, d.radius = W.name) : n = 0; + } + if ('scatter_plot' === a) { + var U = e.filter((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })).sort(g), q = U[0], Y = U[1], $ = e.find((function(e) { + return b(e.levelOfMeasurements, ['Nominal']); + })); + q && Y ? (d.x = q.name, d.y = Y.name, $ && (d.color = $.name)) : n = 0; + } + if ('bubble_chart' === a) { + for (var K = e.filter((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })), J = { x: K[0], y: K[1], corr: 0, size: K[2] }, X = function(e) { + for (var a = function(a) { + var t = c.pearson(K[e], K[a]); + Math.abs(t) > J.corr && (J.x = K[e], J.y = K[a], J.corr = t, J.size = K[u(Array(K.length).keys()).find((function(t) { + return t !== e && t !== a; + })) || 0]); + }, t = e + 1; t < K.length; t++) a(t); + }, Z = 0; Z < K.length; Z++) X(Z); + var V = J.x, ee = J.y, ae = J.size, te = e.find((function(e) { + return v(e.levelOfMeasurements, ['Nominal']); + })); + V && ee && ae && te ? (d.x = V.name, d.y = ee.name, d.size = ae.name, d.color = te.name) : n = 0; + } + if ('histogram' === a) { + var re = e.find((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })); + re ? d.x = re.name : n = 0; + } + if ('heatmap' === a) { + var ne = e.filter((function(e) { + return v(e.levelOfMeasurements, ['Nominal', 'Ordinal']); + })).sort(g), ie = ne[0], oe = ne[1], ce = e.find((function(e) { + return b(e.levelOfMeasurements, ['Interval']); + })); + ie && oe && ce ? (d.x = ie.name, d.y = oe.name, d.color = ce.name) : n = 0; + } + return { type: a, channels: d, score: n }; + })).filter((function(e) { + return e.score && 0 !== e.score && (0, s.translate)(e.type); + })).sort((function(e, a) { + return e.score < a.score ? 1 : e.score > a.score ? -1 : 0; + })); + return console.log('🍒🍒🍒🍒🍒🍒 resultList 🍒🍒🍒🍒🍒🍒'), console.log(n), n; + } + }, function(e, a, t) { + 'use strict'; + + function r(e) { + return (r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && 'function' == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? 'symbol' : typeof e; + })(e); + } + + Object.defineProperty(a, '__esModule', { value: !0 }), Object.defineProperty(a, 'Rule', { + enumerable: !0, + get: function() { + return i.default; + }, + }), Object.defineProperty(a, 'Preferences', { + enumerable: !0, get: function() { + return i.Preferences; + }, + }), a.default = void 0; + var n, i = function(e) { + if (e && e.__esModule) return e; + if (null === e || 'object' !== r(e) && 'function' != typeof e) return { default: e }; + var a = o(); + if (a && a.has(e)) return a.get(e); + var t = {}, n = Object.defineProperty && Object.getOwnPropertyDescriptor; + for (var i in e) if (Object.prototype.hasOwnProperty.call(e, i)) { + var c = n ? Object.getOwnPropertyDescriptor(e, i) : null; + c && (c.get || c.set) ? Object.defineProperty(t, i, c) : t[i] = e[i]; + } + t.default = e, a && a.set(e, t); + return t; + }(t(1)); + + function o() { + if ('function' != typeof WeakMap) return null; + var e = new WeakMap; + return o = function() { + return e; + }, e; + } + + var c = ((n = t(6)) && n.__esModule ? n : { default: n }).default; + a.default = c; + }, function(e, a, t) { + 'use strict'; + Object.defineProperty(a, '__esModule', { value: !0 }), a.default = void 0; + var r, n = (r = t(1)) && r.__esModule ? r : { default: r }; + + function i(e) { + if ('undefined' == typeof Symbol || null == e[Symbol.iterator]) { + if (Array.isArray(e) || (e = function(e, a) { + if (!e) return; + if ('string' == typeof e) return o(e, a); + var t = Object.prototype.toString.call(e).slice(8, -1); + 'Object' === t && e.constructor && (t = e.constructor.name); + if ('Map' === t || 'Set' === t) return Array.from(e); + if ('Arguments' === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)) return o(e, a); + }(e))) { + var a = 0, t = function() { + }; + return { + s: t, n: function() { + return a >= e.length ? { done: !0 } : { done: !1, value: e[a++] }; + }, e: function(e) { + throw e; + }, f: t, + }; + } + throw new TypeError('Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.'); + } + var r, n, i = !0, c = !1; + return { + s: function() { + r = e[Symbol.iterator](); + }, n: function() { + var e = r.next(); + return i = e.done, e; + }, e: function(e) { + c = !0, n = e; + }, f: function() { + try { + i || null == r.return || r.return(); + } finally { + if (c) throw n; + } + }, + }; + } + + function o(e, a) { + (null == a || a > e.length) && (a = e.length); + for (var t = 0, r = new Array(a); t < a; t++) r[t] = e[t]; + return r; + } + + var c = (0, t(2).CKBJson)('en-US', !0), s = Object.keys(c); + + function l(e, a) { + return e.distinct < a.distinct ? 1 : e.distinct > a.distinct ? -1 : 0; + } + + function d(e, a) { + return a.every((function(a) { + return e.includes(a); + })); + } + + function u(e, a) { + return a.some((function(a) { + return e.includes(a); + })); + } + + function m(e, a) { + var t = a.map((function(e) { + return e.levelOfMeasurements; + })); + if (t) { + var r, n = 0, o = i(t); + try { + for (o.s(); !(r = o.n()).done;) { + var c = r.value; + c && u(c, e.fieldConditions) && (n += 1); + } + } catch (e) { + o.e(e); + } finally { + o.f(); + } + if (n >= e.minQty && (n <= e.maxQty || '*' === e.maxQty)) return !0; + } + return !1; + } + + var h = [new n.default('data-check', 'HARD', s, 1, (function(e) { + var a = 0, t = e.dataProps, r = e.chartType; + if (t && r && c[r]) { + a = 1; + var n, o = i(c[r].dataPres || []); + try { + for (o.s(); !(n = o.n()).done;) { + if (!m(n.value, t)) return a = 0; + } + } catch (e) { + o.e(e); + } finally { + o.f(); + } + } + return a; + })), new n.default('data-field-qty', 'HARD', s, 1, (function(e) { + var a = 0, t = e.dataProps, r = e.chartType; + if (t && r && c[r]) { + a = 1; + var n = (c[r].dataPres || []).map((function(e) { + return e.minQty; + })).reduce((function(e, a) { + return e + a; + })); + if (t.length) t.length >= n && (a = 1); + } + return a; + })), new n.default('no-redundant-field', 'HARD', s, 1, (function(e) { + var a = 0, t = e.dataProps, r = e.chartType; + if (t && r && c[r]) { + var n = (c[r].dataPres || []).map((function(e) { + return '*' === e.maxQty ? 99 : e.maxQty; + })).reduce((function(e, a) { + return e + a; + })); + if (t.length) t.length <= n && (a = 1); + } + return a; + })), new n.default('purpose-check', 'HARD', s, 1, (function(e) { + var a = 0, t = e.chartType, r = e.purpose; + if (!r) return a = 1; + if (t && c[t] && r && (c[t].purpose || '').includes(r)) return a = 1; + return a; + })), new n.default('series-qty-limit', 'SOFT', ['pie_chart', 'donut_chart', 'radar_chart', 'rose_chart'], .8, (function(e) { + var a = 0, t = e.dataProps, r = e.chartType, n = 6; + if ('pie_chart' !== r && 'donut_chart' !== r && 'rose_chart' !== r || (n = 6), 'radar_chart' === r && (n = 8), t) { + var i = t.find((function(e) { + return d(e.levelOfMeasurements, ['Nominal']); + })), o = i && i.count ? i.count : 0; + o >= 2 && o <= n && (a = 2 / o); + } + return a; + })), new n.default('bar-series-qty', 'SOFT', ['bar_chart', 'grouped_bar_chart', 'stacked_bar_chart', 'percent_stacked_bar_chart', 'column_chart', 'grouped_column_chart', 'stacked_column_chart', 'percent_stacked_column_chart'], .5, (function(e) { + var a = 0, t = e.dataProps, r = e.chartType; + if (t && r) { + var n = t.find((function(e) { + return d(e.levelOfMeasurements, ['Nominal']); + })), i = n && n.count ? n.count : 0; + i >= 2 && i <= 20 ? a = 1 : i > 20 && (a = 20 / i); + } + return a; + })), new n.default('line-field-time-ordinal', 'SOFT', ['line_chart', 'area_chart', 'stacked_area_chart', 'percent_stacked_area_chart'], 1, (function(e) { + var a = 0, t = e.dataProps; + t && (t.find((function(e) { + return u(e.levelOfMeasurements, ['Ordinal', 'Time']); + })) && (a = 1)); + return a; + })), new n.default('landscape-or-portrait', 'SOFT', ['bar_chart', 'grouped_bar_chart', 'stacked_bar_chart', 'percent_stacked_bar_chart', 'column_chart', 'grouped_column_chart', 'stacked_column_chart', 'percent_stacked_column_chart'], .3, (function(e) { + var a = 0, t = e.dataProps, r = e.chartType, n = e.preferences; + return t && r && n && n.canvasLayout && ('portrait' === n.canvasLayout && ['bar_chart', 'grouped_bar_chart', 'stacked_bar_chart', 'percent_stacked_bar_chart'].includes(r) || 'landscape' === n.canvasLayout && ['column_chart', 'grouped_column_chart', 'stacked_column_chart', 'percent_stacked_column_chart'].includes(r)) && (a = 1), a; + })), new n.default('diff-pie-sector', 'SOFT', ['pie_chart', 'donut_chart'], .5, (function(e) { + var a = 0, t = e.dataProps; + if (t) { + var r = t.find((function(e) { + return d(e.levelOfMeasurements, ['Interval']); + })); + if (r && r.sum && r.samples) { + var n = 1 / r.sum, i = r.samples.map((function(e) { + return e * n; + })).reduce((function(e, a) { + return e * a; + })), o = r.samples.length, c = Math.pow(1 / o, o); + a = Math.abs(c - Math.abs(i)) / c; + } + } + return a; + })), new n.default('nominal-enum-combinatorial', 'SOFT', s, 1, (function(e) { + var a = 0, t = e.dataProps, r = e.chartType; + if (t && s) { + var n = t.filter((function(e) { + return d(e.levelOfMeasurements, ['Nominal']); + })); + if (n.length >= 2) { + var i = n.sort(l), o = i[0], c = i[1]; + if (o.distinct === o.count && ['bar_chart', 'column_chart'].includes(r) && (a = 1), o.count && o.distinct && c.distinct && o.count >= o.distinct * c.distinct) { + ['grouped_bar_chart', 'grouped_column_chart', 'stacked_bar_chart', 'stacked_column_chart'].includes(r) && (a = 1); + } + } + } + return a; + })), new n.default('limit-series', 'SOFT', s, 1, (function(e) { + var a = 0, t = e.dataProps, r = e.chartType; + if (t && s) { + var n = t.filter((function(e) { + return u(e.levelOfMeasurements, ['Nominal', 'Ordinal']); + })); + if (n.length >= 2) { + var i = n.sort(l)[1]; + i.distinct && (a = 1 / i.distinct, i.distinct > 6 && 'heatmap' === r ? a = 2 : 'heatmap' === r && (a = 0)); + } + } + return a; + }))]; + a.default = h; + }, function(e, a, t) { + 'use strict'; + Object.defineProperty(a, '__esModule', { value: !0 }), a.uuid = function() { + return ''.concat('xxxx-xxxx-xxxx'.replace(/x/g, (function() { + return (16 * Math.random() | 0).toString(16); + }))); + }, a.getElementDispay = function(e) { + return getComputedStyle(e, null).display; + }, a.getPosition = function(e) { + var a = e.getBoundingClientRect(), t = a.top, r = a.left; + return { top: t + window.scrollY, left: r + window.scrollX }; + }, a.translate = function(e) { + return { + line_chart: 'Line', + step_line_chart: 'StepLine', + area_chart: 'Area', + stacked_area_chart: 'StackArea', + percent_stacked_area_chart: 'PercentageStackArea', + column_chart: 'Column', + grouped_column_chart: 'GroupColumn', + stacked_column_chart: 'StackColumn', + percent_stacked_column_chart: 'PercentageStackColumn', + bar_chart: 'Bar', + grouped_bar_chart: 'GroupBar', + stacked_bar_chart: 'StackBar', + percent_stacked_bar_chart: 'PercentageStackBar', + histogram: 'Histogram', + pie_chart: 'Pie', + donut_chart: 'Ring', + rose_chart: 'Rose', + scatter_plot: 'Scatter', + bubble_chart: 'Bubble', + radar_chart: 'Radar', + heatmap: 'Matrix', + }[e] || e; + }, a.createLayer = function(e) { + ['relative', 'absolute', 'fixed'].includes(getComputedStyle(e).position) || (e.style.position = 'relative'); + var a = document.createElement('div'); + return a.style.height = '100%', a.style.width = '100%', a.style.position = 'absolute', a.style.top = '0px', a.style.left = '0px', a.style.pointerEvents = 'none', e.appendChild(a), a; + }, a.DEFAULT_FEEDBACK = function(e) { + return function(a) { + var t = document.createElement('div'); + t.className = ''.concat(r.CLASS_PREFIX, 'no_data_content'), t.innerHTML = '\n
\n \n
\n
'.concat(e, '
\n '), a.appendChild(t); + }; + }; + var r = t(8); + }, function(e, a, t) { + 'use strict'; + Object.defineProperty(a, '__esModule', { value: !0 }), a.CLASS_PREFIX = void 0; + var r = '__AUTO_CHART__'; + a.CLASS_PREFIX = r; + var n = '\n .'.concat(r, 'toolbar {\n position: absolute;\n bottom: 0px;\n left: 0px;\n z-index: 10;\n display: none;\n box-sizing: border-box;\n }\n .').concat(r, 'toolbar * {\n box-sizing: border-box;\n }\n .').concat(r, 'advice_container {\n width: 290px;\n display: none;\n padding: 0 16px;\n background: #454857;\n position: absolute;\n bottom: 100%;\n left: 0;\n max-height: 195px;\n overflow: auto;\n }\n .').concat(r, 'advice {\n height: 65px;\n font-size: 12px;\n color: #FFFFFF;\n display: flex;\n padding: 9px 0;\n cursor: pointer;\n border-bottom: 1px solid #D8D8D8;\n }\n .').concat(r, 'advice img {\n height: 46px;\n width: 46px;\n background: #fff;\n }\n .').concat(r, 'advice * {\n pointer-events: none;\n line-height: 46px;\n font-size: 14px;\n }\n .').concat(r, 'advice>div:nth-child(1) {\n width: 46px;\n }\n .').concat(r, 'advice>div:nth-child(2) {\n width: 46px;\n }\n .').concat(r, 'advice>div:nth-child(3) {\n margin-left: 8px;\n flex-grow: 1;\n }\n .').concat(r, 'advice>div:nth-child(3) div {\n line-height: 23px;\n text-align: right;\n }\n .').concat(r, 'advice:last-child{\n border: none;\n }\n .').concat(r, 'chart_type_btn {\n height: 24px;\n width: 24px;\n text-align: center;\n display: inline-block;\n padding: 6px;\n background: #454857;\n color: #fff;\n cursor: pointer;\n }\n .').concat(r, 'chart_type_btn img {\n pointer-events: none;\n height: 12px;\n width: 12px;\n vertical-align: top;\n }\n .').concat(r, 'dev_btn {\n height: 27px;\n line-height: 27px;\n background: #454857;\n padding: 0 7px;\n color: #fff;\n display: none;\n position: absolute;\n bottom: 0;\n right: 0;\n user-select: none;\n cursor: pointer;\n }\n .').concat(r, 'dev_panel {\n border-radius: 5px;\n overflow: hidden;\n box-shadow: 10px 10px 20px rgba(0, 0, 0, 0.25);\n box-sizing: border-box;\n position: absolute;\n background: #fff;\n z-index: 1000;\n display: none;\n }\n .').concat(r, 'dev_panel header {\n box-sizing: border-box;\n height: ').concat(32, 'px;\n width: 100%;\n padding-left: 16px;\n line-height: ').concat(32, 'px;\n cursor: move; \n color: #fff;\n position: relative;\n z-index: 1;\n background-color: #454857;\n box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.45);\n }\n .').concat(r, 'dev_panel_close {\n margin: 8px;\n height: 16px;\n width: 16px;\n border-radius: 50%;\n background: #fff;\n text-align: center;\n color: #454857;\n font-size: 14px;\n line-height: 14px;\n cursor: pointer;\n float: right;\n }\n .').concat(r, 'dev_panel_content {\n width: 100%;\n height: calc(100% - ').concat(32, 'px);\n }\n .').concat(r, 'dev_panel_content iframe {\n height: 100%;\n width: 100%;\n border: none;\n }\n .').concat(r, 'dev_panel_mask {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: -1;\n }\n .').concat(r, 'no_data_content, .').concat(r, 'mock_guide {\n color: #aaa;\n text-align: center;\n position: relative;\n top: 50%;\n transform: translateY(-50%);\n }\n .').concat(r, 'mock_guide_button {\n margin-top: 22px;\n border-radius: 3px;\n height: 30px;\n width: 116px;\n font-size: 14px;\n display: inline-block;\n line-height: 30px;\n background: #454859;\n color: #fff;\n cursor: pointer;\n }\n \n'), + i = document.createElement('style'); + i.textContent = n, document.head.prepend(i); + }, function(e, a, t) { + 'use strict'; + Object.defineProperty(a, '__esModule', { value: !0 }), a.getMappingForLib = function(e) { + return { typeMapping: n[e], configMapping: i[e] }; + }; + var r = t(10), n = { G2Plot: r.G2PLOT_TYPE_MAPPING, antdCharts: r.G2PLOT_TYPE_MAPPING }, + i = { G2Plot: r.G2PLOT_CONFIG_MAPPING, antdCharts: r.G2PLOT_CONFIG_MAPPING }; + }, function(e, a, t) { + 'use strict'; + Object.defineProperty(a, '__esModule', { value: !0 }), a.G2PLOT_TYPE_MAPPING = a.G2PLOT_CONFIG_MAPPING = void 0; + a.G2PLOT_CONFIG_MAPPING = { + line_chart: { x: 'xField', y: 'yField', color: 'seriesField' }, + area_chart: { x: 'xField', y: 'yField' }, + bar_chart: { x: 'xField', y: 'yField', color: 'colorField' }, + column_chart: { x: 'xField', y: 'yField', color: 'colorField' }, + pie_chart: { angle: 'angleField', color: 'colorField' }, + donut_chart: { angle: 'angleField', color: 'colorField' }, + grouped_bar_chart: { y: 'yField', y2: 'groupField', x: 'xField' }, + stacked_bar_chart: { y: 'yField', y2: 'stackField', x: 'xField' }, + percent_stacked_bar_chart: { y: 'yField', y2: 'stackField', x: 'xField' }, + grouped_column_chart: { x: 'xField', x2: 'groupField', y: 'yField' }, + stacked_column_chart: { x: 'xField', x2: 'stackField', y: 'yField' }, + percent_stacked_column_chart: { x: 'xField', x2: 'stackField', y: 'yField' }, + stacked_area_chart: { x: 'xField', x2: 'stackField', y: 'yField' }, + percent_stacked_area_chart: { x: 'xField', x2: 'stackField', y: 'yField' }, + radar_chart: { angle: 'angleField', radius: 'radiusField', series: 'seriesField' }, + scatter_plot: { x: 'xField', y: 'yField', color: 'colorField' }, + bubble_chart: { x: 'xField', y: 'yField', size: 'sizeField', color: 'colorField' }, + heatmap: { x: 'xField', y: 'yField', color: 'colorField', size: 'sizeField' }, + density_heatmap: { x: 'xField', y: 'yField', color: 'colorField' }, + step_line_chart: { x: 'xField', y: 'yField', color: 'seriesField' }, + funnel_chart: { x: 'xField', y: 'yField' }, + waterfall_chart: { x: 'xField', y: 'yField' }, + mirror_funnel_chart: { x: 'xField', y: 'yField', x2: 'compareField' }, + histogram: { x: 'binField' }, + }; + a.G2PLOT_TYPE_MAPPING = { + line_chart: 'Line', + step_line_chart: 'StepLine', + area_chart: 'Area', + stacked_area_chart: 'StackedArea', + percent_stacked_area_chart: 'PercentageStackedArea', + column_chart: 'Column', + grouped_column_chart: 'GroupedColumn', + stacked_column_chart: 'StackedColumn', + percent_stacked_column_chart: 'PercentageStackedColumn', + bar_chart: 'Bar', + grouped_bar_chart: 'GroupedBar', + stacked_bar_chart: 'StackedBar', + percent_stacked_bar_chart: 'PercentageStackedBar', + histogram: 'Histogram', + pie_chart: 'Pie', + donut_chart: 'Donut', + rose_chart: 'Rose', + scatter_plot: 'Scatter', + bubble_chart: 'Bubble', + radar_chart: 'Radar', + heatmap: 'Heatmap', + }; + }, function(e, a, t) { + 'use strict'; + t.r(a), t.d(a, 'type', (function() { + return j; + })), t.d(a, 'typeAll', (function() { + return I; + })), t.d(a, 'isOrdinal', (function() { + return B; + })), t.d(a, 'isConst', (function() { + return z; + })), t.d(a, 'isUnique', (function() { + return E; + })), t.d(a, 'isDiscrete', (function() { + return H; + })), t.d(a, 'isContinuous', (function() { + return W; + })), t.d(a, 'isInterval', (function() { + return U; + })), t.d(a, 'isNominal', (function() { + return q; + })), t.d(a, 'isTime', (function() { + return Y; + })), t.d(a, 'pearson', (function() { + return $; + })); + var r = t(0), n = '([-_./\\s])', i = '\\d{2,4}', o = '(0?[1-9]|1[012])', c = '(0?[1-9]|[12]\\d|3[01])', + s = '(0?\\d|1\\d|2[0-4])', l = '(0?\\d|[012345]\\d)', d = '(Z|[+-]' + s + '(:' + l + ')?)', + u = ['' + i + n + '?W([0-4]\\d|5[0-2])(' + n + '?([1-7]))?', '' + o + n + '?' + c + n + '?' + i, '' + i + n + '?' + o + n + '?' + c, '' + i + n + o, '' + i + n + '?((([0-2]\\d|3[0-5])\\d)|36[0-6])'], + m = [s + ':?' + l + ':?(0?\\d|[012345]\\d)([.,]\\d{1,4})?' + d + '?', s + ':?' + l + '?' + d], + h = Object(r.c)(u, m); + u.forEach((function(e) { + m.forEach((function(a) { + h.push(e + '[T\\s]' + a); + })); + })); + var p = h.map((function(e) { + return new RegExp('^' + e + '$'); + })); + var f = [/^(19|20)\d{2}$/, /^\d{4}(0?[1-9]|1[012])$/, /^\d{4}(0?[1-9]|1[012])(0?[1-9]|[12]\d|3[01])$/]; + + function y(e, a) { + if (e) throw new Error(a); + } + + function _(e) { + return null == e || '' === e || Number.isNaN(e) || 'null' === e; + } + + function g(e) { + return 'number' == typeof e ? Number.isInteger(e) : !('string' != typeof e || !C(e)) && !e.includes('.'); + } + + function b(e) { + return 'number' == typeof e ? !Number.isNaN(e) && !Number.isInteger(e) : !('string' != typeof e || !C(e)) && e.includes('.'); + } + + function v(e) { + return !(!e || Object.getPrototypeOf(e) !== Date.prototype) || 'string' == typeof e && function(e) { + var a, t; + try { + for (var n = Object(r.d)(p), i = n.next(); !i.done; i = n.next()) { + if (i.value.test(e.trim())) return !0; + } + } catch (e) { + a = { error: e }; + } finally { + try { + i && !i.done && (t = n.return) && t.call(n); + } finally { + if (a) throw a.error; + } + } + return !1; + }(e); + } + + function C(e) { + var a, t, n = !1; + /^[+-]/.test(e) && (e = e.slice(1)); + try { + for (var i = Object(r.d)(e), o = i.next(); !o.done; o = i.next()) { + var c = o.value; + if ('.' === c) { + if (!1 === n) { + n = !0; + continue; + } + return !1; + } + if (!/[0-9]/.test(c)) return !1; + } + } catch (e) { + a = { error: e }; + } finally { + try { + o && !o.done && (t = i.return) && t.call(i); + } finally { + if (a) throw a.error; + } + } + return '' !== e.trim(); + } + + var x = new WeakMap; + + function P(e, a, t) { + return x.get(e) || x.set(e, new Map), x.get(e).set(a, t), t; + } + + function O(e, a) { + var t = x.get(e); + if (t) return t.get(a); + } + + function S(e) { + var a = O(e, 'min'); + return void 0 !== a ? a : P(e, 'min', Math.min.apply(Math, Object(r.c)(e))); + } + + function R(e) { + var a = O(e, 'max'); + return void 0 !== a ? a : P(e, 'max', Math.max.apply(Math, Object(r.c)(e))); + } + + function k(e) { + var a = O(e, 'minIndex'); + return void 0 !== a ? a : P(e, 'minIndex', function(e) { + var a = e[0], t = 0; + for (var r in e) e[r] < a && (t = Number(r), a = e[r]); + return t; + }(e)); + } + + function w(e) { + var a = O(e, 'maxIndex'); + return void 0 !== a ? a : P(e, 'maxIndex', function(e) { + var a = e[0], t = 0; + for (var r in e) e[r] > a && (t = Number(r), a = e[r]); + return t; + }(e)); + } + + function Q(e) { + var a = O(e, 'sum'); + return void 0 !== a ? a : P(e, 'sum', e.reduce((function(e, a) { + return a + e; + }), 0)); + } + + function D(e) { + var a = {}; + return e.forEach((function(e) { + a[e] ? a[e] += 1 : a[e] = 1; + })), a; + } + + function M(e) { + return e.sort((function(e, a) { + return e > a ? 1 : -1; + })); + } + + function T(e, a, t) { + return void 0 === t && (t = !1), y(a <= 0 || a >= 100, 'percent cannot be between (0, 100)'), (t ? e : M(e))[Math.ceil(e.length * a / 100) - 1]; + } + + function A(e) { + return Q(e) / e.length; + } + + function N(e) { + var a = A(e), t = O(e, 'variance'); + return void 0 === t ? P(e, 'variance', e.reduce((function(e, t) { + return e + Math.pow(t - a, 2); + }), 0) / e.length) : t; + } + + function L(e) { + return Math.sqrt(N(e)); + } + + function F(e, a) { + return function(e, a) { + return y(e.length !== a.length, 'x and y must has same length'), A(e.map((function(e, t) { + return e * a[t]; + }))) - A(e) * A(a); + }(e, a) / (Math.sqrt(A(e.map((function(e) { + return e * e; + }))) - Math.pow(A(e), 2)) * Math.sqrt(A(a.map((function(e) { + return e * e; + }))) - Math.pow(A(a), 2))); + } + + function G(e) { + return _(e) ? 'null' : 'number' == typeof e ? Number.isInteger(e) ? 'integer' : 'float' : 'string' == typeof e && C(e) ? e.includes('.') ? 'float' : 'integer' : v(e) ? 'date' : 'string'; + } + + function j(e) { + var a, t = e.map((function(e) { + return _(e) ? null : e; + })), r = D(t), n = r.null ? t.filter((function(e) { + return null !== e; + })) : t, i = t.map((function(e) { + return G(e); + })), o = Object.keys(D(i)).filter((function(e) { + return 'null' !== e; + })); + switch (o.length) { + case 0: + a = 'null'; + break; + case 1: + if ('integer' === (a = o[0])) for (var c = t.filter((function(e) { + return null !== e; + })), s = function(e) { + var t = f[e]; + if (!c.some((function(e) { + return !t.test(e); + }))) return a = 'date', 'break'; + }, l = 0; l < f.length; l++) { + if ('break' === s(l)) break; + } + break; + case 2: + a = o.includes('integer') && o.includes('float') ? 'float' : 'string'; + break; + default: + a = 'string'; + } + var d, u = function(e) { + return Array.from(new Set(e)); + }(n), m = { + count: e.length, + distinct: u.length, + type: o.length <= 1 ? o[0] || 'null' : 'mixed', + recommendation: a, + missing: r.null || 0, + samples: e, + valueMap: r, + }; + if (o.length > 1) { + var h = {}; + o.forEach((function(e) { + 'date' === e ? h.date = j(n.filter(v)) : 'integer' === e ? h.integer = j(n.filter(g)) : 'float' === e ? h.float = j(n.filter(b)) : 'string' === e && (h.string = j(n.filter((function(e) { + return 'string' === G(e); + })))); + })), m.meta = h; + } + return 2 === m.distinct && 'date' !== m.recommendation && (t.length >= 100 ? m.recommendation = 'boolean' : (d = u, [[!0, !1], [0, 1], ['true', 'false'], ['Yes', 'No'], ['True', 'False'], ['0', '1'], ['是', '否']].some((function(e) { + return d.every((function(a) { + return e.includes(a); + })); + })) && (m.recommendation = 'boolean'))), 'string' === a && Object.assign(m, function(e) { + var a = e.map((function(e) { + return e.length; + })); + return { + maxLength: R(a), minLength: S(a), meanLength: A(a), containsChars: e.some((function(e) { + return /[A-z]/.test(e); + })), containsDigits: e.some((function(e) { + return /[0-9]/.test(e); + })), containsSpace: e.some((function(e) { + return /\s/.test(e); + })), containsNonWorlds: !1, + }; + }(n.map((function(e) { + return '' + e; + })))), 'integer' !== a && 'float' !== a || Object.assign(m, function(e) { + return { + minimum: S(e), + maximum: R(e), + mean: A(e), + percentile5: T(e, 5), + percentile25: T(e, 25), + percentile50: T(e, 50), + percentile75: T(e, 75), + percentile95: T(e, 95), + sum: Q(e), + variance: N(e), + stdev: L(e), + zeros: e.filter((function(e) { + return 0 === e; + })).length, + }; + }(n.map((function(e) { + return 1 * e; + })))), 'date' === a && Object.assign(m, function(e, a) { + void 0 === a && (a = !1); + var t = e.map((function(e) { + if (a) { + var t = '' + e; + if (8 === t.length) return new Date(t.substr(0, 4) + '/' + t.substr(4, 2) + '/' + t.substr(6, 2)).getTime(); + } + return new Date(e).getTime(); + })); + return { minimum: e[k(t)], maximum: e[w(t)] }; + }(n, 'integer' === m.type)), m; + } + + function I(e, a) { + if (y(a && 0 === a.length, 'fields.length woudle greater than 0'), !a) { + var t = new Set; + e.forEach((function(e) { + return Object.keys(e).forEach((function(e) { + return t.add(e); + })); + })), a = Object(r.c)(t); + } + return a.map((function(a) { + return Object(r.a)(Object(r.a)({}, j(e.map((function(e) { + return e[a]; + })))), { name: a }); + })); + } + + function B(e) { + var a = e.samples; + if ('string' !== e.recommendation) return !1; + if (z(e)) return !1; + for (var t = a.filter((function(e) { + return !_(e); + })), r = null, n = null, i = -1, o = -1; ;) { + for (var c = !0, s = 0; s < t.length; s++) { + var l = (d = t[s])[i + 1]; + if (null !== r && 0 !== s || (r = l), l !== r) { + c = !1; + break; + } + } + if (!c) break; + i += 1; + } + for (; ;) { + for (c = !0, s = 0; s < t.length; s++) { + var d; + l = (d = t[s])[d.length - 1 - (o + 1)]; + if (null !== n && 0 !== s || (n = l), l !== n) { + c = !1; + break; + } + } + if (!c) break; + o += 1; + } + var u = [/\d+/, /(零|一|二|三|四|五|六|七|八|九|十)+/, /(一|二|三|四|五|六|日)/, /^[a-z]$/, /^[A-Z]$/]; + if (-1 === i && -1 === o) return !1; + var m = t.map((function(e) { + return e.slice(-1 === i ? 0 : i + 1, -1 === o ? void 0 : e.length - o - 1); + })), h = function(e) { + var a = u[e]; + if (!m.some((function(e) { + return !a.test(e); + }))) return { value: !0 }; + }; + for (s = 0; s < u.length; s++) { + var p = h(s); + if ('object' == typeof p) return p.value; + } + return !1; + } + + function z(e) { + return 1 === e.distinct; + } + + function E(e) { + return e.distinct === e.count; + } + + function H(e) { + return 'integer' === e.recommendation; + } + + function W(e) { + return 'float' === e.recommendation; + } + + function U(e) { + return 'integer' === e.recommendation || 'float' === e.recommendation; + } + + function q(e) { + return 'boolean' === e.recommendation || 'string' === e.recommendation && !B(e); + } + + function Y(e) { + return 'date' === e.recommendation; + } + + function $(e, a) { + var t = ['integer', 'float']; + y(!(t.includes(e.recommendation) && t.includes(a.recommendation)), 'field\'s type must be integer or float'); + var n = e.samples, i = a.samples, o = Object(r.b)(function(e, a) { + for (var t = [], r = [], n = 0; n < e.length; n++) _(e[n]) || _(a[n]) || (t.push(e[n]), r.push(a[n])); + return [t, r]; + }(n, i), 2), c = o[0], s = o[1]; + return F(c.map(Number.parseFloat), s.map(Number.parseFloat)); + } + }]); +})); +//# sourceMappingURL=index.js.map \ No newline at end of file From b981d8be031964d4861730f4236229d05eff32ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=B2=B3?= <445798420@qq.com> Date: Sun, 28 Jun 2020 14:48:29 +0800 Subject: [PATCH 2/3] =?UTF-8?q?CHART-13666=20=E5=9B=BE=E8=A1=A8=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=8E=A8=E8=8D=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mainframe/chart/info/ChartInfo.java | 25 +- .../chart/info/ChartInfoCollector.java | 17 +- .../com/fr/design/chart/AutoChartDialog.java | 4 +- .../fr/design/chart/AutoChartTypePane.java | 36 +- .../java/com/fr/design/chart/ChartDialog.java | 7 +- .../design/chart/auto/AutoChartDataModel.java | 46 - .../design/chart/auto/AutoTypeCalculate.java | 17 +- .../com/fr/design/chart/auto/ColumnInfo.java | 56 - .../strategy/AbstractAutoTypeStrategy.java | 265 -- .../chart/auto/strategy/AutoTypeStrategy.java | 22 - .../design/chart/auto/strategy/AvaType.java | 79 - .../chart/auto/strategy/imp/AvaStrategy.java | 106 - .../strategy/imp/BubbleChartStrategy.java | 76 - .../strategy/imp/SingleDimensionStrategy.java | 68 - .../strategy/imp/SingleTargetStrategy.java | 45 - .../com/fr/design/chart/auto/js/analyze.js | 66 - .../com/fr/design/chart/auto/js/ava.js | 2729 ----------------- 17 files changed, 74 insertions(+), 3590 deletions(-) delete mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/AutoChartDataModel.java delete mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/ColumnInfo.java delete mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AbstractAutoTypeStrategy.java delete mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AutoTypeStrategy.java delete mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AvaType.java delete mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/AvaStrategy.java delete mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/BubbleChartStrategy.java delete mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleDimensionStrategy.java delete mode 100644 designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleTargetStrategy.java delete mode 100644 designer-chart/src/main/resources/com/fr/design/chart/auto/js/analyze.js delete mode 100644 designer-chart/src/main/resources/com/fr/design/chart/auto/js/ava.js diff --git a/designer-base/src/main/java/com/fr/design/mainframe/chart/info/ChartInfo.java b/designer-base/src/main/java/com/fr/design/mainframe/chart/info/ChartInfo.java index 4c546c4cd..9025b9806 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/chart/info/ChartInfo.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/chart/info/ChartInfo.java @@ -54,6 +54,8 @@ public class ChartInfo extends AbstractPointInfo { private static final String ATTR_OVER_CHART_TYPE_COUNT = "overChartTypeCount"; private static final String ATTR_IS_NEW = "isNew"; private static final String ATTR_IS_REUSE = "isReuse"; + private static final String ATTR_AUTO_CHART_CREATE_TIME = "autoChartCreateTime"; + private static final String ATTR_AUTO_CHART_ENSURE_TIME = "autoChartEnsureTime"; private static final int COMPLETE_DAY_COUNT = 3; // 判断图表是否可以上传的天数 @@ -122,10 +124,10 @@ public class ChartInfo extends AbstractPointInfo { } public static ChartInfo newInstance(ChartProvider chartProvider) { - return newInstance(chartProvider, null, false, false); + return newInstance(chartProvider, null, false, false, false); } - public static ChartInfo newInstance(ChartProvider chartProvider, String createTime, boolean isNew, boolean isReuse) { + public static ChartInfo newInstance(ChartProvider chartProvider, String createTime, boolean isNew, boolean isReuse, boolean isAutoChart) { HashMap chartConsumingMap = new HashMap<>(); String username = MarketConfig.getInstance().getBbsUsername(); @@ -163,6 +165,13 @@ public class ChartInfo extends AbstractPointInfo { chartConsumingMap.put(ATTR_OVER_CHART_TYPE_COUNT, "0"); chartConsumingMap.put(ATTR_IS_NEW, String.valueOf(isNew)); chartConsumingMap.put(ATTR_IS_REUSE, String.valueOf(isReuse)); + if (isAutoChart) { + chartConsumingMap.put(ATTR_AUTO_CHART_CREATE_TIME, createTime); + chartConsumingMap.put(ATTR_AUTO_CHART_ENSURE_TIME, typeTime); + } else { + chartConsumingMap.put(ATTR_AUTO_CHART_CREATE_TIME, StringUtils.EMPTY); + chartConsumingMap.put(ATTR_AUTO_CHART_ENSURE_TIME, StringUtils.EMPTY); + } ChartInfo chartInfo = new ChartInfo(chartId, templateId, book); chartInfo.chartConsumingMap = chartConsumingMap; @@ -202,6 +211,9 @@ public class ChartInfo extends AbstractPointInfo { writer.attr(ATTR_OVER_CHART_TYPE_COUNT, chartConsumingMap.get(ATTR_OVER_CHART_TYPE_COUNT)); writer.attr(ATTR_IS_NEW, chartConsumingMap.get(ATTR_IS_NEW)); writer.attr(ATTR_IS_REUSE, chartConsumingMap.get(ATTR_IS_REUSE)); + writer.attr(ATTR_AUTO_CHART_CREATE_TIME, chartConsumingMap.get(ATTR_AUTO_CHART_CREATE_TIME)); + writer.attr(ATTR_AUTO_CHART_ENSURE_TIME, chartConsumingMap.get(ATTR_AUTO_CHART_ENSURE_TIME)); + writer.end(); chartConfigInfo.writeXML(writer); @@ -238,6 +250,8 @@ public class ChartInfo extends AbstractPointInfo { chartConsumingMap.put(ATTR_OVER_CHART_TYPE_COUNT, reader.getAttrAsString(ATTR_OVER_CHART_TYPE_COUNT, "0")); chartConsumingMap.put(ATTR_IS_NEW, reader.getAttrAsString(ATTR_IS_NEW, StringUtils.EMPTY)); chartConsumingMap.put(ATTR_IS_REUSE, reader.getAttrAsString(ATTR_IS_REUSE, StringUtils.EMPTY)); + chartConsumingMap.put(ATTR_AUTO_CHART_CREATE_TIME, reader.getAttrAsString(ATTR_AUTO_CHART_CREATE_TIME, StringUtils.EMPTY)); + chartConsumingMap.put(ATTR_AUTO_CHART_ENSURE_TIME, reader.getAttrAsString(ATTR_AUTO_CHART_ENSURE_TIME, StringUtils.EMPTY)); } if (ChartConfigInfo.XML_TAG.equals(name)) { this.chartConfigInfo = (ChartConfigInfo) reader.readXMLObject(new ChartConfigInfo()); @@ -276,6 +290,10 @@ public class ChartInfo extends AbstractPointInfo { } public void updateChartType(ChartProvider chartProvider) { + updateChartType(chartProvider, false); + } + + public void updateChartType(ChartProvider chartProvider, boolean isAutoChart) { String typeTime = DateTime.now().toString("yyyy-MM-dd HH:mm:ss"); chartConsumingMap.put(ATTR_CHART_TYPE_TIME, typeTime); @@ -285,6 +303,9 @@ public class ChartInfo extends AbstractPointInfo { String count = chartConsumingMap.get(ATTR_OVER_CHART_TYPE_COUNT); count = StringUtils.isEmpty(count) ? "1" : String.valueOf(Integer.parseInt(count) + 1); chartConsumingMap.put(ATTR_OVER_CHART_TYPE_COUNT, count); + if (isAutoChart) { + chartConsumingMap.put(ATTR_AUTO_CHART_ENSURE_TIME, typeTime); + } resetChartConfigInfo(chartProvider); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/chart/info/ChartInfoCollector.java b/designer-base/src/main/java/com/fr/design/mainframe/chart/info/ChartInfoCollector.java index 87dc8ca40..cd651fc6b 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/chart/info/ChartInfoCollector.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/chart/info/ChartInfoCollector.java @@ -12,6 +12,7 @@ import com.fr.stable.StringUtils; import com.fr.stable.xml.XMLPrintWriter; import com.fr.stable.xml.XMLableReader; import com.fr.third.joda.time.DateTime; + import java.util.HashMap; import java.util.Map; @@ -49,18 +50,22 @@ public class ChartInfoCollector extends AbstractPointCollector { } public void collection(ChartProvider chartProvider, String createTime) { - collection(chartProvider, createTime, false); + collection(chartProvider, createTime, false, false); + } + + public void collection(ChartProvider chartProvider, String createTime, boolean isReuse) { + collection(chartProvider, createTime, isReuse, false); } /** * 新建图表,保存状态 */ - public void collection(ChartProvider chartProvider, String createTime, boolean isReuse) { + public void collection(ChartProvider chartProvider, String createTime, boolean isReuse, boolean isAutoChart) { String chartId = chartProvider.getChartUuid(); if (!shouldCollectInfo() || StringUtils.isEmpty(chartId)) { return; } - ChartInfo chartInfo = ChartInfo.newInstance(chartProvider, createTime, true, isReuse); + ChartInfo chartInfo = ChartInfo.newInstance(chartProvider, createTime, true, isReuse, isAutoChart); chartInfoCacheMap.put(chartId, chartInfo); } @@ -116,6 +121,10 @@ public class ChartInfoCollector extends AbstractPointCollector { * 图表类型变化,更新类型和类型确认时间 */ public void updateChartTypeTime(ChartProvider chartProvider, String oldType) { + updateChartTypeTime(chartProvider, oldType, false); + } + + public void updateChartTypeTime(ChartProvider chartProvider, String oldType, boolean isAutoChart) { if (!shouldCollectInfo() || StringUtils.isEmpty(chartProvider.getChartUuid())) { return; } @@ -123,7 +132,7 @@ public class ChartInfoCollector extends AbstractPointCollector { ChartInfo chartInfo = getOrCreateChartInfo(chartProvider, oldType); //更新类型确认时间和类型 - chartInfo.updateChartType(chartProvider); + chartInfo.updateChartType(chartProvider, isAutoChart); //重置计数 chartInfo.resetIdleDayCount(); diff --git a/designer-chart/src/main/java/com/fr/design/chart/AutoChartDialog.java b/designer-chart/src/main/java/com/fr/design/chart/AutoChartDialog.java index ddf4a0b40..058e07045 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/AutoChartDialog.java +++ b/designer-chart/src/main/java/com/fr/design/chart/AutoChartDialog.java @@ -36,11 +36,11 @@ public class AutoChartDialog extends ChartDialog { return autoChartTypePane; } - protected ActionListener getActionListener() { + protected ActionListener getActionListener(final String createTime) { return new ActionListener() { public void actionPerformed(ActionEvent e) { ChartCollection chartCollection = (ChartCollection) getChartCollection(); - autoChartTypePane.update(chartCollection); + autoChartTypePane.update(chartCollection, createTime); if (chartCollection.getChartCount() > 0) { doOK(); } else { diff --git a/designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java b/designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java index a7ad368fb..1d827c00f 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java +++ b/designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java @@ -2,7 +2,6 @@ package com.fr.design.chart; import com.fr.base.chart.chartdata.CallbackEvent; import com.fr.chart.chartattr.ChartCollection; -import com.fr.chartx.attr.ChartProvider; import com.fr.design.chart.auto.AutoTypeCalculate; import com.fr.design.data.DesignTableDataManager; import com.fr.design.data.datapane.TableDataComboBox; @@ -15,6 +14,7 @@ import com.fr.design.gui.iprogressbar.AutoProgressBar; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.chart.info.ChartInfoCollector; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.GeneralUtils; import com.fr.log.FineLoggerFactory; @@ -225,8 +225,9 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent } } catch (Exception e) { if (!(e instanceof CancellationException)) { + connectionBar.close(); FineLoggerFactory.getLogger().error(e.getMessage(), e); - FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), e.getMessage(), + FineJOptionPane.showMessageDialog(AutoChartTypePane.this, e.getMessage(), Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); } } finally { @@ -243,16 +244,7 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent @Override public void update(ChartCollection cc) { - if (chartViewList.getSelectedIndex() < 0) { - return; - } - AutoChartIcon chartIcon = (AutoChartIcon) chartViewList.getSelectedValue(); - ChartProvider chartProvider = chartIcon.getChartCollection().getSelectedChartProvider(ChartProvider.class); - if (cc.getChartCount() > 0) { - cc.setSelectChart(chartProvider); - } else { - cc.addChart(chartProvider); - } + update(cc, null); } public void populate(String tableName, String[] dataFields) { @@ -264,6 +256,26 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent dataFieldBox.setSelectedValues(map); } + public void update(ChartCollection cc, String createTime) { + if (chartViewList.getSelectedIndex() < 0) { + return; + } + AutoChartIcon chartIcon = (AutoChartIcon) chartViewList.getSelectedValue(); + VanChart vanChart = chartIcon.getChartCollection().getSelectedChartProvider(VanChart.class); + if (cc.getChartCount() > 0) { + VanChart selectedChartProvider = cc.getSelectedChartProvider(VanChart.class); + if (selectedChartProvider.getChartUuid() != null) { + vanChart.setUuid(selectedChartProvider.getChartUuid()); + } + cc.setSelectChart(vanChart); + ChartInfoCollector.getInstance().updateChartTypeTime(vanChart, null, true); + } else { + cc.addChart(vanChart); + //记录埋点 + ChartInfoCollector.getInstance().collection(vanChart, createTime, false, true); + } + } + @Override public void callback() { this.repaint(); diff --git a/designer-chart/src/main/java/com/fr/design/chart/ChartDialog.java b/designer-chart/src/main/java/com/fr/design/chart/ChartDialog.java index 9251bdbc8..b2d273a60 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/ChartDialog.java +++ b/designer-chart/src/main/java/com/fr/design/chart/ChartDialog.java @@ -31,7 +31,6 @@ public class ChartDialog extends MiddleChartDialog { private UIButton ok; private UIButton cancel; private ChartTypePane chartTypePane; - private String createTime; public ChartDialog(Frame owner) { super(owner); @@ -44,7 +43,7 @@ public class ChartDialog extends MiddleChartDialog { } private void initComponent() { - createTime = DateTime.now().toString("yyyy-MM-dd HH:mm:ss"); + String createTime = DateTime.now().toString("yyyy-MM-dd HH:mm:ss"); this.setModal(true); this.setLayout(new BorderLayout()); setTitle(getDialogTitle()); @@ -61,7 +60,7 @@ public class ChartDialog extends MiddleChartDialog { ok = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_OK")); cancel = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Cancel")); - ok.addActionListener(getActionListener()); + ok.addActionListener(getActionListener(createTime)); cancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { doCancel(); @@ -83,7 +82,7 @@ public class ChartDialog extends MiddleChartDialog { return chartTypePane; } - protected ActionListener getActionListener() { + protected ActionListener getActionListener(final String createTime) { return new ActionListener() { public void actionPerformed(ActionEvent e) { chartTypePane.update((ChartCollection) cc, createTime); diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/AutoChartDataModel.java b/designer-chart/src/main/java/com/fr/design/chart/auto/AutoChartDataModel.java deleted file mode 100644 index 76889dcd2..000000000 --- a/designer-chart/src/main/java/com/fr/design/chart/auto/AutoChartDataModel.java +++ /dev/null @@ -1,46 +0,0 @@ -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 columnInfoList; - - public AutoChartDataModel(List 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); - } -} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/AutoTypeCalculate.java b/designer-chart/src/main/java/com/fr/design/chart/auto/AutoTypeCalculate.java index 73c23bd1c..db20af8cf 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/auto/AutoTypeCalculate.java +++ b/designer-chart/src/main/java/com/fr/design/chart/auto/AutoTypeCalculate.java @@ -1,14 +1,15 @@ package com.fr.design.chart.auto; +import com.fr.chart.auto.ColumnInfo; +import com.fr.chart.auto.strategy.AutoTypeStrategy; +import com.fr.chart.auto.strategy.imp.AvaStrategy; +import com.fr.chart.auto.strategy.imp.BubbleChartStrategy; +import com.fr.chart.auto.strategy.imp.SingleDimensionStrategy; +import com.fr.chart.auto.strategy.imp.SingleTargetStrategy; 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; @@ -114,14 +115,14 @@ public class AutoTypeCalculate { } private static List getColumnData(EmbeddedTableData tableData, String columnName) { - int colIndex = getColIndex(tableData, columnName); + List columnData = new ArrayList<>(); + int colIndex = getColIndex(tableData, columnName); if (colIndex == DataModel.COLUMN_NAME_NOT_FOUND) { - return null; + return columnData; } int size = tableData.getRowCount(); - List columnData = new ArrayList<>(); for (int i = 0; i < size; i++) { Object valueAt = tableData.getValueAt(i, colIndex); columnData.add(GeneralUtils.objectToString(valueAt)); diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/ColumnInfo.java b/designer-chart/src/main/java/com/fr/design/chart/auto/ColumnInfo.java deleted file mode 100644 index 9d27925df..000000000 --- a/designer-chart/src/main/java/com/fr/design/chart/auto/ColumnInfo.java +++ /dev/null @@ -1,56 +0,0 @@ -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 values; - private DataFunction function; - private List resultValues = new ArrayList<>(); - - public ColumnInfo(String columnName, List values) { - this.columnName = columnName; - this.values = values; - } - - public String getColumnName() { - return columnName; - } - - public void setColumnName(String columnName) { - this.columnName = columnName; - } - - public List getValues() { - return values; - } - - public void setValues(List values) { - this.values = values; - } - - public DataFunction getFunction() { - return function; - } - - public void setFunction(DataFunction function) { - this.function = function; - } - - public List getResultValues() { - return resultValues; - } - - public void setResultValues(List resultValues) { - this.resultValues = resultValues; - } -} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AbstractAutoTypeStrategy.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AbstractAutoTypeStrategy.java deleted file mode 100644 index 417cd036c..000000000 --- a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AbstractAutoTypeStrategy.java +++ /dev/null @@ -1,265 +0,0 @@ -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 dimensions, List targets) { - //> 需要聚合计算的数据数组。eg:{a-x-:{fieldId3:[1,4],fieldId4:[5,8]},a-y-:{fieldId3:[3],fieldId4:[7]}}。 - Map>> targetFieldMap = new HashMap<>(); - - //关键字段可能有数据字典属性,需要拿到数据字典的映射值>。eg:{a-x-:{fieldId1:(a,a1),fieldId1:(x,x1)},a-y-:{fieldId1:(a,a1),fieldId1:(y,y1)}} - Map> dimensionFieldMap = new LinkedHashMap<>(); - - int size = dimensions.get(0).getValues().size(); - - for (int rowIndex = 0; rowIndex < size; rowIndex++) { - String key = StringUtils.EMPTY; - Map keyValueMap = new HashMap<>(); - //处理维度字段 - for (ColumnInfo field : dimensions) { - String columnName = field.getColumnName(); - String result = field.getValues().get(rowIndex); - List 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> map = targetFieldMap.get(key); - if (map == null) { - map = new HashMap<>(); - targetFieldMap.put(key, map); - } - String columnName = field.getColumnName(); - List 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> dimensionFieldMap, - Map>> targetFieldMap, - List dimensions, List targets) { - for (String key : dimensionFieldMap.keySet()) { - Map> targetValues = targetFieldMap.get(key); - //对需要计算的字段使用dataFunction进行计算 - for (ColumnInfo field : targets) { - DataFunction dataFunction = field.getFunction(); - dataFunction.reset(); - List valueList = targetValues.get(field.getColumnName()); - field.getResultValues().add(ChartDataUtils.calculateByFunction(dataFunction, valueList)); - } - - Map keyValue = dimensionFieldMap.get(key); - for (ColumnInfo field : dimensions) { - String result = keyValue.get(field.getColumnName()); - field.getResultValues().add(result); - } - } - } - - protected List analyzeByAva(List dimensions, List targets) { - - List 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 selectHighRankChart(List rankChartList) { - Collections.sort(rankChartList); - List 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 { - - 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; - } - } -} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AutoTypeStrategy.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AutoTypeStrategy.java deleted file mode 100644 index 12c794568..000000000 --- a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AutoTypeStrategy.java +++ /dev/null @@ -1,22 +0,0 @@ -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 rankChart(String tableName, List dimensions, List targets); -} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AvaType.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AvaType.java deleted file mode 100644 index 29f242279..000000000 --- a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/AvaType.java +++ /dev/null @@ -1,79 +0,0 @@ -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; - } -} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/AvaStrategy.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/AvaStrategy.java deleted file mode 100644 index aef4999f0..000000000 --- a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/AvaStrategy.java +++ /dev/null @@ -1,106 +0,0 @@ -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 rankChart(String tableName, List dimensions, List targets) { - List rankChartList = new ArrayList<>(); - - for (ColumnInfo columnInfo : targets) { - columnInfo.setFunction(new SumFunction()); - } - if (dimensions.size() == 1) { - //一个维度+一个指标匹配 - for (ColumnInfo target : targets) { - List 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 newDimensions = new ArrayList<>(); - newDimensions.add(dimensions.get(i)); - newDimensions.add(dimensions.get(j)); - List newTargets = new ArrayList<>(); - newTargets.add(target); - rankChartList.addAll(rankChartByAva(tableName, newDimensions, newTargets)); - } - } - } - } - - return selectHighRankChart(rankChartList); - } - - private List rankChartByAva(String tableName, List dimensions, List targets) { - for (ColumnInfo columnInfo : dimensions) { - columnInfo.setResultValues(new ArrayList<>()); - } - for (ColumnInfo columnInfo : targets) { - columnInfo.setResultValues(new ArrayList<>()); - } - calculateColumn(dimensions, targets); - //调用ava - List rankChartList = analyzeByAva(dimensions, targets); - - List 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 dimensions, List 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()); - } - } -} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/BubbleChartStrategy.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/BubbleChartStrategy.java deleted file mode 100644 index 6f10f561b..000000000 --- a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/BubbleChartStrategy.java +++ /dev/null @@ -1,76 +0,0 @@ -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 rankChart(String tableName, List dimensions, List targets) { - List rankChartList = new ArrayList<>(); - for (ColumnInfo columnInfo : dimensions) { - List resultValues = columnInfo.getResultValues(); - for (String str : columnInfo.getValues()) { - resultValues.add(str); - } - } - for (ColumnInfo columnInfo : targets) { - List 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 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 rankChartByAva(String tableName, List dimensions, List targets) { - //调用ava - List rankChartList = analyzeByAva(dimensions, targets); - - List 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; - } -} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleDimensionStrategy.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleDimensionStrategy.java deleted file mode 100644 index 4d7ad03f4..000000000 --- a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleDimensionStrategy.java +++ /dev/null @@ -1,68 +0,0 @@ -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 rankChart(String tableName, List dimensions, List targets) { - List rankChartList = new ArrayList<>(); - for (ColumnInfo columnInfo : dimensions) { - ColumnInfo target = new ColumnInfo(columnInfo.getColumnName(), columnInfo.getValues()); - target.setFunction(new CountFunction()); - target.setColumnName("value"); - - List newDimension = new ArrayList<>(); - List newTarget = new ArrayList<>(); - newDimension.add(columnInfo); - newTarget.add(target); - - rankChartList.addAll(rankChartByAva(tableName, newDimension, newTarget)); - } - return selectHighRankChart(rankChartList); - } - - private List rankChartByAva(String tableName, List dimensions, List targets) { - calculateColumn(dimensions, targets); - //调用ava - List 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 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()); - } - } -} diff --git a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleTargetStrategy.java b/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleTargetStrategy.java deleted file mode 100644 index 5679b6125..000000000 --- a/designer-chart/src/main/java/com/fr/design/chart/auto/strategy/imp/SingleTargetStrategy.java +++ /dev/null @@ -1,45 +0,0 @@ -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 rankChart(String tableName, List dimensions, List targets) { - //只有一个指标,匹配直方图 - VanChart vanChart = AvaType.COLUMN_CHART.getVanChart(); - List 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 xAxisList = plot.getXAxisList(); - VanChartAxis vanChartAxis = xAxisList.get(0); - VanChartValueAxis axis = new VanChartValueAxis(vanChartAxis.getAxisName(), vanChartAxis.getPosition()); - xAxisList.set(0, axis); - - List vanChartList = new ArrayList<>(); - vanChartList.add(vanChart); - return vanChartList; - } -} diff --git a/designer-chart/src/main/resources/com/fr/design/chart/auto/js/analyze.js b/designer-chart/src/main/resources/com/fr/design/chart/auto/js/analyze.js deleted file mode 100644 index c181cd20e..000000000 --- a/designer-chart/src/main/resources/com/fr/design/chart/auto/js/analyze.js +++ /dev/null @@ -1,66 +0,0 @@ -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); -} \ No newline at end of file diff --git a/designer-chart/src/main/resources/com/fr/design/chart/auto/js/ava.js b/designer-chart/src/main/resources/com/fr/design/chart/auto/js/ava.js deleted file mode 100644 index 07965c88f..000000000 --- a/designer-chart/src/main/resources/com/fr/design/chart/auto/js/ava.js +++ /dev/null @@ -1,2729 +0,0 @@ -!function(e, a) { - 'object' == typeof exports && 'object' == typeof module ? module.exports = a() : 'function' == typeof define && define.amd ? define([], a) : 'object' == typeof exports ? exports.Advisor = a() : e.Advisor = a(); -}(window, (function() { - return function(e) { - var a = {}; - - function t(r) { - if (a[r]) return a[r].exports; - var n = a[r] = { i: r, l: !1, exports: {} }; - return e[r].call(n.exports, n, n.exports, t), n.l = !0, n.exports; - } - - return t.m = e, t.c = a, t.d = function(e, a, r) { - t.o(e, a) || Object.defineProperty(e, a, { enumerable: !0, get: r }); - }, t.r = function(e) { - 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: 'Module' }), Object.defineProperty(e, '__esModule', { value: !0 }); - }, t.t = function(e, a) { - if (1 & a && (e = t(e)), 8 & a) return e; - if (4 & a && 'object' == typeof e && e && e.__esModule) return e; - var r = Object.create(null); - if (t.r(r), Object.defineProperty(r, 'default', { - enumerable: !0, - value: e, - }), 2 & a && 'string' != typeof e) for (var n in e) t.d(r, n, function(a) { - return e[a]; - }.bind(null, n)); - return r; - }, t.n = function(e) { - var a = e && e.__esModule ? function() { - return e.default; - } : function() { - return e; - }; - return t.d(a, 'a', a), a; - }, t.o = function(e, a) { - return Object.prototype.hasOwnProperty.call(e, a); - }, t.p = '', t(t.s = 3); - }([function(e, a, t) { - 'use strict'; - t.d(a, 'a', (function() { - return r; - })), t.d(a, 'd', (function() { - return n; - })), t.d(a, 'b', (function() { - return i; - })), t.d(a, 'c', (function() { - return o; - })); - var r = function() { - return (r = Object.assign || function(e) { - for (var a, t = 1, r = arguments.length; t < r; t++) for (var n in a = arguments[t]) Object.prototype.hasOwnProperty.call(a, n) && (e[n] = a[n]); - return e; - }).apply(this, arguments); - }; - - function n(e) { - var a = 'function' == typeof Symbol && Symbol.iterator, t = a && e[a], r = 0; - if (t) return t.call(e); - if (e && 'number' == typeof e.length) return { - next: function() { - return e && r >= e.length && (e = void 0), { value: e && e[r++], done: !e }; - }, - }; - throw new TypeError(a ? 'Object is not iterable.' : 'Symbol.iterator is not defined.'); - } - - function i(e, a) { - var t = 'function' == typeof Symbol && e[Symbol.iterator]; - if (!t) return e; - var r, n, i = t.call(e), o = []; - try { - for (; (void 0 === a || a-- > 0) && !(r = i.next()).done;) o.push(r.value); - } catch (e) { - n = { error: e }; - } finally { - try { - r && !r.done && (t = i.return) && t.call(i); - } finally { - if (n) throw n.error; - } - } - return o; - } - - function o() { - for (var e = [], a = 0; a < arguments.length; a++) e = e.concat(i(arguments[a])); - return e; - } - }, function(e, a, t) { - 'use strict'; - - function r(e, a) { - for (var t = 0; t < a.length; t++) { - var r = a[t]; - r.enumerable = r.enumerable || !1, r.configurable = !0, 'value' in r && (r.writable = !0), Object.defineProperty(e, r.key, r); - } - } - - function n(e, a, t) { - return a in e ? Object.defineProperty(e, a, { - value: t, - enumerable: !0, - configurable: !0, - writable: !0, - }) : e[a] = t, e; - } - - Object.defineProperty(a, '__esModule', { value: !0 }), a.default = void 0; - var i = function() { - function e(a, t, r, i, o) { - !function(e, a) { - if (!(e instanceof a)) throw new TypeError('Cannot call a class as a function'); - }(this, e), n(this, '_id', void 0), n(this, '_hardOrSoft', void 0), n(this, '_specChartTypes', void 0), n(this, '_weight', void 0), n(this, 'validator', void 0), this._id = a, this._hardOrSoft = t, this._specChartTypes = r, this._weight = i, this.validator = o; - } - - var a, t, i; - return a = e, (t = [{ - key: 'toString', value: function() { - return 'RULE: '.concat(this._id, '^').concat(this._hardOrSoft, '^').concat(this._specChartTypes.toString(), '^*').concat(this.weight); - }, - }, { - key: 'check', value: function(e) { - return this.validator(e) * this._weight; - }, - }, { - key: 'id', get: function() { - return this._id; - }, - }, { - key: 'hardOrSoft', get: function() { - return this._hardOrSoft; - }, - }, { - key: 'specChartTypes', get: function() { - return this._specChartTypes; - }, - }, { - key: 'weight', get: function() { - return this._weight; - }, - }]) && r(a.prototype, t), i && r(a, i), e; - }(); - a.default = i; - }, function(e, a, t) { - 'use strict'; - t.r(a), t.d(a, 'CKBJson', (function() { - return o; - })), t.d(a, 'addChart', (function() { - return c; - })), t.d(a, 'CKBOptions', (function() { - return _; - })), t.d(a, 'FAMILY_OPTIONS', (function() { - return l; - })), t.d(a, 'PURPOSE_OPTIONS', (function() { - return d; - })), t.d(a, 'COORD_TYPE_OPTIONS', (function() { - return u; - })), t.d(a, 'GRAPHIC_CATEGORY_OPTIONS', (function() { - return m; - })), t.d(a, 'SHAPE_OPTIONS', (function() { - return h; - })), t.d(a, 'LOM_OPTIONS', (function() { - return p; - })), t.d(a, 'CHANNEL_OPTIONS', (function() { - return f; - })), t.d(a, 'RECOMMEND_RATING_OPTIONS', (function() { - return y; - })), t.d(a, 'CHART_ID_OPTIONS', (function() { - return g; - })); - var r = { - 'en-US': null, 'zh-CN': { - concepts: { - family: { - LineCharts: '折线图类', - ColumnCharts: '柱状图类', - BarCharts: '条形图类', - PieCharts: '饼图类', - AreaCharts: '面积图类', - ScatterCharts: '散点图类', - FunnelCharts: '漏斗图类', - HeatmapCharts: '热力图类', - RadarCharts: '雷达图类', - TreeGraph: '树形关系类', - GeneralGraph: '关系图类', - PointLayer: '点图层类', - LineLayer: '线图层类', - PolygonLayer: '面图层类', - HeatmapLayer: '地图热力图类', - Others: '其他类', - }, - category: { Statistic: '统计图表', Diagram: '示意图', Graph: '关系图', Map: '地图' }, - purpose: { - Comparison: '比较', - Trend: '趋势', - Distribution: '分布', - Rank: '排名', - Proportion: '占比', - Composition: '组成', - Relation: '关系', - Hierarchy: '层级', - Flow: '流向', - Spatial: '空间', - }, - coord: { - NumberLine: '数轴', - Cartesian2D: '二维直角坐标系', - SymmetricCartesian: '对称直角坐标系', - Cartesian3D: '三维直角坐标系', - Polar: '极坐标系', - NodeLink: '点线关系网络', - Radar: '雷达型坐标系', - Geo: '地理坐标系', - Other: '其他', - }, - shape: { - Lines: '线形', - Bars: '条形', - Round: '圆形', - Square: '方形', - Area: '面形', - Scatter: '散点形', - Symmetric: '对称形', - Network: '网络形', - Map: '地图', - }, - channel: { - Position: '位置', - Length: '长度', - Color: '颜色', - Area: '面积', - Angle: '角度', - ArcLength: '弧长', - Direction: '方向', - Size: '大小', - Opacity: '透明度', - Stroke: '线色', - LineWidth: '线粗', - Lightness: '亮度', - }, - lom: { Continuous: '连续', Discrete: '离散', Interval: '数值', Nominal: '无序名词', Ordinal: '有序名词', Time: '时间' }, - recRate: { Recommended: '推荐', 'Use with Caution': '慎用', 'Not Recommended': '不推荐' }, - }, chartTypes: { - line_chart: { name: '折线图', alias: ['折线图', '线图'], def: '使用折线的线段显示数据在一个具有顺序性的维度上的变化。' }, - step_line_chart: { - name: '阶梯图', - alias: ['阶梯线'], - def: '折线根据分类字段分为多根在 x 方向(时间)的信息是完全一致、颜色及 y 方向(变量)信息不一致的折线,通常用作同一时间区间内多个变量发展趋势的对比。', - }, - area_chart: { name: '面积图', alias: [], def: '使用带填充区域的线段显示数据在一个具有顺序性的维度上的变化。' }, - stacked_area_chart: { - name: '堆叠面积图', - alias: [], - def: '使用带不同样式的填充区域的层叠线段来显示多组数据在同一个具有顺序性的维度上的变化,线段在同一维度值上的端点高度按照数值累加。', - }, - percent_stacked_area_chart: { - name: '百分比堆叠面积图', - alias: ['%堆叠面积图', '100%堆叠面积图'], - def: '一种特殊的堆叠面积图,线段在同一维度值上的端点高度代表值在其中的占比,占比总和为百分之百。', - }, - interval_area_chart: { name: '', alias: [], def: 'TBD' }, - stream_chart: { name: '', alias: [], def: 'TBD' }, - column_chart: { name: '柱状图', alias: ['柱形图'], def: '使用柱形显示维度的数值。横轴显示分类维度,纵轴显示相应的值。' }, - grouped_column_chart: { - name: '分组柱状图', - alias: ['簇状柱状图'], - def: '使用颜色不同的柱形并排组成小组来显示各维度的数值。横轴标示出分组,颜色标示出分类,纵轴显示相应的值。', - }, - stacked_column_chart: { - name: '堆叠柱状图', - alias: [], - def: '使用颜色不同的堆叠的柱形来显示各维度的数值。横轴标示出第一个分类维度,颜色标示出第二个分类维度,纵轴显示相应的值。', - }, - percent_stacked_column_chart: { - name: '百分比堆叠柱状图', - alias: ['%堆叠柱状图', '100%堆叠柱状图'], - def: '使用颜色不同的堆叠的柱形来显示各维度的数值。横轴标示出第一个分类维度,颜色标示出第二个分类维度,纵轴显示相应分类所占的百分比。', - }, - interval_column_chart: { name: '', alias: [], def: 'TBD' }, - range_column_chart: { name: '区间柱状图', alias: [], def: '区间柱状图是一种特殊的柱状图,柱子不一定要从 0 开始,而是用柱子长度表示一个从起始值到终止值的区间。' }, - waterfall_chart: { name: '瀑布图', alias: ['桥图'], def: '瀑布图形似瀑布流水,采用绝对值与相对值结合的方式,适用于表达数个特定数值之间的数量变化关系。' }, - histogram: { name: '直方图', alias: [], def: '直方图是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。' }, - bar_chart: { name: '条形图', alias: ['条状图'], def: '使用条形显示维度的数值。纵轴显示分类维度,横轴显示相应的值。' }, - grouped_bar_chart: { - name: '分组条形图', - alias: ['簇状条形图'], - def: '使用颜色不同的条形并排组成小组来显示维度的数值。纵轴标示出分组,颜色标示出分类,横轴显示相应的值。', - }, - stacked_bar_chart: { - name: '堆叠条形图', - alias: [], - def: '使用颜色不同的堆叠的条形来显示各维度的数值。纵轴标示出第一个分类维度,颜色标示出第二个分类维度,横轴显示相应的值。', - }, - percent_stacked_bar_chart: { - name: '百分比堆叠条形图', - alias: ['%堆叠条形图', '100%堆叠条形图'], - def: '使用颜色不同的堆叠的条形来显示各维度的数值。纵轴标示出第一个分类维度,颜色标示出第二个分类维度,横轴显示相应分类所占的百分比。', - }, - interval_bar_chart: { name: '', alias: [], def: 'TBD' }, - range_bar_chart: { name: '区间条形图', alias: [], def: '区间条形图是一种特殊的条形图,条不一定要从 0 开始,而是用长度表示一个从起始值到终止值的区间。' }, - radial_bar_chart: { name: '', alias: [], def: 'TBD' }, - mirror_bar_chart: { name: '', alias: [], def: 'TBD' }, - bullet_chart: { name: '子弹图', alias: ['靶心图', '标靶图'], def: '子弹图可用于将度量的绩效可视化并与目标值和定性刻度。' }, - pie_chart: { name: '饼图', alias: [], def: '通过扇形区块的颜色和弧长(角度、面积)来展现数据的分类和占比情况。' }, - donut_chart: { name: '环图', alias: ['甜甜圈图'], def: '通过弧形区块的颜色和弧长来展现数据的分类和占比情况。' }, - nested_pie_chart: { name: '', alias: [], def: 'TBD' }, - rose_chart: { - name: '玫瑰图', - alias: ['南丁格尔图', '鸡冠花图', '极坐标面积图'], - def: '统计学家和医学改革家佛罗伦萨‧南丁格尔在克里米亚战争期间创造了这种图表。尽管外形很像饼图,但本质上来说,南丁格尔玫瑰图更像在极坐标下绘制的柱状图或堆叠柱状图。只不过,它用半径来反映数值。', - }, - scatter_plot: { name: '散点图', alias: [], def: '散点图是将所有的数据以不同颜色的点的形式展现在平面直角坐标系上的统计图表。' }, - bubble_chart: { name: '气泡图', alias: [], def: '气泡图是一种多变量的统计图表,由笛卡尔坐标系(直角坐标系)和大小不一、颜色不同的圆组成,可以看作是散点图的变形。' }, - non_ribbon_chord_diagram: { name: '', alias: [], def: 'TBD' }, - arc_diagram: { name: '弧形图', alias: [], def: '弧形图是一种关系图的特殊布局,节点被排列在同一水平线上,关系由节点间的圆弧线表示。' }, - chord_diagram: { name: '', alias: [], def: 'TBD' }, - treemap: { name: '', alias: [], def: 'TBD' }, - sankey_diagram: { name: '桑基图', alias: ['桑吉图'], def: '桑基图,是一种表现流程的示意图,用于描述一组值到另一组值的流向。分支的宽度对应了数据流量的大小。' }, - funnel_chart: { name: '漏斗图', alias: [], def: '漏斗图,形如“漏斗”,用于单流程分析,在开始和结束之间由N个流程环节组成。' }, - overlapping_funnel_chart: { name: '', alias: [], def: 'TBD' }, - mirror_funnel_chart: { name: '对比漏斗图', alias: ['对称漏斗图', '镜像漏斗图'], def: '对比漏斗图是两个独立的漏斗图以一根中轴线对称展开的图表形式。' }, - boxplot: { name: '', alias: [], def: 'TBD' }, - heatmap: { name: '热力图', alias: ['区块热力图'], def: '热力图,是一种通过对色块着色来显示数据的统计图表。' }, - density_heatmap: { name: '密度热力图', alias: ['热力图'], def: '密度热力图是一种用在连续坐标系上用色点展现密度分布的统计图表。' }, - gauge_chart: { name: '', alias: [], def: 'TBD' }, - radar_chart: { - name: '雷达图', - alias: ['蛛网图'], - def: '将不同系列的多个维度的数据量映射到坐标轴上,这些坐标轴起始于同一个圆心点,通常结束于圆周边缘,将同一组的点使用线连接起来,用颜色区分系列。', - }, - wordcloud: { name: '', alias: [], def: 'TBD' }, - candlestick_chart: { name: '', alias: [], def: 'TBD' }, - compact_box_tree: { name: '紧凑树', alias: [], def: '紧凑树是一种树图布局,从根节点开始,同一深度的节点在同一层,并且布局时会将节点大小考虑进去。' }, - dendrogram: { name: '生态树', alias: [], def: '生态树是一种树图布局,不管数据的深度多少,总是叶节点对齐。不考虑节点大小,布局时将节点视为 1 个像素点。' }, - indented_tree: { name: '缩进树', alias: [], def: '缩进树是一种树图布局,缩进树布局。每个元素会占一行/一列。' }, - radial_tree: { name: '辐射树', alias: [], def: '辐射树是一种树图布局,跟节点位于辐射树中心,其他分支辐射式展开。' }, - flow_diagram: { name: '流程图', alias: [], def: '流程图是一种图解,可视表示在过程或功能内部诸如事件、步骤等之间的顺序关系。' }, - fruchterman_layout_graph: { name: 'Fruchterman 布局力导向图', alias: [], def: '一种使用 Fruchterman 布局算法的力导向图。' }, - force_directed_layout_graph: { - name: '力导向图', - alias: [], - def: '力导向图布局作为较早被发明的一种实际应用布局算法,经过研究者多年改进、扩展,已发展成为一类算法的集合。该类算法的特点是模拟物理世界中的作用力,施加在节点上,并迭代计算以达到合理放置节点、美观布局的一类算法。', - }, - circular_layout_graph: { name: '环形布局关系图', alias: [], def: '环形布局根据参数指定的排序方式对节点进行排序后,将节点排列在圆环上。' }, - spiral_layout_graph: { name: '螺旋布局关系图', alias: [], def: '螺旋布局图的节点排列在一根螺旋线上。' }, - radial_layout_graph: { - name: '辐射布局关系图', - alias: [], - def: '辐射布局根据指定的中心点,根据其他节点与中心点的拓扑距离(最短路径长度)将其余节点放置在以中心点为圆心的同心圆上。', - }, - concentric_layout_graph: { name: '同心圆布局关系图', alias: [], def: '同心圆布局关系图将所有节点放置在同心圆上。' }, - grid_layout_graph: { name: '网格布局关系图', alias: [], def: '网格布局根据参数指定的排序方式对节点进行排序后,将节点排列在网格上。' }, - symbol_map: { - name: '符号地图', - alias: [], - def: '散点地图的变体,用具象的图标指代抽象的圆点,无需图例就能直观看出数据点代表的内容,常用于地图上重要地标的显示或数据量较少时的信息表达。', - }, - chart_map: { name: '复合图表地图', alias: [], def: '是定点地图的变体,使用二维统计图表代替点状符号的一种特殊复合形式。' }, - column_map_3d: { name: '3D 柱状图', alias: [], def: '用形状大小相同的柱状体代替点状符号,高度与数值大小映射共同表达离散现象分布特征的地图' }, - scatter_map: { name: '散点地图', alias: [], def: '指地图上可用一个形状大小相同的圆点来定位,用表达离散现象分布特征的地图,如人口、农作物、动植物等的分布' }, - path_map: { - name: '路径地图', - alias: [], - def: '指需要用一连串首尾不闭合的点坐标对(xi,yi)来定位的一类图层。属于半依比例图层,线端点依附地图比例缩放,但线的粗细不会变化。', - }, - isoline_map: { name: '等值线地图', alias: [], def: 'TBD' }, - arc_map_3d: { - name: '3D 弧线地图', - alias: [], - def: '将两个点的连线绘制成弧形,绘制的弧线可以是贝塞尔曲线,大圆航线,通常用来表示两种地理事物关系和联系,或者人口迁移,物流起点目的地等。', - }, - choropleth_map: { name: '填充地图', alias: [], def: '填充图,也叫分级统计图,可在地图上不同领土区域进行着色,查看区域间的分布对比情况' }, - choropleth_map_3d: { name: '3D 填充地图', alias: [], def: '填充地图的增强实现,通过三维视角中的高度模拟真实地物的高度。' }, - hexagonal_heat_map: { - name: '蜂窝热力地图', - alias: [], - def: '使用六边形将地图区域进行分割,计算每个区域中点数或其他累加值,将离散的点转换为数值。然后将数值映射到每个区域的色值、高度或其他参数', - }, - hexagonal_heat_map_3d: { - name: '3D 蜂窝热力地图', - alias: [], - def: '使用3D 六边形将地图区域进行分割,计算每个区域中点数或其他累加值,将离散的点转换为数值。然后将数值映射到每个区域的色值、高度或其他参数', - }, - classical_heat_map: { name: '热力地图', alias: [], def: '密度热力图是一种用在连续坐标系上用色点展现密度分布的统计地图。' }, - grid_heat_map: { - name: '网格热力地图', - alias: [], - def: '使用网格区域进行分割,计算每个区域中点数或其他累加值,将离散的点转换为数值。然后将数值映射到每个区域的色值、高度或其他参数', - }, - bubble_map: { name: '气泡地图', alias: [], def: '指地图上用一个形状相同、面积大小和数值成正比的圆点来定位的地图,是散点图的扩展,用于表达离散现象分布特征的地图。' }, - bubble_light_map: { - name: '亮点地图', - alias: [], - def: '散点图的变形,指用一个点代表一个值,连续渐进颜色代表数值大小,并通过色彩的叠加的达到效果增强,专为海量散点数据运用而生,解决远视角下,点颜色无法区分问题', - }, - packed_circles: { name: '', alias: [], def: 'TBD' }, - polar_treemap: { name: '', alias: [], def: 'TBD' }, - sunburst_diagram: { name: '', alias: [], def: 'TBD' }, - liquid_chart: { name: '水波图', alias: ['进度球'], def: '一种用来表示进度的拟物化示意图' }, - }, - }, - }; - - function n(e) { - return e && Object.keys(r).includes(e) ? r[e] : null; - } - - var i = { - line_chart: { - id: 'line_chart', - name: 'Line Chart', - alias: ['Lines'], - family: ['LineCharts'], - def: 'A line chart uses lines with segments to show changes in data in a ordinal dimension.', - purpose: ['Comparison', 'Trend'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Lines'], - dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Time', 'Ordinal'] }, { - minQty: 0, - maxQty: 1, - fieldConditions: ['Nominal'], - }, { minQty: 1, maxQty: 1, fieldConditions: ['Interval'] }], - channel: ['Position', 'Direction'], - recRate: 'Recommended', - }, - step_line_chart: { - id: 'step_line_chart', - name: 'Step Line Chart', - alias: ['Step Lines'], - family: ['LineCharts'], - def: 'A step line chart is a line chart in which points of each line are connected by horizontal and vertical line segments, looking like steps of a staircase.', - purpose: ['Comparison', 'Trend'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Lines'], - dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Time', 'Ordinal'] }, { - minQty: 0, - maxQty: 1, - fieldConditions: ['Nominal'], - }, { minQty: 1, maxQty: 1, fieldConditions: ['Interval'] }], - channel: ['Position', 'Direction'], - recRate: 'Recommended', - }, - area_chart: { - id: 'area_chart', - name: 'Area Chart', - alias: [], - family: ['AreaCharts'], - def: 'An area chart uses series of line segments with overlapped areas to show the change in data in a ordinal dimension.', - purpose: ['Comparison', 'Trend'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Area'], - dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Time', 'Ordinal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }, { minQty: 0, maxQty: 1, fieldConditions: ['Nominal'] }], - channel: ['Color', 'Position'], - recRate: 'Recommended', - }, - stacked_area_chart: { - id: 'stacked_area_chart', - name: 'Stacked Area Chart', - alias: [], - family: ['AreaCharts'], - def: 'A stacked area chart uses layered line segments with different styles of padding regions to display how multiple sets of data change in the same ordinal dimension, and the endpoint heights of the segments on the same dimension tick are accumulated by value.', - purpose: ['Comparison', 'Composition', 'Trend'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Area'], - dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Time', 'Ordinal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }, { minQty: 1, maxQty: 1, fieldConditions: ['Nominal'] }], - channel: ['Color', 'Length'], - recRate: 'Recommended', - }, - percent_stacked_area_chart: { - id: 'percent_stacked_area_chart', - name: 'Percent Stacked Area Chart', - alias: ['Percent Stacked Area', '% Stacked Area', '100% Stacked Area'], - family: ['AreaCharts'], - def: 'A percent stacked area chart is an extented stacked area chart in which the height of the endpoints of the line segment on the same dimension tick is the accumulated proportion of the ratio, which is 100% of the total.', - purpose: ['Comparison', 'Composition', 'Proportion', 'Trend'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Area'], - dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Time', 'Ordinal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }, { minQty: 1, maxQty: 1, fieldConditions: ['Nominal'] }], - channel: ['Color', 'Length'], - recRate: 'Recommended', - }, - interval_area_chart: { - id: 'interval_area_chart', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - stream_chart: { - id: 'stream_chart', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - column_chart: { - id: 'column_chart', - name: 'Column Chart', - alias: ['Columns'], - family: ['ColumnCharts'], - def: 'A column chart uses series of columns to display the value of the dimension. The horizontal axis shows the classification dimension and the vertical axis shows the corresponding value.', - purpose: ['Comparison', 'Distribution', 'Rank'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 1, maxQty: 2, fieldConditions: ['Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Position', 'Color'], - recRate: 'Recommended', - }, - grouped_column_chart: { - id: 'grouped_column_chart', - name: 'Grouped Column Chart', - alias: ['Grouped Column'], - family: ['ColumnCharts'], - def: 'A grouped column chart uses columns of different colors to form a group to display the values ​​of dimensions. The horizontal axis indicates the grouping of categories, the color indicates the categories, and the vertical axis shows the corresponding value.', - purpose: ['Comparison', 'Distribution', 'Rank'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Color', 'Position'], - recRate: 'Recommended', - }, - stacked_column_chart: { - id: 'stacked_column_chart', - name: 'Stacked Column Chart', - alias: ['Stacked Column'], - family: ['ColumnCharts'], - def: 'A stacked column chart uses stacked bars of different colors to display the values ​​for each dimension. The horizontal axis indicates the first classification dimension, the color indicates the second classification dimension, and the vertical axis shows the corresponding value.', - purpose: ['Comparison', 'Composition', 'Distribution', 'Rank'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Color', 'Length', 'Position'], - recRate: 'Recommended', - }, - percent_stacked_column_chart: { - id: 'percent_stacked_column_chart', - name: 'Percent Stacked Column Chart', - alias: ['Percent Stacked Column', '% Stacked Column', '100% Stacked Column'], - family: ['ColumnCharts'], - def: 'A percent stacked column chart uses stacked bars of different colors to display the values ​​for each dimension. The horizontal axis indicates the first classification dimension, the color indicates the second classification dimension, and the vertical axis shows the percentage of the corresponding classification.', - purpose: ['Comparison', 'Composition', 'Distribution', 'Proportion'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Color', 'Length'], - recRate: 'Recommended', - }, - interval_column_chart: { - id: 'interval_column_chart', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - range_column_chart: { - id: 'range_column_chart', - name: 'Range Column Chart', - alias: [], - family: ['ColumnCharts'], - def: 'A column chart that does not have to start from zero axis.', - purpose: ['Comparison'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Interval'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Nominal'], - }], - channel: ['Length'], - recRate: 'Recommended', - }, - waterfall_chart: { - id: 'waterfall_chart', - name: 'Waterfall Chart', - alias: ['Flying Bricks Chart', 'Mario Chart', 'Bridge Chart', 'Cascade Chart'], - family: ['ColumnCharts'], - def: 'A waterfall chart is used to portray how an initial value is affected by a series of intermediate positive or negative values', - purpose: ['Comparison', 'Trend'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Ordinal', 'Time', 'Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Color', 'Length', 'Position'], - recRate: 'Recommended', - }, - histogram: { - id: 'histogram', - name: 'Histogram', - alias: [], - family: ['ColumnCharts'], - def: 'A histogram is an accurate representation of the distribution of numerical data.', - purpose: ['Distribution'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Interval'] }], - channel: ['Position'], - recRate: 'Recommended', - }, - bar_chart: { - id: 'bar_chart', - name: 'Bar Chart', - alias: ['Bars'], - family: ['BarCharts'], - def: 'A bar chart uses series of bars to display the value of the dimension. The vertical axis shows the classification dimension and the horizontal axis shows the corresponding value.', - purpose: ['Comparison', 'Distribution', 'Rank'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 1, maxQty: 2, fieldConditions: ['Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Position', 'Color'], - recRate: 'Recommended', - }, - grouped_bar_chart: { - id: 'grouped_bar_chart', - name: 'Grouped Bar Chart', - alias: ['Grouped Bar'], - family: ['BarCharts'], - def: 'A grouped bar chart uses bars of different colors to form a group to display the values of the dimensions. The vertical axis indicates the grouping of categories, the color indicates the categories, and the horizontal axis shows the corresponding value.', - purpose: ['Comparison', 'Distribution', 'Rank'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Color', 'Position'], - recRate: 'Recommended', - }, - stacked_bar_chart: { - id: 'stacked_bar_chart', - name: 'Stacked Bar Chart', - alias: ['Stacked Bar'], - family: ['BarCharts'], - def: 'A stacked bar chart uses stacked bars of different colors to display the values ​​for each dimension. The vertical axis indicates the first classification dimension, the color indicates the second classification dimension, and the horizontal axis shows the corresponding value.', - purpose: ['Comparison', 'Composition', 'Distribution', 'Rank'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Color', 'Length', 'Position'], - recRate: 'Recommended', - }, - percent_stacked_bar_chart: { - id: 'percent_stacked_bar_chart', - name: 'Percent Stacked Bar Chart', - alias: ['Percent Stacked Bar', '% Stacked Bar', '100% Stacked Bar'], - family: ['BarCharts'], - def: 'A percent stacked column chart uses stacked bars of different colors to display the values ​​for each dimension. The vertical axis indicates the first classification dimension, the color indicates the second classification dimension, and the horizontal axis shows the percentage of the corresponding classification.', - purpose: ['Comparison', 'Composition', 'Distribution', 'Proportion'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Color', 'Length'], - recRate: 'Recommended', - }, - interval_bar_chart: { - id: 'interval_bar_chart', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - range_bar_chart: { - id: 'range_bar_chart', - name: 'Range Bar Chart', - alias: [], - family: ['BarCharts'], - def: 'A bar chart that does not have to start from zero axis.', - purpose: ['Comparison'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Interval'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Nominal'], - }], - channel: ['Length'], - recRate: 'Recommended', - }, - radial_bar_chart: { - id: 'radial_bar_chart', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - mirror_bar_chart: { - id: 'mirror_bar_chart', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - bullet_chart: { - id: 'bullet_chart', - name: 'Bullet Chart', - alias: [], - family: ['BarCharts'], - def: 'A bullet graph is a variation of a bar graph developed by Stephen Few. Seemingly inspired by the traditional thermometer charts and progress bars found in many dashboards, the bullet graph serves as a replacement for dashboard gauges and meters.', - purpose: ['Proportion'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Bars'], - dataPres: [{ minQty: 3, maxQty: 3, fieldConditions: ['Interval'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Nominal'], - }], - channel: ['Position', 'Color'], - recRate: 'Recommended', - }, - pie_chart: { - id: 'pie_chart', - name: 'Pie Chart', - alias: ['Circle Chart', 'Pie'], - family: ['PieCharts'], - def: 'A pie chart is a chart that the classification and proportion of data are represented by the color and arc length (angle, area) of the sector.', - purpose: ['Comparison', 'Composition', 'Proportion'], - coord: ['Polar'], - category: ['Statistic'], - shape: ['Round'], - dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Angle', 'Area', 'Color'], - recRate: 'Use with Caution', - }, - donut_chart: { - id: 'donut_chart', - name: 'Donut Chart', - alias: ['Donut', 'Doughnut', 'Doughnut Chart', 'Ring Chart'], - family: ['PieCharts'], - def: 'A donut chart is a variation on a Pie chart except it has a round hole in the center which makes it look like a donut.', - purpose: ['Comparison', 'Composition', 'Proportion'], - coord: ['Polar'], - category: ['Statistic'], - shape: ['Round'], - dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['ArcLength'], - recRate: 'Recommended', - }, - nested_pie_chart: { - id: 'nested_pie_chart', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - rose_chart: { - id: 'rose_chart', - name: 'Rose Chart', - alias: ['Nightingale Chart', 'Polar Area Chart', 'Coxcomb Chart'], - family: ['PieCharts'], - def: 'Nightingale Rose Chart is a peculiar combination of the Radar Chart and Stacked Column Chart types of data visualization.', - purpose: ['Comparison', 'Composition', 'Proportion'], - coord: ['Polar'], - category: ['Statistic'], - shape: ['Round'], - dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Angle', 'Color', 'Length'], - recRate: 'Use with Caution', - }, - scatter_plot: { - id: 'scatter_plot', - name: 'Scatter Plot', - alias: ['Scatter Chart', 'Scatterplot'], - family: ['ScatterCharts'], - def: 'A scatter plot is a type of plot or mathematical diagram using Cartesian coordinates to display values for typically two variables for series of data.', - purpose: ['Comparison', 'Distribution'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Scatter'], - dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Interval'] }, { - minQty: 0, - maxQty: 1, - fieldConditions: ['Nominal'], - }], - channel: ['Color', 'Position'], - recRate: 'Recommended', - }, - bubble_chart: { - id: 'bubble_chart', - name: 'Bubble Chart', - alias: ['Bubble Chart'], - family: ['ScatterCharts'], - def: 'A bubble chart is a type of chart that displays four dimensions of data with x, y positions, circle size and circle color.', - purpose: ['Comparison', 'Distribution'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Scatter'], - dataPres: [{ minQty: 3, maxQty: 3, fieldConditions: ['Interval'] }, { - minQty: 0, - maxQty: 1, - fieldConditions: ['Nominal'], - }], - channel: ['Color', 'Position', 'Size'], - recRate: 'Recommended', - }, - non_ribbon_chord_diagram: { - id: 'non_ribbon_chord_diagram', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - arc_diagram: { - id: 'arc_diagram', - name: 'Arc Diagram', - alias: [], - family: ['GeneralGraph'], - def: 'A graph where the edges are represented as arcs.', - purpose: ['Relation'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - chord_diagram: { - id: 'chord_diagram', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - treemap: { - id: 'treemap', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - sankey_diagram: { - id: 'sankey_diagram', - name: 'Sankey Diagram', - alias: [], - family: ['GeneralGraph'], - def: 'A graph shows the flows with weights between objects.', - purpose: ['Flow', 'Trend', 'Relation'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - funnel_chart: { - id: 'funnel_chart', - name: 'Funnel Chart', - alias: [], - family: ['FunnelCharts'], - def: 'A funnel chart is often used to represent stages in a sales process and show the amount of potential revenue for each stage.', - purpose: ['Trend'], - coord: ['SymmetricCartesian'], - category: ['Statistic'], - shape: ['Symmetric'], - dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Ordinal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Color', 'Length'], - recRate: 'Recommended', - }, - overlapping_funnel_chart: { - id: 'overlapping_funnel_chart', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - mirror_funnel_chart: { - id: 'mirror_funnel_chart', - name: 'Mirror Funnel Chart', - alias: ['Contrast Funnel Chart'], - family: ['FunnelCharts'], - def: 'A mirror funnel chart is a funnel chart divided into two series by a central axis.', - purpose: ['Comparison', 'Trend'], - coord: ['SymmetricCartesian'], - category: ['Statistic'], - shape: ['Symmetric'], - dataPres: [{ minQty: 1, maxQty: 1, fieldConditions: ['Ordinal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }, { minQty: 1, maxQty: 1, fieldConditions: ['Nominal'] }], - channel: ['Color', 'Length', 'Direction'], - recRate: 'Recommended', - }, - boxplot: { - id: 'boxplot', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - heatmap: { - id: 'heatmap', - name: 'Heatmap', - alias: [], - family: ['HeatmapCharts'], - def: 'A heatmap is a graphical representation of data where the individual values contained in a matrix are represented as colors.', - purpose: ['Distribution'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Square'], - dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Nominal', 'Ordinal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Color', 'Position'], - recRate: 'Recommended', - }, - density_heatmap: { - id: 'density_heatmap', - name: 'Density Heatmap', - alias: ['Heatmap'], - family: ['HeatmapCharts'], - def: 'A density heatmap is a heatmap for representing the density of dots.', - purpose: ['Distribution'], - coord: ['Cartesian2D'], - category: ['Statistic'], - shape: ['Area'], - dataPres: [{ minQty: 3, maxQty: 3, fieldConditions: ['Interval'] }], - channel: ['Color', 'Position', 'Area'], - recRate: 'Recommended', - }, - gauge_chart: { - id: 'gauge_chart', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - radar_chart: { - id: 'radar_chart', - name: 'Radar Chart', - alias: ['Web Chart', 'Spider Chart', 'Star Chart', 'Cobweb Chart', 'Irregular Polygon', 'Kiviat diagram'], - family: ['RadarCharts'], - def: 'A radar chart maps series of data volume of multiple dimensions onto the axes. Starting at the same center point, usually ending at the edge of the circle, connecting the same set of points using lines.', - purpose: ['Comparison'], - coord: ['Radar'], - category: ['Statistic'], - shape: ['Round'], - dataPres: [{ minQty: 1, maxQty: 2, fieldConditions: ['Nominal'] }, { - minQty: 1, - maxQty: 1, - fieldConditions: ['Interval'], - }], - channel: ['Color', 'Position'], - recRate: 'Recommended', - }, - wordcloud: { - id: 'wordcloud', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - candlestick_chart: { - id: 'candlestick_chart', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - compact_box_tree: { - id: 'compact_box_tree', - name: 'CompactBox Tree', - alias: [], - family: ['TreeGraph'], - def: 'A type of tree graph layout which arranges the nodes with same depth on the same level.', - purpose: ['Relation', 'Hierarchy'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - dendrogram: { - id: 'dendrogram', - name: 'Dendrogram', - alias: [], - family: ['TreeGraph'], - def: 'A type of tree graph layout which arranges the leaves on the same level and ignores the node size.', - purpose: ['Relation', 'Hierarchy'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - indented_tree: { - id: 'indented_tree', - name: 'Indented Tree Layout', - alias: [], - family: ['TreeGraph'], - def: 'A type of tree graph layout where each node takes a row or a column.', - purpose: ['Relation', 'Hierarchy'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - radial_tree: { - id: 'radial_tree', - name: 'Radial Tree Layout', - alias: [], - family: ['TreeGraph'], - def: 'A type of tree graph layout which places the root at the center, and the branches around the root radially.', - purpose: ['Relation', 'Hierarchy'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - flow_diagram: { - id: 'flow_diagram', - name: 'Flow Diagram', - alias: ['Dagre Graph Layout', 'Dagre', 'Flow Chart'], - family: ['GeneralGraph'], - def: 'Directed flow graph.', - purpose: ['Relation', 'Flow'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - fruchterman_layout_graph: { - id: 'fruchterman_layout_graph', - name: 'Fruchterman Graph Layout', - alias: [], - family: ['GeneralGraph'], - def: 'A type of force directed graph layout.', - purpose: ['Relation'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - force_directed_layout_graph: { - id: 'force_directed_layout_graph', - name: 'Force Directed Graph Layout', - alias: [], - family: ['GeneralGraph'], - def: 'The classical force directed graph layout.', - purpose: ['Relation'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - circular_layout_graph: { - id: 'circular_layout_graph', - name: 'Circular Graph Layout', - alias: [], - family: ['GeneralGraph'], - def: 'A type of graph layout which arranges all the nodes on a circle.', - purpose: ['Relation'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - spiral_layout_graph: { - id: 'spiral_layout_graph', - name: 'Spiral Graph Layout', - alias: [], - family: ['GeneralGraph'], - def: 'A type of graph layout which arranges all the nodes along a spiral line.', - purpose: ['Relation'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - radial_layout_graph: { - id: 'radial_layout_graph', - name: 'Radial Graph Layout', - alias: [], - family: ['GeneralGraph'], - def: 'A type of graph layout which places a focus node on the center and the others on the concentrics centered at the focus node according to the shortest path length to the it.', - purpose: ['Relation'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - concentric_layout_graph: { - id: 'concentric_layout_graph', - name: 'Concentric Graph Layout', - alias: [], - family: ['GeneralGraph'], - def: 'A type of graph layout which arranges the nodes on concentrics.', - purpose: ['Relation'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - grid_layout_graph: { - id: 'grid_layout_graph', - name: 'Grid Graph Layout', - alias: [], - family: ['GeneralGraph'], - def: 'A type of graph layout arranges the nodes on grids.', - purpose: ['Relation'], - coord: ['Cartesian2D'], - category: ['Graph'], - shape: ['Network'], - dataPres: [{ minQty: 1, maxQty: '*', fieldConditions: ['Nominal'] }], - channel: ['Color', 'Size', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - symbol_map: { - id: 'symbol_map', - name: 'Symbol Map', - alias: [], - family: ['PointLayer'], - def: 'Overlay symbols on the map as glyphs.', - purpose: ['Distribution', 'Comparison', 'Spatial'], - coord: ['Geo'], - category: ['Map'], - shape: ['Scatter', 'Map'], - dataPres: [], - channel: ['Position'], - recRate: 'Recommended', - }, - chart_map: { - id: 'chart_map', - name: 'Chart Map', - alias: [], - family: ['PointLayer'], - def: 'Overlay charts on the map as glyphs.', - purpose: ['Composition', 'Distribution', 'Comparison', 'Spatial'], - coord: ['Geo'], - category: ['Map'], - shape: ['Map'], - dataPres: [], - channel: ['Position'], - recRate: 'Recommended', - }, - column_map_3d: { - id: 'column_map_3d', - name: '3D Column Map', - alias: [], - family: ['PointLayer'], - def: 'Maps that use height of 3D columns to represent distribution.', - purpose: ['Distribution', 'Comparison', 'Spatial'], - coord: [], - category: ['Map'], - shape: ['Map'], - dataPres: [], - channel: ['Position', 'Length'], - recRate: 'Recommended', - }, - scatter_map: { - id: 'scatter_map', - name: 'Scatter Map', - alias: [], - family: ['PointLayer'], - def: 'Overlay dots with same size on the map as glyphs.', - purpose: ['Distribution', 'Spatial'], - coord: ['Geo'], - category: ['Map'], - shape: ['Scatter', 'Map'], - dataPres: [], - channel: ['Size', 'Color', 'Position', 'Opacity'], - recRate: 'Recommended', - }, - path_map: { - id: 'path_map', - name: 'Path Map', - alias: [], - family: ['LineLayer'], - def: 'Overlay paths on the map as glyphs.', - purpose: ['Spatial'], - coord: ['Geo'], - category: ['Map'], - shape: ['Lines'], - dataPres: [], - channel: ['Size', 'Color', 'Position', 'Opacity'], - recRate: 'Recommended', - }, - isoline_map: { - id: 'isoline_map', - name: 'Isoline Map', - alias: [], - family: ['LineLayer'], - def: '', - purpose: ['Comparison'], - coord: ['Geo'], - category: ['Map'], - shape: ['Lines'], - dataPres: [], - channel: ['Size', 'Color', 'Position', 'Opacity'], - recRate: 'Recommended', - }, - arc_map_3d: { - id: 'arc_map_3d', - name: '3D Arc Map', - alias: [], - family: ['LineLayer'], - def: '', - purpose: ['Relation', 'Spatial'], - coord: ['Geo'], - category: ['Map'], - shape: ['Lines'], - dataPres: [], - channel: ['Size', 'Color', 'Position', 'Opacity'], - recRate: 'Recommended', - }, - choropleth_map: { - id: 'choropleth_map', - name: 'Choropleth Map', - alias: [], - family: ['PolygonLayer'], - def: 'A choropleth map is a type of thematic map in which areas are shaded or patterned in proportion to a statistical variable that represents an aggregate summary of a geographic characteristic within each area, such as population density or per-capita income.', - purpose: ['Comparison', 'Spatial'], - coord: ['Geo'], - category: ['Map'], - shape: ['Area', 'Map'], - dataPres: [], - channel: ['Color', 'Position', 'Opacity', 'Stroke', 'LineWidth'], - recRate: 'Recommended', - }, - choropleth_map_3d: { - id: 'choropleth_map_3d', - name: '3D Choropleth Map', - alias: ['Extrude Map'], - family: ['PolygonLayer'], - def: '', - purpose: ['Comparison'], - coord: ['Geo'], - category: ['Map'], - shape: ['Area', 'Map'], - dataPres: [], - channel: ['Size', 'Color', 'Position', 'Opacity'], - recRate: 'Recommended', - }, - hexagonal_heat_map: { - id: 'hexagonal_heat_map', - name: 'Hexagonal Heat Map', - alias: [], - family: [], - def: 'Dividing the map area using hexagons.', - purpose: ['Distribution', 'Spatial'], - coord: ['Geo'], - category: ['Map'], - shape: ['Area', 'Map'], - dataPres: [], - channel: ['Size', 'Color', 'Position', 'Opacity'], - recRate: 'Recommended', - }, - hexagonal_heat_map_3d: { - id: 'hexagonal_heat_map_3d', - name: '3D Hexagonal Heat Map', - alias: [], - family: [], - def: 'Dividing the 3D map area using hexagons.', - purpose: ['Distribution'], - coord: ['Geo'], - category: ['Map'], - shape: ['Map'], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - classical_heat_map: { - id: 'classical_heat_map', - name: 'Classical Heat Map', - alias: [], - family: [], - def: '', - purpose: ['Distribution'], - coord: ['Geo'], - category: ['Map'], - shape: ['Map'], - dataPres: [], - channel: ['Color', 'Position', 'Opacity'], - recRate: 'Recommended', - }, - grid_heat_map: { - id: 'grid_heat_map', - name: 'Gird Heat Map', - alias: [], - family: [], - def: '', - purpose: ['Distribution'], - coord: [], - category: ['Map'], - shape: ['Map'], - dataPres: [], - channel: ['Color', 'Position', 'Opacity'], - recRate: 'Recommended', - }, - bubble_map: { - id: 'bubble_map', - name: 'Bubble Map', - alias: [], - family: ['PointLayer'], - def: 'Overlay bubbles on the map as glyphs.', - purpose: ['Distribution', 'Spatial'], - coord: ['Geo'], - category: ['Map'], - shape: ['Scatter', 'Map'], - dataPres: [], - channel: ['Position', 'Color', 'Size'], - recRate: 'Recommended', - }, - bubble_light_map: { - id: 'bubble_light_map', - name: 'Bubble Light Map', - alias: [], - family: ['PointLayer'], - def: 'Overlay bubbles with different lightness on the map as glyphs.', - purpose: ['Distribution', 'Spatial'], - coord: ['Geo'], - category: ['Map'], - shape: ['Scatter', 'Map'], - dataPres: [], - channel: ['Position', 'Color', 'Size', 'Opacity'], - recRate: 'Recommended', - }, - packed_circles: { - id: 'packed_circles', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - polar_treemap: { - id: 'polar_treemap', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - sunburst_diagram: { - id: 'sunburst_diagram', - name: '', - alias: [], - family: [], - def: '', - purpose: [], - coord: [], - category: [], - shape: [], - dataPres: [], - channel: [], - recRate: 'Recommended', - }, - liquid_chart: { - id: 'liquid_chart', - name: 'Liquid Chart', - alias: ['Liquid Ball', 'Progress Ball'], - family: ['Others'], - def: 'Liquid chart is a diagram to represent progress.', - purpose: ['Composition'], - coord: ['Other'], - category: ['Diagram'], - shape: ['Round'], - dataPres: [{ minQty: 2, maxQty: 2, fieldConditions: ['Interval'] }], - channel: ['Position'], - recRate: 'Not Recommended', - }, - }; - - function o(e, a) { - void 0 === e && (e = 'en-US'), void 0 === a && (a = !1); - var t = JSON.parse(JSON.stringify(i)), r = {}; - Object.keys(t).forEach((function(e) { - var n = t[e], i = !0; - if (a) for (var o = Object.keys(n), c = 0; c < o.length; c++) { - var s = o[c], l = n[s]; - if ('alias' !== s && 'boolean' != typeof l && (Array.isArray(l) && 0 === l.length || !l)) { - i = !1; - break; - } - } - i && (r[e] = n); - })); - var o = {}; - if (e && 'en-US' != e) { - var c = n(e), s = Object.keys(r); - c && s.forEach((function(e) { - o[e] = {}, o[e].id = e, o[e].name = c.chartTypes[e].name, o[e].alias = c.chartTypes[e].alias, o[e].def = c.chartTypes[e].def, o[e].family = r[e].family.map((function(e) { - return c.concepts.family[e]; - })), o[e].purpose = r[e].purpose.map((function(e) { - return c.concepts.purpose[e]; - })), o[e].coord = r[e].coord.map((function(e) { - return c.concepts.coord[e]; - })), o[e].category = r[e].category.map((function(e) { - return c.concepts.category[e]; - })), o[e].shape = r[e].shape.map((function(e) { - return c.concepts.shape[e]; - })), o[e].channel = r[e].channel.map((function(e) { - return c.concepts.channel[e]; - })), o[e].dataPres = r[e].dataPres.map((function(e) { - var a = {}; - return a.minQty = e.minQty, a.maxQty = e.maxQty, a.fieldConditions = e.fieldConditions.map((function(e) { - return c.concepts.lom[e]; - })), a; - })); - })); - } else o = r; - return o; - } - - function c(e, a) { - var t = e.id; - i[t] = e, Object.keys(a).forEach((function(e) { - var n = r[e]; - n && (n.chartTypes[t] = a[e]); - })); - } - - var s = t(0), - l = ['LineCharts', 'ColumnCharts', 'BarCharts', 'PieCharts', 'AreaCharts', 'ScatterCharts', 'FunnelCharts', 'HeatmapCharts', 'RadarCharts', 'TreeGraph', 'GeneralGraph', 'PolygonLayer', 'LineLayer', 'PointLayer', 'HeatmapLayer', 'Others'], - d = ['Comparison', 'Trend', 'Distribution', 'Rank', 'Proportion', 'Composition', 'Relation', 'Hierarchy', 'Flow', 'Spatial'], - u = ['NumberLine', 'Cartesian2D', 'SymmetricCartesian', 'Cartesian3D', 'Polar', 'NodeLink', 'Radar', 'Geo', 'Other'], - m = ['Statistic', 'Diagram', 'Graph', 'Map'], - h = ['Lines', 'Bars', 'Round', 'Square', 'Area', 'Scatter', 'Symmetric', 'Network', 'Map'], - p = ['Nominal', 'Ordinal', 'Interval', 'Discrete', 'Continuous', 'Time'], - f = ['Position', 'Length', 'Color', 'Area', 'Angle', 'ArcLength', 'Direction', 'Size', 'Opacity', 'Stroke', 'LineWidth', 'Lightness'], - y = ['Recommended', 'Use with Caution', 'Not Recommended']; - - function _(e) { - if (void 0 === e && (e = 'en-US'), e && 'en-US' != e) { - var a = n(e); - if (a && a.concepts) { - var t = a.concepts; - return { - family: Object.values(t.family), - category: Object.values(t.category), - purpose: Object.values(t.purpose), - coord: Object.values(t.coord), - shape: Object.values(t.shape), - channel: Object.values(t.channel), - lom: Object.values(t.lom), - recRate: Object.values(t.recRate), - }; - } - } - return { - family: Object(s.c)(l), - category: Object(s.c)(m), - purpose: Object(s.c)(d), - coord: Object(s.c)(u), - shape: Object(s.c)(h), - channel: Object(s.c)(f), - lom: Object(s.c)(p), - recRate: Object(s.c)(y), - }; - } - - var g = ['line_chart', 'step_line_chart', 'area_chart', 'stacked_area_chart', 'percent_stacked_area_chart', 'interval_area_chart', 'stream_chart', 'column_chart', 'grouped_column_chart', 'stacked_column_chart', 'percent_stacked_column_chart', 'interval_column_chart', 'range_column_chart', 'waterfall_chart', 'histogram', 'bar_chart', 'stacked_bar_chart', 'percent_stacked_bar_chart', 'grouped_bar_chart', 'interval_bar_chart', 'range_bar_chart', 'radial_bar_chart', 'mirror_bar_chart', 'bullet_chart', 'pie_chart', 'donut_chart', 'nested_pie_chart', 'rose_chart', 'scatter_plot', 'bubble_chart', 'non_ribbon_chord_diagram', 'arc_diagram', 'chord_diagram', 'treemap', 'sankey_diagram', 'funnel_chart', 'overlapping_funnel_chart', 'mirror_funnel_chart', 'boxplot', 'heatmap', 'density_heatmap', 'gauge_chart', 'radar_chart', 'wordcloud', 'candlestick_chart', 'compact_box_tree', 'dendrogram', 'indented_tree', 'radial_tree', 'flow_diagram', 'fruchterman_layout_graph', 'force_directed_layout_graph', 'circular_layout_graph', 'spiral_layout_graph', 'radial_layout_graph', 'concentric_layout_graph', 'grid_layout_graph', 'symbol_map', 'chart_map', 'column_map_3d', 'scatter_map', 'path_map', 'isoline_map', 'arc_map_3d', 'choropleth_map', 'choropleth_map_3d', 'hexagonal_heat_map', 'hexagonal_heat_map_3d', 'classical_heat_map', 'grid_heat_map', 'bubble_map', 'bubble_light_map', 'packed_circles', 'polar_treemap', 'sunburst_diagram', 'liquid_chart']; - }, function(e, a, t) { - 'use strict'; - var r = t(4); - window.analyze = r.analyze; - }, function(e, a, t) { - 'use strict'; - - function r(e) { - return (r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function(e) { - return typeof e; - } : function(e) { - return e && 'function' == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? 'symbol' : typeof e; - })(e); - } - - Object.defineProperty(a, '__esModule', { value: !0 }), a.dataToDataProps = C, a.dataPropsToSpecs = x, a.analyze = function(e, a) { - console.log('💠💠💠💠💠💠 data 💠💠💠💠💠💠'), console.log(e), console.log('🍯🍯🍯🍯🍯🍯 options 🍯🍯🍯🍯🍯🍯'), console.log(a); - var t = C(e); - return console.log('🔶🔶🔶🔶🔶🔶 dataset analysis 🔶🔶🔶🔶🔶🔶'), console.log(t), x(t, a); - }, a.specToLibConfig = function(e, a) { - var t = (0, l.getMappingForLib)(a), r = t.typeMapping, n = t.configMapping, i = e.type, o = e.channels, c = {}; - i && r[i] && (c.type = r[i]); - for (var s = {}, d = 0, u = Object.entries(o); d < u.length; d++) { - var h = (g = u[d], b = 2, function(e) { - if (Array.isArray(e)) return e; - }(g) || function(e, a) { - if ('undefined' == typeof Symbol || !(Symbol.iterator in Object(e))) return; - var t = [], r = !0, n = !1, i = void 0; - try { - for (var o, c = e[Symbol.iterator](); !(r = (o = c.next()).done) && (t.push(o.value), !a || t.length !== a); r = !0) ; - } catch (e) { - n = !0, i = e; - } finally { - try { - r || null == c.return || c.return(); - } finally { - if (n) throw i; - } - } - return t; - }(g, b) || m(g, b) || function() { - throw new TypeError('Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.'); - }()), p = h[0], f = h[1], y = n[i]; - if (y) { - var _ = y[p]; - _ && (s[_] = f); - } - } - var g, b; - return c.configs = s, c; - }; - var n, i = t(2), o = (n = t(5)) && n.__esModule ? n : { default: n }, c = function(e) { - if (e && e.__esModule) return e; - if (null === e || 'object' !== r(e) && 'function' != typeof e) return { default: e }; - var a = d(); - if (a && a.has(e)) return a.get(e); - var t = {}, n = Object.defineProperty && Object.getOwnPropertyDescriptor; - for (var i in e) if (Object.prototype.hasOwnProperty.call(e, i)) { - var o = n ? Object.getOwnPropertyDescriptor(e, i) : null; - o && (o.get || o.set) ? Object.defineProperty(t, i, o) : t[i] = e[i]; - } - t.default = e, a && a.set(e, t); - return t; - }(t(11)), s = t(7), l = t(9); - - function d() { - if ('function' != typeof WeakMap) return null; - var e = new WeakMap; - return d = function() { - return e; - }, e; - } - - function u(e) { - return function(e) { - if (Array.isArray(e)) return h(e); - }(e) || function(e) { - if ('undefined' != typeof Symbol && Symbol.iterator in Object(e)) return Array.from(e); - }(e) || m(e) || function() { - throw new TypeError('Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.'); - }(); - } - - function m(e, a) { - if (e) { - if ('string' == typeof e) return h(e, a); - var t = Object.prototype.toString.call(e).slice(8, -1); - return 'Object' === t && e.constructor && (t = e.constructor.name), 'Map' === t || 'Set' === t ? Array.from(e) : 'Arguments' === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? h(e, a) : void 0; - } - } - - function h(e, a) { - (null == a || a > e.length) && (a = e.length); - for (var t = 0, r = new Array(a); t < a; t++) r[t] = e[t]; - return r; - } - - function p(e, a) { - var t = Object.keys(e); - if (Object.getOwnPropertySymbols) { - var r = Object.getOwnPropertySymbols(e); - a && (r = r.filter((function(a) { - return Object.getOwnPropertyDescriptor(e, a).enumerable; - }))), t.push.apply(t, r); - } - return t; - } - - function f(e) { - for (var a = 1; a < arguments.length; a++) { - var t = null != arguments[a] ? arguments[a] : {}; - a % 2 ? p(Object(t), !0).forEach((function(a) { - y(e, a, t[a]); - })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : p(Object(t)).forEach((function(a) { - Object.defineProperty(e, a, Object.getOwnPropertyDescriptor(t, a)); - })); - } - return e; - } - - function y(e, a, t) { - return a in e ? Object.defineProperty(e, a, { - value: t, - enumerable: !0, - configurable: !0, - writable: !0, - }) : e[a] = t, e; - } - - var _ = (0, i.CKBJson)('en-US', !0); - - function g(e, a) { - return e.distinct < a.distinct ? 1 : e.distinct > a.distinct ? -1 : 0; - } - - function b(e, a) { - return a.every((function(a) { - return e.includes(a); - })); - } - - function v(e, a) { - return a.some((function(a) { - return e.includes(a); - })); - } - - function C(e) { - var a = c.typeAll(e), t = []; - return a.forEach((function(e) { - var a = []; - c.isNominal(e) && a.push('Nominal'), c.isOrdinal(e) && a.push('Ordinal'), c.isInterval(e) && a.push('Interval'), c.isDiscrete(e) && a.push('Discrete'), c.isContinuous(e) && a.push('Continuous'), c.isTime(e) && a.push('Time'); - var r = f(f({}, e), {}, { levelOfMeasurements: a }); - t.push(r); - })), t; - } - - function x(e, a) { - var t = a ? a.purpose : '', r = a ? a.preferences : void 0; - var n = Object.keys(_).map((function(a) { - var n = 0, i = {}, s = 1; - o.default.filter((function(e) { - return 'HARD' === e.hardOrSoft && e.specChartTypes.includes(a); - })).forEach((function(n) { - var o = n.check({ dataProps: e, chartType: a, purpose: t, preferences: r }); - s *= o, i[n.id] = o; - })); - var l = 0; - o.default.filter((function(e) { - return 'SOFT' === e.hardOrSoft && e.specChartTypes.includes(a); - })).forEach((function(n) { - var o = n.check({ dataProps: e, chartType: a, purpose: t, preferences: r }); - l += o, i[n.id] = o; - })), n = s * (1 + l), console.log('💯score: ', n, '=', s, '* (1 +', l, ') ;charttype: ', a), console.log(i); - var d = {}; - if ('pie_chart' === a || 'donut_chart' === a) { - var m = e.find((function(e) { - return b(e.levelOfMeasurements, ['Nominal']); - })), h = e.find((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })); - h && m ? (d.color = m.name, d.angle = h.name) : n = 0; - } - if ('line_chart' === a || 'step_line_chart' == a) { - var p = e.find((function(e) { - return v(e.levelOfMeasurements, ['Time', 'Ordinal']); - })), f = e.find((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })), y = e.find((function(e) { - return b(e.levelOfMeasurements, ['Nominal']); - })); - y && (d.color = y.name), p && f ? (d.x = p.name, d.y = f.name) : n = 0; - } - if ('area_chart' === a) { - var _ = e.find((function(e) { - return v(e.levelOfMeasurements, ['Time', 'Ordinal']); - })), C = e.find((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })); - _ && C ? (d.x = _.name, d.y = C.name) : n = 0; - } - if ('bar_chart' === a) { - var x = e.filter((function(e) { - return b(e.levelOfMeasurements, ['Nominal']); - })).sort(g), P = x[0], O = x[1], S = e.find((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })); - S && P ? (d.y = P.name, d.x = S.name, O && (d.color = O.name)) : n = 0; - } - if ('column_chart' === a) { - var R = e.filter((function(e) { - return b(e.levelOfMeasurements, ['Nominal']); - })).sort(g), k = R[0], w = R[1], Q = e.find((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })); - k && Q ? (d.y = Q.name, d.x = k.name, w && (d.color = w.name)) : n = 0; - } - if ('grouped_bar_chart' === a || 'stacked_bar_chart' === a || 'percent_stacked_bar_chart' === a) { - var D = e.filter((function(e) { - return b(e.levelOfMeasurements, ['Nominal']); - })).sort(g), M = D[0], T = D[1], A = e.find((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })); - M && T && A ? (d.y = M.name, d.y2 = T.name, d.x = A.name) : n = 0; - } - if ('grouped_column_chart' === a || 'stacked_column_chart' === a || 'percent_stacked_column_chart' === a) { - var N = e.filter((function(e) { - return b(e.levelOfMeasurements, ['Nominal']); - })).sort(g), L = N[0], F = N[1], G = e.find((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })); - L && F && G ? (d.x = L.name, d.x2 = F.name, d.y = G.name) : n = 0; - } - if ('stacked_area_chart' === a || 'percent_stacked_area_chart' === a) { - var j = e.find((function(e) { - return v(e.levelOfMeasurements, ['Time', 'Ordinal']); - })), I = e.find((function(e) { - return b(e.levelOfMeasurements, ['Nominal']); - })), B = e.find((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })); - j && I && B ? (d.x = j.name, d.x2 = I.name, d.y = B.name) : n = 0; - } - if ('radar_chart' === a) { - var z = e.filter((function(e) { - return b(e.levelOfMeasurements, ['Nominal']); - })).sort(g), E = z[0], H = z[1], W = e.find((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })); - E && H && W ? (d.angle = E.name, d.series = H.name, d.radius = W.name) : n = 0; - } - if ('scatter_plot' === a) { - var U = e.filter((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })).sort(g), q = U[0], Y = U[1], $ = e.find((function(e) { - return b(e.levelOfMeasurements, ['Nominal']); - })); - q && Y ? (d.x = q.name, d.y = Y.name, $ && (d.color = $.name)) : n = 0; - } - if ('bubble_chart' === a) { - for (var K = e.filter((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })), J = { x: K[0], y: K[1], corr: 0, size: K[2] }, X = function(e) { - for (var a = function(a) { - var t = c.pearson(K[e], K[a]); - Math.abs(t) > J.corr && (J.x = K[e], J.y = K[a], J.corr = t, J.size = K[u(Array(K.length).keys()).find((function(t) { - return t !== e && t !== a; - })) || 0]); - }, t = e + 1; t < K.length; t++) a(t); - }, Z = 0; Z < K.length; Z++) X(Z); - var V = J.x, ee = J.y, ae = J.size, te = e.find((function(e) { - return v(e.levelOfMeasurements, ['Nominal']); - })); - V && ee && ae && te ? (d.x = V.name, d.y = ee.name, d.size = ae.name, d.color = te.name) : n = 0; - } - if ('histogram' === a) { - var re = e.find((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })); - re ? d.x = re.name : n = 0; - } - if ('heatmap' === a) { - var ne = e.filter((function(e) { - return v(e.levelOfMeasurements, ['Nominal', 'Ordinal']); - })).sort(g), ie = ne[0], oe = ne[1], ce = e.find((function(e) { - return b(e.levelOfMeasurements, ['Interval']); - })); - ie && oe && ce ? (d.x = ie.name, d.y = oe.name, d.color = ce.name) : n = 0; - } - return { type: a, channels: d, score: n }; - })).filter((function(e) { - return e.score && 0 !== e.score && (0, s.translate)(e.type); - })).sort((function(e, a) { - return e.score < a.score ? 1 : e.score > a.score ? -1 : 0; - })); - return console.log('🍒🍒🍒🍒🍒🍒 resultList 🍒🍒🍒🍒🍒🍒'), console.log(n), n; - } - }, function(e, a, t) { - 'use strict'; - - function r(e) { - return (r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function(e) { - return typeof e; - } : function(e) { - return e && 'function' == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? 'symbol' : typeof e; - })(e); - } - - Object.defineProperty(a, '__esModule', { value: !0 }), Object.defineProperty(a, 'Rule', { - enumerable: !0, - get: function() { - return i.default; - }, - }), Object.defineProperty(a, 'Preferences', { - enumerable: !0, get: function() { - return i.Preferences; - }, - }), a.default = void 0; - var n, i = function(e) { - if (e && e.__esModule) return e; - if (null === e || 'object' !== r(e) && 'function' != typeof e) return { default: e }; - var a = o(); - if (a && a.has(e)) return a.get(e); - var t = {}, n = Object.defineProperty && Object.getOwnPropertyDescriptor; - for (var i in e) if (Object.prototype.hasOwnProperty.call(e, i)) { - var c = n ? Object.getOwnPropertyDescriptor(e, i) : null; - c && (c.get || c.set) ? Object.defineProperty(t, i, c) : t[i] = e[i]; - } - t.default = e, a && a.set(e, t); - return t; - }(t(1)); - - function o() { - if ('function' != typeof WeakMap) return null; - var e = new WeakMap; - return o = function() { - return e; - }, e; - } - - var c = ((n = t(6)) && n.__esModule ? n : { default: n }).default; - a.default = c; - }, function(e, a, t) { - 'use strict'; - Object.defineProperty(a, '__esModule', { value: !0 }), a.default = void 0; - var r, n = (r = t(1)) && r.__esModule ? r : { default: r }; - - function i(e) { - if ('undefined' == typeof Symbol || null == e[Symbol.iterator]) { - if (Array.isArray(e) || (e = function(e, a) { - if (!e) return; - if ('string' == typeof e) return o(e, a); - var t = Object.prototype.toString.call(e).slice(8, -1); - 'Object' === t && e.constructor && (t = e.constructor.name); - if ('Map' === t || 'Set' === t) return Array.from(e); - if ('Arguments' === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)) return o(e, a); - }(e))) { - var a = 0, t = function() { - }; - return { - s: t, n: function() { - return a >= e.length ? { done: !0 } : { done: !1, value: e[a++] }; - }, e: function(e) { - throw e; - }, f: t, - }; - } - throw new TypeError('Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.'); - } - var r, n, i = !0, c = !1; - return { - s: function() { - r = e[Symbol.iterator](); - }, n: function() { - var e = r.next(); - return i = e.done, e; - }, e: function(e) { - c = !0, n = e; - }, f: function() { - try { - i || null == r.return || r.return(); - } finally { - if (c) throw n; - } - }, - }; - } - - function o(e, a) { - (null == a || a > e.length) && (a = e.length); - for (var t = 0, r = new Array(a); t < a; t++) r[t] = e[t]; - return r; - } - - var c = (0, t(2).CKBJson)('en-US', !0), s = Object.keys(c); - - function l(e, a) { - return e.distinct < a.distinct ? 1 : e.distinct > a.distinct ? -1 : 0; - } - - function d(e, a) { - return a.every((function(a) { - return e.includes(a); - })); - } - - function u(e, a) { - return a.some((function(a) { - return e.includes(a); - })); - } - - function m(e, a) { - var t = a.map((function(e) { - return e.levelOfMeasurements; - })); - if (t) { - var r, n = 0, o = i(t); - try { - for (o.s(); !(r = o.n()).done;) { - var c = r.value; - c && u(c, e.fieldConditions) && (n += 1); - } - } catch (e) { - o.e(e); - } finally { - o.f(); - } - if (n >= e.minQty && (n <= e.maxQty || '*' === e.maxQty)) return !0; - } - return !1; - } - - var h = [new n.default('data-check', 'HARD', s, 1, (function(e) { - var a = 0, t = e.dataProps, r = e.chartType; - if (t && r && c[r]) { - a = 1; - var n, o = i(c[r].dataPres || []); - try { - for (o.s(); !(n = o.n()).done;) { - if (!m(n.value, t)) return a = 0; - } - } catch (e) { - o.e(e); - } finally { - o.f(); - } - } - return a; - })), new n.default('data-field-qty', 'HARD', s, 1, (function(e) { - var a = 0, t = e.dataProps, r = e.chartType; - if (t && r && c[r]) { - a = 1; - var n = (c[r].dataPres || []).map((function(e) { - return e.minQty; - })).reduce((function(e, a) { - return e + a; - })); - if (t.length) t.length >= n && (a = 1); - } - return a; - })), new n.default('no-redundant-field', 'HARD', s, 1, (function(e) { - var a = 0, t = e.dataProps, r = e.chartType; - if (t && r && c[r]) { - var n = (c[r].dataPres || []).map((function(e) { - return '*' === e.maxQty ? 99 : e.maxQty; - })).reduce((function(e, a) { - return e + a; - })); - if (t.length) t.length <= n && (a = 1); - } - return a; - })), new n.default('purpose-check', 'HARD', s, 1, (function(e) { - var a = 0, t = e.chartType, r = e.purpose; - if (!r) return a = 1; - if (t && c[t] && r && (c[t].purpose || '').includes(r)) return a = 1; - return a; - })), new n.default('series-qty-limit', 'SOFT', ['pie_chart', 'donut_chart', 'radar_chart', 'rose_chart'], .8, (function(e) { - var a = 0, t = e.dataProps, r = e.chartType, n = 6; - if ('pie_chart' !== r && 'donut_chart' !== r && 'rose_chart' !== r || (n = 6), 'radar_chart' === r && (n = 8), t) { - var i = t.find((function(e) { - return d(e.levelOfMeasurements, ['Nominal']); - })), o = i && i.count ? i.count : 0; - o >= 2 && o <= n && (a = 2 / o); - } - return a; - })), new n.default('bar-series-qty', 'SOFT', ['bar_chart', 'grouped_bar_chart', 'stacked_bar_chart', 'percent_stacked_bar_chart', 'column_chart', 'grouped_column_chart', 'stacked_column_chart', 'percent_stacked_column_chart'], .5, (function(e) { - var a = 0, t = e.dataProps, r = e.chartType; - if (t && r) { - var n = t.find((function(e) { - return d(e.levelOfMeasurements, ['Nominal']); - })), i = n && n.count ? n.count : 0; - i >= 2 && i <= 20 ? a = 1 : i > 20 && (a = 20 / i); - } - return a; - })), new n.default('line-field-time-ordinal', 'SOFT', ['line_chart', 'area_chart', 'stacked_area_chart', 'percent_stacked_area_chart'], 1, (function(e) { - var a = 0, t = e.dataProps; - t && (t.find((function(e) { - return u(e.levelOfMeasurements, ['Ordinal', 'Time']); - })) && (a = 1)); - return a; - })), new n.default('landscape-or-portrait', 'SOFT', ['bar_chart', 'grouped_bar_chart', 'stacked_bar_chart', 'percent_stacked_bar_chart', 'column_chart', 'grouped_column_chart', 'stacked_column_chart', 'percent_stacked_column_chart'], .3, (function(e) { - var a = 0, t = e.dataProps, r = e.chartType, n = e.preferences; - return t && r && n && n.canvasLayout && ('portrait' === n.canvasLayout && ['bar_chart', 'grouped_bar_chart', 'stacked_bar_chart', 'percent_stacked_bar_chart'].includes(r) || 'landscape' === n.canvasLayout && ['column_chart', 'grouped_column_chart', 'stacked_column_chart', 'percent_stacked_column_chart'].includes(r)) && (a = 1), a; - })), new n.default('diff-pie-sector', 'SOFT', ['pie_chart', 'donut_chart'], .5, (function(e) { - var a = 0, t = e.dataProps; - if (t) { - var r = t.find((function(e) { - return d(e.levelOfMeasurements, ['Interval']); - })); - if (r && r.sum && r.samples) { - var n = 1 / r.sum, i = r.samples.map((function(e) { - return e * n; - })).reduce((function(e, a) { - return e * a; - })), o = r.samples.length, c = Math.pow(1 / o, o); - a = Math.abs(c - Math.abs(i)) / c; - } - } - return a; - })), new n.default('nominal-enum-combinatorial', 'SOFT', s, 1, (function(e) { - var a = 0, t = e.dataProps, r = e.chartType; - if (t && s) { - var n = t.filter((function(e) { - return d(e.levelOfMeasurements, ['Nominal']); - })); - if (n.length >= 2) { - var i = n.sort(l), o = i[0], c = i[1]; - if (o.distinct === o.count && ['bar_chart', 'column_chart'].includes(r) && (a = 1), o.count && o.distinct && c.distinct && o.count >= o.distinct * c.distinct) { - ['grouped_bar_chart', 'grouped_column_chart', 'stacked_bar_chart', 'stacked_column_chart'].includes(r) && (a = 1); - } - } - } - return a; - })), new n.default('limit-series', 'SOFT', s, 1, (function(e) { - var a = 0, t = e.dataProps, r = e.chartType; - if (t && s) { - var n = t.filter((function(e) { - return u(e.levelOfMeasurements, ['Nominal', 'Ordinal']); - })); - if (n.length >= 2) { - var i = n.sort(l)[1]; - i.distinct && (a = 1 / i.distinct, i.distinct > 6 && 'heatmap' === r ? a = 2 : 'heatmap' === r && (a = 0)); - } - } - return a; - }))]; - a.default = h; - }, function(e, a, t) { - 'use strict'; - Object.defineProperty(a, '__esModule', { value: !0 }), a.uuid = function() { - return ''.concat('xxxx-xxxx-xxxx'.replace(/x/g, (function() { - return (16 * Math.random() | 0).toString(16); - }))); - }, a.getElementDispay = function(e) { - return getComputedStyle(e, null).display; - }, a.getPosition = function(e) { - var a = e.getBoundingClientRect(), t = a.top, r = a.left; - return { top: t + window.scrollY, left: r + window.scrollX }; - }, a.translate = function(e) { - return { - line_chart: 'Line', - step_line_chart: 'StepLine', - area_chart: 'Area', - stacked_area_chart: 'StackArea', - percent_stacked_area_chart: 'PercentageStackArea', - column_chart: 'Column', - grouped_column_chart: 'GroupColumn', - stacked_column_chart: 'StackColumn', - percent_stacked_column_chart: 'PercentageStackColumn', - bar_chart: 'Bar', - grouped_bar_chart: 'GroupBar', - stacked_bar_chart: 'StackBar', - percent_stacked_bar_chart: 'PercentageStackBar', - histogram: 'Histogram', - pie_chart: 'Pie', - donut_chart: 'Ring', - rose_chart: 'Rose', - scatter_plot: 'Scatter', - bubble_chart: 'Bubble', - radar_chart: 'Radar', - heatmap: 'Matrix', - }[e] || e; - }, a.createLayer = function(e) { - ['relative', 'absolute', 'fixed'].includes(getComputedStyle(e).position) || (e.style.position = 'relative'); - var a = document.createElement('div'); - return a.style.height = '100%', a.style.width = '100%', a.style.position = 'absolute', a.style.top = '0px', a.style.left = '0px', a.style.pointerEvents = 'none', e.appendChild(a), a; - }, a.DEFAULT_FEEDBACK = function(e) { - return function(a) { - var t = document.createElement('div'); - t.className = ''.concat(r.CLASS_PREFIX, 'no_data_content'), t.innerHTML = '\n
\n \n
\n
'.concat(e, '
\n '), a.appendChild(t); - }; - }; - var r = t(8); - }, function(e, a, t) { - 'use strict'; - Object.defineProperty(a, '__esModule', { value: !0 }), a.CLASS_PREFIX = void 0; - var r = '__AUTO_CHART__'; - a.CLASS_PREFIX = r; - var n = '\n .'.concat(r, 'toolbar {\n position: absolute;\n bottom: 0px;\n left: 0px;\n z-index: 10;\n display: none;\n box-sizing: border-box;\n }\n .').concat(r, 'toolbar * {\n box-sizing: border-box;\n }\n .').concat(r, 'advice_container {\n width: 290px;\n display: none;\n padding: 0 16px;\n background: #454857;\n position: absolute;\n bottom: 100%;\n left: 0;\n max-height: 195px;\n overflow: auto;\n }\n .').concat(r, 'advice {\n height: 65px;\n font-size: 12px;\n color: #FFFFFF;\n display: flex;\n padding: 9px 0;\n cursor: pointer;\n border-bottom: 1px solid #D8D8D8;\n }\n .').concat(r, 'advice img {\n height: 46px;\n width: 46px;\n background: #fff;\n }\n .').concat(r, 'advice * {\n pointer-events: none;\n line-height: 46px;\n font-size: 14px;\n }\n .').concat(r, 'advice>div:nth-child(1) {\n width: 46px;\n }\n .').concat(r, 'advice>div:nth-child(2) {\n width: 46px;\n }\n .').concat(r, 'advice>div:nth-child(3) {\n margin-left: 8px;\n flex-grow: 1;\n }\n .').concat(r, 'advice>div:nth-child(3) div {\n line-height: 23px;\n text-align: right;\n }\n .').concat(r, 'advice:last-child{\n border: none;\n }\n .').concat(r, 'chart_type_btn {\n height: 24px;\n width: 24px;\n text-align: center;\n display: inline-block;\n padding: 6px;\n background: #454857;\n color: #fff;\n cursor: pointer;\n }\n .').concat(r, 'chart_type_btn img {\n pointer-events: none;\n height: 12px;\n width: 12px;\n vertical-align: top;\n }\n .').concat(r, 'dev_btn {\n height: 27px;\n line-height: 27px;\n background: #454857;\n padding: 0 7px;\n color: #fff;\n display: none;\n position: absolute;\n bottom: 0;\n right: 0;\n user-select: none;\n cursor: pointer;\n }\n .').concat(r, 'dev_panel {\n border-radius: 5px;\n overflow: hidden;\n box-shadow: 10px 10px 20px rgba(0, 0, 0, 0.25);\n box-sizing: border-box;\n position: absolute;\n background: #fff;\n z-index: 1000;\n display: none;\n }\n .').concat(r, 'dev_panel header {\n box-sizing: border-box;\n height: ').concat(32, 'px;\n width: 100%;\n padding-left: 16px;\n line-height: ').concat(32, 'px;\n cursor: move; \n color: #fff;\n position: relative;\n z-index: 1;\n background-color: #454857;\n box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.45);\n }\n .').concat(r, 'dev_panel_close {\n margin: 8px;\n height: 16px;\n width: 16px;\n border-radius: 50%;\n background: #fff;\n text-align: center;\n color: #454857;\n font-size: 14px;\n line-height: 14px;\n cursor: pointer;\n float: right;\n }\n .').concat(r, 'dev_panel_content {\n width: 100%;\n height: calc(100% - ').concat(32, 'px);\n }\n .').concat(r, 'dev_panel_content iframe {\n height: 100%;\n width: 100%;\n border: none;\n }\n .').concat(r, 'dev_panel_mask {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: -1;\n }\n .').concat(r, 'no_data_content, .').concat(r, 'mock_guide {\n color: #aaa;\n text-align: center;\n position: relative;\n top: 50%;\n transform: translateY(-50%);\n }\n .').concat(r, 'mock_guide_button {\n margin-top: 22px;\n border-radius: 3px;\n height: 30px;\n width: 116px;\n font-size: 14px;\n display: inline-block;\n line-height: 30px;\n background: #454859;\n color: #fff;\n cursor: pointer;\n }\n \n'), - i = document.createElement('style'); - i.textContent = n, document.head.prepend(i); - }, function(e, a, t) { - 'use strict'; - Object.defineProperty(a, '__esModule', { value: !0 }), a.getMappingForLib = function(e) { - return { typeMapping: n[e], configMapping: i[e] }; - }; - var r = t(10), n = { G2Plot: r.G2PLOT_TYPE_MAPPING, antdCharts: r.G2PLOT_TYPE_MAPPING }, - i = { G2Plot: r.G2PLOT_CONFIG_MAPPING, antdCharts: r.G2PLOT_CONFIG_MAPPING }; - }, function(e, a, t) { - 'use strict'; - Object.defineProperty(a, '__esModule', { value: !0 }), a.G2PLOT_TYPE_MAPPING = a.G2PLOT_CONFIG_MAPPING = void 0; - a.G2PLOT_CONFIG_MAPPING = { - line_chart: { x: 'xField', y: 'yField', color: 'seriesField' }, - area_chart: { x: 'xField', y: 'yField' }, - bar_chart: { x: 'xField', y: 'yField', color: 'colorField' }, - column_chart: { x: 'xField', y: 'yField', color: 'colorField' }, - pie_chart: { angle: 'angleField', color: 'colorField' }, - donut_chart: { angle: 'angleField', color: 'colorField' }, - grouped_bar_chart: { y: 'yField', y2: 'groupField', x: 'xField' }, - stacked_bar_chart: { y: 'yField', y2: 'stackField', x: 'xField' }, - percent_stacked_bar_chart: { y: 'yField', y2: 'stackField', x: 'xField' }, - grouped_column_chart: { x: 'xField', x2: 'groupField', y: 'yField' }, - stacked_column_chart: { x: 'xField', x2: 'stackField', y: 'yField' }, - percent_stacked_column_chart: { x: 'xField', x2: 'stackField', y: 'yField' }, - stacked_area_chart: { x: 'xField', x2: 'stackField', y: 'yField' }, - percent_stacked_area_chart: { x: 'xField', x2: 'stackField', y: 'yField' }, - radar_chart: { angle: 'angleField', radius: 'radiusField', series: 'seriesField' }, - scatter_plot: { x: 'xField', y: 'yField', color: 'colorField' }, - bubble_chart: { x: 'xField', y: 'yField', size: 'sizeField', color: 'colorField' }, - heatmap: { x: 'xField', y: 'yField', color: 'colorField', size: 'sizeField' }, - density_heatmap: { x: 'xField', y: 'yField', color: 'colorField' }, - step_line_chart: { x: 'xField', y: 'yField', color: 'seriesField' }, - funnel_chart: { x: 'xField', y: 'yField' }, - waterfall_chart: { x: 'xField', y: 'yField' }, - mirror_funnel_chart: { x: 'xField', y: 'yField', x2: 'compareField' }, - histogram: { x: 'binField' }, - }; - a.G2PLOT_TYPE_MAPPING = { - line_chart: 'Line', - step_line_chart: 'StepLine', - area_chart: 'Area', - stacked_area_chart: 'StackedArea', - percent_stacked_area_chart: 'PercentageStackedArea', - column_chart: 'Column', - grouped_column_chart: 'GroupedColumn', - stacked_column_chart: 'StackedColumn', - percent_stacked_column_chart: 'PercentageStackedColumn', - bar_chart: 'Bar', - grouped_bar_chart: 'GroupedBar', - stacked_bar_chart: 'StackedBar', - percent_stacked_bar_chart: 'PercentageStackedBar', - histogram: 'Histogram', - pie_chart: 'Pie', - donut_chart: 'Donut', - rose_chart: 'Rose', - scatter_plot: 'Scatter', - bubble_chart: 'Bubble', - radar_chart: 'Radar', - heatmap: 'Heatmap', - }; - }, function(e, a, t) { - 'use strict'; - t.r(a), t.d(a, 'type', (function() { - return j; - })), t.d(a, 'typeAll', (function() { - return I; - })), t.d(a, 'isOrdinal', (function() { - return B; - })), t.d(a, 'isConst', (function() { - return z; - })), t.d(a, 'isUnique', (function() { - return E; - })), t.d(a, 'isDiscrete', (function() { - return H; - })), t.d(a, 'isContinuous', (function() { - return W; - })), t.d(a, 'isInterval', (function() { - return U; - })), t.d(a, 'isNominal', (function() { - return q; - })), t.d(a, 'isTime', (function() { - return Y; - })), t.d(a, 'pearson', (function() { - return $; - })); - var r = t(0), n = '([-_./\\s])', i = '\\d{2,4}', o = '(0?[1-9]|1[012])', c = '(0?[1-9]|[12]\\d|3[01])', - s = '(0?\\d|1\\d|2[0-4])', l = '(0?\\d|[012345]\\d)', d = '(Z|[+-]' + s + '(:' + l + ')?)', - u = ['' + i + n + '?W([0-4]\\d|5[0-2])(' + n + '?([1-7]))?', '' + o + n + '?' + c + n + '?' + i, '' + i + n + '?' + o + n + '?' + c, '' + i + n + o, '' + i + n + '?((([0-2]\\d|3[0-5])\\d)|36[0-6])'], - m = [s + ':?' + l + ':?(0?\\d|[012345]\\d)([.,]\\d{1,4})?' + d + '?', s + ':?' + l + '?' + d], - h = Object(r.c)(u, m); - u.forEach((function(e) { - m.forEach((function(a) { - h.push(e + '[T\\s]' + a); - })); - })); - var p = h.map((function(e) { - return new RegExp('^' + e + '$'); - })); - var f = [/^(19|20)\d{2}$/, /^\d{4}(0?[1-9]|1[012])$/, /^\d{4}(0?[1-9]|1[012])(0?[1-9]|[12]\d|3[01])$/]; - - function y(e, a) { - if (e) throw new Error(a); - } - - function _(e) { - return null == e || '' === e || Number.isNaN(e) || 'null' === e; - } - - function g(e) { - return 'number' == typeof e ? Number.isInteger(e) : !('string' != typeof e || !C(e)) && !e.includes('.'); - } - - function b(e) { - return 'number' == typeof e ? !Number.isNaN(e) && !Number.isInteger(e) : !('string' != typeof e || !C(e)) && e.includes('.'); - } - - function v(e) { - return !(!e || Object.getPrototypeOf(e) !== Date.prototype) || 'string' == typeof e && function(e) { - var a, t; - try { - for (var n = Object(r.d)(p), i = n.next(); !i.done; i = n.next()) { - if (i.value.test(e.trim())) return !0; - } - } catch (e) { - a = { error: e }; - } finally { - try { - i && !i.done && (t = n.return) && t.call(n); - } finally { - if (a) throw a.error; - } - } - return !1; - }(e); - } - - function C(e) { - var a, t, n = !1; - /^[+-]/.test(e) && (e = e.slice(1)); - try { - for (var i = Object(r.d)(e), o = i.next(); !o.done; o = i.next()) { - var c = o.value; - if ('.' === c) { - if (!1 === n) { - n = !0; - continue; - } - return !1; - } - if (!/[0-9]/.test(c)) return !1; - } - } catch (e) { - a = { error: e }; - } finally { - try { - o && !o.done && (t = i.return) && t.call(i); - } finally { - if (a) throw a.error; - } - } - return '' !== e.trim(); - } - - var x = new WeakMap; - - function P(e, a, t) { - return x.get(e) || x.set(e, new Map), x.get(e).set(a, t), t; - } - - function O(e, a) { - var t = x.get(e); - if (t) return t.get(a); - } - - function S(e) { - var a = O(e, 'min'); - return void 0 !== a ? a : P(e, 'min', Math.min.apply(Math, Object(r.c)(e))); - } - - function R(e) { - var a = O(e, 'max'); - return void 0 !== a ? a : P(e, 'max', Math.max.apply(Math, Object(r.c)(e))); - } - - function k(e) { - var a = O(e, 'minIndex'); - return void 0 !== a ? a : P(e, 'minIndex', function(e) { - var a = e[0], t = 0; - for (var r in e) e[r] < a && (t = Number(r), a = e[r]); - return t; - }(e)); - } - - function w(e) { - var a = O(e, 'maxIndex'); - return void 0 !== a ? a : P(e, 'maxIndex', function(e) { - var a = e[0], t = 0; - for (var r in e) e[r] > a && (t = Number(r), a = e[r]); - return t; - }(e)); - } - - function Q(e) { - var a = O(e, 'sum'); - return void 0 !== a ? a : P(e, 'sum', e.reduce((function(e, a) { - return a + e; - }), 0)); - } - - function D(e) { - var a = {}; - return e.forEach((function(e) { - a[e] ? a[e] += 1 : a[e] = 1; - })), a; - } - - function M(e) { - return e.sort((function(e, a) { - return e > a ? 1 : -1; - })); - } - - function T(e, a, t) { - return void 0 === t && (t = !1), y(a <= 0 || a >= 100, 'percent cannot be between (0, 100)'), (t ? e : M(e))[Math.ceil(e.length * a / 100) - 1]; - } - - function A(e) { - return Q(e) / e.length; - } - - function N(e) { - var a = A(e), t = O(e, 'variance'); - return void 0 === t ? P(e, 'variance', e.reduce((function(e, t) { - return e + Math.pow(t - a, 2); - }), 0) / e.length) : t; - } - - function L(e) { - return Math.sqrt(N(e)); - } - - function F(e, a) { - return function(e, a) { - return y(e.length !== a.length, 'x and y must has same length'), A(e.map((function(e, t) { - return e * a[t]; - }))) - A(e) * A(a); - }(e, a) / (Math.sqrt(A(e.map((function(e) { - return e * e; - }))) - Math.pow(A(e), 2)) * Math.sqrt(A(a.map((function(e) { - return e * e; - }))) - Math.pow(A(a), 2))); - } - - function G(e) { - return _(e) ? 'null' : 'number' == typeof e ? Number.isInteger(e) ? 'integer' : 'float' : 'string' == typeof e && C(e) ? e.includes('.') ? 'float' : 'integer' : v(e) ? 'date' : 'string'; - } - - function j(e) { - var a, t = e.map((function(e) { - return _(e) ? null : e; - })), r = D(t), n = r.null ? t.filter((function(e) { - return null !== e; - })) : t, i = t.map((function(e) { - return G(e); - })), o = Object.keys(D(i)).filter((function(e) { - return 'null' !== e; - })); - switch (o.length) { - case 0: - a = 'null'; - break; - case 1: - if ('integer' === (a = o[0])) for (var c = t.filter((function(e) { - return null !== e; - })), s = function(e) { - var t = f[e]; - if (!c.some((function(e) { - return !t.test(e); - }))) return a = 'date', 'break'; - }, l = 0; l < f.length; l++) { - if ('break' === s(l)) break; - } - break; - case 2: - a = o.includes('integer') && o.includes('float') ? 'float' : 'string'; - break; - default: - a = 'string'; - } - var d, u = function(e) { - return Array.from(new Set(e)); - }(n), m = { - count: e.length, - distinct: u.length, - type: o.length <= 1 ? o[0] || 'null' : 'mixed', - recommendation: a, - missing: r.null || 0, - samples: e, - valueMap: r, - }; - if (o.length > 1) { - var h = {}; - o.forEach((function(e) { - 'date' === e ? h.date = j(n.filter(v)) : 'integer' === e ? h.integer = j(n.filter(g)) : 'float' === e ? h.float = j(n.filter(b)) : 'string' === e && (h.string = j(n.filter((function(e) { - return 'string' === G(e); - })))); - })), m.meta = h; - } - return 2 === m.distinct && 'date' !== m.recommendation && (t.length >= 100 ? m.recommendation = 'boolean' : (d = u, [[!0, !1], [0, 1], ['true', 'false'], ['Yes', 'No'], ['True', 'False'], ['0', '1'], ['是', '否']].some((function(e) { - return d.every((function(a) { - return e.includes(a); - })); - })) && (m.recommendation = 'boolean'))), 'string' === a && Object.assign(m, function(e) { - var a = e.map((function(e) { - return e.length; - })); - return { - maxLength: R(a), minLength: S(a), meanLength: A(a), containsChars: e.some((function(e) { - return /[A-z]/.test(e); - })), containsDigits: e.some((function(e) { - return /[0-9]/.test(e); - })), containsSpace: e.some((function(e) { - return /\s/.test(e); - })), containsNonWorlds: !1, - }; - }(n.map((function(e) { - return '' + e; - })))), 'integer' !== a && 'float' !== a || Object.assign(m, function(e) { - return { - minimum: S(e), - maximum: R(e), - mean: A(e), - percentile5: T(e, 5), - percentile25: T(e, 25), - percentile50: T(e, 50), - percentile75: T(e, 75), - percentile95: T(e, 95), - sum: Q(e), - variance: N(e), - stdev: L(e), - zeros: e.filter((function(e) { - return 0 === e; - })).length, - }; - }(n.map((function(e) { - return 1 * e; - })))), 'date' === a && Object.assign(m, function(e, a) { - void 0 === a && (a = !1); - var t = e.map((function(e) { - if (a) { - var t = '' + e; - if (8 === t.length) return new Date(t.substr(0, 4) + '/' + t.substr(4, 2) + '/' + t.substr(6, 2)).getTime(); - } - return new Date(e).getTime(); - })); - return { minimum: e[k(t)], maximum: e[w(t)] }; - }(n, 'integer' === m.type)), m; - } - - function I(e, a) { - if (y(a && 0 === a.length, 'fields.length woudle greater than 0'), !a) { - var t = new Set; - e.forEach((function(e) { - return Object.keys(e).forEach((function(e) { - return t.add(e); - })); - })), a = Object(r.c)(t); - } - return a.map((function(a) { - return Object(r.a)(Object(r.a)({}, j(e.map((function(e) { - return e[a]; - })))), { name: a }); - })); - } - - function B(e) { - var a = e.samples; - if ('string' !== e.recommendation) return !1; - if (z(e)) return !1; - for (var t = a.filter((function(e) { - return !_(e); - })), r = null, n = null, i = -1, o = -1; ;) { - for (var c = !0, s = 0; s < t.length; s++) { - var l = (d = t[s])[i + 1]; - if (null !== r && 0 !== s || (r = l), l !== r) { - c = !1; - break; - } - } - if (!c) break; - i += 1; - } - for (; ;) { - for (c = !0, s = 0; s < t.length; s++) { - var d; - l = (d = t[s])[d.length - 1 - (o + 1)]; - if (null !== n && 0 !== s || (n = l), l !== n) { - c = !1; - break; - } - } - if (!c) break; - o += 1; - } - var u = [/\d+/, /(零|一|二|三|四|五|六|七|八|九|十)+/, /(一|二|三|四|五|六|日)/, /^[a-z]$/, /^[A-Z]$/]; - if (-1 === i && -1 === o) return !1; - var m = t.map((function(e) { - return e.slice(-1 === i ? 0 : i + 1, -1 === o ? void 0 : e.length - o - 1); - })), h = function(e) { - var a = u[e]; - if (!m.some((function(e) { - return !a.test(e); - }))) return { value: !0 }; - }; - for (s = 0; s < u.length; s++) { - var p = h(s); - if ('object' == typeof p) return p.value; - } - return !1; - } - - function z(e) { - return 1 === e.distinct; - } - - function E(e) { - return e.distinct === e.count; - } - - function H(e) { - return 'integer' === e.recommendation; - } - - function W(e) { - return 'float' === e.recommendation; - } - - function U(e) { - return 'integer' === e.recommendation || 'float' === e.recommendation; - } - - function q(e) { - return 'boolean' === e.recommendation || 'string' === e.recommendation && !B(e); - } - - function Y(e) { - return 'date' === e.recommendation; - } - - function $(e, a) { - var t = ['integer', 'float']; - y(!(t.includes(e.recommendation) && t.includes(a.recommendation)), 'field\'s type must be integer or float'); - var n = e.samples, i = a.samples, o = Object(r.b)(function(e, a) { - for (var t = [], r = [], n = 0; n < e.length; n++) _(e[n]) || _(a[n]) || (t.push(e[n]), r.push(a[n])); - return [t, r]; - }(n, i), 2), c = o[0], s = o[1]; - return F(c.map(Number.parseFloat), s.map(Number.parseFloat)); - } - }]); -})); -//# sourceMappingURL=index.js.map \ No newline at end of file From 55ce7416233fe7bc9f589306b30b37f9fe462eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=B2=B3?= <445798420@qq.com> Date: Sun, 28 Jun 2020 15:50:46 +0800 Subject: [PATCH 3/3] =?UTF-8?q?CHART-13666=20=E8=87=AA=E5=8A=A8=E6=8E=A8?= =?UTF-8?q?=E8=8D=90=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fr/design/chart/AutoChartDialog.java | 11 +++++++++++ .../java/com/fr/design/chart/AutoChartTypePane.java | 12 ++++++++++-- .../main/java/com/fr/design/chart/ChartDialog.java | 11 ++++++++--- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/designer-chart/src/main/java/com/fr/design/chart/AutoChartDialog.java b/designer-chart/src/main/java/com/fr/design/chart/AutoChartDialog.java index 058e07045..34dacfa90 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/AutoChartDialog.java +++ b/designer-chart/src/main/java/com/fr/design/chart/AutoChartDialog.java @@ -7,6 +7,9 @@ import com.fr.chartx.TwoTuple; import com.fr.design.i18n.Toolkit; import com.fr.plugin.chart.vanchart.VanChart; +import javax.swing.JList; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; import java.awt.Component; import java.awt.Dialog; import java.awt.Frame; @@ -33,6 +36,14 @@ public class AutoChartDialog extends ChartDialog { protected Component initCenterPane() { autoChartTypePane = new AutoChartTypePane(); + getOk().setEnabled(false); + + autoChartTypePane.registsListAction(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + getOk().setEnabled(((JList) e.getSource()).getSelectedIndex() >= 0); + } + }); return autoChartTypePane; } diff --git a/designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java b/designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java index 1d827c00f..b7974fb6e 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java +++ b/designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java @@ -13,7 +13,6 @@ import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.iprogressbar.AutoProgressBar; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.chart.info.ChartInfoCollector; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.GeneralUtils; @@ -31,6 +30,7 @@ import javax.swing.JSplitPane; import javax.swing.ListCellRenderer; import javax.swing.SwingWorker; import javax.swing.UIManager; +import javax.swing.event.ListSelectionListener; import javax.swing.plaf.SplitPaneUI; import javax.swing.plaf.basic.BasicSplitPaneUI; import java.util.ArrayList; @@ -159,6 +159,10 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent } } + public void registsListAction(ListSelectionListener listSelectionListener) { + chartViewList.addListSelectionListener(listSelectionListener); + } + private void refreshBox() { TableDataWrapper dataWrap = tableNameComboBox.getSelectedItem(); @@ -225,12 +229,12 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent } } catch (Exception e) { if (!(e instanceof CancellationException)) { - connectionBar.close(); FineLoggerFactory.getLogger().error(e.getMessage(), e); FineJOptionPane.showMessageDialog(AutoChartTypePane.this, e.getMessage(), Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); } } finally { + connectionBar.close(); refreshButton.setEnabled(true); } } @@ -254,6 +258,10 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent map.put(dataField, true); } dataFieldBox.setSelectedValues(map); + if (refreshButton.isEnabled()) { + refreshButton.setEnabled(false); + calculateAutoChart(); + } } public void update(ChartCollection cc, String createTime) { diff --git a/designer-chart/src/main/java/com/fr/design/chart/ChartDialog.java b/designer-chart/src/main/java/com/fr/design/chart/ChartDialog.java index b2d273a60..4cd00e577 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/ChartDialog.java +++ b/designer-chart/src/main/java/com/fr/design/chart/ChartDialog.java @@ -48,6 +48,9 @@ public class ChartDialog extends MiddleChartDialog { this.setLayout(new BorderLayout()); setTitle(getDialogTitle()); + ok = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_OK")); + cancel = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Cancel")); + this.applyClosingAction(); this.applyEscapeAction(); this.setBasicDialogSize(BasicDialog.DEFAULT); @@ -57,9 +60,6 @@ public class ChartDialog extends MiddleChartDialog { buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT)); this.add(buttonPane, BorderLayout.SOUTH); - ok = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_OK")); - cancel = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Cancel")); - ok.addActionListener(getActionListener(createTime)); cancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -91,6 +91,11 @@ public class ChartDialog extends MiddleChartDialog { }; } + + public UIButton getOk() { + return ok; + } + /** * 不处理 */