Browse Source

试验图表

yangyj 1 year ago
parent
commit
64ec8a5519

+ 13 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ElementData.java

@@ -1,6 +1,7 @@
 package org.springblade.manager.dto;
 
 
+import org.springblade.common.utils.BaseUtils;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringPool;
 
@@ -97,6 +98,18 @@ public class ElementData implements Serializable {
             return null;
         }
     }
+    public Number numberValue(){
+        if (Func.isNotEmpty(this.value)&& BaseUtils.isNumber(this.value)) {
+              String tmp =stringValue();
+              if(stringValue().contains(".")){
+                  return Double.parseDouble(tmp);
+              }else {
+                  return Integer.parseInt(tmp);
+              }
+        } else {
+            return null;
+        }
+    }
 
     public Boolean isEmpty() {
         return Func.isEmpty(this.value);

+ 3 - 3
blade-service/blade-manager/pom.xml

@@ -161,11 +161,11 @@
             <artifactId>commons-text</artifactId>
             <version>1.10.0</version>
         </dependency>
-        <!-- https://mvnrepository.com/artifact/jfree/jfreechart 绘制图表-->
+        <!-- https://mvnrepository.com/artifact/org.jfree/jfreechart -->
         <dependency>
-            <groupId>jfree</groupId>
+            <groupId>org.jfree</groupId>
             <artifactId>jfreechart</artifactId>
-            <version>1.0.13</version>
+            <version>1.5.4</version>
         </dependency>
         <dependency>
             <groupId>commons-net</groupId>

+ 4 - 0
blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java

@@ -1574,6 +1574,10 @@ public class CustomFunction {
         return result;
     }
 
+/*    public static void main(String[] args) {
+        Double[] a = scopeParse("≤30",0,1);
+        System.out.println(a);
+    }*/
 
 
     public static Double[] scopeParse(Object dev, Object design, Object xN) {

+ 137 - 86
blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java

@@ -1,44 +1,31 @@
 package com.mixsmart.utils;
 
 
-import cn.hutool.core.date.DateField;
-import cn.hutool.core.date.DatePattern;
-import cn.hutool.core.date.DateTime;
-import cn.hutool.core.date.DateUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.aliyun.oss.OSS;
-import com.aliyun.oss.OSSClientBuilder;
-import com.aliyun.oss.model.CannedAccessControlList;
-import com.aliyun.oss.model.ObjectMetadata;
-import com.aliyun.oss.model.PutObjectRequest;
-import com.aliyun.oss.model.PutObjectResult;
-import com.jfireel.expression.Expression;
+
 import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.ss.usermodel.*;
 import java.awt.Color;
 import org.jfree.chart.ChartFactory;
 import org.jfree.chart.ChartPanel;
-import org.jfree.chart.ChartUtilities;
+import org.jfree.chart.ChartUtils;
 import org.jfree.chart.JFreeChart;
 import org.jfree.chart.axis.NumberAxis;
 import org.jfree.chart.axis.NumberTickUnit;
-import org.jfree.chart.axis.TickUnits;
 import org.jfree.chart.plot.PlotOrientation;
 import org.jfree.chart.plot.ValueMarker;
 import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
-import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
-import org.jfree.chart.renderer.xy.XYStepRenderer;
+import org.jfree.chart.renderer.xy.XYSplineRenderer;
 import org.jfree.chart.title.TextTitle;
 import org.jfree.data.xy.DefaultXYDataset;
-import org.jfree.ui.RectangleInsets;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
 import org.jsoup.Jsoup;
-import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.IoUtil;
-import org.springblade.core.tool.utils.ResourceUtil;
+import org.springblade.core.tool.utils.StringPool;
 import org.springblade.manager.bean.TableInfo;
 import org.springblade.manager.dto.Coords;
 import org.springblade.manager.dto.ElementData;
@@ -48,15 +35,16 @@ import org.springblade.manager.utils.FileUtils;
 
 import java.awt.*;
 import java.awt.Font;
+import java.awt.Shape;
 import java.awt.geom.Ellipse2D;
 import java.io.*;
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
+
 import java.util.*;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static java.util.regex.Pattern.*;
 
@@ -487,6 +475,44 @@ public class FormulaUtils {
         return null;
     }
 
+    public static List<ElementData> getElementDataList(String coords,String values){
+        if(StringUtils.isNotEmpty(coords,values)){
+            List<Coords> coordsList = Stream.of(coords).flatMap(s -> Arrays.stream(s.split(";"))).map(s -> {
+                String[] xy = s.split("_");
+                return new Coords(xy[1], xy[0]);
+            }).collect(Collectors.toList());
+            return str2ElementData(values,coordsList,null,null);
+        }
+        return Collections.emptyList();
+    }
+    public static List<ElementData> str2ElementData(String pg, List<Coords> coordsList ,String code,Integer index){
+        List<ElementData> eds = new ArrayList<>();
+        if(StringUtils.isNotEmpty(pg)&&ListUtils.isNotEmpty(coordsList)) {
+            if(code==null){
+                code="code";
+            }
+            if(index==null){
+                index=1;
+            }
+            String[] val = pg.split("☆");
+            Map<String, Object> tmpMap = new LinkedHashMap<>();
+            for (String s : val) {
+                String[] t = s.split("_\\^_");
+                String[] c = t[1].split("_");
+                tmpMap.put(StringUtils.join(code, 0, index, Func.toInt(c[1]), Func.toInt(c[0]), StringPool.AT), t[0]);
+            }
+            for (Coords c : coordsList) {
+                Object data = null;
+                String key = StringUtils.join(code, 0, index, c.getX(), c.getY(), StringPool.AT);
+                if (tmpMap.containsKey(key)) {
+                    data = tmpMap.get(key);
+                }
+                eds.add(new ElementData(index, 0, data, c.getX(), c.getY()));
+            }
+        }
+        return eds;
+    }
+
     /**
      * @Description  Poi 动态执行公式 测试
      * @Param [url]
@@ -526,7 +552,7 @@ public class FormulaUtils {
     public static Map<String, String> getElementCell(String uri) {
         try {
             InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(uri);
-            return Jsoup.parse(IoUtil.readToString(inputStreamByUrl))
+            Map<String,String> result= Jsoup.parse(IoUtil.readToString(inputStreamByUrl))
                     .select("table").first()
                     .select("tr").stream()
                     .flatMap(tr -> tr.select("td").stream())
@@ -539,79 +565,104 @@ public class FormulaUtils {
                                     (v1, v2) -> v1 + ";" + v2
                             )
                     );
+            if(result.size()>0){
+                for(Map.Entry<String,String> entry:result.entrySet()){
+                    entry.setValue(FormulaUtils.coordsSorted(entry.getValue()));
+                }
+            }
+            return result;
         }catch (Exception e){
             e.printStackTrace();
             return new HashMap<>();
         }
     }
 
-    /*public static void main(String[] args) {
-        Map<String,String> map =getElementCell("");
+/*    public static void main(String[] args) {
+        Map<String,String> map=getElementCell("/www/wwwroot/Users/hongchuangyanfa/Desktop/privateUrl/1645328487982039040.html");
         System.out.println();
     }*/
+    /**
+     * @Description  定位信息排序
+     * @Param [coords]
+     * @return java.lang.String
+     * @Author yangyj
+     * @Date 2023.07.11 15:39
+     **/
+     public static String coordsSorted(String coords){
+           if(StringUtils.isNotEmpty(coords)){
+               List<String> dataList=Arrays.asList(coords.split(";"));
+               if(dataList.size()>2){
+                   LinkedList<Integer> list=dataList.stream().map(e->e.split("_")[1]).distinct().map(Integer::parseInt).sorted(Comparator.comparingInt(e->e)).collect(Collectors.toCollection(LinkedList::new));
+                   if(list.getLast()-list.getFirst()>list.size()-1){
+                        coords=dataList.stream()
+                                .sorted(Comparator.comparingInt((String str) -> Integer.parseInt(str.split("_")[1]))
+                                        .thenComparingInt(str -> Integer.parseInt(str.split("_")[0])))
+                                .collect(Collectors.joining(";"));
+                   }
+               }
+           }
+           return coords;
+     }
+
+    public static void mainT(String[] args) throws IOException {
+        XYSeries series = new XYSeries("Data Series");
+        series.add(10.2, 1.82);
+        series.add(11.9, 1.86);
+        series.add(15.9, 1.87);
+        series.add(19.3, 1.85);
+        series.add(20.3, 1.80);
+
+        XYSeriesCollection dataset = new XYSeriesCollection();
+        dataset.addSeries(series);
+
+        JFreeChart chart = ChartFactory.createXYLineChart(
+                "测试散点图", // 标题
+                "X", // 横轴标题
+                "Y", // 纵轴标题
+                dataset, // 数据集
+                PlotOrientation.VERTICAL, // 图表方向
+                true, // 是否显示图例
+                false, // 是否生成工具提示
+                false // 是否生成URL链接
+        );
+        // 设置字体
+        Font titleFont = new Font("SimSun", Font.PLAIN, 18); // 指定使用宋体字体
+        Font axisFont = new Font("SimSun", Font.PLAIN, 12); // 指定使用宋体字体
+
+        // 设置标题字体
+        TextTitle title = chart.getTitle();
+        title.setFont(titleFont);
+        XYPlot plot = (XYPlot) chart.getPlot();
+        XYSplineRenderer renderer = new XYSplineRenderer();
+        plot.setRenderer(renderer);
+        plot.setBackgroundPaint(Color.WHITE);
+        // Set the line stroke and shape for the renderer
+        renderer.setSeriesStroke(0, new BasicStroke(2.0f));
+        Shape circle = new Ellipse2D.Double(-3, -3, 6, 6);
+        renderer.setSeriesShape(0, circle);
+        renderer.setSeriesPaint(0, Color.BLUE);
+        // 自定义 X 轴刻度
+        NumberAxis domainAxis = (NumberAxis) plot.getDomainAxis();
+        domainAxis.setTickUnit(new NumberTickUnit(5)); // 设置刻度间隔
+        domainAxis.setRange(0.0, 25); // 设置轴的范围
+        // 自定义 Y 轴刻度
+        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
+        rangeAxis.setTickUnit(new NumberTickUnit(0.01)); // 设置刻度间隔
+        rangeAxis.setRange(1.79, 1.90); // 设置轴的范围
+        // 添加横杠
+        for(int i=175;i<190;i++){
+            ValueMarker marker = new ValueMarker((double) i /100);
+            marker.setPaint(Color.BLUE); // 横杠的颜色
+            plot.addRangeMarker(marker);
+        }
+        ChartPanel chartPanel = new ChartPanel(chart);
+        chartPanel.setPreferredSize(new Dimension(500, 400));
+        // 保存图表为图片
+        int width = 800;
+        int height = 600;
+        ChartUtils.saveChartAsPNG(new File("C:/Users/yangyj/Desktop/Swap_space/poi_statistics.png"), chart, width, height);
 
-
-
-//    public static void mainXy(String[] args) {
-//        DefaultXYDataset dataset = new DefaultXYDataset();
-//        double[][] data = { { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0 } };
-//        dataset.addSeries("Series 1", data);
-//
-//        JFreeChart chart = ChartFactory.createScatterPlot(
-//                "测试散点图", // 标题
-//                "X", // 横轴标题
-//                "Y", // 纵轴标题
-//                dataset, // 数据集
-//                PlotOrientation.VERTICAL, // 图表方向
-//                true, // 是否显示图例
-//                false, // 是否生成工具提示
-//                false // 是否生成URL链接
-//        );
-//        // 设置字体
-//        Font titleFont = new Font("SimSun", Font.PLAIN, 18); // 指定使用宋体字体
-//        Font axisFont = new Font("SimSun", Font.PLAIN, 12); // 指定使用宋体字体
-//
-//        // 设置标题字体
-//        TextTitle title = chart.getTitle();
-//        title.setFont(titleFont);
-//        XYPlot plot = (XYPlot) chart.getPlot();
-//        plot.setBackgroundPaint(Color.WHITE);
-//        plot.getRenderer().setSeriesShape(0, new Ellipse2D.Double(-4, -4, 8, 8));
-//        plot.getRenderer().setSeriesPaint(0, Color.BLUE);
-//        // 自定义 X 轴刻度
-//        NumberAxis domainAxis = (NumberAxis) plot.getDomainAxis();
-//        domainAxis.setTickUnit(new NumberTickUnit(1)); // 设置刻度间隔
-//        domainAxis.setRange(0.0, 7.5); // 设置轴的范围
-//
-//        // 自定义 Y 轴刻度
-//        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
-//       // rangeAxis.setTickUnit(NumberAxis.createStandardTickUnits().get(0)); // 设置刻度间隔
-//        rangeAxis.setRange(0.0, 7.0); // 设置轴的范围
-//
-//        // 添加横杠
-//        for(int i=1;i<5;i++){
-//            double value = i; // 横杠的位置
-//            ValueMarker marker = new ValueMarker(value);
-//            marker.setPaint(Color.BLUE); // 横杠的颜色
-//            plot.addRangeMarker(marker);
-//        }
-//        ChartPanel chartPanel = new ChartPanel(chart);
-//        chartPanel.setPreferredSize(new Dimension(500, 400));
-//
-//
-//        // 保存图表为图片
-//        try {
-//            int width = 800;
-//            int height = 600;
-//            ChartUtilities.saveChartAsPNG(new File("C:/Users/yangyj/Desktop/Swap_space/poi_statistics.png"), chart, width, height);
-//
-//        } catch (IOException e) {
-//            e.printStackTrace();
-//        }
-//
-//
-//    }
-
+    }
 
 
 

+ 48 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java

@@ -1,6 +1,7 @@
 package org.springblade.manager.controller;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -41,6 +42,7 @@ import java.io.FileNotFoundException;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * @author yangyj
@@ -496,5 +498,51 @@ public class FormulaController {
         return R.data(map);
     }
 
+    @GetMapping("/chart-init")
+    @ApiOperationSupport(order = 11)
+    public R<Object> chartInit(Long pkeyId,String id){
+            WbsTreePrivate wtp = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId,pkeyId));
+            if(wtp!=null&&Func.isNotEmpty(id)){
+                /*获取配置*/
+               List<Map<String,Object>> listMap= this.jdbcTemplate.queryForList("select content from m_formula_panel  a  join m_wbs_tree_private b on a.id=b.init_table_id where b.p_key_id="+pkeyId);
+               if(Func.isNotEmpty(listMap)){
+                   JSONObject job = JSON.parseObject(listMap.get(0).get("content").toString());
+                   /*获取关联数据*/
+                   List<Map<String,Object>>  configList= this.jdbcTemplate.queryForList("select d.rely ,b.e_key ekey from m_wbs_tree_private a join  m_wbs_form_element b on a.init_table_id=b.f_id join m_element_formula_mapping c on b.id=c.element_id join m_formula d on c.formula_id=d.id  where p_key_id="+wtp.getPKeyId()+" and b.is_deleted=0 and  d.formula like 'FC.chart%' limit 1");
+                   if(Func.isNotEmpty(configList)){
+                       Map<String,Object> config =configList.get(0);
+                       String[] rely = Func.toStr(config.get("rely")).split(",");
+                       String ky=rely[0].split(":")[1];
+                       String kx=rely[1].split(":")[1];
+                       List<Map<String,Object>> dataMap= this.jdbcTemplate.queryForList("select "+ky+","+kx+" from "+wtp.getInitTableName() +" where group_id="+id+" and p_key_id ="+pkeyId);
+                       if(Func.isNotEmpty(dataMap)){
+                           Map<String,Object> data = dataMap.get(0);
+                           String dy= Func.toStr(data.get(ky));
+                           String dx=Func.toStr(data.get(kx));
+                           if(dy.length()>0&&dx.length()>0){
+                              Map<String,String> coordsMap = FormulaUtils.getElementCell(wtp.getHtmlUrl());
+                              List<ElementData> ly = FormulaUtils.getElementDataList(coordsMap.get(ky),dy);
+                              List<ElementData> lx = FormulaUtils.getElementDataList(coordsMap.get(kx),dx);
+                               JSONArray jsonArray =new JSONArray();
+                              for(int i=0;i< Math.min(ly.size(),lx.size());i++){
+                                     ElementData edy= ly.get(i);
+                                     ElementData edx = lx.get(i);
+                                     if(StringUtils.isNotEmpty(edy.stringValue(),edx.stringValue())){
+                                         jsonArray.add(new JSONArray().fluentAdd(edx.numberValue()).fluentAdd(edy.numberValue()));;
+                                     }
+                              }
+                              if(!jsonArray.isEmpty()){
+                                  JSONObject chartData= job.getJSONArray("series").getJSONObject(0);
+                                  chartData.put("data",jsonArray);
+                                  return R.data(job.toJSONString());
+                              }
+                           }
+                       }
+                   }
+               }
+            }
+            return R.data("{}");
+    }
+
 
 }

