一、JFreeChart
第三方jar包,开源、免费(开发指南收费)。提供了饼状图、柱状图、折线图、散点图、甘特图和刻度盘等等。
maven依赖
<dependencies>
<dependency>
<groupId>jfree</groupId>
<artifactId>jcommon</artifactId>
<version>1.0.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jfree/jfreechart -->
<dependency>
<groupId>jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.13</version>
</dependency>
</dependencies>
二、实验
1)饼状图
package jfreechart.piechart;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PiePlot;
import org.jfree.data.DefaultKeyedValues;
import org.jfree.data.KeyedValues;
import org.jfree.data.general.DefaultPieDataset;
import javax.swing.*;
import java.awt.*;
public class PieChart2DTest extends JFrame {
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public PieChart2DTest() {
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
setContentPane(createPane());
}
/**
* 1.画图
* 2.填数据
* 3.放入panel显示
* @return
*/
private Container createPane() {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
DefaultKeyedValues keyedValues = new DefaultKeyedValues();
keyedValues.addValue("足球概念", 20.9);
keyedValues.addValue("基建", 40.1);
keyedValues.addValue("国产软件", 39.0);
DefaultPieDataset data = new DefaultPieDataset(keyedValues);
PiePlot plot = new PiePlot(data);
JFreeChart chart = new JFreeChart(plot);
panel.add(new ChartPanel(chart));
return panel;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
PieChart2DTest frame = new PieChart2DTest();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
设置标题
3D效果
2)柱状图
package jfreechart.barchart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.ApplicationFrame;
import java.awt.*;
public class BarChartDemo1 extends ApplicationFrame {
public BarChartDemo1(String title) {
super(title);
CategoryDataset dataset = createDataset();
JFreeChart chart = createChart(dataset);
ChartPanel chartPanel = new ChartPanel(chart, false);
chartPanel.setFillZoomRectangle(true);
chartPanel.setMouseWheelEnabled(true);
chartPanel.setPreferredSize(new Dimension(500, 270));
setContentPane(chartPanel);
}
/**
* Returns a sample dataset.
*
* @return The dataset.
*/
private static CategoryDataset createDataset() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(10000, "足球概念", "足球概念1");
dataset.addValue(40000, "基建", "基建1");
dataset.addValue(39999, "国产软件", "国产软件1");
return dataset;
}
/**
* Creates a sample chart.
*
* @param dataset the dataset.
* @return The chart.
*/
private static JFreeChart createChart(CategoryDataset dataset) {
//创建主题样式,避免中文乱码
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("投资总揽", "股票类型" /* x-axis label*/,
"投资金额" /* y-axis label */, dataset, PlotOrientation.VERTICAL, true, true, false);
chart.setBackgroundPaint(Color.WHITE);
chart.getLegend().setFrame(BlockBorder.NONE);
return chart;
}
public static void main(String[] args) {
BarChartDemo1 demo = new BarChartDemo1("JFreeChart: BarChartDemo1.java");
demo.pack();
demo.setLocationRelativeTo(null);// 居中显示
demo.setVisible(true);
}
}
分组柱状图
private static CategoryDataset createDataset() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(10000, "足球概念", "张三");
dataset.addValue(40000, "基建", "张三");
dataset.addValue(39999, "国产软件", "张三");
dataset.addValue(1000, "足球概念", "李四");
dataset.addValue(4000, "基建", "李四");
dataset.addValue(3999, "国产软件", "李四");
return dataset;
}
3D效果
JFreeChart chart = ChartFactory.createBarChart3D("投资总揽", "股票类型" /* x-axis label*/,
"投资金额" /* y-axis label */, dataset, PlotOrientation.VERTICAL, true, true, false);
3)时间折线图
package jfreechart.timserieschart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.time.Month;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;
import java.awt.*;
public class TimeSeriesChartDemo1 extends ApplicationFrame {
public TimeSeriesChartDemo1(String title) {
super(title);
XYDataset dataset = createDataset();
JFreeChart chart = createChart(dataset);
ChartPanel chartPanel = new ChartPanel(chart, false);
chartPanel.setFillZoomRectangle(true);
chartPanel.setMouseWheelEnabled(true);
chartPanel.setPreferredSize(new Dimension(500, 270));
setContentPane(chartPanel);
}
/**
* Returns a sample dataset.
*
* @return The dataset.
*/
private static XYDataset createDataset() {
TimeSeries s1 = new TimeSeries("张三");
s1.add(new Month(2, 2001), 181.8);
s1.add(new Month(3, 2001), 167.3);
s1.add(new Month(4, 2001), 153.8);
s1.add(new Month(5, 2001), 167.6);
s1.add(new Month(6, 2001), 158.8);
s1.add(new Month(7, 2001), 148.3);
s1.add(new Month(8, 2001), 153.9);
s1.add(new Month(9, 2001), 142.7);
s1.add(new Month(10, 2001), 123.2);
s1.add(new Month(11, 2001), 131.8);
s1.add(new Month(12, 2001), 139.6);
s1.add(new Month(1, 2002), 142.9);
s1.add(new Month(2, 2002), 138.7);
s1.add(new Month(3, 2002), 137.3);
s1.add(new Month(4, 2002), 143.9);
s1.add(new Month(5, 2002), 139.8);
s1.add(new Month(6, 2002), 137.0);
s1.add(new Month(7, 2002), 132.8);
TimeSeries s2 = new TimeSeries("李四");
s2.add(new Month(2, 2001), 129.6);
s2.add(new Month(3, 2001), 123.2);
s2.add(new Month(4, 2001), 117.2);
s2.add(new Month(5, 2001), 124.1);
s2.add(new Month(6, 2001), 122.6);
s2.add(new Month(7, 2001), 119.2);
s2.add(new Month(8, 2001), 116.5);
s2.add(new Month(9, 2001), 112.7);
s2.add(new Month(10, 2001), 101.5);
s2.add(new Month(11, 2001), 106.1);
s2.add(new Month(12, 2001), 110.3);
s2.add(new Month(1, 2002), 111.7);
s2.add(new Month(2, 2002), 111.0);
s2.add(new Month(3, 2002), 109.6);
s2.add(new Month(4, 2002), 113.2);
s2.add(new Month(5, 2002), 111.6);
s2.add(new Month(6, 2002), 108.8);
s2.add(new Month(7, 2002), 101.6);
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(s1);
dataset.addSeries(s2);
return dataset;
}
/**
* Creates a sample chart.
*
* @param dataset the dataset.
* @return The chart.
*/
private static JFreeChart createChart(XYDataset dataset) {
//创建主题样式,避免中文乱码
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);
String title = "投资情况调查";
String timeAxisLabel = "月份";
String valueAxisLabel = "投资金额(单位:万元)";
JFreeChart chart = ChartFactory.createTimeSeriesChart(title, timeAxisLabel, valueAxisLabel, dataset, true,
true, true);
chart.setBackgroundPaint(Color.WHITE);
chart.getLegend().setFrame(BlockBorder.NONE);
return chart;
}
public static void main(String[] args) {
TimeSeriesChartDemo1 demo = new TimeSeriesChartDemo1("JFreeChart: TimeSeriesChartDemo1.java");
demo.pack();
demo.setLocationRelativeTo(null);// 居中显示
demo.setVisible(true);
}
}
4)XYLine折线图
package jfreechart.timserieschart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.time.Month;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.DefaultXYDataset;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;
import java.awt.*;
public class TimeSeriesChartDemo2 extends ApplicationFrame {
public TimeSeriesChartDemo2(String title) {
super(title);
XYDataset dataset = createDataset();
JFreeChart chart = createChart(dataset);
ChartPanel chartPanel = new ChartPanel(chart, false);
chartPanel.setFillZoomRectangle(true);
chartPanel.setMouseWheelEnabled(true);
chartPanel.setPreferredSize(new Dimension(500, 270));
setContentPane(chartPanel);
}
/**
* Returns a sample dataset.
*
* @return The dataset.
*/
private static XYDataset createDataset() {
double[][] series1 = {{1, 2, 3}, {10, 22, 18}};
double[][] series2 = {{1, 2, 3}, {50, 10, 20}};
DefaultXYDataset xyDataset = new DefaultXYDataset();
xyDataset.addSeries("张三", series1);
xyDataset.addSeries("李四", series2);
return xyDataset;
}
/**
* Creates a sample chart.
*
* @param dataset the dataset.
* @return The chart.
*/
private static JFreeChart createChart(XYDataset dataset) {
//创建主题样式,避免中文乱码
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);
String title = "投资情况调查";
String xAxisLabel = "月份";
String yAxisLabel = "投资金额(单位:万元)";
JFreeChart chart = ChartFactory.createXYLineChart(title, xAxisLabel, yAxisLabel, dataset,
PlotOrientation.VERTICAL,true,
true, true);
chart.setBackgroundPaint(Color.WHITE);
chart.getLegend().setFrame(BlockBorder.NONE);
return chart;
}
public static void main(String[] args) {
TimeSeriesChartDemo2 demo = new TimeSeriesChartDemo2("JFreeChart: TimeSeriesChartDemo1.java");
demo.pack();
demo.setLocationRelativeTo(null);// 居中显示
demo.setVisible(true);
}
}
5)仪表盘DialPlot
package jfreechart.dialplot;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Point;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.dial.DialBackground;
import org.jfree.chart.plot.dial.DialCap;
import org.jfree.chart.plot.dial.DialFrame;
import org.jfree.chart.plot.dial.DialPlot;
import org.jfree.chart.plot.dial.DialTextAnnotation;
import org.jfree.chart.plot.dial.DialValueIndicator;
import org.jfree.chart.plot.dial.StandardDialFrame;
import org.jfree.chart.plot.dial.StandardDialRange;
import org.jfree.chart.plot.dial.StandardDialScale;
import org.jfree.chart.plot.dial.DialPointer.Pointer;
import org.jfree.data.general.DefaultValueDataset;
import org.jfree.ui.GradientPaintTransformType;
import org.jfree.ui.RefineryUtilities;
import org.jfree.ui.StandardGradientPaintTransformer;
/**
* 仪表盘制作
* @author Administrator
*
*/
public class DialPlotDemo {
public static void main(String[] args){
//1,数据集合对象 此处为DefaultValueDataset
DefaultValueDataset dataset = new DefaultValueDataset();
// 当前指针指向的位置,即:我们需要显示的数据
dataset.setValue(10D);
/**
* 获取图表区域对象
*
* A. setDataSet(int index, DataSet dataSet);
* 为表盘设定使用的数据集,通常一个表盘上可能存在多个指针,
* 因此需要制定该数据集与哪个指针相互关联。
* 可以将指针想象成数据集的一种体现方式。
*/
DialPlot dialplot = new DialPlot();
dialplot.setView(0.0D, 0.0D, 1.0D, 1.0D);
dialplot.setDataset(0,dataset);
/**
* 开始设置显示框架结构
* B. setDailFrame(DailFrame dailFrame);设置表盘的底层面板图像,通常表盘是整个仪表的最底层。
*/
DialFrame dialframe =new StandardDialFrame();
dialplot.setDialFrame(dialframe);
/**
* 结束设置显示框架结构
* C. setBackground(Color color);设置表盘的颜色,可以采用Java内置的颜色控制方式来调用该方法。
*/
GradientPaint gradientpaint = new GradientPaint(new Point(), new Color(255, 255, 255), new Point(), new Color(170, 170, 220));
DialBackground dialbackground = new DialBackground(gradientpaint);
dialbackground.setGradientPaintTransformer(new StandardGradientPaintTransformer(GradientPaintTransformType.VERTICAL));
dialplot.setBackground(dialbackground);
// 设置显示在表盘中央位置的信息
DialTextAnnotation dialtextannotation = new DialTextAnnotation("温度");
dialtextannotation.setFont(new Font("Dialog", 1, 14));
dialtextannotation.setRadius(0.69999999999999996D);
dialplot.addLayer(dialtextannotation);
DialValueIndicator dialvalueindicator = new DialValueIndicator(0);
dialplot.addLayer(dialvalueindicator);
// 根据表盘的直径大小(0.75),设置总刻度范围
/**
* E. addScale(int index, DailScale dailScale);
* 用于设定表盘上的量程,index指明该量程属于哪一个指针所指向的数据集,
* DailScale指明该量程的样式,如量程的基本单位等信息。
*
* StandardDialScale(double lowerBound, double upperBound, double startAngle,
* double extent, double majorTickIncrement, int minorTickCount)
* new StandardDialScale(-40D, 60D, -120D, -300D,30D);
*/
//
StandardDialScale standarddialscale =new StandardDialScale();
standarddialscale.setLowerBound(-40D);
standarddialscale.setUpperBound(60D);
standarddialscale.setStartAngle(-120D);
standarddialscale.setExtent(-300D);
standarddialscale.setTickRadius(0.88D);
standarddialscale.setTickLabelOffset(0.14999999999999999D);
standarddialscale.setTickLabelFont(new Font("Dialog", 0, 14));
dialplot.addScale(0, standarddialscale);
/**
* F. addLayer(DailRange dailRange);
* 用于设定某一特定量程的特殊表现,通常位于量程之下,如红色范围标注,绿色范围标注等。
* 在调用该方法之前需要设定DailRange的一些信息,包括位置信息,颜色信息等等。
*/
//设置刻度范围(红色)
StandardDialRange standarddialrange = new StandardDialRange(40D, 60D, Color.red);
standarddialrange.setInnerRadius(0.52000000000000002D);
standarddialrange.setOuterRadius(0.55000000000000004D);
dialplot.addLayer(standarddialrange);
//设置刻度范围(橘黄色)
StandardDialRange standarddialrange1 = new StandardDialRange(10D, 40D, Color.orange);
standarddialrange1.setInnerRadius(0.52000000000000002D);
standarddialrange1.setOuterRadius(0.55000000000000004D);
dialplot.addLayer(standarddialrange1);
//设置刻度范围(绿色)
StandardDialRange standarddialrange2 = new StandardDialRange(-40D, 10D, Color.green);
standarddialrange2.setInnerRadius(0.52000000000000002D);
standarddialrange2.setOuterRadius(0.55000000000000004D);
dialplot.addLayer(standarddialrange2);
/**
* 设置指针
* G. addPointer(DailPointer dailPointer);
* 用于设定表盘使用的指针样式,JFreeChart中有很多可供选择指针样式,
* 用户可以根据使用需要,采用不同的DailPoint的实现类来调用该方法
*/
Pointer pointer = new Pointer(); //内部内
dialplot.addPointer(pointer); //addLayer(pointer);
/**
* 实例化DialCap
* H. setCap(DailCap dailCap);设定指针上面的盖帽的样式。
*/
DialCap dialcap = new DialCap();
dialcap.setRadius(0.10000000000000001D);
dialplot.setCap(dialcap);
//生成chart对象
JFreeChart jfreechart = new JFreeChart(dialplot);
//设置标题
jfreechart.setTitle("设备取水温度采样");
ChartFrame frame = new ChartFrame("CityInfoPort公司组织架构图 ", jfreechart,true);
frame.pack();
//屏幕居中
RefineryUtilities.centerFrameOnScreen(frame);
frame.setVisible(true);
}
}
三、小记
慢慢探索、深入,争取写出点有意义的东西。ChartFactory提供了一些常见的创建图表的工厂方法,但是没有创建仪表盘DialPlot,需要new。仪表盘复杂些,其他的还好,设置数据,创建图表,显示就完事了。仪表盘代码借用JfreeChart实现仪表盘
四、引用、参考
[1]demo https://github.com/jfree/jfree-demos
[2]JFreeChart官网http://www.jfree.org/index.html
[3]JFreeChart源码https://github.com/jfree/jfreechart
[4]在线APIhttp://www.jfree.org/jfreechart/api/javadoc/index.html
[5]https://www.cnblogs.com/xingyun/archive/2012/02/05/2339237.html
[6]仪表盘https://blog.youkuaiyun.com/zdj342472776/article/details/7172773