FormulaUtils.java 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. package com.mixsmart.utils;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  5. import org.apache.poi.ss.usermodel.*;
  6. import java.awt.Color;
  7. import org.jfree.chart.ChartFactory;
  8. import org.jfree.chart.ChartPanel;
  9. import org.jfree.chart.ChartUtilities;
  10. import org.jfree.chart.JFreeChart;
  11. import org.jfree.chart.axis.NumberAxis;
  12. import org.jfree.chart.axis.NumberTickUnit;
  13. import org.jfree.chart.axis.TickUnits;
  14. import org.jfree.chart.plot.PlotOrientation;
  15. import org.jfree.chart.plot.ValueMarker;
  16. import org.jfree.chart.plot.XYPlot;
  17. import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
  18. import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
  19. import org.jfree.chart.renderer.xy.XYStepRenderer;
  20. import org.jfree.chart.title.TextTitle;
  21. import org.jfree.data.xy.DefaultXYDataset;
  22. import org.jfree.ui.RectangleInsets;
  23. import org.jsoup.Jsoup;
  24. import org.springblade.core.tool.utils.Func;
  25. import org.springblade.core.tool.utils.IoUtil;
  26. import org.springblade.core.tool.utils.ResourceUtil;
  27. import org.springblade.manager.bean.TableInfo;
  28. import org.springblade.manager.dto.Coords;
  29. import org.springblade.manager.dto.ElementData;
  30. import org.springblade.manager.dto.FormData;
  31. import org.springblade.manager.entity.Formula;
  32. import java.awt.*;
  33. import java.awt.Font;
  34. import java.awt.geom.Ellipse2D;
  35. import java.io.*;
  36. import java.util.*;
  37. import java.util.List;
  38. import java.util.regex.Matcher;
  39. import java.util.regex.Pattern;
  40. import java.util.stream.Collectors;
  41. import static java.util.regex.Pattern.*;
  42. /**
  43. * @author yangyj
  44. * @Date 2022/7/14 15:55
  45. * @description TODO
  46. */
  47. public class FormulaUtils {
  48. public static Map<String,Object> triangleSquare(Object ranges){
  49. Map<String,Object> map =new HashMap<>();
  50. if(StringUtils.isEmpty(ranges)){
  51. //z的默认取值范围
  52. ranges="(0,15)";
  53. }
  54. Matcher m = RegexUtils.matcher("(\\-?\\d+)(\\D)(\\+?\\d+)",ranges.toString());
  55. if(m.find()) {
  56. System.out.println();
  57. int min = StringUtils.handObj2Integer(m.group(1));
  58. int max = StringUtils.handObj2Integer(m.group(3));
  59. Integer[] r = pythagorean(min, max);
  60. map.put("X", String.valueOf(r[0]));
  61. map.put("Y", String.valueOf(r[1]));
  62. map.put("Z", String.valueOf(r[2]));
  63. }
  64. return map;
  65. }
  66. /**
  67. * @Description 字符串相似度
  68. * @Param [s1, s2]
  69. * @return double
  70. * @Author yangyj
  71. * @Date 2023.04.12 18:01
  72. **/
  73. public static double getJaccardSimilarity(String s1, String s2) {
  74. Set<Character> set1 = new HashSet<>();
  75. Set<Character> set2 = new HashSet<>();
  76. for (char c : s1.toCharArray()) {
  77. set1.add(c);
  78. }
  79. for (char c : s2.toCharArray()) {
  80. set2.add(c);
  81. }
  82. Set<Character> intersection = new HashSet<>(set1);
  83. intersection.retainAll(set2);
  84. Set<Character> union = new HashSet<>(set1);
  85. union.addAll(set2);
  86. return (double) intersection.size() / union.size();
  87. }
  88. public static Double similarity(String s1,String s2){
  89. return getJaccardSimilarity(parseItemName(s1),parseItemName(s2));
  90. }
  91. /**
  92. * result[0]^2+result[1]^2=result[2]^2 result[] 元素均为正整数
  93. */
  94. public static Integer[] pythagorean(Integer min,Integer max){
  95. Integer[] result = null;
  96. List<Integer[]> list = new ArrayList<>();
  97. for(int i=1;i<=max;i++){
  98. for(int j=1;j<=max;j++){
  99. double tmp = Math.sqrt(Math.pow(i,2)+Math.pow(j,2));
  100. int z= (int) Math.round(tmp);
  101. if(min<z&&z<=max){
  102. Integer[] arr = new Integer[]{ i,j,z};
  103. list.add(arr);
  104. }
  105. }
  106. }
  107. if(ListUtils.isNotEmpty(list)){
  108. Random rm = new Random();
  109. result = list.get(rm.nextInt(list.size()));
  110. }
  111. return result;
  112. }
  113. public static void write(FormData fd, Object data,Boolean nullOrBlank ){
  114. if(Func.isEmpty(fd.getValues())){
  115. /*无定位信息不写入*/
  116. return;
  117. }
  118. /*写入前清空内容*/
  119. fd.getValues().forEach(t->t.setValue(null));
  120. if(data instanceof List){
  121. List<Object> values = (List<Object>) data;
  122. if(!nullOrBlank){
  123. values=values.stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
  124. }
  125. if(values.size()>fd.getValues().size()){
  126. /*当生成的数据超过实际容量的时候,会自动追加页数*/
  127. if(fd.getCoordsList().size()==1){
  128. if(values.stream().filter(CustomFunction::containsZH).anyMatch(e->e.toString().contains("\n"))){
  129. fd.getValues().get(0).setValue(values.stream().filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining()));
  130. }else{
  131. fd.getValues().get(0).setValue(values.stream().map(StringUtils::handleNull).collect(Collectors.joining("、")));
  132. }
  133. }else{
  134. // copy(fd,values);
  135. for(int n=0;n<fd.getValues().size();n++){
  136. fd.getValues().get(n).setValue(values.get(n));
  137. }
  138. List<Object> overList=values.stream().skip(fd.getValues().size()).collect(Collectors.toList());
  139. List<Coords> coordsList = fd.getCoordsList();
  140. int addPage=(int)Math.ceil((double)overList.size()/(double)coordsList.size());
  141. fd.setAddPages(addPage);
  142. ElementData last =fd.getValues().get(fd.getValues().size()-1);
  143. int indexBase=last.getIndex()+1;
  144. List<ElementData> addList= new ArrayList<>();
  145. for(int i=0;i<addPage;i++){
  146. for(int j=0;j<coordsList.size();j++){
  147. /*超页就尽管写进去,格式化阶段再加表*/
  148. Coords coords = coordsList.get(j);
  149. Object v=null;
  150. int st=i*coordsList.size()+j;
  151. if(st<overList.size()){
  152. v= overList.get(st);
  153. }
  154. addList.add(new ElementData(indexBase+i,last.getGroupId(),v,coords.getX(),coords.getY()));
  155. }
  156. }
  157. fd.getValues().addAll(addList);
  158. }
  159. }else{
  160. for(int n=0;n<values.size();n++){
  161. fd.getValues().get(n).setValue(values.get(n));
  162. }
  163. }
  164. }else{
  165. if(Formula.FULL.equals(fd.getFormula().getOutm())){
  166. /*填充策略*/
  167. fd.getValues().forEach(e->e.setValue(data));
  168. }else{
  169. fd.getValues().get(0).setValue(data);
  170. }
  171. }
  172. }
  173. public static List<TableInfo> getTableInfoList(JSONArray dataArray) {
  174. if (dataArray != null && !dataArray.isEmpty()) {
  175. List<TableInfo> result = new ArrayList<>();
  176. for (int m = 0; m < dataArray.size(); m++) {
  177. TableInfo tableInfo = new TableInfo();
  178. JSONObject dataInfo2 = dataArray.getJSONObject(m);
  179. //
  180. tableInfo.setContractId(dataInfo2.getString("contractId"));
  181. tableInfo.setPkeyId(dataInfo2.getString("pkeyId"));
  182. tableInfo.setProjectId(dataInfo2.getString("projectId"));
  183. //huangjn 填报的类型,施工或监理
  184. tableInfo.setClassify(dataInfo2.getString("classify"));
  185. //设置首件信息
  186. setFirstData(dataInfo2, tableInfo);
  187. // //设置日志信息
  188. setTheLogData(dataInfo2, tableInfo);
  189. dataInfo2.fluentRemove("contractId")
  190. .fluentRemove("pkeyId")
  191. .fluentRemove("p_key_id")
  192. .fluentRemove("projectId")
  193. .fluentRemove("classify")
  194. .fluentRemove("pickerKey")
  195. .fluentRemove("id")
  196. .fluentRemove("isFirst")
  197. .fluentRemove("firstNodeId")
  198. .fluentRemove("isTheLog")
  199. .fluentRemove("theLogId")
  200. .fluentRemove("linkTabIds")
  201. .fluentRemove("recordTime")
  202. .fluentRemove("businessId")
  203. .fluentRemove("sourceUrl")
  204. .fluentRemove("pdfUrl")
  205. .fluentRemove("firstFileName")
  206. .fluentRemove("");
  207. // 计算数据
  208. LinkedHashMap<String, List<String>> dataMap = dataInfo2.keySet().stream().filter(e -> e.contains("__")).collect(Collectors.groupingBy(e -> e.split("__")[0], LinkedHashMap<String, List<String>>::new, Collectors.toList()));
  209. LinkedHashMap<String, String> dataMap2 = new LinkedHashMap<>();
  210. // 字段组合
  211. for (String k : dataMap.keySet()) {
  212. if (dataMap.get(k).size() > 1 && !dataMap.get(k).contains("000Z")) {
  213. String[] ziduan = dataMap.get(k).toArray(new String[]{});
  214. String temp = "";
  215. for (int i = 0; i < ziduan.length - 1; i++) {
  216. for (int j = 0; j < ziduan.length - i - 1; j++) {
  217. Integer tr = Integer.parseInt((ziduan[j].split("__")[1]).split("_")[0]);
  218. Integer td = Integer.parseInt(ziduan[j].split("__")[1].split("_")[1]);
  219. Integer tr_1 = Integer.parseInt(ziduan[j + 1].split("__")[1].split("_")[0]);
  220. Integer td_1 = Integer.parseInt(ziduan[j + 1].split("__")[1].split("_")[1]);
  221. if (tr > tr_1 && td == td_1) { //纵向排序
  222. temp = ziduan[j];
  223. ziduan[j] = ziduan[j + 1];
  224. ziduan[j + 1] = temp;
  225. }
  226. }
  227. }
  228. String lastStr = dataInfo2.getString(ziduan[0]) + "_^_" + ziduan[0].split("__")[1];
  229. for (int i = 1; i < ziduan.length; i++) {
  230. String keyData = dataInfo2.getString(ziduan[i]);
  231. if (!keyData.equals("")) {
  232. lastStr += "☆" + dataInfo2.getString(ziduan[i]) + "_^_" + ziduan[i].split("__")[1];
  233. }
  234. }
  235. dataMap2.put(k, lastStr);
  236. } else {
  237. String dataVal = dataInfo2.getString(dataMap.get(k).get(0));
  238. dataMap2.put(k, dataVal + "_^_" + dataMap.get(k).get(0).split("__")[1]);
  239. }
  240. }
  241. dataMap2.put("p_key_id", tableInfo.getPkeyId());
  242. tableInfo.setDataMap(dataMap2);
  243. result.add(tableInfo);
  244. }
  245. return result;
  246. }
  247. return null;
  248. }
  249. public static void setFirstData(JSONObject dataInfo2, TableInfo tableInfo) {
  250. //huangjn 判断是否是首件
  251. if (dataInfo2.containsKey("isFirst")) {
  252. tableInfo.setIsFirst(dataInfo2.getString("isFirst"));
  253. }
  254. //huangjn 判断是否是首件
  255. //首件资料绑定的节点
  256. if (dataInfo2.containsKey("firstNodeId")) {
  257. tableInfo.setFirstNodeId(dataInfo2.getString("firstNodeId"));
  258. }
  259. //首件ID(编辑时有值,新增时为空)
  260. if (dataInfo2.containsKey("firstId")) {
  261. tableInfo.setFirstId(dataInfo2.getString("firstId"));
  262. }
  263. //源文件
  264. if (dataInfo2.containsKey("sourceUrl")) {
  265. tableInfo.setSourceUrl(dataInfo2.getString("sourceUrl"));
  266. }
  267. //pdfUrl
  268. if (dataInfo2.containsKey("pdfUrl")) {
  269. tableInfo.setPdfUrl(dataInfo2.getString("pdfUrl"));
  270. }
  271. //文件名称
  272. if (dataInfo2.containsKey("firstFileName")) {
  273. tableInfo.setFirstFileName(dataInfo2.getString("firstFileName"));
  274. }
  275. //关联的信息
  276. if (dataInfo2.containsKey("linkProcessList")) {
  277. tableInfo.setLinkProcessList(dataInfo2.getJSONArray("linkProcessList"));
  278. }
  279. }
  280. /**
  281. * 设置日志信息
  282. */
  283. public static void setTheLogData(JSONObject dataInfo2, TableInfo tableInfo) {
  284. //huangjn 判断是否是日志
  285. if (dataInfo2.containsKey("isTheLog")) {
  286. tableInfo.setIsTheLog(dataInfo2.getString("isTheLog"));
  287. }
  288. //huangjn 判断是否是日志
  289. //huangjn 日志ID
  290. if (dataInfo2.containsKey("theLogId")) {
  291. tableInfo.setTheLogId(dataInfo2.getString("theLogId"));
  292. }
  293. //huangjn 日志ID
  294. //huangjn 日志勾选的工序
  295. if (dataInfo2.containsKey("linkTabIds")) {
  296. tableInfo.setLinkTabIds(dataInfo2.getJSONArray("linkTabIds"));
  297. }
  298. //huangjn 日志勾选的工序
  299. //huangjn 日志所选时间
  300. if (dataInfo2.containsKey("recordTime")) {
  301. tableInfo.setRecordTime(dataInfo2.getString("recordTime"));
  302. }
  303. //huangjn 日志所选时间
  304. //huangjn 每份填报数据的id,目前日志专用
  305. if (dataInfo2.containsKey("id")) {
  306. tableInfo.setBusinessId(dataInfo2.getString("id"));
  307. }
  308. //huangjn 每份填报数据的id,目前日志专用
  309. }
  310. /**从元素名称中解析项目名称*/
  311. public static String parseItemName(String eName){
  312. if (StringUtils.isEmpty(eName)) {
  313. return eName;
  314. }
  315. String str = eName.replaceAll("\\s", "");
  316. Pattern pattern = compile("[((_]");
  317. String[] candidate = pattern.split(str);
  318. String regex = "[^\\u4e00-\\u9fa5]+";
  319. Pattern p = compile(regex);
  320. return Arrays.stream(candidate)
  321. .filter(s -> !isContainKeywords(s))
  322. .map(s -> filterString(s, p))
  323. .collect(Collectors.joining());
  324. }
  325. private static String filterString(String s, Pattern p) {
  326. Matcher matcher = p.matcher(s);
  327. return matcher.replaceAll("").replaceAll(getRegex(), "").replaceAll("(设计|合格).*","");
  328. }
  329. private static String getRegex() {
  330. return "(在合格标准内|满足设计要求|质量评定|评定|判定|项目|总数|抽测|实测|偏差|尺量)";
  331. }
  332. private static boolean isContainKeywords(String s) {
  333. List<String> keywords = Arrays.asList( "每", "个","附录","抽查","测","求","小于","大于","检查","仪","按");
  334. return keywords.stream().anyMatch(s::contains);
  335. }
  336. /**
  337. * @Description 深度拷贝
  338. * @Param [originalList]
  339. * @return java.util.List<T>
  340. * @Author yangyj
  341. * @Date 2023.04.28 14:18
  342. **/
  343. public static <T extends Serializable> List<T> copyList(List<T> originalList) {
  344. try {
  345. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  346. ObjectOutputStream oos = new ObjectOutputStream(baos);
  347. oos.writeObject(originalList);
  348. oos.close();
  349. ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
  350. ObjectInputStream ois = new ObjectInputStream(bais);
  351. @SuppressWarnings("unchecked")
  352. List<T> copiedList = (List<T>) ois.readObject();
  353. ois.close();
  354. return copiedList;
  355. } catch (Exception e) {
  356. e.printStackTrace();
  357. }
  358. return null;
  359. }
  360. /**
  361. * @Description Poi 动态执行公式 测试
  362. * @Param [url]
  363. * @Author yangyj
  364. * @Date 2023.05.05 14:28
  365. **/
  366. public static void evaluateFormulaCell(String url) {
  367. try {
  368. url="C:/Users/yangyj/Desktop/test.xlsx";
  369. Workbook workbook = WorkbookFactory.create(new File(url));
  370. Sheet sheet = workbook.getSheetAt(0);
  371. Cell cell = sheet.getRow(0).getCell(0);
  372. FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
  373. CellType cellType = evaluator.evaluateFormulaCellEnum(cell);
  374. if (cellType == CellType.NUMERIC) {
  375. double value = cell.getNumericCellValue();
  376. System.out.println("公式计算结果:" + value);
  377. } else if (cellType == CellType.STRING) {
  378. String value = cell.getStringCellValue();
  379. System.out.println("公式计算结果:" + value);
  380. }
  381. cell.setCellFormula("B1+C1+D1");
  382. evaluator.clearAllCachedResultValues();
  383. cellType = evaluator.evaluateFormulaCellEnum(cell);
  384. if (cellType == CellType.NUMERIC) {
  385. double value = cell.getNumericCellValue();
  386. System.out.println("公式计算结果:" + value);
  387. } else if (cellType == CellType.STRING) {
  388. String value = cell.getStringCellValue();
  389. System.out.println("公式计算结果:" + value);
  390. }
  391. }catch (IOException | InvalidFormatException e){
  392. e.printStackTrace();
  393. }
  394. }
  395. public static Map<String, String> getElementCell(String uri) {
  396. try {
  397. return Jsoup.parse(IoUtil.readToString(new FileInputStream(ResourceUtil.getFile(uri))))
  398. .select("table").first()
  399. .select("tr").stream()
  400. .flatMap(tr->tr.select("td").stream())
  401. .filter(d->!d.children().isEmpty())
  402. .map(d->d.children().get(0)).map(d->d.attr("keyname")).filter(StringUtils::isNotEmpty).map(e->e.split("__"))
  403. .collect(
  404. Collectors.toMap(
  405. b -> b[0],
  406. b -> b[1],
  407. (v1, v2) -> v1 + ";" + v2
  408. )
  409. );
  410. }catch (Exception e){
  411. e.printStackTrace();
  412. return new HashMap<>();
  413. }
  414. }
  415. public static List<String> itemNames =Arrays.asList(
  416. ""
  417. ,"压 实 度 (%)下路床 特重、极重交通荷载等级 设计值"
  418. ,"1△_压 实 度 (%)_下路床_轻、中及重交通 荷载等级_0.3m~0.8m_≧96_≧95_≧94_实测值或实测偏差值"
  419. ,"1△_压 实 度 (%)_下路提_轻、中及重交通 荷载等级_&gt;1.5m_≧93_≧92_≧90_实测值或实测偏差值"
  420. ,"1△_压 实 度 (%)_上路提_轻、中及重交通 荷载等级_0.8m~1.5m_≧94_≧94_≧93_实测值或实测偏差值"
  421. ,"压 实 度 (%)下路提 轻、中及重交通荷载等级 设计值"
  422. ,"压 实 度 (%)下路床 特重、极重交通荷载等级 合格率"
  423. ,"压 实 度 (%)下路提 轻、中及重交通荷载等级\t合格率"
  424. ,"5△_保护层 厚度 (mm)_基础、锚碇、墩台身、墩柱_±10_实测值或实测偏差值"
  425. ,"钢筋骨架尺寸宽、高或直径 (mm)_尺量:按骨架总数30%抽测_±5_实测值或实测偏差值"
  426. ,"钢筋骨架尺寸长 (mm)_±10_尺量:按骨架总数30%抽测_实测值或实测偏差值"
  427. , "受力钢筋间距 (mm)同排 梁、板、拱肋及拱上建筑 设计值"
  428. ,"受力钢筋间距 (mm)同排 梁、板、拱肋及拱上建筑 合格率"
  429. ," 箍筋、构造钢筋、螺旋筋间距(mm) 设计值"
  430. ,"箍筋、构造钢筋、螺旋筋间距(mm) 合格率"
  431. ,"实测项目_桩位 (mm)_群桩_≤100_质量评定_合格判定"
  432. ,"实测项目_桩位 (mm)_群桩_≤100_实测值或实测偏差值"
  433. ,"实测项目_桩位 (mm)_排架桩_实测值或实测偏差值"
  434. ,"实测项目_桩位 (mm)_排架桩_质量评定_合格判定"
  435. ,"实测项目_桩位 (mm)_群桩_≤100_质量评定_合格率(%)"
  436. ,"实测项目_桩位 (mm)_排架桩_质量评定_合格率(%)"
  437. ,"3△_支座高程(mm)_满足设计要求;设 计未要求时±5_水准仪:测每支座中心线_实测值或实测偏差值"
  438. ,"基底承载力(KPa)_不小于设计_直观或动力触探试验_实测值或实测偏差值"
  439. ,"实 测 项 目_花卉数量_满足设计要求_实测值或实测偏差值"
  440. ,"实 测 项 目_2△_草坪、草本地被覆盖率(%)_取弃土场绿 地_≥90_实测值或实测偏差值"
  441. ,"轴线偏位(mm)_全站仪:20m检查3点_实测值或实测偏差值"
  442. ,"1△_基材混合物喷射厚度(mm)_设计厚度±10_实测值或实测偏差值"
  443. ,"1△_混凝土强度 (MPA)_在合格标准内_按附录D检查_实测值或实测偏差值"
  444. );
  445. public static void mainOo(String[] args) {
  446. itemNames.stream().map(FormulaUtils::parseItemName).forEach(System.out::println);
  447. }
  448. // public static void mainXy(String[] args) {
  449. // DefaultXYDataset dataset = new DefaultXYDataset();
  450. // double[][] data = { { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0 } };
  451. // dataset.addSeries("Series 1", data);
  452. //
  453. // JFreeChart chart = ChartFactory.createScatterPlot(
  454. // "测试散点图", // 标题
  455. // "X", // 横轴标题
  456. // "Y", // 纵轴标题
  457. // dataset, // 数据集
  458. // PlotOrientation.VERTICAL, // 图表方向
  459. // true, // 是否显示图例
  460. // false, // 是否生成工具提示
  461. // false // 是否生成URL链接
  462. // );
  463. // // 设置字体
  464. // Font titleFont = new Font("SimSun", Font.PLAIN, 18); // 指定使用宋体字体
  465. // Font axisFont = new Font("SimSun", Font.PLAIN, 12); // 指定使用宋体字体
  466. //
  467. // // 设置标题字体
  468. // TextTitle title = chart.getTitle();
  469. // title.setFont(titleFont);
  470. // XYPlot plot = (XYPlot) chart.getPlot();
  471. // plot.setBackgroundPaint(Color.WHITE);
  472. // plot.getRenderer().setSeriesShape(0, new Ellipse2D.Double(-4, -4, 8, 8));
  473. // plot.getRenderer().setSeriesPaint(0, Color.BLUE);
  474. // // 自定义 X 轴刻度
  475. // NumberAxis domainAxis = (NumberAxis) plot.getDomainAxis();
  476. // domainAxis.setTickUnit(new NumberTickUnit(1)); // 设置刻度间隔
  477. // domainAxis.setRange(0.0, 7.5); // 设置轴的范围
  478. //
  479. // // 自定义 Y 轴刻度
  480. // NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
  481. // // rangeAxis.setTickUnit(NumberAxis.createStandardTickUnits().get(0)); // 设置刻度间隔
  482. // rangeAxis.setRange(0.0, 7.0); // 设置轴的范围
  483. //
  484. // // 添加横杠
  485. // for(int i=1;i<5;i++){
  486. // double value = i; // 横杠的位置
  487. // ValueMarker marker = new ValueMarker(value);
  488. // marker.setPaint(Color.BLUE); // 横杠的颜色
  489. // plot.addRangeMarker(marker);
  490. // }
  491. // ChartPanel chartPanel = new ChartPanel(chart);
  492. // chartPanel.setPreferredSize(new Dimension(500, 400));
  493. //
  494. //
  495. // // 保存图表为图片
  496. // try {
  497. // int width = 800;
  498. // int height = 600;
  499. // ChartUtilities.saveChartAsPNG(new File("C:/Users/yangyj/Desktop/Swap_space/poi_statistics.png"), chart, width, height);
  500. //
  501. // } catch (IOException e) {
  502. // e.printStackTrace();
  503. // }
  504. //
  505. //
  506. // }
  507. }