package com.mixsmart.utils; import cn.hutool.log.StaticLog; 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.ChartUtils; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.NumberTickUnit; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.ValueMarker; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYSplineRenderer; import org.jfree.chart.title.TextTitle; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.springblade.common.utils.BaseUtils; import org.springblade.core.tool.utils.CollectionUtil; import org.springblade.core.tool.utils.Func; import org.springblade.core.tool.utils.IoUtil; import org.springblade.core.tool.utils.StringPool; import org.springblade.manager.dto.Coords; import org.springblade.manager.dto.ElementData; import org.springblade.manager.dto.FormData; import org.springblade.manager.dto.LocalVariable; import org.springblade.manager.entity.Formula; import org.springblade.manager.formula.NodeTable; 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.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.*; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; import static java.util.regex.Pattern.*; /** * @author yangyj * @Date 2022/7/14 15:55 * @description TODO */ public class FormulaUtils { public static Map triangleSquare(Object ranges){ Map map =new HashMap<>(); if(StringUtils.isEmpty(ranges)){ //z的默认取值范围 ranges="(0,15)"; } Matcher m = RegexUtils.matcher("(\\-?\\d+)(\\D)(\\+?\\d+)",ranges.toString()); if(m.find()) { System.out.println(); int min = StringUtils.handObj2Integer(m.group(1)); int max = StringUtils.handObj2Integer(m.group(3)); Integer[] r = pythagorean(min, max); map.put("X", String.valueOf(r[0])); map.put("Y", String.valueOf(r[1])); map.put("Z", String.valueOf(r[2])); } return map; } /** * @Description 字符串相似度 * @Param [s1, s2] * @return double * @Author yangyj * @Date 2023.04.12 18:01 **/ public static double getJaccardSimilarity(String s1, String s2) { Set set1 = new HashSet<>(); Set set2 = new HashSet<>(); for (char c : s1.toCharArray()) { set1.add(c); } for (char c : s2.toCharArray()) { set2.add(c); } Set intersection = new HashSet<>(set1); intersection.retainAll(set2); Set union = new HashSet<>(set1); union.addAll(set2); return (double) intersection.size() / union.size(); } public static Double similarity(String s1,String s2){ return getJaccardSimilarity(parseItemName(s1),parseItemName(s2)); } /** * result[0]^2+result[1]^2=result[2]^2 result[] 元素均为正整数 */ public static Integer[] pythagorean(Integer min,Integer max){ Integer[] result = null; List list = new ArrayList<>(); for(int i=1;i<=max;i++){ for(int j=1;j<=max;j++){ double tmp = Math.sqrt(Math.pow(i,2)+Math.pow(j,2)); int z= (int) Math.round(tmp); if(min list = new ArrayList<>(); list.add(new ElementData(1,1,1)); test(fd); System.out.println(fd.getEName()); }*/ /**写人元素数据,每个元素都是一个集合,每页的单元格数量乘以页数就是总长度*/ public static void write(FormData fd, Object data){ write(fd,data,false); } public static void write(FormData fd, Object data,Boolean nullOrBlank ){ if(Func.isEmpty(fd.getValues())){ /*无定位信息不写入*/ return; } try { /*一个单元格且存在多张,全部设置为自动拓展 20230816*/ if(fd.getCoordsList().size()==1&&fd.getValues().size()>1&&fd.getFormula()!=null){ fd.getFormula().setOutm(Formula.FULL); } /*写入前清空内容*/ fd.getValues().forEach(t->t.setValue(null)); if(data instanceof List){ List values = (List) data; if(!nullOrBlank){ values=values.stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList()); } if(values.size()>fd.getValues().size()){ if(fd.getCoordsList().size()==1){ /*元素只绑定了一个单元格的情况*/ if(values.stream().filter(CustomFunction::containsZH).anyMatch(e->e.toString().contains("\n"))){ fd.getValues().get(0).setValue(values.stream().filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining())); }else{ /*日期类型的元素只获取最后一个非空*/ if(StringUtils.isEquals(4,fd.getEType())){ fd.getValues().get(0).setValue(values.stream().filter(StringUtils::isNotEmpty).reduce((first, second) -> second).orElse(null)); }else if(values.stream().filter(StringUtils::isNotEmpty).distinct().count()==1L){ /*如果输入元素全是是一样的内容,则输入出元素则每个单元格也写入一样的内容*/ values.stream().filter(StringUtils::isNotEmpty).findFirst().ifPresent(t->{ for(int n=0;n overList=values.stream().skip(fd.getValues().size()).collect(Collectors.toList()); List coordsList = fd.getCoordsList(); int addPage=(int)Math.ceil((double)overList.size()/(double)coordsList.size()); fd.setAddPages(addPage); ElementData last =fd.getValues().get(fd.getValues().size()-1); int indexBase=last.getIndex()+1; List addList= new ArrayList<>(); for(int i=0;ie.setValue(data)); }else{ fd.getValues().get(0).setValue(data); } } fd.setUpdate(1); }catch (Exception e){ e.printStackTrace(); } } /**从元素名称中解析项目名称,细化项目匹配用*/ public static String parseItemName(String eName){ if (StringUtils.isEmpty(eName)) { return eName; } String str = eName.replaceAll("\\s", ""); Pattern pattern = compile("[((][^\\u4e00-\\u9fa5]+[))]|_+"); String[] candidate = pattern.split(str); /*非中文非罗马数字1到10*/ String regex = "[^\\u4e00-\\u9fa5\\u2160-\\u2169))((]+"; Pattern p = compile(regex); return Arrays.stream(candidate) .filter(s -> !isContainKeywords(s)) .map(s -> filterString(s, p)) .collect(Collectors.joining()); } /*A15检查内容专用*/ public static String checkItemName(String eName){ if (StringUtils.isEmpty(eName)) { return eName; } /*分割字符串,选取第一个匹配的子串*/ String str = eName.replaceAll("\\s", ""); Pattern pattern = compile("[((][^\\u4e00-\\u9fa5]+[))]|_+"); String[] candidate = pattern.split(str); String regex = "[^\\u4e00-\\u9fa5]+"; return Arrays.stream(candidate).map(s->s.replaceAll(regex,"")).distinct().filter(StringUtils::isNotEmpty).filter(s->!isContainKeywords2(s)).findFirst().orElse(""); } private static String filterString(String s, Pattern p) { s=s.replaceAll("【[^【】]+】",""); Matcher matcher = p.matcher(s); return matcher.replaceAll("").replaceAll(getRegex(), "").replaceAll("(设计|合格).*",""); } private static String getRegex() { return "(在合格标准内|满足设计要求|质量评定|评定|判定|项目|总数|抽测|实测|偏差|尺量)"; } private static boolean isContainKeywords(String s) { List keywords = Arrays.asList( ":", "个","附录","抽查","测","求","小于","大于","检查","仪","按","不","各","记录","且","规定","值或实","≤","≥","平均"); return keywords.stream().anyMatch(s::contains); } private static boolean isContainKeywords2(String s) { List keywords = Arrays.asList( "实测项目"); return keywords.stream().anyMatch(s::contains); } /**回归·测试变量*/ public static List itemNames =Arrays.asList( "" ,"压 实 度 (%)下路床 特重、极重交通荷载等级 设计值" ,"1△_压 实 度 (%)_下路床_轻、中及重交通 荷载等级_0.3m~0.8m_≧96_≧95_≧94_实测值或实测偏差值" ,"1△_压 实 度 (%)_下路提_轻、中及重交通 荷载等级_>1.5m_≧93_≧92_≧90_实测值或实测偏差值" ,"1△_压 实 度 (%)_上路提_轻、中及重交通 荷载等级_0.8m~1.5m_≧94_≧94_≧93_实测值或实测偏差值" ,"压 实 度 (%)下路提 轻、中及重交通荷载等级 设计值" ,"压 实 度 (%)下路床 特重、极重交通荷载等级 合格率" ,"压 实 度 (%)下路提 轻、中及重交通荷载等级\t合格率" ,"5△_保护层 厚度 (mm)_基础、锚碇、墩台身、墩柱_±10_实测值或实测偏差值" ,"钢筋骨架尺寸宽、高或直径 (mm)_尺量:按骨架总数30%抽测_±5_实测值或实测偏差值" ,"钢筋骨架尺寸长 (mm)_±10_尺量:按骨架总数30%抽测_实测值或实测偏差值" , "受力钢筋间距 (mm)同排 梁、板、拱肋及拱上建筑 设计值" ,"受力钢筋间距 (mm)同排 梁、板、拱肋及拱上建筑 合格率" ," 箍筋、构造钢筋、螺旋筋间距(mm) 设计值" ,"箍筋、构造钢筋、螺旋筋间距(mm) 合格率" ,"实测项目_桩位 (mm)_群桩_≤100_质量评定_合格判定" ,"实测项目_桩位 (mm)_群桩_≤100_实测值或实测偏差值" ,"实测项目_桩位 (mm)_排架桩_实测值或实测偏差值" ,"实测项目_桩位 (mm)_排架桩_质量评定_合格判定" ,"实测项目_桩位 (mm)_群桩_≤100_质量评定_合格率(%)" ,"实测项目_桩位 (mm)_排架桩_质量评定_合格率(%)" ,"3△_支座高程(mm)_满足设计要求;设 计未要求时±5_水准仪:测每支座中心线_实测值或实测偏差值" ,"基底承载力(KPa)_不小于设计_直观或动力触探试验_实测值或实测偏差值" ,"实 测 项 目_花卉数量_满足设计要求_实测值或实测偏差值" ,"实 测 项 目_2△_草坪、草本地被覆盖率(%)_取弃土场绿 地_≥90_实测值或实测偏差值" ,"轴线偏位(mm)_全站仪:20m检查3点_实测值或实测偏差值" ,"1△_基材混合物喷射厚度(mm)_设计厚度±10_实测值或实测偏差值" ,"1△_混凝土强度 (MPA)_在合格标准内_按附录D检查_实测值或实测偏差值" ,"边坡坡度_不陡于设计值_水准仪:每200m测2点,且不少于5点_实测值或实测偏差值" ,"几何尺寸(mm)_±50_尺量:长、宽、高、壁厚各2点_实测值或实测偏差值" ,"4△_桩长(mm)_不小于设计_查施工记录_实测值或偏差值" ,"单桩每延米喷粉 (浆)量_不小于设计_查施工记录_实测值或偏差值" ,"搭接宽度(mm)_≥150【纵向】_尺量:抽查2%_实测值或实测偏差值", "搭接宽度(mm)_≥50(横向)_尺量:抽查2%_实测值或实测偏差值" ,"竖直度(mm)_挖孔桩_0.5%桩长,且≤200_铅锤线:每桩检测_实测值或实测偏差值" , "2△_压浆压力值 (Mpa)_满足施工技术 规范规定_查油压表读书;每管道检查_实测值或实测偏差值" , "基底承载力(KPa)_不小于设计_实测值或实测偏差值" ,"1△_受力钢筋间距 (mm)_两排以上间距_±5_实测值或实测偏差值" ,"1△梁(板)长度 (mm)_±5_实测值或实测偏差值" ,"墙面平整度(mm)_施工缝、变形缝处≤20_实测值或实测偏差值" ,"基底承载力(KPa)_不小于设计_实测值或实测偏差值" ,"1△_拱部超挖(mm)_Ⅱ、Ⅲ、Ⅳ级围岩(中硬岩 、软岩)_平均150,最大250_实测值或实测偏差值" ); /* public static void main(String[] args) { itemNames.stream().map(FormulaUtils::parseItemName).forEach(System.out::println); // itemNames.stream().map(FormulaUtils::checkItemName).forEach(System.out::println); }*/ public static Object getValue(Cell cell) { if (cell != null) { switch (cell.getCellTypeEnum()) { case STRING: return cell.getStringCellValue() == null ? null : cell.getStringCellValue().trim(); case NUMERIC: HSSFDataFormatter dataFormatter = new HSSFDataFormatter(); return dataFormatter.formatCellValue(cell); case BOOLEAN: return cell.getBooleanCellValue(); case ERROR: return cell.getErrorCellValue(); case FORMULA: try { return cell.getStringCellValue(); } catch (IllegalStateException e) { return cell.getNumericCellValue(); } default: cell.setCellType(CellType.STRING); return cell.getStringCellValue() == null ? null : cell.getStringCellValue().trim(); } } return null; } public static List getElementDataList(String coords,String values){ if(StringUtils.isNotEmpty(coords,values)){ List 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 str2ElementData(String pg, List coordsList ,String code,Integer index){ List 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 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] * @Author yangyj * @Date 2023.05.05 14:28 **/ public static void evaluateFormulaCell(String url) { try { url="C:/Users/yangyj/Desktop/test.xlsx"; Workbook workbook = WorkbookFactory.create(new File(url)); Sheet sheet = workbook.getSheetAt(0); Cell cell = sheet.getRow(0).getCell(0); FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); CellType cellType = evaluator.evaluateFormulaCellEnum(cell); if (cellType == CellType.NUMERIC) { double value = cell.getNumericCellValue(); System.out.println("公式计算结果:" + value); } else if (cellType == CellType.STRING) { String value = cell.getStringCellValue(); System.out.println("公式计算结果:" + value); } cell.setCellFormula("B1+C1+D1"); evaluator.clearAllCachedResultValues(); cellType = evaluator.evaluateFormulaCellEnum(cell); if (cellType == CellType.NUMERIC) { double value = cell.getNumericCellValue(); System.out.println("公式计算结果:" + value); } else if (cellType == CellType.STRING) { String value = cell.getStringCellValue(); System.out.println("公式计算结果:" + value); } }catch (IOException | InvalidFormatException e){ e.printStackTrace(); } } public static Map getElementCell(String uri){ return getElementCell(uri,null,null); } public static Map getElementCell(String uri,String key) { return getElementCell(uri,key,null); } public static Map getElementCell(String uri,String key,Document document) { try { String filter=" [keyname]"; if(Func.isNotBlank(key)){ filter="[keyname^="+key+"__]"; } if(document==null){ InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(uri); document=Jsoup.parse(IoUtil.readToString(inputStreamByUrl)); } Map result= document .select("table").first() .select(filter).stream() .map(d -> d.attr("keyname")).filter(StringUtils::isNotEmpty).map(e -> e.split("__")) .collect( Collectors.toMap( b -> b[0], b -> b[1], (v1, v2) -> v1 + ";" + v2 ) ); if(result.size()>0){ for(Map.Entry entry:result.entrySet()){ entry.setValue(FormulaUtils.coordsSorted(entry.getValue())); } } return result; }catch (Exception e){ e.printStackTrace(); return new HashMap<>(); } } public static List setScale(Integer scale, List data){ if(scale==null){ scale=StringUtils.getScale(data.stream().map(ElementData::getValue).filter(StringUtils::isDouble).collect(Collectors.toList())); } Integer finalScale = scale; return data.stream().peek(e->{if(StringUtils.isDouble(e.getValue())){e.setValue(StringUtils.number2StringZero(e.getValue(),finalScale));}}).collect(Collectors.toList()); } /* public static void main(String[] args) { Map map=getElementCell("/www/wwwroot/Users/hongchuangyanfa/Desktop/privateUrl/1694630551069130752.html","key_22"); System.out.println(map); }*/ /** * @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 dataList=Arrays.asList(coords.split(";")); if(dataList.size()>2){ LinkedList 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 String coordsSorted2(String coords){ if(StringUtils.isNotEmpty(coords)){ List dataList=Arrays.asList(coords.split(";")); if(dataList.size()>2){ /*判断分区:根据行列长度*/ List row =dataList.stream().map(e->e.split("_")[0]).distinct().map(Integer::parseInt).collect(Collectors.toList()); List column=dataList.stream().map(e->e.split("_")[1]).distinct().map(Integer::parseInt).collect(Collectors.toList()); if(row.size()>=column.size()){ /*纵向*/ if(column.size()>1){ List> consecutiveGroups = IntStream.range(0, column.size()) .boxed() .collect(Collectors.collectingAndThen( Collectors.groupingBy( i -> i - column.get(i), LinkedHashMap::new, Collectors.mapping(column::get, Collectors.toList()) ), map -> new ArrayList<>(map.values()) )); } } /* 确定区内方向:*/ } } return coords; } /* public static void main(String[] args) { List column = Arrays.asList(1, 2, 3, 5, 6, 7, 9, 11, 17); List> consecutiveGroups = IntStream.range(0, column.size()) .boxed() .collect(Collectors.collectingAndThen( Collectors.groupingBy( i -> i - column.get(i), LinkedHashMap::new, Collectors.mapping(column::get, Collectors.toList()) ), map -> new ArrayList<>(map.values()) )); AtomicInteger i = new AtomicInteger(column.get(0)); List> consecutiveGroups2= new ArrayList<>(column.stream().collect(Collectors.groupingBy(e -> e - i.getAndSet(e) > 1, LinkedHashMap::new, Collectors.toList())).values()); System.out.println(); }*/ public static List slice(List local, String formula){ int min =0; List result = new ArrayList<>(); try { pretreatment(local,formula); List r= local.stream().map(e-> { /*所有依赖元素的内容必须非空才进行计算,否则返回空值*/ return e.hasEmptyElementValue()?"": Expression.parse(e.getFormula()).calculate(e.getCurrentMap()).toString(); }).collect(Collectors.toList()); if(CollectionUtil.isNotEmpty(r)&&r.stream().anyMatch(StringUtils::isNotEmpty)){ result.addAll(r); } }catch (Exception e){ StaticLog.error("公式:{},执行出错",formula); } return result; } public static void pretreatment(List local,String formula){ formula=StringUtils.removeMultiSpace(formula); if(formula.contains("LIST")){ Matcher m=RegexUtils.matcher("\\(([^)]*)\\)/LIST",formula); while (m.find()){ List codes=getCodeList(m.group(1).replaceAll("[+-]",",")); local=local.stream().peek(e->{ @SuppressWarnings("unckecked") Map map = (Map) e.getCurrentMap().getOrDefault("E",new HashMap<>()); int listSize=(int)codes.stream().filter(c->StringUtils.isNotEmpty(map.get(c))).count(); if(listSize<=0||listSize>codes.size()){ listSize=codes.size(); } map.put("LIST",listSize); }).collect(Collectors.toList()); } } } /**从方法参数中获取全部code*/ public static List getCodeList(String param){ List list = new ArrayList<>(); if(StringUtils.isNotEmpty(param)){ Arrays.stream(param.split(",")).forEach(s->{ list.add(s.replaceAll("[E\\[\\]']","")); }); } return list; } /**从时间段中获取最后一个日期*/ static final String RANGE_DATE_REG="^\\[(\\d{4}[年.\\-]\\d{2}[月.\\-]\\d{2}[日]?),\\s+(\\d{4}[年.\\-]\\d{2}[月.\\-]\\d{2}[日]?)]$"; public static String range2end(String t){ if(t!=null&&Pattern.matches(RANGE_DATE_REG,t)){ t=t.replaceAll("^\\[|]$","").split(",")[1].trim(); } return t; } public static FormData createFormDataFast(String name,String code,String values,String coords){ if(StringUtils.isNotEmpty(code,name)){ if(StringUtils.isNotEmpty(coords)) { /*定位信息存在才合法*/ List 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()); List eds = new ArrayList<>(); if (StringUtils.isNotEmpty(values)) { String[] pages = values.split(";;"); for (int index = 0; index < pages.length; index++) { String pg = pages[index]; if (Func.isNotBlank(pg)) { String[] val = pg.split("☆"); Map 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())); } } } } else { eds = coordsList.stream().map(c -> new ElementData(0, 0, null, c.getX(), c.getY())).collect(Collectors.toList()); } FormData one = new FormData(code, eds, null, coords); one.setEName(name); /*备份原始数据,用于更新比较*/ one.init(); return one; } } return null; } 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); } /**字符串sha256映射*/ public static String sha256(String input) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] encodedHash = digest.digest(input.getBytes(StandardCharsets.UTF_8)); StringBuilder hexString = new StringBuilder(); for (byte b : encodedHash) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } /**根据步长获取字符*/ public static String getEveryNthChar(String input, int step) { StringBuilder result = new StringBuilder(); for (int i = 0; i < input.length(); i += step) { result.append(input.charAt(i)); } return result.toString(); } /**最大循环次数*/ public static int MAX_LOOP=20; /** * @Description 当前提交表单数据公式执行最小影响元素范围 * @Param [curTableNames:当前提交页面对应表编号, processFds:当前工序包含的所有元素] * @Author yangyj * @Date 2023.10.09 15:26 **/ public static List registerFd(List curTableNames, List processFds){ Map> group = processFds.stream().collect(Collectors.partitioningBy(e->curTableNames.contains(e.getTableName()))); List curFormDatas =group.get(true); /*提交叶包含元素*/ List initiator= new ArrayList<>(curFormDatas); List other=group.get(false); /*当前提交页元素影响到的元素都要重新执行公式*/ pick(curFormDatas,other,curFormDatas,fds->fds.stream().map(FormData::getCode).collect(Collectors.toSet())); /*当前提交页的元素公式依赖加载*/ pick(initiator,other,curFormDatas,fds->fds.stream().filter(FormData::executable).flatMap(f->f.getFormula().getRelyList().stream()).collect(Collectors.toSet())); return curFormDatas; } /** * @Description 调训符合条件的元素 * @Param [initiator 初始集合, other 待选集合, curFormDatas 结果集, function:挑选方法] * @Author yangyj * @Date 2023.10.12 14:53 **/ public static void pick(List initiator,List other,List curFormDatas ,Function,Set> function){ List curFormDatasAdd=new ArrayList<>(initiator); int loop=0; do{ loop++; Set codeSet= function.apply(curFormDatasAdd); Map> groupTmp = other.stream().collect(Collectors.partitioningBy(e->codeSet.contains(e.getCode()))); curFormDatasAdd=groupTmp.get(true); if(curFormDatasAdd.isEmpty()){ loop=MAX_LOOP; }else{ curFormDatas.addAll(curFormDatasAdd); } other=groupTmp.get(false); }while (!other.isEmpty()&&loop> relatedPages(List curFormDatas ,List tableAll){ Set initTableNames= curFormDatas.stream().map(FormData::getTableName).collect(Collectors.toSet()); return tableAll.stream().filter(e->initTableNames.contains(e.getInitTableName())).collect(Collectors.groupingBy(NodeTable::getInitTableName,Collectors.mapping(NodeTable::getPKeyId,Collectors.toList()))); } /*比较两组单元格内容是否一样*/ public static boolean compareElementDataList(List before ,List cur){ if(Func.isNotEmpty(before)&&Func.isNotEmpty(cur)&&before.size()==cur.size()){ String sa= before.stream().map(ElementData::stringValue).collect(Collectors.joining()); String sc= cur.stream().map(ElementData::stringValue).collect(Collectors.joining()); return sa.equals(sc); } return false; } /**分割treeCode*/ public static List treeCodeSplit(String treeCode){ List result = new ArrayList<>(); if(Func.isNotBlank(treeCode)){ /*字符总长度*/ int max =treeCode.length(), /*累计字符长度字符*/ sum=0, /*第几次循环*/ count=0; do{ result.add(treeCode.substring(0, sum+=Math.min(3,++count))); }while (sum