使用highcharts动态绘制折线图——so easy


之前学习highcharts发现网上的教程大部分是对highcharts数据的注释,如何动态绘制数据大部分一笔带过,让那些初涉开发的小白云里雾里,所以我就写了一篇这样的博客。

<html>

    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                <title>测试</title>
        <script type="text/javascript" src="http://cdn.hcharts.cn/jquery/jquery-1.8.2.min.js"></script>
        <script src="js/highcharts.js"></script>
        <script src="js/exporting.js"></script>
        <script>
            var chart; 
$(function() { 
     var url="test.php";// 后台路径
                var std=document.getElementById('std').value;
                var end=document.getElementById('end').value;
                var day="";
                var beij="";
                var  guangz="";
                $.ajax({
              type: "POST",
              url: url,
             async:false,// 异步发送数据,默认是true,如果不加可能会出错
              data: {"std":std,"end":end},
              success: function(data){
                                var dat=JSON.parse(data);
                                day=dat.day;
                                beij=dat.beij;
                                guangz=dat.guangz;
                               
              }
          });
    $('#container').highcharts({ 
        chart: { 
            renderTo: 'chart_line', //图表放置的容器,DIV 
            defaultSeriesType: 'line', //图表类型line(折线图), 
            zoomType: 'x'   //x轴方向可以缩放 
        }, 
        credits: { 
            enabled: false   //右下角不显示LOGO 
        }, 
        title: { 
            text: '主要城市月平均气温' //图表标题 
        }, 
        subtitle: { 
            text: '2011年'  //副标题 
        }, 
        xAxis: {  //x轴 
            categories: day, //x轴标签名称 
            gridLineWidth: 1, //设置网格宽度为1 
            lineWidth: 2,  //基线宽度 
            labels:{y:26}  //x轴标签位置:距X轴下方26像素 
        }, 
        yAxis: {  //y轴 
            title: {text: '平均气温(°C)'}, //标题 
            lineWidth: 2 //基线宽度 
        }, 
        plotOptions:{ //设置数据点 
            line:{ 
                dataLabels:{ 
                    enabled:true  //在数据点上显示对应的数据值 
                }, 
                enableMouseTracking: false //取消鼠标滑向触发提示框 
            } 
        }, 
        legend: {  //图例 
            layout: 'horizontal',  //图例显示的样式:水平(horizontal)/垂直(vertical) 
            backgroundColor: '#ffc', //图例背景色 
            align: 'left',  //图例水平对齐方式 
            verticalAlign: 'top',  //图例垂直对齐方式 
            x: 100,  //相对X位移 
            y: 70,   //相对Y位移 
            floating: true, //设置可浮动 
            shadow: true  //设置阴影 
        }, 
        exporting: { 
            enabled: false  //设置导出按钮不可用 
        }, 
        series: [{  //数据列 
            name: '北京', 
            data: beij 
        }, 
        { 
            name: '广州', 
            data: guangz
        }] 
    }); 
});
        </script>
    </head>
    <form action="#" method="post">
        <span id="sp2">
                开始时间:<input type="text" name="startDay" id="std"/>
                结束时间:<input type="text" name="endDay" id="end"/> 
                </span>
                <input type="submit" value="查询" name="chaxun"/>
</form>
    <div id="container" style="min-width: 310px; height: 400px;"></div>
</html>

在后台的代码我就不贴了,无非就是判断一下起始时间和结束时间是否为空,如果不为空就从数据库中查出来,使用将数据转化成json数据发到前端。

参考博客地址:http://www.helloweba.com/view-blog-157.html