+ 12 - 9
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -770,15 +770,18 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             }else{
                                 @SuppressWarnings("unchecked")
                                 Map<String,Object> em = (Map<String, Object>) currentMap.computeIfAbsent(E,(k)-> new HashMap<>());
-                                if(ele.stream().map(e->e.getCoordsList().size()).max(Comparator.comparingInt(e->e)).orElse(1)==1&&fd.getCoordsList().size()==1){
-                                    ele.forEach(e->{
-                                        em.put(e.getCode(),e.getValues().get(0).getValue());
-                                    });
-                                }else{
-                                    ele.forEach(e->{
-                                        em.put(e.getCode(),e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList()));
-                                    });
-                                }
+//                                if(ele.stream().map(e->e.getCoordsList().size()).max(Comparator.comparingInt(e->e)).orElse(1)==1&&fd.getCoordsList().size()==1){
+//                                    ele.forEach(e->{
+//                                        em.put(e.getCode(),e.getValues().get(0).getValue());
+//                                    });
+//                                }else{
+//                                    ele.forEach(e->{
+//                                        em.put(e.getCode(),e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList()));
+//                                    });
+//                                }
+                                ele.forEach(e->{
+                                        em.put(e.getCode(),e.getRawValue());
+                                });
                                 Object data =Expression.parse(formula.getFormula()).calculate(currentMap);
                                 write(fd,data);
                             }

