Sfoglia il codice sorgente

试验-保存
1、细集料筛分生成图表 补充

LHB 1 mese fa
parent
commit
d9ec16e2e6

+ 217 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/SieveAnalysisChart.java

@@ -0,0 +1,217 @@
+package org.springblade.manager.utils;
+
+import com.mixsmart.utils.RegexUtils;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.ChartUtils;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.CategoryAxis;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.axis.NumberTickUnit;
+import org.jfree.chart.plot.CategoryPlot;
+import org.jfree.chart.plot.DatasetRenderingOrder;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.renderer.category.LineAndShapeRenderer;
+import org.jfree.chart.ui.RectangleInsets;
+import org.jfree.data.category.DefaultCategoryDataset;
+
+import java.awt.*;
+import java.io.File;
+import java.io.IOException;
+import java.util.regex.Matcher;
+
+/**
+ * 筛分分析图表生成工具类
+ */
+public class SieveAnalysisChart {
+    private double[][] data;
+
+    /**
+     * 构造函数
+     * @param data 筛分分析数据,格式: {{筛孔尺寸, 通过率, 累计筛余率, 第二种数据下限, 第二种数据上限}, ...}
+     */
+    public SieveAnalysisChart(double[][] data) {
+        this.data = data;
+    }
+
+    /**
+     * 生成筛分分析图表并保存为图片
+     * @param filename 输出文件名
+     * @param width 图片宽度
+     * @param height 图片高度
+     * @throws IOException 当保存文件出错时抛出
+     */
+    public void generateChart(String filename, int width, int height) throws IOException {
+        // 创建数据集 - 累计筛余率
+        DefaultCategoryDataset retainedDataset = new DefaultCategoryDataset();
+        // 创建数据集 - 通过率
+        DefaultCategoryDataset passingDataset = new DefaultCategoryDataset();
+        // 创建第二种数据 - 范围下限
+        DefaultCategoryDataset secondDataLowerDataset = new DefaultCategoryDataset();
+        // 创建第二种数据 - 范围上限
+        DefaultCategoryDataset secondDataUpperDataset = new DefaultCategoryDataset();
+
+        // 填充数据
+        for (double[] point : data) {
+            String sieveSize = String.valueOf(point[0]);
+            double retainedPercent = point[1];
+            double passingPercent = point[2];
+            double secondLower = point[3];
+            double secondUpper = point[4];
+
+            retainedDataset.addValue(retainedPercent, "累计筛余率", sieveSize);
+            passingDataset.addValue(passingPercent, "通过率", sieveSize);
+            secondDataLowerDataset.addValue(secondLower, "第二种数据下限", sieveSize);
+            secondDataUpperDataset.addValue(secondUpper, "第二种数据上限", sieveSize);
+        }
+
+        // 创建图表(不显示图例)
+        JFreeChart chart = ChartFactory.createLineChart(
+                // 标题
+                "集料级配曲线",
+                // X轴标题
+                "筛孔尺寸(mm)",
+                // 不显示左侧Y轴标题
+                "",
+                // 数据集
+                retainedDataset,
+                PlotOrientation.VERTICAL,
+                // 不显示图例
+                false,
+                false,
+                false
+        );
+
+        // 设置中文字体,防止乱码
+        Font chineseFont = new Font("SimSun", Font.BOLD, 12);
+        chart.getTitle().setFont(new Font("SimSun", Font.BOLD, 16));
+
+        // 获取图表区域对象
+        CategoryPlot plot = chart.getCategoryPlot();
+
+        // 设置左侧Y轴 (累计筛余率)
+        NumberAxis retainedAxis = (NumberAxis) plot.getRangeAxis();
+        retainedAxis.setRange(0, 100);
+        retainedAxis.setTickUnit(new NumberTickUnit(10));
+        retainedAxis.setLabelFont(chineseFont);
+        retainedAxis.setTickLabelFont(chineseFont);
+        // 在轴线内侧添加标签
+        retainedAxis.setLabel("累计筛余率(%)");
+        retainedAxis.setLabelInsets(new RectangleInsets(0, 0, 0, 0));
+
+        // 创建并设置右侧Y轴 (通过率)
+        NumberAxis passingAxis = new NumberAxis("");
+        // 正常范围设置
+        passingAxis.setRange(0, 100);
+        // 反转Y轴,使100在顶部,0在底部
+        passingAxis.setInverted(true);
+        passingAxis.setTickUnit(new NumberTickUnit(10));
+        passingAxis.setLabelFont(chineseFont);
+        passingAxis.setTickLabelFont(chineseFont);
+        // 在轴线内侧添加标签
+        passingAxis.setLabel("通过率百分比(%)");
+        passingAxis.setLabelInsets(new RectangleInsets(0, 0, 0, 0));
+
+        // 设置X轴
+        CategoryAxis domainAxis = plot.getDomainAxis();
+        domainAxis.setLabelFont(chineseFont);
+        domainAxis.setTickLabelFont(chineseFont);
+
+        // 将右侧Y轴添加到图表
+        plot.setRangeAxis(1, passingAxis);
+
+        plot.setAxisOffset(new RectangleInsets(0,0,0,0));
+
+        // 添加通过率数据集
+        plot.setDataset(1, passingDataset);
+        // 将第二个数据集映射到第二个Y轴
+        plot.mapDatasetToRangeAxis(1, 1);
+
+        // 添加第二种数据范围数据集
+        plot.setDataset(2, secondDataLowerDataset);
+        plot.setDataset(3, secondDataUpperDataset);
+        // 映射到左侧Y轴
+        plot.mapDatasetToRangeAxis(2, 0);
+        // 映射到左侧Y轴
+        plot.mapDatasetToRangeAxis(3, 0);
+
+        // 设置渲染器 - 累计筛余率(实线,不显示数据点)
+        LineAndShapeRenderer retainedRenderer = (LineAndShapeRenderer) plot.getRenderer();
+        // 不显示数据点
+        retainedRenderer.setDefaultShapesVisible(false);
+        retainedRenderer.setSeriesPaint(0, Color.BLACK);
+        // 设置渲染器 - 通过率(实线,不显示数据点)
+        LineAndShapeRenderer passingRenderer = new LineAndShapeRenderer();
+        // 不显示数据点
+        passingRenderer.setDefaultShapesVisible(false);
+        passingRenderer.setSeriesPaint(0, Color.BLACK);
+        plot.setRenderer(1, passingRenderer);
+
+        // 设置渲染器 - 第二种数据范围(虚线,不显示数据点)
+        LineAndShapeRenderer secondLowerRenderer = new LineAndShapeRenderer();
+        // 不显示数据点
+        secondLowerRenderer.setDefaultShapesVisible(false);
+
+        // 设置虚线样式
+        secondLowerRenderer.setSeriesStroke(0, new BasicStroke(
+                1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
+                1.0f, new float[] {6.0f, 6.0f}, 0.0f
+        ));
+        // 设置颜色
+        secondLowerRenderer.setSeriesPaint(0, Color.BLACK);
+
+        LineAndShapeRenderer secondUpperRenderer = new LineAndShapeRenderer();
+        // 不显示数据点
+        secondUpperRenderer.setDefaultShapesVisible(false);
+        // 设置虚线样式
+        secondUpperRenderer.setSeriesStroke(0, new BasicStroke(
+                1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
+                1.0f, new float[] {6.0f, 6.0f}, 0.0f
+        ));
+        // 设置颜色
+        secondUpperRenderer.setSeriesPaint(0, Color.BLACK);
+
+        // 设置渲染器
+        plot.setRenderer(2, secondLowerRenderer);
+        plot.setRenderer(3, secondUpperRenderer);
+
+        // 设置数据集渲染顺序,确保所有线都可见
+        plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
+
+        // 设置背景网格线为实线
+        plot.setDomainGridlineStroke(new BasicStroke(1.0f));
+        plot.setRangeGridlineStroke(new BasicStroke(1.0f));
+        plot.setDomainGridlinePaint(Color.LIGHT_GRAY);
+        plot.setRangeGridlinePaint(Color.LIGHT_GRAY);
+        // 确保网格线可见
+        plot.setDomainGridlinesVisible(true);
+        plot.setRangeGridlinesVisible(true);
+
+        // 设置背景颜色为白色
+        plot.setBackgroundPaint(Color.WHITE);
+
+        // 保存为图片文件
+        ChartUtils.saveChartAsPNG(new File(filename), chart, width, height);
+    }
+    public static final String FC_REG = "T\\(com.mixsmart.utils.CustomFunction\\)\\.";
+    /**
+     * 使用示例
+     */
+    public static void main11(String[] args) {
+        try {
+            // 示例数据格式: {{筛孔尺寸, 通过率, 累计筛余率, 第二种数据下限, 第二种数据上限}, ...}
+            double[][] data = {
+                    {4.75, 5.0, 85.0, 0.0, 10.0},
+                    {2.36, 25.0, 55.0, 0.0, 35.0}
+            };
+
+            // 创建图表生成器
+            SieveAnalysisChart generator = new SieveAnalysisChart(data);
+
+            // 生成图表并保存为图片
+            generator.generateChart("sieve_analysis_chart.png", 800, 400);
+            System.out.println("图表已保存为 sieve_analysis_chart.png");
+        } catch (IOException e) {
+            System.err.println("保存图表时出错: " + e.getMessage());
+        }
+    }
+}