记一次空格引发的错误


 前段时间测试那边和我说我之前写的一个统计查询数据异常,然后我就从界面开始一点一点排查,浪费了半个多小时时间终于查出了原因,在这里记录一下以提醒自己,同时告诫大家写程序时一定要小心,写完后要检查一遍。

  原因:这个统计系统是要统计每个游戏中用户操作用来对数据分析,但是因为之前历史遗留的原因数据都放到一个表中,导致我这边查询异常缓慢。

  经过:因为之前的统计配置已经在安装包中配置好了,重新修改无疑会增加很大的工作量,所以我这边准备写一个perl程序(tnlog.pl)手动的将统计数据从总的统计表中插入到分游戏表中并删除总游戏表中的数据用来提高效率,同时写一个监控查询监控我写的perl程序是否挂掉,一旦挂掉就重启这个程序,最后在linux服务器上添加计划任务不断运行监控程序使数据能够实时传递。

  结果:经过我的排查发现我写的那个将数据从总游戏中插入分游戏表的程序(tnlog.pl)一直在不断启动,最后发现是我再action_list的参数有空格导致无法查到插数据的perl程序在运行,所以一直在不断启动那个程序,导致数据出现异常

  下面附录我写的那个监控插入数据运行的perl程序:

  

#!/usr/bin/perl



$user = "root"; #程序所属用户
$proghome = '/root/dtj';
@action_list = (

#               #######   由tnlog统计表向各游戏表导入数据
                'tnlog.pl brick',
                'tnlog.pl pudding',



#
#               
#                       
               );

$ps =`ps auxw |grep $proghome |grep -v grep`;
#print "$ps\n";
foreach $act (@action_list) {
        $action = "$proghome/$act";
        #print "$action\n";
        if($ps !~ /$action/) {
                print "$act is not running ...start it !!!\n";
                system("$action > /dev/null&");
        }

}

总结:写程序时一定要小心,不要忽视任何的特殊符号(尤其是空格,特别不好检查),写完要再检查一遍,并亲自运行一下以保证程序的正常运行


perl脚本去除文件中重复数据


今天第一天写博客,写的不好请大家多多指教,废话不多说了,干货送上:

#############################################################

#!/usr/bin/perl
use warnings;
use strict;
my %hash;
my $source_file=$ARGV[0]; #输入文件
my $dest_file = $ARGV[1];#输出文件
open (FILE,"<$source_file") or die "Cannot open file $!\n"; #打开文件
open (SORTED,">$dest_file") or die "Cannot open file $!\n";
while(defined (my $line = <FILE>))
{#从文件中取出要去重的数据
        chomp($line);#去除空格
     #$line=~ s/[\r\n]+//mg;#取出换行符
        $hash{$line} += 1;
}
foreach my $k (keys %hash) {
        print SORTED "$k\n";#改行打印出列和该列出现的次数到目标文件
}
close (FILE);
close (SORTED);
#############################################################

将这个#号中的内容添加好以后使用chmod +x 文件名加上权限,使用“./data.pl 源文件 目标文件”命令运行即可


eclipse集成ijkplayer项目


1.ijkplayer是什么

ijkplayer是b站开源的一个视频插件,基于ffmpeg, 支持 Android 和 iOS,可以代替android自带的videview,有不错的体验,支持的视频文件格式也挺多的。

2.编译ijkplayer

由于编译ijkplayer比较耗时间,我这边有现成编译好的so包,你这边直接拿去用就可以了,下面会给出下载的连接。

3.eclipse集成ijkplayer

3.1 导入相应的资源

由于集成ijkplayer需要导入相应的so文件,也就是第2步编译生成的,你那边直接把我项目下libs目录中的jar包和so文件拿过去复制进自己的项目即可。

注:由于ijkplayer需要v7包的支持,你需要把我提供的appcompat这个library引入到自己的项目中

3.2 初始化播放器

在自己的activity中需要加入以下代码,引入刚才编译好的so文件

IjkMediaPlayer.loadLibrariesOnce(null);
IjkMediaPlayer.native_profileBegin("libijkplayer.so");

3.3 初始化自定义播放器

//这里使用的是Demo中提供的AndroidMediaController类控制播放相关操作
mMediaController = new AndroidMediaController(this, false);
mMediaController.setSupportActionBar(actionBar);
mVideoView = (IjkVideoView) findViewById(R.id.video_view);
mVideoView.setMediaController(mMediaController);

