From 0d0aba638634a98eb402267feaeec5871e38ac15 Mon Sep 17 00:00:00 2001 From: quyixiao <2621048238@qq.com> Date: Sat, 18 Oct 2025 03:44:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api-mapper/pom.xml | 7 + .../com/heyu/api/data/utils/ChartUtil.java | 776 ++++++++++++++++++ .../heyu/api/data/utils/DingDingUtils.java | 1 + .../heyu/api/data/utils/GouDeZhaoDDUtils.java | 161 ++++ .../com/heyu/api/data/utils/LineChartDTO.java | 33 + pom.xml | 1 - 6 files changed, 978 insertions(+), 1 deletion(-) create mode 100644 api-mapper/src/main/java/com/heyu/api/data/utils/ChartUtil.java create mode 100644 api-mapper/src/main/java/com/heyu/api/data/utils/GouDeZhaoDDUtils.java create mode 100644 api-mapper/src/main/java/com/heyu/api/data/utils/LineChartDTO.java diff --git a/api-mapper/pom.xml b/api-mapper/pom.xml index e3ee688..fcd402b 100644 --- a/api-mapper/pom.xml +++ b/api-mapper/pom.xml @@ -49,6 +49,13 @@ + + org.jfree + jfreechart + 1.0.19 + + + org.lz.en.plugins lz-mybatis-en-plugins diff --git a/api-mapper/src/main/java/com/heyu/api/data/utils/ChartUtil.java b/api-mapper/src/main/java/com/heyu/api/data/utils/ChartUtil.java new file mode 100644 index 0000000..3c4fc3b --- /dev/null +++ b/api-mapper/src/main/java/com/heyu/api/data/utils/ChartUtil.java @@ -0,0 +1,776 @@ +package com.heyu.api.data.utils; + +import com.lz.mybatis.plugin.utils.OsUtil; +import lombok.extern.slf4j.Slf4j; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartUtilities; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.StandardChartTheme; +import org.jfree.chart.axis.CategoryAxis; +import org.jfree.chart.axis.CategoryLabelPositions; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; +import org.jfree.chart.labels.StandardPieSectionLabelGenerator; +import org.jfree.chart.plot.CategoryPlot; +import org.jfree.chart.plot.PiePlot3D; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.renderer.category.BarRenderer; +import org.jfree.chart.renderer.category.LineAndShapeRenderer; +import org.jfree.chart.renderer.category.StackedBarRenderer; +import org.jfree.chart.title.TextTitle; +import org.jfree.data.category.CategoryDataset; +import org.jfree.data.general.DatasetUtilities; +import org.jfree.data.general.DefaultPieDataset; +import org.jfree.data.general.PieDataset; +import org.springframework.stereotype.Component; + +import java.awt.*; +import java.io.File; +import java.io.FileOutputStream; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.*; +import java.util.List; + + +/** + *


+ * + * @version v1.0.0 + * @className CreateChartServiceImpl.java
+ * @packageName com.sinosoft.webmodule.landLibrary
+ * @date 2014-3-23 下午04:39:19
+ *

+ */ +@Component +@Slf4j +public class ChartUtil { + + private static String CHART_PATH = "/Users/quyixiao/Desktop/xxx"; + + static { + if (OsUtil.isLinux()) { + CHART_PATH = "/Users/quyixiao/Desktop/xxx"; + } + } + + public static void main(String[] args) { + ChartUtil pm = new ChartUtil(); +// // 生成饼状图 +// pm.makePieChart(); +// // 生成单组柱状图 + //pm.makeBarChart(); +// // 生成单组柱状图 +// pm.makeBarChart2(); +// // 生成多组柱状图 + //pm.makeBarGroupChart(); +// // 生成堆积柱状图 +// pm.makeStackedBarChart(); + // 生成折线图 + // pm.makeLineAndShapeChart(); + + + String headerTitle = "近7天的订单量及 退款量"; + + String xTitle = "时间"; + String yTitle = "数量"; + + + List list = new ArrayList<>(); + + list.add(new LineChartDTO("2019-07-03", 60, "订单数量")); + list.add(new LineChartDTO("2019-07-04", 45, "订单数量")); + list.add(new LineChartDTO("2019-07-05", 70, "订单数量")); + list.add(new LineChartDTO("2019-07-06", 80, "订单数量")); + list.add(new LineChartDTO("2019-07-07", 30, "订单数量")); + list.add(new LineChartDTO("2019-07-08", 20, "订单数量")); + list.add(new LineChartDTO("2019-07-09", 90, "订单数量")); + + list.add(new LineChartDTO("2019-07-06", 4, "退款订单数量")); + list.add(new LineChartDTO("2019-07-03", 3, "退款订单数量")); + list.add(new LineChartDTO("2019-07-07", 1, "退款订单数量")); + list.add(new LineChartDTO("2019-07-04", 5, "退款订单数量")); + list.add(new LineChartDTO("2019-07-05", 2, "退款订单数量")); + list.add(new LineChartDTO("2019-07-08", 4, "退款订单数量")); + list.add(new LineChartDTO("2019-07-09", 2, "退款订单数量")); + + pm.makeLineAndShapeChart2(headerTitle,xTitle,yTitle, list); + + + + } + + /** + * 生成折线图 + */ + public void makeLineAndShapeChart() { + + double[][] data = new double[][]{{60, 45, 60, 70, 65, 75, 65}, {65, 70, 63, 65, 73, 70, 68}, {68, 65, 70, 72, 75, 60, 70}, {70, 45, 60, 65, 70, 68, 79}}; + + String[] rowKeys = {"one period", "two period", "three period", "four period"}; + + String[] columnKeys = {"2019-07-03", "2019-07-04", "2019-07-05", "2019-07-06", "2019-07-07", "2019-07-08", "2019-07-09"}; + + + CategoryDataset dataset = getBarData(data, rowKeys, columnKeys); + createTimeXYChar("七日同比还款数据", "16点", "repay percent %", dataset, "/repayChart.jpg"); + } + + + public void makeLineAndShapeChart2(String headerName, String xName, String yName, List list) { + Set setName = new LinkedHashSet<>(); + + Set setX = new LinkedHashSet<>(); + Map dataMap = new LinkedHashMap<>(); + for (LineChartDTO lineChartDTO : list) { + setName.add(lineChartDTO.getName()); + setX.add(lineChartDTO.getX()); + dataMap.put(lineChartDTO.getName() + lineChartDTO.getX(), lineChartDTO.getY()); + } + + String[] rowKeys = setName.toArray(new String[setName.size()]); + String[] columnKeys = setX.toArray(new String[setX.size()]); + double[][] data = new double[rowKeys.length][columnKeys.length]; + + for (int i = 0; i < rowKeys.length; i++) { + double[] column = new double[columnKeys.length]; + for (int j = 0; j < columnKeys.length; j++) { + String key = rowKeys[i]+ columnKeys[j]; + Double value = dataMap.get(key); + if(value == null){ + value = new Double(0); + } + column[j] = value; + } + data[i] = column; + } + log.info("makeLineAndShapeChart2 rowKeys:{},columnKeys:{},data:{}", Arrays.toString(rowKeys),Arrays.toString(columnKeys),Arrays.deepToString(data)); + CategoryDataset dataset = getBarData(data, rowKeys, columnKeys); + createTimeXYChar(headerName, xName, yName, dataset, "/" + System.currentTimeMillis() + ".jpg"); + } + + /** + * 折线图 + * + * @param chartTitle + * @param x + * @param y + * @param xyDataset + * @param charName + * @return + */ + public String createTimeXYChar(String chartTitle, String x, String y, + CategoryDataset xyDataset, String charName) { + + JFreeChart chart = ChartFactory.createLineChart(chartTitle, x, y, xyDataset, PlotOrientation.VERTICAL, true, true, false); + chart.setTextAntiAlias(false); + chart.setBackgroundPaint(Color.WHITE); + // 设置图标题的字体重新设置title + Font font = new Font("隶书", Font.BOLD, 25); + TextTitle title = new TextTitle(chartTitle); + title.setFont(font); + chart.setTitle(title); + // 设置面板字体 + Font labelFont = new Font("SansSerif", Font.TRUETYPE_FONT, 12); + + + CategoryPlot categoryplot = (CategoryPlot) chart.getPlot(); + // x轴 // 分类轴网格是否可见 + categoryplot.setDomainGridlinesVisible(true); + // y轴 //数据轴网格是否可见 + categoryplot.setRangeGridlinesVisible(true); + categoryplot.setRangeGridlinePaint(Color.BLACK);// 虚线色彩 + categoryplot.setDomainGridlinePaint(Color.black);// 虚线色彩 + categoryplot.setBackgroundPaint(Color.lightGray); + categoryplot.setBackgroundPaint(Color.white); + + // 设置轴和面板之间的距离 +// categoryplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D)); + + CategoryAxis domainAxis = categoryplot.getDomainAxis(); + domainAxis.setLabelFont(labelFont);// 轴标题 + domainAxis.setTickLabelFont(labelFont);// 轴数值 + domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // 横轴上的 + // 设置横轴的字体 + domainAxis.setLabelFont(new Font("宋体", Font.BOLD, 16)); + // Lable + // 45度倾斜 + // 设置距离图片左端距离 + domainAxis.setLowerMargin(0.0); + // 设置距离图片右端距离 + domainAxis.setUpperMargin(0.0); + // 取得纵轴 + NumberAxis numberaxis = (NumberAxis) categoryplot.getRangeAxis(); + numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); + numberaxis.setAutoRangeIncludesZero(true); + // 设置纵轴的字体 + numberaxis.setLabelFont(new Font("黑体", Font.PLAIN, 18)); + // 获得renderer 注意这里是下嗍造型到lineandshaperenderer!! + LineAndShapeRenderer lineandshaperenderer = (LineAndShapeRenderer) categoryplot.getRenderer(); + //折线加粗 +// lineandshaperenderer.setSeriesStroke(0, new BasicStroke(3F)); +// lineandshaperenderer.setSeriesStroke(1, new BasicStroke(3F)); +// lineandshaperenderer.setSeriesStroke(2, new BasicStroke(3F)); + + lineandshaperenderer.setBaseShapesVisible(true); // series 点(即数据点)可见 + lineandshaperenderer.setBaseLinesVisible(true); // series 点(即数据点)间有连线可见 + +// lineandshaperenderer.setSeriesPaint(0, new Color(204, 204, 255)); +// lineandshaperenderer.setSeriesPaint(1, new Color(153, 204, 255)); +// lineandshaperenderer.setSeriesPaint(2, new Color(51, 204, 204)); + // 显示折点数据 + lineandshaperenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); + lineandshaperenderer.setBaseItemLabelsVisible(true); + + //显示 +// ChartFrame frame = new ChartFrame("try1", chart); +// frame.pack(); +// frame.setVisible(true); +// return null; + + FileOutputStream fos_jpg = null; + try { + isChartPathExist(CHART_PATH); + String chartName = CHART_PATH + charName; + fos_jpg = new FileOutputStream(chartName); + + // 将报表保存为png文件 + ChartUtilities.writeChartAsPNG(fos_jpg, chart, 500, 510); + + return chartName; + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + try { + fos_jpg.close(); + System.out.println("create time-createTimeXYChar."); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + + /** + * 生成分组的柱状图 + */ + public void makeBarGroupChart() { + double[][] data = new double[][]{{672, 766, 223, 540, 126}, + {325, 521, 210, 340, 106}, {332, 256, 523, 240, 526}}; + String[] rowKeys = {"苹果", "梨子", "葡萄"}; + String[] columnKeys = {"北京", "上海", "广州", "成都", "深圳"}; + CategoryDataset dataset = getBarData(data, rowKeys, columnKeys); + createBarChart(dataset, "x坐标", "y坐标", "柱状图", "barGroup.jpg"); + } + + /** + * 生成柱状图 + */ + public void makeBarChart() { + double[][] data = new double[][]{{672, 766, 223, 540, 126}}; + String[] rowKeys = {"苹果"}; + String[] columnKeys = {"北京", "上海", "广州", "成都", "深圳"}; + CategoryDataset dataset = getBarData(data, rowKeys, columnKeys); + createBarChart(dataset, "x坐标", "y坐标", "柱状图", "bar.jpg"); + } + + /** + * 生成柱状图 + */ + public void makeBarChart2() { + double[][] data = new double[][]{{672, 766, 223, 540, 126}}; + String[] rowKeys = {"苹果"}; + String[] columnKeys = {"北京", "上海", "广州", "成都", "深圳"}; + CategoryDataset dataset = getBarData(data, rowKeys, columnKeys); + createHorizontalBarChart(dataset, "x坐标", "y坐标", "柱状图", "bar2.jpg"); + } + + /** + * 生成堆栈柱状图 + */ + public void makeStackedBarChart() { + double[][] data = new double[][]{{0.21, 0.66, 0.23, 0.40, 0.26}, + {0.25, 0.21, 0.10, 0.40, 0.16}}; + String[] rowKeys = {"苹果", "梨子"}; + String[] columnKeys = {"北京", "上海", "广州", "成都", "深圳"}; + CategoryDataset dataset = getBarData(data, rowKeys, columnKeys); + createStackedBarChart(dataset, "x坐标", "y坐标", "柱状图", "stsckedBar.jpg"); + } + + /** + * 生成饼状图 + */ + public void makePieChart() { + double[] data = {9, 91}; + String[] keys = {"失败率", "成功率"}; + + createValidityComparePimChar(getDataPieSetByUtil(data, keys), "饼状图", + "pie2.png", keys); + } + + // 柱状图,折线图 数据集 + public CategoryDataset getBarData(double[][] data, String[] rowKeys, String[] columnKeys) { + return DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data); + + } + + // 饼状图 数据集 + public PieDataset getDataPieSetByUtil(double[] data, + String[] datadescription) { + + if (data != null && datadescription != null) { + if (data.length == datadescription.length) { + DefaultPieDataset dataset = new DefaultPieDataset(); + for (int i = 0; i < data.length; i++) { + dataset.setValue(datadescription[i], data[i]); + } + return dataset; + } + + } + + return null; + } + + /** + * 柱状图 + * + * @param dataset 数据集 + * @param xName x轴的说明(如种类,时间等) + * @param yName y轴的说明(如速度,时间等) + * @param chartTitle 图标题 + * @param charName 生成图片的名字 + * @return + */ + public String createBarChart(CategoryDataset dataset, String xName, + String yName, String chartTitle, String charName) { + StandardChartTheme standardChartTheme = new StandardChartTheme("CN");//设置标题字体 + standardChartTheme.setExtraLargeFont(new Font("隶书", Font.BOLD, 20));//设置图例的字体 + standardChartTheme.setRegularFont(new Font("隶书", Font.PLAIN, 15));//设置轴向的字体 + standardChartTheme.setLargeFont(new Font("隶书", Font.PLAIN, 15));//应用主题样式 + ChartFactory.setChartTheme(standardChartTheme); + JFreeChart chart = ChartFactory.createBarChart(chartTitle, // 图表标题 + xName, // 目录轴的显示标签 + yName, // 数值轴的显示标签 + dataset, // 数据集 + PlotOrientation.VERTICAL, // 图表方向:水平、垂直 + true, // 是否显示图例(对于简单的柱状图必须是false) + false, // 是否生成工具 + false // 是否生成URL链接 + ); + // 设置面板字体 + Font labelFont = new Font("SansSerif", Font.TRUETYPE_FONT, 12); + + /* + * VALUE_TEXT_ANTIALIAS_OFF表示将文字的抗锯齿关闭, + * 使用的关闭抗锯齿后,字体尽量选择12到14号的宋体字,这样文字最清晰好看 + */ + chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); + chart.setTextAntiAlias(false); + chart.setBackgroundPaint(Color.white); + // create plot + CategoryPlot plot = chart.getCategoryPlot(); + + // 设置横虚线可见 + plot.setRangeGridlinesVisible(true); + // 虚线色彩 + plot.setRangeGridlinePaint(Color.gray); + + + // 数据轴精度 + NumberAxis vn = (NumberAxis) plot.getRangeAxis(); + vn.setAutoRangeIncludesZero(true); + DecimalFormat df = new DecimalFormat("#0.00"); + vn.setNumberFormatOverride(df); // 数据轴数据标签的显示格式 + // x轴设置 + CategoryAxis domainAxis = plot.getDomainAxis(); + domainAxis.setLabelFont(labelFont);// 轴标题 + domainAxis.setTickLabelFont(labelFont);// 轴数值 + + // Lable(Math.PI/3.0)度倾斜 + // domainAxis.setCategoryLabelPositions(CategoryLabelPositions + // .createUpRotationLabelPositions(Math.PI / 3.0)); + + domainAxis.setMaximumCategoryLabelWidthRatio(0.6f);// 横轴上的 Lable 是否完整显示 + + // 设置距离图片左端距离 + domainAxis.setLowerMargin(0.1); + // 设置距离图片右端距离 + domainAxis.setUpperMargin(0.1); + // 设置 columnKey 是否间隔显示 +// domainAxis.setSkipCategoryLabelsToFit(true); + plot.setDomainAxis(domainAxis); + // 设置柱图背景色(注意,系统取色的时候要使用16位的模式来查看颜色编码,这样比较准确) + plot.setBackgroundPaint(new Color(255, 255, 204)); + + // y轴设置 + ValueAxis rangeAxis = plot.getRangeAxis(); + rangeAxis.setLabelFont(labelFont); + rangeAxis.setTickLabelFont(labelFont); + // 设置最高的一个 Item 与图片顶端的距离 + rangeAxis.setUpperMargin(0.15); + // 设置最低的一个 Item 与图片底端的距离 + rangeAxis.setLowerMargin(0.15); + plot.setRangeAxis(rangeAxis); + + BarRenderer renderer = new BarRenderer(); + // 设置柱子宽度 + renderer.setMaximumBarWidth(0.05); + // 设置柱子高度 + renderer.setMinimumBarLength(0.2); + // 设置柱子边框颜色 + renderer.setBaseOutlinePaint(Color.BLACK); + // 设置柱子边框可见 + renderer.setDrawBarOutline(true); + + // // 设置柱的颜色 + renderer.setSeriesPaint(0, new Color(204, 255, 255)); + renderer.setSeriesPaint(1, new Color(153, 104, 255)); + renderer.setSeriesPaint(2, new Color(51, 204, 204)); + + // 设置每个地区所包含的平行柱的之间距离 + renderer.setItemMargin(-1); + + // 显示每个柱的数值,并修改该数值的字体属性 + renderer.setIncludeBaseInRange(true); + renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); + renderer.setBaseItemLabelsVisible(true); + + plot.setRenderer(renderer); + // 设置柱的透明度 + plot.setForegroundAlpha(1.0f); + + FileOutputStream fos_jpg = null; + try { + isChartPathExist(CHART_PATH); + String chartName = CHART_PATH + charName; + fos_jpg = new FileOutputStream(chartName); + ChartUtilities.writeChartAsPNG(fos_jpg, chart, 500, 500, true, 10); + return chartName; + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + try { + fos_jpg.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 横向图 + * + * @param dataset 数据集 + * @param xName x轴的说明(如种类,时间等) + * @param yName y轴的说明(如速度,时间等) + * @param chartTitle 图标题 + * @param charName 生成图片的名字 + * @return + */ + public String createHorizontalBarChart(CategoryDataset dataset, + String xName, String yName, String chartTitle, String charName) { + JFreeChart chart = ChartFactory.createBarChart(chartTitle, // 图表标题 + xName, // 目录轴的显示标签 + yName, // 数值轴的显示标签 + dataset, // 数据集 + PlotOrientation.VERTICAL, // 图表方向:水平、垂直 + true, // 是否显示图例(对于简单的柱状图必须是false) + false, // 是否生成工具 + false // 是否生成URL链接 + ); + + CategoryPlot plot = chart.getCategoryPlot(); + // 数据轴精度 + NumberAxis vn = (NumberAxis) plot.getRangeAxis(); + // 设置刻度必须从0开始 + // vn.setAutoRangeIncludesZero(true); + DecimalFormat df = new DecimalFormat("#0.00"); + vn.setNumberFormatOverride(df); // 数据轴数据标签的显示格式 + + CategoryAxis domainAxis = plot.getDomainAxis(); + + domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // 横轴上的 + // Lable + Font labelFont = new Font("SansSerif", Font.TRUETYPE_FONT, 12); + + domainAxis.setLabelFont(labelFont);// 轴标题 + domainAxis.setTickLabelFont(labelFont);// 轴数值 + + domainAxis.setMaximumCategoryLabelWidthRatio(0.8f);// 横轴上的 Lable 是否完整显示 + // domainAxis.setVerticalCategoryLabels(false); + plot.setDomainAxis(domainAxis); + + ValueAxis rangeAxis = plot.getRangeAxis(); + // 设置最高的一个 Item 与图片顶端的距离 + rangeAxis.setUpperMargin(0.15); + // 设置最低的一个 Item 与图片底端的距离 + rangeAxis.setLowerMargin(0.15); + plot.setRangeAxis(rangeAxis); + BarRenderer renderer = new BarRenderer(); + // 设置柱子宽度 + renderer.setMaximumBarWidth(0.03); + // 设置柱子高度 + renderer.setMinimumBarLength(30); + +// renderer.setBaseOutlinePaint(Color.BLACK); + + // 设置柱的颜色 + renderer.setSeriesPaint(0, Color.GREEN); + renderer.setSeriesPaint(1, new Color(0, 0, 255)); + // 设置每个地区所包含的平行柱的之间距离 + renderer.setItemMargin(0.5); + // 显示每个柱的数值,并修改该数值的字体属性 +// renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); + // 设置柱的数值可见 +// renderer.setBaseItemLabelsVisible(true); + + plot.setRenderer(renderer); + // 设置柱的透明度 + plot.setForegroundAlpha(0.6f); + + FileOutputStream fos_jpg = null; + try { + isChartPathExist(CHART_PATH); + String chartName = CHART_PATH + charName; + fos_jpg = new FileOutputStream(chartName); +// ChartUtilities.writeChartAsPNG(fos_jpg, chart, 500, 500, true, 10); + return chartName; + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + try { + fos_jpg.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 饼状图 + * + * @param dataset 数据集 + * @param chartTitle 图标题 + * @param charName 生成图的名字 + * @param pieKeys 分饼的名字集 + * @return + */ + public String createValidityComparePimChar(PieDataset dataset, + String chartTitle, String charName, String[] pieKeys) { + JFreeChart chart = ChartFactory.createPieChart3D(chartTitle, // chart + // title + dataset,// data + true,// include legend + true, false); + + // 使下说明标签字体清晰,去锯齿类似于 + // chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);的效果 + chart.setTextAntiAlias(false); + // 图片背景色 + chart.setBackgroundPaint(Color.white); + // 设置图标题的字体重新设置title + Font font = new Font("隶书", Font.BOLD, 25); + TextTitle title = new TextTitle(chartTitle); + title.setFont(font); + chart.setTitle(title); + + PiePlot3D plot = (PiePlot3D) chart.getPlot(); + // 图片中显示百分比:默认方式 + + // 指定饼图轮廓线的颜色 + // plot.setBaseSectionOutlinePaint(Color.BLACK); + // plot.setBaseSectionPaint(Color.BLACK); + + // 设置无数据时的信息 + plot.setNoDataMessage("无对应的数据,请重新查询。"); + + // 设置无数据时的信息显示颜色 + plot.setNoDataMessagePaint(Color.red); + + // 图片中显示百分比:自定义方式,{0} 表示选项, {1} 表示数值, {2} 表示所占比例 ,小数点后两位 + plot.setLabelGenerator(new StandardPieSectionLabelGenerator( + "{0}={1}({2})", NumberFormat.getNumberInstance(), + new DecimalFormat("0.00%"))); + // 图例显示百分比:自定义方式, {0} 表示选项, {1} 表示数值, {2} 表示所占比例 + plot.setLegendLabelGenerator(new StandardPieSectionLabelGenerator( + "{0}={1}({2})")); + + plot.setLabelFont(new Font("SansSerif", Font.TRUETYPE_FONT, 12)); + + // 指定图片的透明度(0.0-1.0) + plot.setForegroundAlpha(0.65f); + // 指定显示的饼图上圆形(false)还椭圆形(true) + plot.setCircular(false, true); + + // 设置第一个 饼块section 的开始位置,默认是12点钟方向 + plot.setStartAngle(90); + + // // 设置分饼颜色 + plot.setSectionPaint(pieKeys[0], new Color(244, 194, 144)); + plot.setSectionPaint(pieKeys[1], new Color(144, 233, 144)); + + FileOutputStream fos_jpg = null; + try { + // 文件夹不存在则创建 + isChartPathExist(CHART_PATH); + String chartName = CHART_PATH + charName; + fos_jpg = new FileOutputStream(chartName); + // 高宽的设置影响椭圆饼图的形状 + ChartUtilities.writeChartAsPNG(fos_jpg, chart, 500, 230); + + return chartName; + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + try { + fos_jpg.close(); + System.out.println("create pie-chart."); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + + /** + * 判断文件夹是否存在,如果不存在则新建 + * + * @param chartPath + */ + private void isChartPathExist(String chartPath) { + File file = new File(chartPath); + if (!file.exists()) { + file.mkdirs(); + // log.info("CHART_PATH="+CHART_PATH+"create."); + } + } + + /** + * 堆栈柱状图 + * + * @param dataset + * @param xName + * @param yName + * @param chartTitle + * @param charName + * @return + */ + public String createStackedBarChart(CategoryDataset dataset, String xName, + String yName, String chartTitle, String charName) { + // 1:得到 CategoryDataset + + // 2:JFreeChart对象 + JFreeChart chart = ChartFactory.createStackedBarChart(chartTitle, // 图表标题 + xName, // 目录轴的显示标签 + yName, // 数值轴的显示标签 + dataset, // 数据集 + PlotOrientation.VERTICAL, // 图表方向:水平、垂直 + true, // 是否显示图例(对于简单的柱状图必须是false) + false, // 是否生成工具 + false // 是否生成URL链接 + ); + // 图例字体清晰 + chart.setTextAntiAlias(false); + + chart.setBackgroundPaint(Color.WHITE); + + // 2 .2 主标题对象 主标题对象是 TextTitle 类型 + chart + .setTitle(new TextTitle(chartTitle, new Font("隶书", Font.BOLD, + 25))); + // 2 .2.1:设置中文 + // x,y轴坐标字体 + Font labelFont = new Font("SansSerif", Font.TRUETYPE_FONT, 12); + + // 2 .3 Plot 对象 Plot 对象是图形的绘制结构对象 + CategoryPlot plot = chart.getCategoryPlot(); + + // 设置横虚线可见 + plot.setRangeGridlinesVisible(true); + // 虚线色彩 + plot.setRangeGridlinePaint(Color.gray); + + // 数据轴精度 + NumberAxis vn = (NumberAxis) plot.getRangeAxis(); + // 设置最大值是1 + vn.setUpperBound(1); + // 设置数据轴坐标从0开始 + // vn.setAutoRangeIncludesZero(true); + // 数据显示格式是百分比 + DecimalFormat df = new DecimalFormat("0.00%"); + vn.setNumberFormatOverride(df); // 数据轴数据标签的显示格式 + // DomainAxis (区域轴,相当于 x 轴), RangeAxis (范围轴,相当于 y 轴) + CategoryAxis domainAxis = plot.getDomainAxis(); + + domainAxis.setLabelFont(labelFont);// 轴标题 + domainAxis.setTickLabelFont(labelFont);// 轴数值 + + // x轴坐标太长,建议设置倾斜,如下两种方式选其一,两种效果相同 + // 倾斜(1)横轴上的 Lable 45度倾斜 + // domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); + // 倾斜(2)Lable(Math.PI 3.0)度倾斜 + // domainAxis.setCategoryLabelPositions(CategoryLabelPositions + // .createUpRotationLabelPositions(Math.PI / 3.0)); + + domainAxis.setMaximumCategoryLabelWidthRatio(0.6f);// 横轴上的 Lable 是否完整显示 + + plot.setDomainAxis(domainAxis); + + // y轴设置 + ValueAxis rangeAxis = plot.getRangeAxis(); + rangeAxis.setLabelFont(labelFont); + rangeAxis.setTickLabelFont(labelFont); + // 设置最高的一个 Item 与图片顶端的距离 + rangeAxis.setUpperMargin(0.15); + // 设置最低的一个 Item 与图片底端的距离 + rangeAxis.setLowerMargin(0.15); + plot.setRangeAxis(rangeAxis); + + // Renderer 对象是图形的绘制单元 + StackedBarRenderer renderer = new StackedBarRenderer(); + // 设置柱子宽度 + renderer.setMaximumBarWidth(0.05); + // 设置柱子高度 + renderer.setMinimumBarLength(0.1); + // 设置柱的边框颜色 + renderer.setBaseOutlinePaint(Color.BLACK); + // 设置柱的边框可见 + renderer.setDrawBarOutline(true); + + // // 设置柱的颜色(可设定也可默认) + renderer.setSeriesPaint(0, new Color(204, 255, 204)); + renderer.setSeriesPaint(1, new Color(255, 204, 153)); + + // 设置每个地区所包含的平行柱的之间距离 + renderer.setItemMargin(0.4); + + plot.setRenderer(renderer); + // 设置柱的透明度(如果是3D的必须设置才能达到立体效果,如果是2D的设置则使颜色变淡) + // plot.setForegroundAlpha(0.65f); + + FileOutputStream fos_jpg = null; + try { + isChartPathExist(CHART_PATH); + String chartName = CHART_PATH + charName; + fos_jpg = new FileOutputStream(chartName); + ChartUtilities.writeChartAsPNG(fos_jpg, chart, 500, 500, true, 10); + return chartName; + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + try { + fos_jpg.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/api-mapper/src/main/java/com/heyu/api/data/utils/DingDingUtils.java b/api-mapper/src/main/java/com/heyu/api/data/utils/DingDingUtils.java index 71fb47d..76282c4 100644 --- a/api-mapper/src/main/java/com/heyu/api/data/utils/DingDingUtils.java +++ b/api-mapper/src/main/java/com/heyu/api/data/utils/DingDingUtils.java @@ -21,6 +21,7 @@ public class DingDingUtils { protected static String token = "4e9917f5f782cec0bf139ac867b95c64b9c8bcd71266f334905f5196d9828314"; + // https://oapi.dingtalk.com/robot/send?access_token=590697c16a95c80798c58caa4205b7067258eaceb2ac10610713b2cf5b269bea public static void sendText(String text) { diff --git a/api-mapper/src/main/java/com/heyu/api/data/utils/GouDeZhaoDDUtils.java b/api-mapper/src/main/java/com/heyu/api/data/utils/GouDeZhaoDDUtils.java new file mode 100644 index 0000000..7462a62 --- /dev/null +++ b/api-mapper/src/main/java/com/heyu/api/data/utils/GouDeZhaoDDUtils.java @@ -0,0 +1,161 @@ +package com.heyu.api.data.utils; + + +import com.dingtalk.api.DefaultDingTalkClient; +import com.dingtalk.api.DingTalkClient; +import com.dingtalk.api.request.OapiRobotSendRequest; +import com.dingtalk.api.response.OapiRobotSendResponse; +import com.lz.mybatis.plugins.interceptor.entity.DingTalkDto; +import lombok.extern.slf4j.Slf4j; + +import java.util.Arrays; + +/*** + * https://oapi.dingtalk.com/robot/send?access_token=4e9917f5f782cec0bf139ac867b95c64b9c8bcd71266f334905f5196d9828314 + */ +@Slf4j +public class GouDeZhaoDDUtils { + + + protected static String dingTalkUrlPre = "https://oapi.dingtalk.com/robot/send?access_token="; + protected static String token = "590697c16a95c80798c58caa4205b7067258eaceb2ac10610713b2cf5b269bea"; + + + // https://oapi.dingtalk.com/robot/send?access_token=590697c16a95c80798c58caa4205b7067258eaceb2ac10610713b2cf5b269bea + public static void sendText(String text) { + try { + String content = text + "\n"; + content = "【注意】:" + + "\n" + content; + DingTalkDto dingTalk = new DingTalkDto(); + dingTalk.setToken(""); + dingTalk.setText(content); + dingTalk.setTitle("赶快充钱"); + + dingTalk.setMsgType("text"); + process(dingTalk,token); + } catch (Exception e) { + log.error("DingDingUtils",e); + } + } + + + + + + + + private static OapiRobotSendResponse process(DingTalkDto dingTalk, String token ) throws Exception { + DingTalkClient client = new DefaultDingTalkClient(dingTalkUrlPre + token); + OapiRobotSendRequest request = new OapiRobotSendRequest(); + request.setMsgtype("text"); + + OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text(); + text.setContent(dingTalk.getText()); + request.setText(text); + // 被@人的手机号(在text内容里要有@手机号) + OapiRobotSendRequest.At at = new OapiRobotSendRequest.At(); + + String[] mobiles = "18969093321".split(","); + + + if(StringUtils.isNotBlank(dingTalk.getAtMobiles())){ + mobiles = dingTalk.getAtMobiles().split(","); + } + at.setAtMobiles(Arrays.asList(mobiles)); + + request.setAt(at); + OapiRobotSendResponse response = client.execute(request); + return response; + } + + + + + + + public static void sendText1(String content) throws Exception { + DingTalkClient client = new DefaultDingTalkClient(dingTalkUrlPre + token); + OapiRobotSendRequest request = new OapiRobotSendRequest(); + request.setMsgtype("text"); + OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text(); + text.setContent(content); + request.setText(text); + OapiRobotSendRequest.At at = new OapiRobotSendRequest.At(); + // isAtAll类型如果不为Boolean,请升级至最新SDK + at.setIsAtAll("false"); + at.setAtMobiles(Arrays.asList("136700000","15200000")); + request.setAt(at); + OapiRobotSendResponse response = client.execute(request); + log.info("success:{}, code:{}, errorCode:{}, errorMsg:{}",response.isSuccess(),response.getCode(),response.getErrcode(),response.getErrmsg()); + } + + + + + public static void sendLink() throws Exception { + DingTalkClient client = new DefaultDingTalkClient(dingTalkUrlPre + token); + OapiRobotSendRequest request = new OapiRobotSendRequest(); + request.setMsgtype("link"); + OapiRobotSendRequest.Link link = new OapiRobotSendRequest.Link(); + link.setMessageUrl("https://www.dingtalk.com/"); + link.setPicUrl("https://gw.alicdn.com/tfs/TB1ut3xxbsrBKNjSZFpXXcXhFXa-846-786.png"); + link.setTitle("滴滴滴滴时代的火车向前开"); + link.setText("【注意】打开不打完卡不打卡不打卡金娃"); + request.setLink(link); + OapiRobotSendResponse response = client.execute(request); + + } + + + public static void sendMarkDown() throws Exception { + DingTalkClient client = new DefaultDingTalkClient(dingTalkUrlPre + token); + OapiRobotSendRequest request = new OapiRobotSendRequest(); + OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown(); + request.setMsgtype("markdown"); + markdown.setTitle("下单数据"); + markdown.setText("【注意】 杭州天气 \n" + + "> 9度,西北风1级,空气良89,相对温度73%\n\n" + + "> ![screenshot](https://heyuimage.ihzhy.com/prd/product1.png)\n" + + "> ###### 10点20分发布 [天气](http://www.thinkpage.cn/) \n"); + request.setMarkdown(markdown); + + OapiRobotSendRequest.At at = new OapiRobotSendRequest.At(); + at.setAtMobiles(Arrays.asList("13600006","155xxxx")); + request.setAt(at); + OapiRobotSendResponse response = client.execute(request); + System.out.printf("success:%s, code:%s, errorCode:%s, errorMsg:%s%n",response.isSuccess(),response.getCode(),response.getErrcode(),response.getErrmsg()); + + } + + + + + public static void sendMarkDownOrder() throws Exception { + DingTalkClient client = new DefaultDingTalkClient(dingTalkUrlPre + token); + OapiRobotSendRequest request = new OapiRobotSendRequest(); + OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown(); + request.setMsgtype("markdown"); + markdown.setTitle("近7天下单数据"); + markdown.setText("【注意】 \n" + + "> ![screenshot](https://heyuimage.ihzhy.com/1760730039826.jpg)\n" + + + ""); + request.setMarkdown(markdown); + + OapiRobotSendRequest.At at = new OapiRobotSendRequest.At(); + at.setAtMobiles(Arrays.asList("13600006","155xxxx")); + request.setAt(at); + OapiRobotSendResponse response = client.execute(request); + System.out.printf("success:%s, code:%s, errorCode:%s, errorMsg:%s%n",response.isSuccess(),response.getCode(),response.getErrcode(),response.getErrmsg()); + + } + + + + public static void main(String[] args) throws Exception { + sendMarkDownOrder(); + + } + +} diff --git a/api-mapper/src/main/java/com/heyu/api/data/utils/LineChartDTO.java b/api-mapper/src/main/java/com/heyu/api/data/utils/LineChartDTO.java new file mode 100644 index 0000000..6fbcce2 --- /dev/null +++ b/api-mapper/src/main/java/com/heyu/api/data/utils/LineChartDTO.java @@ -0,0 +1,33 @@ +package com.heyu.api.data.utils; + +import lombok.Data; + +@Data +public class LineChartDTO { + + /*** + * x + */ + private String x ; + + /*** + * y 的值 + */ + private double y ; + + + /*** + * 线的名称 + */ + private String name; + + public LineChartDTO() { + + } + + public LineChartDTO(String x, double y, String name) { + this.x = x; + this.y = y; + this.name = name; + } +} diff --git a/pom.xml b/pom.xml index 5b640f6..41dd9cf 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,6 @@ - org.springframework.boot spring-boot-starter-web