diff --git a/designer-chart/src/main/java/com/fr/design/chartx/component/MapAreaMatchPane.java b/designer-chart/src/main/java/com/fr/design/chartx/component/MapAreaMatchPane.java new file mode 100644 index 000000000..fcf737991 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chartx/component/MapAreaMatchPane.java @@ -0,0 +1,373 @@ +package com.fr.design.chartx.component; + +import com.fr.base.BaseUtils; +import com.fr.base.ParameterMapNameSpace; +import com.fr.chartx.TwoTuple; +import com.fr.chartx.data.ChartDataDefinitionProvider; +import com.fr.chartx.data.DataSetDefinition; +import com.fr.chartx.data.DrillMapChartDataDefinition; +import com.fr.chartx.data.MapChartDataDefinition; +import com.fr.chartx.data.execute.ExecuteDataSetHelper; +import com.fr.chartx.data.field.CollectionWithMapAreaAttr; +import com.fr.data.TableDataSource; +import com.fr.data.TableDataSourceTailor; +import com.fr.data.core.DataCoreUtils; +import com.fr.data.impl.NameTableData; +import com.fr.design.beans.BasicBeanPane; +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.DialogActionAdapter; +import com.fr.design.file.HistoryTemplateListPane; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.chart.gui.data.table.DataPaneHelper; +import com.fr.design.parameter.ParameterInputPane; +import com.fr.general.GeneralUtils; +import com.fr.general.data.DataModel; +import com.fr.general.data.TableDataException; +import com.fr.plugin.chart.drillmap.VanChartDrillMapPlot; +import com.fr.plugin.chart.map.MapMatchResult; +import com.fr.plugin.chart.map.VanChartMapPlot; +import com.fr.plugin.chart.map.server.ChartGEOJSONHelper; +import com.fr.plugin.chart.type.MapType; +import com.fr.plugin.chart.vanchart.VanChart; +import com.fr.script.Calculator; +import com.fr.stable.ArrayUtils; +import com.fr.stable.ParameterProvider; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.table.DefaultTableModel; +import javax.swing.tree.DefaultMutableTreeNode; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2019-11-04 + */ +public class MapAreaMatchPane extends BasicBeanPane { + + private TableDataComboBox tableNameCombox; + private UIComboBox areaNameBox; + private UILabel refreshLabel; + + private MatchAreaTable matchAreaTable; + + private MatchResultTable matchResultTable; + + private static final Object[] HEADER = new Object[]{Toolkit.i18nText("Fine-Design_Chart_Area_Name"), Toolkit.i18nText("Fine-Design_Chart_Match_To")}; + + private static final Object[] HEADER_WITH_EMPTY = new Object[]{Toolkit.i18nText("Fine-Design_Chart_Area_Name"), Toolkit.i18nText("Fine-Design_Chart_Match_To"), ""}; + + private MapType mapType; + + private int level; + + + public MapAreaMatchPane(MapType mapType, int level, TwoTuple> treeNodeAndItems) { + this.mapType = mapType; + this.level = level; + + initButtonGroup(); + initRefreshLabel(); + areaNameBox = new UIComboBox(); + this.setLayout(new BorderLayout(5, 10)); + this.add(createContentPane(), BorderLayout.NORTH); + initTable(treeNodeAndItems); + JScrollPane matchAreaScroll = new JScrollPane(matchAreaTable) { + @Override + public Dimension getPreferredSize() { + return new Dimension(400, 300); + } + }; + this.add(matchAreaScroll, BorderLayout.CENTER); + JScrollPane matchResultScroll = new JScrollPane(matchResultTable) { + @Override + public Dimension getPreferredSize() { + return new Dimension(400, 200); + } + }; + matchResultScroll.setBorder(BorderFactory.createTitledBorder(Toolkit.i18nText("Fine-Design_Chart_Custom_Match_List"))); + this.add(matchResultScroll, BorderLayout.SOUTH); + this.setBorder(BorderFactory.createEmptyBorder(5, 20, 5, 20)); + } + + private JPanel createContentPane() { + JPanel panel = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); + + JPanel tableDataPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); + panel.add(tableDataPane); + tableDataPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Chart_Table_Data") + ":")); + tableNameCombox.setPreferredSize(new Dimension(96, 20)); + tableDataPane.add(tableNameCombox); + + JPanel areaNamePane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); + panel.add(areaNamePane); + areaNamePane.add(new UILabel(Toolkit.i18nText("Fine-Design_Chart_Area_Name") + ":")); + areaNamePane.add(areaNameBox); + areaNameBox.setPreferredSize(new Dimension(96, 20)); + panel.add(refreshLabel); + return panel; + } + + private void initTable(TwoTuple> treeNodeAndItems) { + matchAreaTable = new MatchAreaTable(new Object[0][2], HEADER); + matchAreaTable.setRoot(treeNodeAndItems.getFirst()); + matchAreaTable.setItems(treeNodeAndItems.getSecond()); + + matchResultTable = new MatchResultTable(new Object[0][3], HEADER_WITH_EMPTY); + + DefaultTableModel model = new DefaultTableModel(new Object[0][3], HEADER_WITH_EMPTY); + matchResultTable.setModel(model); + + matchAreaTable.setMatchResultTable(matchResultTable); + matchResultTable.setMatchAreaTable(matchAreaTable); + } + + private void initButtonGroup() { + tableNameCombox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource()); + tableNameCombox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + refreshBox(); + } + } + }); + } + + private void initRefreshLabel() { + Icon refreshImage = BaseUtils.readIcon("/com/fr/design/images/control/refresh.png"); + refreshLabel = new UILabel(refreshImage); + refreshLabel.addMouseListener(new MouseAdapter() { + boolean mouseEntered = false; + boolean buttonPressed = false; + + public void mouseEntered(MouseEvent e) { // 当鼠标进入时候调用. + mouseEntered = true; + if (!buttonPressed) { + refreshLabel.setBackground(java.awt.Color.WHITE); + refreshLabel.setOpaque(true); + refreshLabel.setBorder(BorderFactory.createLineBorder(java.awt.Color.GRAY)); + } + } + + public void mouseExited(MouseEvent e) { + mouseEntered = false; + refreshLabel.setOpaque(false); + refreshLabel.setBorder(BorderFactory.createEmptyBorder()); + } + + public void mousePressed(MouseEvent e) { + buttonPressed = true; + refreshLabel.setBackground(java.awt.Color.lightGray); + } + + public void mouseReleased(MouseEvent e) { + buttonPressed = false; + if (mouseEntered) { + refreshLabel.setBackground(java.awt.Color.WHITE); + populateData(tableNameCombox.getSelectedItem().getTableDataName(), GeneralUtils.objectToString(areaNameBox.getSelectedItem())); + } + } + }); + } + + public void updateBean(VanChart chart) { + MapMatchResult matchResult = new MapMatchResult(); + if (level < 0) { + VanChartMapPlot plot = chart.getPlot(); + plot.setMatchResult(matchResult); + } else { + VanChartDrillMapPlot plot = chart.getPlot(); + plot.getMatchResultList().set(level, matchResult); + } + if (tableNameCombox.getSelectedItem() != null) { + matchResult.setTableName(tableNameCombox.getSelectedItem().getTableDataName()); + } + matchResult.setColumnName(GeneralUtils.objectToString(areaNameBox.getSelectedItem())); + + matchResultTable.updateBean(matchResult); + } + + public void populateBean(VanChart chart) { + //先取保存的数据集名称和区域名,若不存在,就取数据集面板配置的数据集名称和区域名 + MapMatchResult matchResult; + if (level < 0) { + VanChartMapPlot plot = chart.getPlot(); + matchResult = plot.getMatchResult(); + } else { + VanChartDrillMapPlot plot = chart.getPlot(); + matchResult = plot.getMatchResultList().get(level); + } + matchResultTable.populateBean(matchResult); + + String tableName = matchResult.getTableName(); + String areaName = matchResult.getColumnName(); + if (tableName == null) { + DataSetDefinition dataSetDefinition = getDataSetDefinition(chart.getChartDataDefinition()); + if (dataSetDefinition == null) { + return; + } + NameTableData nameTableData = dataSetDefinition.getNameTableData(); + if (nameTableData == null) { + return; + } + tableName = nameTableData.getName(); + CollectionWithMapAreaAttr columnFieldCollection = (CollectionWithMapAreaAttr) dataSetDefinition.getColumnFieldCollection(); + + areaName = columnFieldCollection.getMatchColumn(); + } + tableNameCombox.setSelectedTableDataByName(tableName); + if (StringUtils.isEmpty(areaName)) { + return; + } + areaNameBox.setSelectedItem(areaName); + populateData(tableName, areaName); + } + + private DataSetDefinition getDataSetDefinition(ChartDataDefinitionProvider chartDataDefinitionProvider) { + DataSetDefinition dataSetDefinition = null; + if (chartDataDefinitionProvider instanceof MapChartDataDefinition) { + MapChartDataDefinition mapChartDataDefinition = (MapChartDataDefinition) chartDataDefinitionProvider; + if (mapChartDataDefinition == null) { + return null; + } + switch (mapType) { + case AREA: + dataSetDefinition = (DataSetDefinition) mapChartDataDefinition.getAreaMapDataDefinition(); + break; + case POINT: + dataSetDefinition = (DataSetDefinition) mapChartDataDefinition.getPointMapDataDefinition(); + break; + case LINE: + dataSetDefinition = (DataSetDefinition) mapChartDataDefinition.getLineMapDataDefinition(); + break; + } + } else if (chartDataDefinitionProvider instanceof DrillMapChartDataDefinition) { + DrillMapChartDataDefinition drillMapChartDataDefinition = (DrillMapChartDataDefinition) chartDataDefinitionProvider; + if (drillMapChartDataDefinition == null) { + return null; + } + if (drillMapChartDataDefinition.isFromBottomData()) { + dataSetDefinition = (DataSetDefinition) drillMapChartDataDefinition.getBottomDataDefinition(); + } else { + dataSetDefinition = (DataSetDefinition) drillMapChartDataDefinition.getEachLayerDataDefinitionList().get(level); + } + + } else { + dataSetDefinition = (DataSetDefinition) chartDataDefinitionProvider; + } + return dataSetDefinition; + } + + private void populateData(String tableName, String columnName) { + Object[] columnData = getColumnData(tableName, columnName); + if (columnData == null) { + return; + } + populateMatchData(columnData); + } + + private Object[] getColumnData(String tableName, String columnName) { + NameTableData nameTableData = new NameTableData(tableName); + TableDataSource dataSource = TableDataSourceTailor.extractTableData(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate().getTarget()); + Calculator calculator = Calculator.createCalculator(); + calculator.setAttribute(TableDataSource.KEY, dataSource); + ParameterProvider[] parameters = nameTableData.getParameters(calculator); + final Map parameterMap = new HashMap<>(); + + if (ArrayUtils.isNotEmpty(parameters)) { + final ParameterInputPane pPane = new ParameterInputPane(parameters); + pPane.showSmallWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { + @Override + public void doOk() { + parameterMap.putAll(pPane.update()); + } + }).setVisible(true); + } + for (ParameterProvider parameter : parameters) { + if (parameterMap.containsKey(parameter.getName())) { + parameter.setValue(parameterMap.get(parameter.getName())); + } + } + ParameterMapNameSpace parameterMapNameSpace = ParameterMapNameSpace.create(parameterMap); + calculator.pushNameSpace(parameterMapNameSpace); + + try { + DataModel dataModel = ExecuteDataSetHelper.createDataModel(calculator, nameTableData); + int colIndex = DataCoreUtils.getColumnIndexByName(dataModel, columnName); + if (colIndex == DataModel.COLUMN_NAME_NOT_FOUND) { + return null; + } + int size = dataModel.getRowCount(); + HashSet columnData = new LinkedHashSet<>(); + for (int i = 0; i < size; i++) { + columnData.add(dataModel.getValueAt(i, colIndex)); + } + return columnData.toArray(); + } catch (TableDataException ignore) { + return null; + } + } + + private void populateMatchData(Object[] columnData) { + Set geoAreas = matchAreaTable.getItems(); + + Map resultMap = ChartGEOJSONHelper.matchArea(columnData, geoAreas, matchResultTable.getCustomResult()); + + Object[][] data = new Object[resultMap.size()][2]; + + //构造table的数据结构 + Map areaNameIndex = new HashMap<>(); + int i = 0; + for (Map.Entry entry : resultMap.entrySet()) { + areaNameIndex.put(entry.getKey(), i); + data[i++] = new Object[]{entry.getKey(), entry.getValue()}; + } + + matchAreaTable.setAreaNameIndex(areaNameIndex); + matchAreaTable.setModel(new DefaultTableModel(data, HEADER)); + } + + private void refreshBox() { + TableDataWrapper dataWrap = tableNameCombox.getSelectedItem(); + + if (dataWrap == null) { + return; + } + + List columnNameList = dataWrap.calculateColumnNameList(); + + DataPaneHelper.refreshBoxItems(areaNameBox, columnNameList); + areaNameBox.setSelectedItem(null); + } + + public VanChart updateBean() { + return null; + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Chart_Location_With_Area_Name"); + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chartx/component/MatchAreaTable.java b/designer-chart/src/main/java/com/fr/design/chartx/component/MatchAreaTable.java new file mode 100644 index 000000000..e8f98f2a3 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chartx/component/MatchAreaTable.java @@ -0,0 +1,148 @@ +package com.fr.design.chartx.component; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.general.GeneralUtils; +import com.fr.plugin.chart.map.server.ChartGEOJSONHelper; + +import javax.swing.AbstractCellEditor; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JTree; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumnModel; +import javax.swing.table.TableModel; +import javax.swing.tree.DefaultMutableTreeNode; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.awt.Color; +import java.awt.Component; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2019-11-19 + */ +public class MatchAreaTable extends JTable { + + private Set items; + + private MatchResultTable matchResultTable; + + private Map areaNameIndex = new HashMap<>(); + + private DefaultMutableTreeNode root; + + public MatchAreaTable(Object[][] data, Object[] header) { + super(data, header); + this.getTableHeader().setReorderingAllowed(false); + } + + public void setItems(Set items) { + this.items = items; + } + + public Set getItems() { + return items; + } + + public void setRoot(DefaultMutableTreeNode root) { + this.root = root; + } + + public void setMatchResultTable(MatchResultTable matchResultTable) { + this.matchResultTable = matchResultTable; + } + + public void setAreaNameIndex(Map areaNameIndex) { + this.areaNameIndex = areaNameIndex; + } + + public void setModel(TableModel dataModel) { + super.setModel(dataModel); + + if (items == null) { + items = new HashSet<>(); + } + TableColumnModel columnModel = getColumnModel(); + columnModel.getColumn(0).setCellEditor(new UILabelEditor()); + columnModel.getColumn(1).setCellEditor(new UIComboBoxRenderAndEditor()); + columnModel.getColumn(1).setCellRenderer(new UIComboBoxRenderAndEditor()); + } + + public void reMatch(Object areaName) { + if (!areaNameIndex.containsKey(areaName)) { + return; + } + int index = areaNameIndex.get(areaName); + Map resultMap = ChartGEOJSONHelper.matchArea(new Object[]{areaName}, items); + String result = resultMap.get(areaName); + getColumnModel().getColumn(1).getCellEditor().stopCellEditing(); + this.setValueAt(result, index, 1); + } + + public class UIComboBoxRenderAndEditor extends AbstractCellEditor implements TableCellRenderer, TableCellEditor { + + TableTreeComboBox comboBox; + + public UIComboBoxRenderAndEditor() { + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + initComboBox(value, false); + return comboBox; + } + + public Component getTableCellEditorComponent(final JTable table, Object value, boolean isSelected, final int row, int column) { + initComboBox(value, true); + comboBox.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + UIComboBoxRenderAndEditor.this.stopCellEditing(); + Object areaName = MatchAreaTable.this.getValueAt(row, 0); + Object result = MatchAreaTable.this.getValueAt(row, 1); + if (items.contains(result)) { + matchResultTable.dealMatch(areaName, result); + } + } + }); + return comboBox; + } + + private void initComboBox(Object value, boolean editor) { + comboBox = new TableTreeComboBox(new JTree(root)); + comboBox.setEditable(true); + + comboBox.setSelectedItem(value); + if (!editor && value == null) { + JTextField textField = (JTextField) (comboBox.getEditor().getEditorComponent()); + textField.setForeground(Color.RED); + textField.setText(Toolkit.i18nText("Fine-Design_Chart_Prompt_Not_Selected")); + } + } + + public Object getCellEditorValue() { + return comboBox.getSelectedItem(); + } + } + + public static class UILabelEditor extends AbstractCellEditor implements TableCellEditor { + + UILabel uiLabel; + + public Component getTableCellEditorComponent(JTable table, Object value, + boolean isSelected, + int row, int column) { + uiLabel = new UILabel(GeneralUtils.objectToString(value)); + return uiLabel; + } + + public Object getCellEditorValue() { + return uiLabel.getText(); + } + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chartx/component/MatchResultTable.java b/designer-chart/src/main/java/com/fr/design/chartx/component/MatchResultTable.java new file mode 100644 index 000000000..55287f00a --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chartx/component/MatchResultTable.java @@ -0,0 +1,146 @@ +package com.fr.design.chartx.component; + +import com.fr.base.BaseUtils; +import com.fr.base.Utils; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.i18n.Toolkit; +import com.fr.general.ComparatorUtils; +import com.fr.plugin.chart.map.MapMatchResult; +import com.fr.stable.StringUtils; + +import javax.swing.AbstractCellEditor; +import javax.swing.JOptionPane; +import javax.swing.JTable; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumnModel; +import javax.swing.table.TableModel; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Vector; +import java.awt.Component; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2019-11-20 + */ +public class MatchResultTable extends JTable { + + private MatchAreaTable matchAreaTable; + + public MatchResultTable(Object[][] data, Object[] header) { + super(data, header); + this.getTableHeader().setReorderingAllowed(false); + } + + public void setMatchAreaTable(MatchAreaTable matchAreaTable) { + this.matchAreaTable = matchAreaTable; + } + + public void setModel(TableModel dataModel) { + super.setModel(dataModel); + + TableColumnModel columnModel = getColumnModel(); + columnModel.getColumn(0).setCellEditor(new MatchAreaTable.UILabelEditor()); + columnModel.getColumn(1).setCellEditor(new MatchAreaTable.UILabelEditor()); + columnModel.getColumn(2).setCellEditor(new UIButtonEditorAndRender()); + columnModel.getColumn(2).setCellRenderer(new UIButtonEditorAndRender()); + columnModel.getColumn(2).setMaxWidth(20); + } + + public void dealMatch(Object areaName, Object result) { + int rowCount = this.getRowCount(); + for (int i = 0; i < rowCount; i++) { + if (ComparatorUtils.equals(this.getValueAt(i, 0), areaName)) { + getColumnModel().getColumn(1).getCellEditor().stopCellEditing(); + this.setValueAt(result, i, 1); + return; + } + } + DefaultTableModel model = (DefaultTableModel) this.getModel(); + Vector vector = new Vector(); + vector.add(areaName); + vector.add(result); + vector.add(""); + model.addRow(vector); + } + + public void populateBean(MapMatchResult matchResult) { + if (matchResult == null) { + return; + } + Map customResult = matchResult.getCustomResult(); + if (customResult == null) { + return; + } + DefaultTableModel model = (DefaultTableModel) this.getModel(); + for (Map.Entry entry : customResult.entrySet()) { + Vector vector = new Vector(); + vector.add(entry.getKey()); + vector.add(entry.getValue()); + vector.add(""); + model.addRow(vector); + } + } + + public void updateBean(MapMatchResult matchResult) { + matchResult.setCustomResult(getCustomResult()); + } + + public Map getCustomResult() { + Map customResult = new LinkedHashMap<>(); + DefaultTableModel model = (DefaultTableModel) this.getModel(); + for (int i = 0, rowCount = model.getRowCount(); i < rowCount; i++) { + customResult.put(Utils.objectToString(model.getValueAt(i, 0)), Utils.objectToString(model.getValueAt(i, 1))); + } + return customResult; + } + + public class UIButtonEditorAndRender extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { + + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, final int row, int column) { + UIButton uiButton = new UIButton(BaseUtils.readIcon("com/fr/design/images/toolbarbtn/close.png")); + uiButton.addMouseListener(new MouseAdapter() { + boolean mouseEntered = false; + + public void mouseEntered(MouseEvent e) { // 当鼠标进入时候调用. + mouseEntered = true; + + } + + public void mouseExited(MouseEvent e) { + mouseEntered = false; + } + + public void mouseReleased(MouseEvent e) { + if (mouseEntered) { + MatchResultTable.this.getCellEditor().stopCellEditing(); + int val = JOptionPane.showConfirmDialog(MatchResultTable.this, Toolkit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + "?", + Toolkit.i18nText("Fine-Design_Basic_Remove"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); + if (val == JOptionPane.OK_OPTION) { + DefaultTableModel model = (DefaultTableModel) MatchResultTable.this.getModel(); + Object areaName = MatchResultTable.this.getValueAt(row, 0); + model.removeRow(row); + matchAreaTable.reMatch(areaName); + } + } + } + }); + return uiButton; + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + UIButton button = new UIButton(BaseUtils.readIcon("com/fr/design/images/toolbarbtn/close.png")); + return button; + } + + public Object getCellEditorValue() { + return StringUtils.EMPTY; + } + } + +} diff --git a/designer-chart/src/main/java/com/fr/design/chartx/component/TableTreeComboBox.java b/designer-chart/src/main/java/com/fr/design/chartx/component/TableTreeComboBox.java new file mode 100644 index 000000000..793b49b31 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chartx/component/TableTreeComboBox.java @@ -0,0 +1,100 @@ +package com.fr.design.chartx.component; + +import com.fr.design.gui.icombobox.FRTreeComboBox; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.general.IOUtils; +import com.fr.plugin.chart.map.server.ChartGEOJSONHelper; + +import javax.swing.JTextField; +import javax.swing.JTree; +import javax.swing.MenuSelectionManager; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.util.Enumeration; +import java.awt.Component; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2019-12-24 + */ +public class TableTreeComboBox extends FRTreeComboBox { + + private JTextField textField; + + public TableTreeComboBox(JTree tree) { + super(tree, null); + textField = (JTextField) (this.getEditor().getEditorComponent()); + textField.addKeyListener(treeKeyListener); + tree.setCellRenderer(tableNameTreeRenderer); + } + + @Override + protected void dealSamePath(TreePath parent, TreeNode node, UITextField textField) { + matchLeafNode(parent, node, textField); + } + + private boolean matchLeafNode(TreePath parent, TreeNode node, UITextField textField) { + for (Enumeration e = node.children(); e.hasMoreElements(); ) { + TreeNode n = (TreeNode) e.nextElement(); + TreePath path = parent.pathByAddingChild(n); + TreeNode pathNode = (TreeNode) path.getLastPathComponent(); + if (pathNode.getChildCount() == 0) { + if (pathToString(path).toUpperCase().contains(textField.getText().toUpperCase())) { + tree.scrollPathToVisible(path); + tree.setSelectionPath(path); + return true; + } + } else { + if (matchLeafNode(path, pathNode, textField)) { + return true; + } + } + } + return false; + } + + private KeyListener treeKeyListener = new KeyAdapter() { + public void keyPressed(KeyEvent e) { + int key = e.getKeyCode(); + if (key == KeyEvent.VK_ENTER) { + TreePath treePath = tree.getSelectionPath(); + if (treePath == null) { + return; + } + DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath + .getLastPathComponent(); + if (node.isLeaf()) { + TableTreeComboBox.this.setSelectedItem(treePath); + textField.setText(pathToString(treePath)); + MenuSelectionManager.defaultManager().clearSelectedPath(); + } + } + } + }; + + private TreeCellRenderer tableNameTreeRenderer = new DefaultTreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + if (value instanceof DefaultMutableTreeNode) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Object userObj = node.getUserObject(); + if (node.getChildCount() > 0) { + this.setIcon(IOUtils.readIcon("com/fr/design/images/m_insert/expandCell.gif")); + } + if (userObj != null) { + this.setText(ChartGEOJSONHelper.getPresentNameWithPath(userObj.toString())); + } + } + return this; + } + }; + +} diff --git a/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapChartDataPane.java b/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapChartDataPane.java index ae52b401d..7d1d1c52a 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapChartDataPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapChartDataPane.java @@ -37,7 +37,7 @@ public class DrillMapChartDataPane extends AbstractChartDataPane private EachLayerDataDefinitionPane eachLayerDataDefinitionPane;//各层级分别指定 - public DrillMapDataPane(VanChartDrillMapPlot drillMapPlot) { - bottomDataPane = new SingleDataPane(new AreaMapDataSetFieldsPane(), new AreaMapCellDataFieldsPane()); - eachLayerDataDefinitionPane = new EachLayerDataDefinitionPane(drillMapPlot); + public DrillMapDataPane(VanChart vanChart) { + AreaMapDataSetFieldsPane areaMapDataSetFieldsPane = new AreaMapDataSetFieldsPane(); + areaMapDataSetFieldsPane.setChart(vanChart); + areaMapDataSetFieldsPane.setLevel(ChartGEOJSONHelper.BOTTOM_LEVEL); + bottomDataPane = new SingleDataPane(areaMapDataSetFieldsPane, new AreaMapCellDataFieldsPane()); + eachLayerDataDefinitionPane = new EachLayerDataDefinitionPane(vanChart); dataDefinitionType = new UIComboBoxPane() { @Override diff --git a/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapLayerPane.java b/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapLayerPane.java index b12bf385a..975faffca 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapLayerPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapLayerPane.java @@ -8,6 +8,7 @@ import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.plugin.chart.drillmap.VanChartDrillMapPlot; +import com.fr.plugin.chart.map.MapMatchResult; import com.fr.plugin.chart.map.server.CompatibleGeoJSONTreeHelper; import com.fr.plugin.chart.type.MapType; import com.fr.plugin.chart.type.ZoomLevel; @@ -18,10 +19,11 @@ import com.fr.van.chart.map.designer.type.VanChartMapSourceChoosePane; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.tree.DefaultMutableTreeNode; -import java.awt.BorderLayout; -import java.awt.Component; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.awt.BorderLayout; +import java.awt.Component; /** * Created by Mitisky on 16/6/20. @@ -62,6 +64,7 @@ public class DrillMapLayerPane extends BasicBeanPane { java.util.List levelList = drillMapPlot.getLayerLevelList(); java.util.List mapTypeList = drillMapPlot.getLayerMapTypeList(); + List matchResultList = drillMapPlot.getMatchResultList(); //根据层级初始属性,一切以json那边读到的层级为准 int levelSize = levelList.size(); @@ -73,6 +76,11 @@ public class DrillMapLayerPane extends BasicBeanPane { for (int j = typeSize; j < depth; j++) { mapTypeList.add(mapType); } + + int matchSize = matchResultList.size(); + for (int k = matchSize; k < depth; k++) { + matchResultList.add(new MapMatchResult()); + } } } @@ -120,10 +128,10 @@ public class DrillMapLayerPane extends BasicBeanPane { return panel; } - private JPanel createTitlePane (String title, JPanel panel) { + private JPanel createTitlePane(String title, JPanel panel) { JPanel jPanel = TableLayout4VanChartHelper.createExpandablePaneWithTitle(title, panel); - panel.setBorder(BorderFactory.createEmptyBorder(10,5,0,0)); - jPanel.setBorder(BorderFactory.createEmptyBorder(0,5,0,0)); + panel.setBorder(BorderFactory.createEmptyBorder(10, 5, 0, 0)); + jPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); return jPanel; } diff --git a/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/EachLayerDataDefinitionPane.java b/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/EachLayerDataDefinitionPane.java index 02c6c4d08..a7180e4c5 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/EachLayerDataDefinitionPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/EachLayerDataDefinitionPane.java @@ -13,6 +13,7 @@ import com.fr.design.i18n.Toolkit; import com.fr.general.ComparatorUtils; import com.fr.plugin.chart.drillmap.VanChartDrillMapPlot; import com.fr.plugin.chart.type.MapType; +import com.fr.plugin.chart.vanchart.VanChart; import java.util.ArrayList; import java.util.List; @@ -26,8 +27,11 @@ public class EachLayerDataDefinitionPane extends MultiTabPane oldTypeList; private VanChartDrillMapPlot plot; - public EachLayerDataDefinitionPane(VanChartDrillMapPlot drillMapPlot) { - this.plot = drillMapPlot; + private VanChart vanChart; + + public EachLayerDataDefinitionPane(VanChart vanChart) { + this.vanChart = vanChart; + this.plot = vanChart.getPlot(); initComps(); } @@ -52,17 +56,29 @@ public class EachLayerDataDefinitionPane extends MultiTabPane { +public class AreaMapDataSetFieldsPane extends MapDataSetFieldsPane { private UIComboBox areaName; @@ -27,6 +30,13 @@ public class AreaMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesVal }; } + @Override + protected Component[] fieldComponents() { + return new Component[]{ + createAreaPanel(createAreaName()) + }; + } + private UIComboBox createAreaName() { if (areaName == null) { areaName = new UIComboBox(); @@ -47,4 +57,8 @@ public class AreaMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesVal updateSeriesValuePane(fieldCollection); return fieldCollection; } + + public MapType getMapType() { + return MapType.AREA; + } } diff --git a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/LineMapDataSetFieldsPane.java b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/LineMapDataSetFieldsPane.java index 24220b993..0b5253644 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/LineMapDataSetFieldsPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/LineMapDataSetFieldsPane.java @@ -3,6 +3,7 @@ package com.fr.design.chartx.fields.diff; import com.fr.chartx.data.field.diff.LineMapColumnFieldCollection; import com.fr.design.chartx.data.map.LineMapAreaLngLatPaneWithComboBox; import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.plugin.chart.type.MapType; import com.fr.third.jodd.util.ArraysUtil; import javax.swing.JPanel; @@ -12,7 +13,7 @@ import javax.swing.JPanel; * @version 10.0 * Created by shine on 2019/11/11 */ -public class LineMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesValuePane { +public class LineMapDataSetFieldsPane extends MapDataSetFieldsPane { private LineMapAreaLngLatPaneWithComboBox areaLngLatPane; private UIComboBox lineName; @@ -20,7 +21,7 @@ public class LineMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesVal @Override protected JPanel createNorthPane() { if (areaLngLatPane == null) { - areaLngLatPane = new LineMapAreaLngLatPaneWithComboBox(); + areaLngLatPane = new LineMapAreaLngLatPaneWithComboBox(this); } return areaLngLatPane; } @@ -58,4 +59,8 @@ public class LineMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesVal updateSeriesValuePane(columnFieldCollection); return columnFieldCollection; } + + public MapType getMapType() { + return MapType.LINE; + } } diff --git a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/MapDataSetFieldsPane.java b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/MapDataSetFieldsPane.java new file mode 100644 index 000000000..df7938e07 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/MapDataSetFieldsPane.java @@ -0,0 +1,89 @@ +package com.fr.design.chartx.fields.diff; + +import com.fr.base.BaseUtils; +import com.fr.chartx.TwoTuple; +import com.fr.chartx.data.field.diff.ColumnFieldCollectionWithSeriesValue; +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.chartx.component.MapAreaMatchPane; +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.DialogActionListener; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.plugin.chart.map.VanChartMapPlot; +import com.fr.plugin.chart.map.server.ChartGEOJSONHelper; +import com.fr.plugin.chart.type.MapType; +import com.fr.plugin.chart.vanchart.VanChart; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.tree.DefaultMutableTreeNode; +import java.util.Set; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2019-12-25 + */ +public abstract class MapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesValuePane { + + private VanChart chart; + + //钻取地图有层级,默认-1代表无层级关系 + private int level = ChartGEOJSONHelper.DEFAULT_LEVEL; + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public void setChart(VanChart chart) { + this.chart = chart; + } + + public VanChart getChart() { + return chart; + } + + public JPanel createAreaPanel(UIComboBox areaBox) { + JPanel areaPanel = new JPanel(new BorderLayout(10, 0)); + areaBox.setPreferredSize(new Dimension(91, 20)); + areaPanel.add(areaBox, BorderLayout.WEST); + UIButton uiButton = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/config.png")); + uiButton.addActionListener(new ActionListener() { + private TwoTuple> treeNodeAndItems; + + @Override + public void actionPerformed(ActionEvent e) { + if (treeNodeAndItems == null) { + treeNodeAndItems = ChartGEOJSONHelper.getTreeNodeAndItems(((VanChartMapPlot) chart.getPlot()).getGeoUrl(), level); + } + final BasicBeanPane pane = new MapAreaMatchPane(MapDataSetFieldsPane.this.getMapType(), level, treeNodeAndItems); + pane.populateBean(chart); + BasicDialog dialog = pane.showWindow(new JFrame()); + dialog.addDialogActionListener(new DialogActionListener() { + @Override + public void doOk() { + pane.updateBean(chart); + } + + @Override + public void doCancel() { + + } + }); + dialog.setVisible(true); + } + }); + areaPanel.add(uiButton, BorderLayout.EAST); + return areaPanel; + } + + public abstract MapType getMapType(); +} diff --git a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/PointMapDataSetFieldsPane.java b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/PointMapDataSetFieldsPane.java index 1771637ab..2eae509ca 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/PointMapDataSetFieldsPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/PointMapDataSetFieldsPane.java @@ -3,6 +3,7 @@ package com.fr.design.chartx.fields.diff; import com.fr.chartx.data.field.diff.PointMapColumnFieldCollection; import com.fr.design.chartx.data.map.PointMapAreaLngLatPaneWithComboBox; import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.plugin.chart.type.MapType; import javax.swing.JPanel; @@ -11,13 +12,13 @@ import javax.swing.JPanel; * @version 10.0 * Created by shine on 2019/11/8 */ -public class PointMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesValuePane { +public class PointMapDataSetFieldsPane extends MapDataSetFieldsPane { private PointMapAreaLngLatPaneWithComboBox areaLngLatPane; @Override protected JPanel createNorthPane() { if (areaLngLatPane == null) { - areaLngLatPane = new PointMapAreaLngLatPaneWithComboBox(); + areaLngLatPane = new PointMapAreaLngLatPaneWithComboBox(this); } return areaLngLatPane; } @@ -30,7 +31,7 @@ public class PointMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesVa @Override protected UIComboBox[] filedComboBoxes() { if (areaLngLatPane == null) { - areaLngLatPane = new PointMapAreaLngLatPaneWithComboBox(); + areaLngLatPane = new PointMapAreaLngLatPaneWithComboBox(this); } return areaLngLatPane.allFieldComboBox(); } @@ -48,4 +49,8 @@ public class PointMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesVa updateSeriesValuePane(fieldCollection); return fieldCollection; } + + public MapType getMapType() { + return MapType.POINT; + } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/heatmap/designer/VanHeatMapChartTypeUI.java b/designer-chart/src/main/java/com/fr/van/chart/heatmap/designer/VanHeatMapChartTypeUI.java index 90926a106..f3ad4e22d 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/heatmap/designer/VanHeatMapChartTypeUI.java +++ b/designer-chart/src/main/java/com/fr/van/chart/heatmap/designer/VanHeatMapChartTypeUI.java @@ -66,7 +66,9 @@ public class VanHeatMapChartTypeUI extends VanMapChartTypeUI { return new AbstractVanSingleDataPane(listener) { @Override protected SingleDataPane createSingleDataPane() { - return new SingleDataPane(new PointMapDataSetFieldsPane(), new PointMapCellDataFieldsPane()); + PointMapDataSetFieldsPane pointMapDataSetFieldsPane = new PointMapDataSetFieldsPane(); + pointMapDataSetFieldsPane.setChart(getVanChart()); + return new SingleDataPane(pointMapDataSetFieldsPane, new PointMapCellDataFieldsPane()); } }; }