3.3设置本地播放器位置

mVideoView.setVideoPath(mVideoPath);
mVideoView.start();

3.4 销毁时释放资源

@Override
public void onBackPressed() {
    mBackPressed = true;
    super.onBackPressed();
}
@Override
protected void onStop() {
    super.onStop();
    //点击返回或不允许后台播放时 释放资源
    if (mBackPressed || !mVideoView.isBackgroundPlayEnabled()) {
        mVideoView.stopPlayback();
        mVideoView.release(true);
        mVideoView.stopBackgroundPlay();
    } else {
        mVideoView.enterBackground();
    }
    IjkMediaPlayer.native_profileEnd();
}

3.5 进度条设置

seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListenerImp());
class OnSeekBarChangeListenerImp implements SeekBar.OnSeekBarChangeListener {

        // 触发操作,拖动
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
        }

        // 表示进度条刚开始拖动,开始拖动时候触发的操作
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        // 停止拖动时候
        public void onStopTrackingTouch(SeekBar seekBar) {
            // TODO Auto-generated method stub
            if (player != null && player.isPlaying()) {
                // 设置当前播放的位置
                videoView
                        .seekTo((int) (1.0f * seekBar.getProgress() / 100 * videoView
                                .getDuration()));
            }
        }
    }

复制代码
4。 下载地址
点击下载


android handler传递数据


起因:在android使用get请求获取验证码时需要重开一个线程,这就造成了我无法获取到从服务器后台返回的数据

解决方法:创建全局变量,将返回的数据解析后返回给handler,再在handler中将数据赋值给全局变量

部分代码如下:

请输入代码private void getYzm(int money) {
    // TODO Auto-generated method stub
    String res = "";
    Date nowTime = new Date();
    SimpleDateFormat time = new SimpleDateFormat("yyMMddHHmm");
    String tel = PhoneUtils.getPhoneNumber(context);
    final String paramData = "imsi=" + imsi + "&imei=" + imei + "&tel="
            + tel + "&money=" + money + "&app="
            + app+ "&time=" + time.format(nowTime);
    String resultCode;
    
    new Thread(){
        public void run() {
            final String gainCode = HttpRequest.sendGet(url,
                    paramData);
        // url是请求验证码地址,是一个全局变量,这里没有列出来,paramData是请求参数,HttpRequest是一个工具类,下面发链接
            String resultCode;
            JSONObject dataJson;
            String orderid;
            try {
                dataJson = new JSONObject(gainCode);
                resultCode = dataJson.getString("resultCode");
                orderid=dataJson.getString("orderid");
                if("200000".equals(resultCode)){
                    msg = handler.obtainMessage();
                    Bundle bundle = new Bundle();
                    bundle.putString("orderid", orderid);// 将服务器返回的订单号传到Bundle中,,再通过handler传出
                    msg.setData(bundle);
                    msg.arg1 = 0;   // 0为获取验证码成功
                    handler.sendMessage(msg);
                }else{
                    msg = handler.obtainMessage();
                    msg.arg1 = 1;  // -1为获取验证码失败
                    handler.sendMessage(msg);  
                }
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
    }.start();
    
}
class MsgHandler extends Handler {
     private Activity activity;  
        public MsgHandler(Activity activity){  
            this.activity=activity;
        }
    @Override
    public void handleMessage(Message msg) {
        // TODO Auto-generated method stub
        switch (msg.arg1) {  
        case 0:  
            dialog.show();
            Bundle bundle=msg.getData();
            orderid=bundle.getString("orderid");// 这里的orderid是一个全局变量
            break; 
        case 1:  
            showInfo("获取验证码失败!");  
            break;
        case 2:  
            showInfo("订购成功!");  
            break;
        case 3:  
            showInfo("提交验证码错误,请重新测试!");  
            break;  
        default:  
            break;  
        }  
        super.handleMessage(msg);
    }