Browse Source

折线图查询优化,折线图分组优化

chenw 6 years ago
parent
commit
a6c98ef320

+ 5 - 0
bi-core/pom.xml

@@ -37,6 +37,11 @@
       <groupId>com.alibaba</groupId>
       <artifactId>druid</artifactId>
     </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>20.0</version>
+    </dependency>
   </dependencies>
 
 </project>

+ 146 - 0
bi-core/src/main/java/com/usoftchina/bi/core/utils/CollectionUtils.java

@@ -0,0 +1,146 @@
+package com.usoftchina.bi.core.utils;
+
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.collect.Table;
+
+import java.util.*;
+import java.util.function.Function;
+
+/**
+ * @author ChenWei
+ * @date 2019/04/22
+ */
+public abstract class CollectionUtils extends org.springframework.util.CollectionUtils {
+    /**
+     * 按指定方法,将list分组返回map
+     *
+     * @param sources
+     * @param keyGetter
+     * @param <K>
+     * @param <V>
+     * @return
+     */
+    public static <K, V> Map<K, List<V>> groupBy(List<V> sources, Function<V, K> keyGetter) {
+        Map<K, List<V>> map = new HashMap<>(1);
+        if (!isEmpty(sources)) {
+            sources.forEach(source -> {
+                K key = keyGetter.apply(source);
+                if (map.containsKey(key)) {
+                    map.get(key).add(source);
+                } else {
+                    List<V> childList = new ArrayList<>();
+                    childList.add(source);
+                    map.put(key, childList);
+                }
+            });
+        }
+        return map;
+    }
+
+    /**
+     * 按两个指定方法,将list分组返回复合键map
+     *
+     * @param sources
+     * @param rKeyGetter
+     * @param cKeyGetter
+     * @param <R>
+     * @param <C>
+     * @param <V>
+     * @return
+     */
+    public static <R, C, V> Table<R, C, List<V>> groupBy(List<V> sources, Function<V, R> rKeyGetter, Function<V, C> cKeyGetter) {
+        Table<R, C, List<V>> table = HashBasedTable.create();
+        if (!isEmpty(sources)) {
+            sources.forEach(source -> {
+                R r = rKeyGetter.apply(source);
+                C c = cKeyGetter.apply(source);
+                if (table.contains(r, c)) {
+                    table.get(r, c).add(source);
+                } else {
+                    List<V> childList = new ArrayList<>();
+                    childList.add(source);
+                    table.put(r, c, childList);
+                }
+            });
+        }
+        return table;
+    }
+
+    /**
+     * 按三个指定方法,将list分组返回复合键map
+     *
+     * @param sources
+     * @param rKeyGetter
+     * @param cKeyGetter
+     * @param valueGetter
+     * @param <R>
+     * @param <C>
+     * @param <V>
+     * @param <S>
+     * @return
+     */
+    public static <R, C, V, S> Map<R, Map<C, List<V>>> groupBy(List<S> sources, Function<S, R> rKeyGetter, Function<S, C> cKeyGetter, Function<S, V> valueGetter) {
+        Map<R, Map<C, List<V>>> table = new HashMap<>(1);
+        if (!isEmpty(sources)) {
+            sources.forEach(source -> {
+                R r = rKeyGetter.apply(source);
+                C c = cKeyGetter.apply(source);
+                V v = valueGetter.apply(source);
+
+                if (table.containsKey(r)) {
+                    Map<C, List<V>> rows = table.get(r);
+                    if (rows.containsKey(c)) {
+                        rows.get(c).add(v);
+                    } else {
+                        rows.put(c, Lists.newArrayList(v));
+                    }
+                } else {
+                    Map<C, List<V>> rows = new HashMap<>(1);
+                    rows.put(c, Lists.newArrayList(v));
+                    table.put(r, rows);
+                }
+            });
+        }
+        return table;
+    }
+
+    /**
+     * 按三个指定方法,将list分组返回复合键map
+     *
+     * @param sources
+     * @param rKeyGetter
+     * @param cKeyGetter
+     * @param valueGetter
+     * @param <R>
+     * @param <C>
+     * @param <V>
+     * @param <S>
+     * @return
+     */
+    public static <R, C, V, S> Map<R, Map<C, Set<V>>> distinctBy(List<S> sources, Function<S, R> rKeyGetter, Function<S, C> cKeyGetter, Function<S, V> valueGetter) {
+        Map<R, Map<C, Set<V>>> table = new HashMap<>(1);
+        if (!isEmpty(sources)) {
+            sources.forEach(source -> {
+                R r = rKeyGetter.apply(source);
+                C c = cKeyGetter.apply(source);
+                V v = valueGetter.apply(source);
+
+                if (table.containsKey(r)) {
+                    Map<C, Set<V>> rows = table.get(r);
+                    if (rows.containsKey(c)) {
+                        rows.get(c).add(v);
+                    } else {
+                        rows.put(c, Sets.newHashSet(v));
+                    }
+                } else {
+                    Map<C, Set<V>> rows = new HashMap<>(1);
+                    rows.put(c, Sets.newHashSet(v));
+                    table.put(r, rows);
+                }
+            });
+        }
+        return table;
+    }
+}

