Java绘图——体温折线图
如下图 要实现该体温折线图,原本打算使用Jfreechart实现,苦苦研究几天后没有结果,发现Jfreechart貌似不能实现此复杂的功能,因为我们要实现的列头是两个,而且有重复的columnKey,两点间差值大于1.5用"√"号标记。。。既然没有找到合适的方法实现,于是只好自己编写Graphics类手工绘制,功能基本上满足要求,就是字体、线条、外观感觉还是差了点,大家有什么好的建议还望不吝提出O(∩_∩)O~
实现过程
Ø使用BufferedImage创建Graphics2D对象,然后生成6*7的列(column),7*5的行(row)
/** * column line */ // 时间 int[] times = new int[] { 3, 7, 11 }; int loopTimes = 0; for (int i = 0; i <= CELL_COUNT; i++, loopTimes++) { if (i != CELL_COUNT) { // 列头显示时间 if (loopTimes == 3) loopTimes = 0; graphics.setColor(Color.BLACK); graphics.drawString(times[loopTimes] + "", (int) (MARGIN_LEFT + cellWidth * i + 2.5), cellHeight + 13); } // 每隔一天用分隔符分割 if (0 == i % 6) { graphics.setStroke(separator); graphics.setColor(new Color(162, 115, 73)); graphics.drawLine(MARGIN_LEFT + cellWidth * i, 0, MARGIN_LEFT + cellWidth * i, height); } else { graphics.setStroke(basicStroke); graphics.setColor(new Color(221, 221, 221)); graphics.drawLine(MARGIN_LEFT + cellWidth * i, cellHeight, MARGIN_LEFT + cellWidth * i, height); } } /* * row line */ int temp = TEMPERATURE; graphics.setStroke(basicStroke); for (int i = 1; i <= 40; i++) { // 每隔1°使用分隔符分割 if (0 == i % 5) { // 温度刻度 graphics.setColor(Color.BLACK); graphics.drawString(--temp + "", MARGIN_LEFT - cellWidth, cellHeight * i + 5); if (37 == temp) graphics.setColor(Color.RED); else graphics.setColor(new Color(180, 180, 180));// 分割线 } else graphics.setColor(new Color(201, 221, 221)); // 第二行的线为标题,和表格等宽 if (2 == i) graphics.draw(new Line2D.Float(0, cellHeight * i, MARGIN_LEFT + cellWidth * CELL_COUNT, cellHeight * i)); else graphics.draw(new Line2D.Float(MARGIN_LEFT, cellHeight * i, MARGIN_LEFT + cellWidth * CELL_COUNT, cellHeight * i)); }
Ø创建数据折线
Set<Entry<String, Float[]>> set = map.entrySet(); Iterator<Entry<String, Float[]>> iterator = set.iterator(); int index = 0; graphics.setColor(Color.BLACK); float cellHalfWidth = cellWidth / 2f; // 体温折线开始的位置 Float startY = null, startX = null; float preTemp = 0; // 上一次记录的提问数据 while (iterator.hasNext()) { Entry<String, Float[]> entry = iterator.next(); // 填充时间 graphics.setFont(new Font("宋体", Font.PLAIN, 13)); graphics.drawString(entry.getKey(), (int) (MARGIN_LEFT + cellWidth * (index + 1.1)), 12); // 折线 Float[] values = entry.getValue(); for (int i = 0; i < values.length; i++) { Float currTemp = values[i]; Float endX = MARGIN_LEFT + cellWidth * index + cellHalfWidth; if (null != currTemp) { //降温度值转换为坐标点 Float endY = (TEMPERATURE - currTemp) * (cellHeight * 5); graphics.setColor(Color.BLACK); graphics.fillOval((int) (endX - 2), (int) (float) endY - 2, 5, 5); if (null != startY) { Line2D.Float line = new Line2D.Float(startX, startY, endX, endY); graphics.draw(line); // 两次测量值相差1.5以上,则用"√"标记 if (Math.abs(preTemp - currTemp) >= 1.5) { graphics.setColor(Color.RED); graphics.setFont(new Font("宋体", Font.PLAIN, 30)); graphics.drawString("√", endX - 15, endY - 15); } } startY = endY; startX = endX; preTemp = currTemp; } index++; } }
posted on 2012-12-11 15:59 DreamSea530 阅读(5633) 评论(3) 编辑 收藏 举报
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 为DeepSeek添加本地知识库
· 精选4款基于.NET开源、功能强大的通讯调试工具
· DeepSeek智能编程
· 大模型工具KTransformer的安装
· [计算机/硬件/GPU] 显卡