From cc2a28ad6b99795d05cd9c923d8f7da27b4509e3 Mon Sep 17 00:00:00 2001 From: feiyu02 <risaku@163.com> Date: 星期三, 04 六月 2025 17:31:41 +0800 Subject: [PATCH] 1. 新增动态污染溯源新的判定逻辑(待完成) --- src/main/kotlin/com/flightfeather/uav/common/chart/ChartUtil.kt | 153 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 143 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/com/flightfeather/uav/common/chart/ChartUtil.kt b/src/main/kotlin/com/flightfeather/uav/common/chart/ChartUtil.kt index 4c30e1d..d448cb2 100644 --- a/src/main/kotlin/com/flightfeather/uav/common/chart/ChartUtil.kt +++ b/src/main/kotlin/com/flightfeather/uav/common/chart/ChartUtil.kt @@ -3,10 +3,21 @@ import org.jfree.chart.ChartFactory import org.jfree.chart.ChartUtils import org.jfree.chart.JFreeChart -import org.jfree.chart.title.TextTitle +import org.jfree.chart.axis.NumberAxis +import org.jfree.chart.axis.NumberTickUnit +import org.jfree.chart.labels.StandardCategorySeriesLabelGenerator +import org.jfree.chart.plot.CategoryPlot +import org.jfree.chart.plot.PlotOrientation +import org.jfree.chart.renderer.category.LineAndShapeRenderer import org.jfree.data.category.DefaultCategoryDataset +import java.awt.BasicStroke +import java.awt.Color import java.awt.Font +import java.awt.Paint import java.io.ByteArrayOutputStream +import java.text.DecimalFormat +import kotlin.math.max +import kotlin.math.min /** * 鍥捐〃鐢熸垚 @@ -15,30 +26,152 @@ */ object ChartUtil { - data class ChartValue(val x: String?, val y: Number) + private const val FONT_NAME = "SimHei" + private val defaultColors = listOf( + Color(191, 0, 0), + Color(181, 125, 69), + Color(236, 204, 6), + Color(84, 151, 57), + Color(13, 221, 151), + Color(57, 75, 151), + Color(115, 51, 206), + ) - fun line(title: String, dataset: DefaultCategoryDataset): JFreeChart { - val line = ChartFactory.createLineChart(title, "鏃堕棿", "娴撳害", dataset) - line.categoryPlot.domainAxis.labelFont = Font("瀹嬩綋", Font.PLAIN, 12) - line.categoryPlot.rangeAxis.labelFont = Font("瀹嬩綋", Font.PLAIN, 12) + // 鍥捐〃鏁版嵁鍊煎潗鏍� + data class ChartValue(val x: String?, val y: Double) + // 鍥捐〃鏁版嵁闆� + data class ChartDataset(val dataset: DefaultCategoryDataset, val minValue: Double, val maxValue: Double) + + /** + * 鍒涘缓鎶樼嚎鍥� + */ + fun line(title: String, chartDatasetList: List<ChartDataset>): JFreeChart? { + if (chartDatasetList.isEmpty()) return null + + val line = ChartFactory.createLineChart( + title, "鏃堕棿", "娴撳害(渭g/m3)", + null, PlotOrientation.VERTICAL, true, false, false + ) +// val line = ChartFactory.createLineChart( +// title, "", "娴撳害(渭g/m鲁)", +// null, PlotOrientation.VERTICAL, true, false, false +// ) + var minValue = chartDatasetList[0].minValue + var maxValue = chartDatasetList[0].maxValue + val datasetList = mutableListOf<DefaultCategoryDataset>() + chartDatasetList.forEach { + minValue = min(minValue, it.minValue) + maxValue = max(maxValue, it.maxValue) + datasetList.add(it.dataset) + } + val plot = line.categoryPlot + setLine(line) + setRenderer(plot, datasetList) + setX(plot) + setY(plot, "娴撳害(渭g/m3)", minValue, maxValue) return line } - fun lineToByteArray(title: String, dataset: DefaultCategoryDataset):ByteArray { + /** + * 鏂板缓鎶樼嚎鍥惧苟杞崲涓篵yte鏁扮粍 + */ + fun lineToByteArray(title: String, dataset: List<ChartDataset>): ByteArray { val chart = line(title, dataset) val output = ByteArrayOutputStream() - ChartUtils.writeChartAsPNG(output, chart, 600, 400) + ChartUtils.writeChartAsJPEG(output, chart, 1080, 607) val byteArray = output.toByteArray() output.flush() output.close() return byteArray } - fun newDataset(dataList:List<ChartValue>, seriesName:String): DefaultCategoryDataset { + /** + * 鏂板缓鍥捐〃鏁版嵁闆� + */ + fun newDataset(dataList: List<ChartValue>, seriesName: String): ChartDataset? { + if (dataList.isEmpty()) return null val dataset = DefaultCategoryDataset() + var minValue = dataList[0].y + var maxValue = minValue dataList.forEach { dataset.setValue(it.y, seriesName, it.x) + minValue = min(minValue, it.y) + maxValue = max(maxValue, it.y) } - return dataset + return ChartDataset(dataset, minValue, maxValue) + } + + /** + * 璁剧疆鎶樼嚎鍥炬牱寮� + */ + private fun setLine(chart: JFreeChart) { + chart.legend.itemFont = Font(FONT_NAME, Font.PLAIN, 16) + chart.title.font = Font(FONT_NAME, Font.BOLD, 20) + chart.categoryPlot.apply { + backgroundPaint = Color(255, 255, 255) + rangeGridlinePaint = Color(200, 200, 200) + rangeGridlineStroke = BasicStroke(1f) + isRangeGridlinesVisible = true + } + } + + private fun setRenderer(plot: CategoryPlot, datasetList: List<DefaultCategoryDataset>) { + datasetList.forEachIndexed { index, v -> + val renderer = newBasicRenderer(paint = defaultColors[index % defaultColors.size]) + plot.setDataset(index, v) + plot.setRenderer(index, renderer) + } + + } + + private fun setX(plot: CategoryPlot) { + plot.domainAxis.apply { + // 璁剧疆x杞存瘡涓埢搴︾殑瀛椾綋 + tickLabelFont = Font(FONT_NAME, Font.BOLD, 16) + // 璁剧疆x杞存爣绛剧殑瀛椾綋 + labelFont = Font(FONT_NAME, Font.BOLD, 20) + // 璁剧疆x杞磋酱绾挎槸鍚︽樉绀� + isAxisLineVisible = false + // 璁剧疆x杞村埢搴︽槸鍚︽樉绀� + isTickMarksVisible = false + + upperMargin = .0 + lowerMargin = .0 + } + } + + private fun setY(plot: CategoryPlot, label:String, minValue: Double, maxValue: Double) { + val tickUnit = (maxValue - minValue) / 10 + val axis1 = NumberAxis().apply { + this.label = label + // 鍒诲害灞曠ず鏍煎紡鍖� + numberFormatOverride = DecimalFormat("0.0") + if (tickUnit != .0) { + // 鍙栨秷鑷姩鍒嗛厤闂磋窛 + isAutoTickUnitSelection = false + // 璁剧疆闂撮殧璺濈 + setTickUnit(NumberTickUnit(tickUnit)) + // 璁剧疆鏄剧ず鑼冨洿 + setRange(minValue, maxValue) + } + // 璁剧疆y杞存瘡涓埢搴︾殑瀛椾綋 + tickLabelFont = Font(FONT_NAME, Font.BOLD, 16) + // 璁剧疆y杞存爣绛剧殑瀛椾綋 + labelFont = Font(FONT_NAME, Font.BOLD, 20) + // 璁剧疆y杞磋酱绾夸笉鏄剧ず + isAxisLineVisible = false + // 璁剧疆y杞村埢搴︿笉鏄剧ず + isTickMarksVisible = false + } + plot.rangeAxis = axis1 + } + + private fun newBasicRenderer(series: Int = 0, paint: Paint): LineAndShapeRenderer { + return LineAndShapeRenderer().apply { + legendItemLabelGenerator = StandardCategorySeriesLabelGenerator() + setSeriesStroke(series, BasicStroke(3f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 2000f)) + setSeriesShapesVisible(series, false) + setSeriesPaint(series, paint) + } } } \ No newline at end of file -- Gitblit v1.9.3