+ 24 - 1
bi-server/src/main/java/com/usoftchina/bi/server/dao/chart/ShowChartsMapper.java

@@ -1,6 +1,8 @@
 package com.usoftchina.bi.server.dao.chart;
 
 import com.usoftchina.bi.core.base.TestPage;
+import com.usoftchina.bi.server.model.bo.LineSeriesGroupMap;
+import com.usoftchina.bi.server.model.bo.LineSeriesMap;
 import com.usoftchina.bi.server.model.po.TargetData;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
@@ -9,6 +11,7 @@ import org.springframework.stereotype.Repository;
 
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 @Mapper
 @Repository
@@ -56,7 +59,7 @@ public interface ShowChartsMapper {
 
 
     //时间类型的X轴
-    @Select("select distinct to_char(${xAxisName},${timeType})time from ${tableName} ${screen} and rownum <= #{count} ORDER by to_char(${xAxisName},${timeType}) ASC")
+    @Select("select distinct to_char(${xAxisName},${timeType})time from ${tableName} ${screen} ORDER by to_char(${xAxisName},${timeType}) ASC")
     List<String> getTimeDate(@Param("xAxisName") String xAxisName, @Param("tableName") String tableName,
                              @Param("timeType") String timeType, @Param("screen") String screen, @Param("count") int count);
 
@@ -77,6 +80,12 @@ public interface ShowChartsMapper {
                          @Param("timeType") String timeType, @Param("xColumnIndex") String xColumnIndex,
                          @Param("screen") String screen);
 
+    //无分组时间类型值->优化后
+    @Select("select ${dataType}(${yAxisName}) as \"value\",(to_char(${xAxisName},'YYYY-MM-DD')) as \"date\" from ${tableName} ${screen} GROUP BY (to_char(${xAxisName},'YYYY-MM-DD')) ORDER BY (to_char(${xAxisName},'YYYY-MM-DD'))")
+    List<LineSeriesMap> getTimeValues (@Param("dataType") String dataType, @Param("yAxisName") String yAxisName,
+                                 @Param("tableName") String tableName, @Param("xAxisName") String xAxisName,
+                                 @Param("screen") String screen);
+
     //无分组半年时间值
     @Select("select ${dataType}(${yAxisName}) from ${tableName} where TO_CHAR(${xAxisName},'YYYY-MM') between #{firstIndex} and #{afterIndex} ${screen}")
     String getTimeValueYear(@Param("dataType") String dataType, @Param("yAxisName") String yAxisName, @Param("tableName") String tableName,
@@ -96,6 +105,20 @@ public interface ShowChartsMapper {
                           @Param("xColumn") String xColumn, @Param("timeType") String timeType, @Param("xColumnIndex") String xColumnIndex
                            );
 
+    //查询时间类型分组的值->优化后
+    @Select("select ${dataType}(${yAxisName}) as \"value\",TO_CHAR(${xColumn},${timeType}) as \"date\" from ${tableName} where ${groupsColumn}=#{groupsIndex} GROUP BY TO_CHAR(${xColumn},${timeType}) ")
+    List<LineSeriesMap> getGroupValuesTime(@Param("dataType") String dataType, @Param("yAxisName") String yAxisName, @Param("tableName") String tableName,
+                              @Param("groupsColumn") String groupsColumn, @Param("groupsIndex") String groupsIndex,
+                              @Param("xColumn") String xColumn, @Param("timeType") String timeType
+    );
+
+    //查询时间类型分组的值->优化后
+    @Select("select ${dataType}(${yAxisName}) as \"value\",TO_CHAR(${xColumn},${timeType}) as \"date\",${groupsColumn} as \"group\" from ${tableName} where ${groupsColumn} IN (SELECT ${groupsColumn} FROM ${tableName} GROUP BY ${groupsColumn}) GROUP BY TO_CHAR(${xColumn},${timeType}),${groupsColumn} ")
+    List<LineSeriesGroupMap> getGroupsValuesTime(@Param("dataType") String dataType, @Param("yAxisName") String yAxisName, @Param("tableName") String tableName,
+                                                 @Param("groupsColumn") String groupsColumn, @Param("groupsIndex") String groupsIndex,
+                                                 @Param("xColumn") String xColumn, @Param("timeType") String timeType
+    );
+
     //有分组时时间类型为空值
     @Select("select ${dataType}(${yAxisName}) from ${tableName} where ${groupsColumn} is null and TO_CHAR(${xColumn},${timeType})=#{xColumnIndex} ${screen}")
     String getGroupsValueTimeIsNull(@Param("dataType") String dataType, @Param("yAxisName") String yAxisName, @Param("tableName") String tableName,

+ 39 - 0
bi-server/src/main/java/com/usoftchina/bi/server/model/bo/LineSeriesGroupMap.java

@@ -0,0 +1,39 @@
+package com.usoftchina.bi.server.model.bo;
+
+public class LineSeriesGroupMap {
+    private String date;
+    private Double value;
+    private String group;
+
+    public String getGroup() {
+        return group;
+    }
+
+    public void setGroup(String group) {
+        this.group = group;
+    }
+
+    public String getDate() {
+        return date;
+    }
+
+    public void setDate(String date) {
+        this.date = date;
+    }
+
+    public Double getValue() {
+        return value;
+    }
+
+    public void setValue(Double value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return "LineSeriesMap{" +
+                "date='" + date + '\'' +
+                ", value=" + value +
+                '}';
+    }
+}

+ 9 - 0
bi-server/src/main/java/com/usoftchina/bi/server/model/bo/LineSeriesMap.java

@@ -27,4 +27,13 @@ public class LineSeriesMap {
                 ", value=" + value +
                 '}';
     }
+
+    public LineSeriesMap(String date, Double value) {
+        this.date = date;
+        this.value = value;
+    }
+
+    public LineSeriesMap() {
+
+    }
 }

+ 63 - 55
bi-server/src/main/java/com/usoftchina/bi/server/service/chart/ShowLineService.java

@@ -3,6 +3,7 @@ package com.usoftchina.bi.server.service.chart;
 import com.usoftchina.bi.core.base.RepCode;
 import com.usoftchina.bi.core.base.RepEntity;
 import com.usoftchina.bi.core.utils.CalculationJudgeUtil;
+import com.usoftchina.bi.core.utils.CollectionUtils;
 import com.usoftchina.bi.server.dao.chart.ChartsConfigMapper;
 import com.usoftchina.bi.server.dao.chart.ShowChartsMapper;
 import com.usoftchina.bi.server.model.bo.*;
@@ -10,12 +11,14 @@ import com.usoftchina.bi.server.model.vo.configVo.LineConfigInfo;
 import com.usoftchina.bi.server.model.vo.dataVo.ChartsDataInfo;
 import com.usoftchina.bi.core.jdbc.DynamicDataSourceContextHolder;
 import com.usoftchina.bi.server.utils.ScreenUtil;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 @Service
 public class ShowLineService {
@@ -85,29 +88,29 @@ public class ShowLineService {
         List<LineSeries> serieses = new ArrayList<LineSeries>();    //生成柱状图的系列
         List<String> xAxisData = new ArrayList<String>();  //X轴自己用
 
-            //取筛选列表
-            List<Screen> screens = lineConfigInfo.getFilters();
-            ScreenStr scr = new ScreenStr();
-            String screen = "";               //正常筛选条件
-            String screenToColumn = "";       //跟目标列相同的筛选条件
-            String screenToColumnS = "";       //跟目标列相同的筛选条件
-            if ("".equals(screens) || screens == null || screens.size() == 0){
-                screen = "";
-            }else {
-                scr = screenUtil.screensUtil(screens, xColumn, xAxisType);
-                screen = scr.getRet();
-                screenToColumn = scr.getWithColumnRet();
-                StringBuilder sb = new StringBuilder(screenToColumn);
-                if (screenToColumn != null && !("".equals(screenToColumn))){
-                    screenToColumnS = screenToColumn + " " + screen;               //and
-                    screenToColumn = String.valueOf(sb .replace(1, 5, "where "));
-                    screen = screenToColumn + " " + screen;         //where
-                } else {
-                    StringBuilder sb1 = new StringBuilder(screen);
-                    screenToColumnS = screen;
-                    screen = String.valueOf(sb1 .replace(1, 5, "where "));
-                }
+        //取筛选列表
+        List<Screen> screens = lineConfigInfo.getFilters();
+        ScreenStr scr = new ScreenStr();
+        String screen = "";               //正常筛选条件
+        String screenToColumn = "";       //跟目标列相同的筛选条件
+        String screenToColumnS = "";       //跟目标列相同的筛选条件
+        if ("".equals(screens) || screens == null || screens.size() == 0){
+            screen = "";
+        }else {
+            scr = screenUtil.screensUtil(screens, xColumn, xAxisType);
+            screen = scr.getRet();
+            screenToColumn = scr.getWithColumnRet();
+            StringBuilder sb = new StringBuilder(screenToColumn);
+            if (screenToColumn != null && !("".equals(screenToColumn))){
+                screenToColumnS = screenToColumn + " " + screen;               //and
+                screenToColumn = String.valueOf(sb .replace(1, 5, "where "));
+                screen = screenToColumn + " " + screen;         //where
+            } else {
+                StringBuilder sb1 = new StringBuilder(screen);
+                screenToColumnS = screen;
+                screen = String.valueOf(sb1 .replace(1, 5, "where "));
             }
+        }
 
         //X轴
         //判断是否为日期类型
@@ -120,29 +123,8 @@ public class ShowLineService {
         }
 
         //无分组时Y值
-        Iterator itX = xAxisData.iterator();
-        while (itX.hasNext()){
-            String xdata = (String)itX.next();
-            if (xdata == null || "".equals(xdata)){
-                continue;
-            }
-            double valueOne = 0;
-            String valueOnes = null;
-//                ("Y:"+ yColumn + "........x:" + xColumn + "........yAxistype:" + yAxisType + "...xtpye:+"+yAxisType+ "   xdata:"+xdata);
-                valueOnes = timeConverterUtil.getTimeValueConverter(yColumn, xColumn, tableName, yAxisType, xAxisType, xdata, screenToColumnS);
-//                ("value:"+valueOnes);
-            if (valueOnes == null || "".equals(valueOnes)){
-                valueOne = 0;
-            }else {
-                valueOne = Double.parseDouble(valueOnes);
-            }
-            LineSeriesMap lineSeriesMap = new LineSeriesMap();
-            lineSeriesMap.setValue(valueOne);
-            lineSeriesMap.setDate(xdata);
-            value.add(lineSeriesMap);
-        }
+        value = showChartsMapper.getTimeValues(yAxisType, yColumn, tableName, xColumn, screen);
         LineSeries series = new LineSeries();
-//        series.setName(yColumn);
         series.setMdata(value);
 
         serieses.add(series);
@@ -152,24 +134,23 @@ public class ShowLineService {
             serieses.remove(0);
             Iterator itGroup = groupBy.iterator();  //分组数
 
-            //便利分组
+            //遍历分组
             while (itGroup.hasNext()){
                 String groupByName = (String) itGroup.next();
-                int counts = showChartsMapper.getGroupsCount(groupByName,tableName, screenToColumnS);
-                if (counts > lineConfigInfo.getMaxCount()){
-                    chartsDataInfo.setTooMany(true);
-                }
                 List<String> groupsData = showChartsMapper.getGroups(groupByName,tableName, screenToColumnS, lineConfigInfo.getMaxCount()); //查询每个分组系列
                 Iterator itGroupsData = groupsData.iterator();
-
-                //每个分组得到得每个系列
+                if (groupsData.size() > lineConfigInfo.getMaxCount()){
+                    chartsDataInfo.setTooMany(true);
+                }
+                String groupsName = (String)itGroupsData.next();
+                /*//每个分组得到得每个系列
                 while(itGroupsData.hasNext()){
                     String groupsName = (String)itGroupsData.next();
                     if ("".equals(groupsName) || groupsName == null){
                         continue;
                     }
                     List<LineSeriesMap> groupsValue = new ArrayList<LineSeriesMap>();
-                    Iterator itXAxisData = xAxisData.iterator();
+                    *//*Iterator itXAxisData = xAxisData.iterator();
 
                     //每个系列对应X轴上的值
                     while (itXAxisData.hasNext()){
@@ -180,7 +161,7 @@ public class ShowLineService {
                         double groupsValueOne = 0;
                         String groupsValueOnes = null;
                         groupsValueOnes = timeConverterUtil.getGroupTimeConverter(yAxisType, yColumn, tableName, groupByName, xAxisType,
-                                    groupsName, xColumn, xAxisDataOne, screenToColumnS);
+                                groupsName, xColumn, xAxisDataOne, screenToColumnS);
                         if ("".equals(groupsValueOnes) || groupsValueOnes == null){
                             groupsValueOne = 0;
                         }else{
@@ -190,12 +171,26 @@ public class ShowLineService {
                         lineSeriesMap.setDate(xAxisDataOne);
                         lineSeriesMap.setValue(groupsValueOne);
                         groupsValue.add(lineSeriesMap);
-                    }
-
+                    }*//*
+                    groupsValue = showChartsMapper.getGroupValuesTime(yAxisType, yColumn, tableName, groupByName, groupsName, xColumn, "'YYYY-MM-DD'");
                     LineSeries lineSeries = new LineSeries();
                     lineSeries.setMdata(groupsValue);
                     lineSeries.setName(groupsName);
                     serieses.add(lineSeries);
+                }*/
+
+                List<LineSeriesGroupMap> lineSeriesGroupMapList = showChartsMapper.getGroupsValuesTime(yAxisType, yColumn, tableName, groupByName, groupsName, xColumn, "'YYYY-MM-DD'");
+                Map<String, List<LineSeriesGroupMap>> lineSeriesGroupMap = CollectionUtils.groupBy(lineSeriesGroupMapList, LineSeriesGroupMap::getGroup);
+                Iterator<Map.Entry<String, List<LineSeriesGroupMap>>> it = lineSeriesGroupMap.entrySet().iterator();
+                List<LineSeriesMap> lineSeriesMapList = null;
+                while (it.hasNext()) {
+                    Map.Entry<String, List<LineSeriesGroupMap>> entry = it.next();
+                    LineSeries lineSeries = new LineSeries();
+                    lineSeries.setName(entry.getKey());
+                    lineSeriesMapList = new ArrayList<>();
+                    copyProperties(entry.getValue(), lineSeriesMapList);
+                    lineSeries.setMdata(lineSeriesMapList);
+                    serieses.add(lineSeries);
                 }
             }
         }
@@ -212,5 +207,18 @@ public class ShowLineService {
         return new RepEntity(RepCode.success, chartsDataInfo);
     }
 
+    /**
+     * LineSeriesGroupMap 转 LineSeriesMap
+     * @param source
+     * @param target
+     */
+    private void copyProperties(List<LineSeriesGroupMap> source, List<LineSeriesMap> target){
+        if (!CollectionUtils.isEmpty(source)) {
+            for (LineSeriesGroupMap lineSeriesGroupMap : source) {
+                target.add(new LineSeriesMap(lineSeriesGroupMap.getDate(), lineSeriesGroupMap.getValue()));
+            }
+        }
+    }
+
 
 }