+ 23 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java

@@ -2166,12 +2166,35 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
             }
         }
         doc.select("Col").remove();
+        /*Echart*/
+        chart(table,wbsTreePrivate);
         if (fileInputStream != null) {
             fileInputStream.close();
         }
         return R.data(table + "");
     }
 
+    private void  chart(  Element table,WbsTreePrivate wtp){
+       List<Map<String,Object>>  configList= this.jdbcTemplate.queryForList("select d.rely ,b.e_key ekey from m_wbs_tree_private a join  m_wbs_form_element b on a.init_table_id=b.f_id join m_element_formula_mapping c on b.id=c.element_id join m_formula d on c.formula_id=d.id  where p_key_id="+wtp.getPKeyId()+" and b.is_deleted=0 and d.formula like 'FC.chart%' limit 1");
+       if(Func.isNotEmpty(configList)){
+           Map<String,Object> config =configList.get(0);
+           String[] rely = Func.toStr(config.get("rely")).split(",");
+           String ky=rely[0].split(":")[1];
+           String kx=rely[1].split(":")[1];
+           String kt=Func.toStr(config.get("ekey"));
+           Element inputElement = table.select("el-input[keyname^="+kt+"__").first();
+           String keyname=inputElement.attr("keyname");
+           Element echartElement = new Element("hc-echart");
+           echartElement.attr(":option", "formData."+keyname);
+           echartElement.attr("id", keyname);
+           echartElement.attr("keyname", keyname);
+           inputElement.replaceWith(echartElement);
+           table.select("el-input[keyname^="+ky+"__").forEach(e->e.attr("chartX","").attr("@blur","setChartData"));
+           table.select("el-input[keyname^="+kx+"__").forEach(e->e.attr("@blur","setChartData").attr("chartY",""));
+       }
+
+    }
+
     @Transactional(rollbackFor = Exception.class)
     public boolean insertBatch(Collection<WbsTreePrivate> entityList, int batchSize) {
         try {