动态曲线 直观显示数据

数字职场

本期知识:动态曲线绘制

知识运用:各种数据统计软件

本期题目:股票市场、期货市场的曲线图,可以帮助投资者快速地了解价格的变化趋势。你能编程实现吗?

在实际生活中,经常需要统计一组数据的动态变化,例如股票市场、期货市场的K线图,当天温度的变化等,直接显示数据不直观,所以大家想到了用曲线来表示数据的变化,这样既直观也可以很方便地研判数据的变化趋势。

这种方法的原理很简单,就是通过采集一系列数据点(包含时间和具体的数值,例如股价数据等),然后按照一定的规则将这些数据进行处理和变换,变为坐标点数据,最后将坐标点数据依次使用直线连接起来即可。整个过程,重点的步骤有两个:

1.数据处理

数据处理是曲线显示的逻辑实现部分,根据x轴刻度单位、y轴的刻度单位、显示数据的范围,计算出每个数据点的坐标。

2.曲线绘制

在数据处理完成以后,获得的就是一组数据点的坐标,只需要依次将数据点按照顺序,由直线连接起来即可。

曲线绘制代码

假设连续十天的上证指数为{2600,2630,2650,2620,2600,2690,2710,

2650,2610,2664},那么将这十日的数据以曲线图的形式显示在绘图区域为240×160的区域内。关键代码如下所示(完整代码下载地址:http://www.icpcw.com/bzsoft):

private int data = {2600,2630,2650,

2620,2600,2690,2710,2650,2610,2664};

private int convertData(int data){

int num = data.length;

int pointer = new int[num];

//计算x和y的刻度

int dx = 240 / (num - 1);

int dy = 160 / 11; //11个间隔

int sepY = (max - min) / 10; //y的间隔

//计算坐标点

for(int i = 0;i < num;i++){

pointer[i] = i * dx;

pointer[i] = 160 - (data[i] - min) / sepY * dy;

System.out.println(pointer[i] + "," + pointer[i]);

//在计算y坐标时,对于屏幕的坐标单位dy采用11个间隔,而对于数值刻度sepY采用10个间隔,主要是考虑到数据不能整除时,不至于将点绘制到绘图区域以外

//连接坐标点

g.setColor(0xffffff);

for(int i = 0;i < p.length - 1;i++){

g.drawLine(p[i], p[i], p[i + 1], p[i + 1]);

优化代码

上面的代码比较复杂,需要进行优化,优化的思路是将代码中的硬编码部分转换为动态实现,关键代码如下所示(完整代码下载地址:http://www.icpcw.com/bzsoft):

private int data = {2600,2630,2650,

2620,2600,2690,2710,2650,2610,2664};

private int areaWidth = 240;

private int areaHeight = 160;

private int sepNum = 11; //间隔数量

private int convertData(int data){

int num = data.length;

int pointer = new int[num];

//计算x和y的刻度

int dx = areaWidth / (num - 1);

int dy = areaHeight / sepNum;

int sepY = (max - min) / (sepNum - 1); //y的间隔

实际应用

数据以曲线的形式显示,使人对于数据的认识更直观,更符合人的认知观念,使得软件更符合用户的使用习惯,所以在实际软件开发、动态曲线绘制时被常常用到。在股票软件、温度显示、计算机系统中的CPU利用率显示中,都在使用曲线显示数据,而且为了显示更加复杂的数据,还不仅仅使用曲线,还会通过柱状图、饼状图甚至更复杂的图形来显示数据。

露一手

上期的题目,很多编程爱好者踊跃参与,其中来自河北的李国垒,表现非常耀眼,他的程序考虑周到、高效实用,关键代码如下所示。我们将给予河北的李国垒现金奖励。

int waitTime = 5; //假设一辆车需要等待5秒钟

int time = (new Random().nextInt(10) + 1)* waitTime;

boolean direction = false;//false代表南北向绿灯,true代表东西向绿灯

while (true){

if(direction){

System.out.println("东西向绿灯剩余"+time+"秒,南北向绿灯剩余"+time);

}else{

System.out.println("南北向绿灯剩余"+time+"秒");

}

//延时1秒

try{

Thread.sleep(100); ■