本人在使用Extjs时,用到AmChart(flash版本)来作图,开始做的时候我用ajax请求后,把结果替换 flashVars中的chart_data的数值,以为能够实现动态刷新的效果,可是界面没有任何改变,于是我使用重绘的方式实现了,但刷新的效果,界面总是一闪一闪的,不是很理想。后来我无意中发现了一种非常简单好用的方式,居然实现了。现分享出来。

首先,需要在ExtJS界面中创建一个flash模块,如下

createFlashChart: function() {
        var me = this;
        me.flashchart = {
            id: 'flashchart',
            xtype: 'flash',
            stateful: true,
            url: 'resources/flashline.swf',
            EXPRESS_INSTALL_URL: 'resources/flash/expressInstall.swf',
            flashVars: {
                path: "resources/flash/",
                data_file: "chart/getRtValue.shtml",
                settings_file: "resourcesartsetartsetting.xml"
            },
            flashParams: {
                bgcolor: "#0000ff",
                wmode: "transparent",
                menu: "false"
            }
        }
    },

这里面包含一些swf文件,amline.swf是amchart中的直线模板,可以在文档中下载,expressInstall.swf可以在网上下载,path: "resources/flash/"设置的是amchart的模板库位置,data_file: "chart/getRtValue.shtml"设置的是我请求的数据URL,settings_file: "resources/ch

artset/ch artsetting.xml" 设置的是图表样式文档。

然后,你需要在你的样式文档chartsetting.xml中设置如下内容,代表刷新频率

<reload_data_interval>3</reload_data_interval>

接着,你需要后台方法来获取数据,我这里使用的spring3MVC,返回的数据是xml文件,我先封装了一个转换map成xml的类,如下

package com.fly.util;

import java.util.List;
import java.util.Map;

/**
 * @作用 数据转换类
 * @author Fly
 */
public final class SystemUtil {

    public static String parseToXml(List<Map<String, Object>> mapList, String series, String[] graphs) {
        StringBuilder result = new StringBuilder("<?xml version='1.0' encoding='UTF-8'?><chart><series>");
        for (int i = 0; i < mapList.size(); i++) {
            Object o = mapList.get(i).get(series);
            result.append("<value xid='").append(i).append("'>").append(o).append("</value>");
        }
        result.append("</series><graphs>");
        for (int j = 0; j < graphs.length; j++) {
            result.append("<graph gid='").append(j).append("'>");
            for (int i = 0; i < mapList.size(); i++) {
                Object o = mapList.get(i).get(graphs[j]);
                result.append("<value xid='").append(i).append("'>").append(o).append("</value>");
            }
            result.append("</graph>");
        }
        result.append("</graphs></chart>");
        return result.toString();
    }

    public static List getRtMapList(List<Map<String, Object>> mapList, Map<String, Object> map) {
        if (mapList.size() > 100) {
            mapList.remove(0);
        }
        mapList.add(map);
        return mapList;
    }
}

这里面有两个函数,第一个函数是把map装换成xml的方法,它有三个参数,第一个是传递进来的map,第二个参数x轴的变量名,第三个是y轴的数据值。

第二个函数的意思就是当数据的长度大于100的时候,去掉第一个数据,重新加载进来一个数据。

有了这个类后,你就可以写controller类的方法了。如下

@RequestMapping(value = "chart/getRtValue")
    @ResponseBody
    public String getRtValue(HttpSession session) {
        Test1 t1 = getTest1Info(session);
        int tp = t1.getTpId();
        Test1 t2 = getTest2Info(session);
        int rp = t2.getpId();
        if (chartValues == null) {
            long endtime = (new Date()).getTime() / 1000;
            long starttime = endtime - 48 * 3600;
            chartValues = chartService.getHisValue(tp, rp, starttime, endtime);
        }
        Map<String, Object> map = chartService.getRtValue(tp, rp);
        chartValues = SystemUtil.getRtMapList(chartValues, map);
        return SystemUtil.parseToXml(chartValues, "datatime", new String[]{"tp", "rp"});
    }

这个方法中的@RequestMapping(value = "chart/getRtValue") 的value就是extjs中flash模块data_file对应的地址。chartValues是一个储存数据数据的全局map类list,如果这个数据为空的话,我就取一段历史数据加载进来,如果不为空就直接加载当前最新值。chartService是我封装的获取数据的数据业务。你可以在这里面根据自己的需求封装数据,但最终需要利用SystemUtil.parseToXml方法,转换成xml类型数据。当然amchart还支持csv数据格式。