ExtJS图表的动态数据存储

时间:2011-12-31 19:57:28

标签: java json list jsp extjs

我正在尝试在服务器端使用JSP来执行可变数量的查询,并将所有查询的结果作为ExtJS折线图的单个JSON数据块输出。

查询数量可变的原因是因为每个查询在折线图上表示不同的系列(不同的行),并且系列的数量因用户选择的折线图而不同。

我正在使用hibernate,我的持久化类将每个查询数据返回为:List<Map<String, Object>>(每个Map代表一行)。

总会有至少一个系列(图中一行,一个查询要执行),所以我想设置它的方式如下:

1)运行初始查询并获取第一个系列

2)运行另一个查询以检查应该在图表上的任何其他系列

3)对于在第二个查询中找到的每个“其他”系列运行一个查询,该查询获取该系列的数据(相同的行数),然后将该数据合并到#中返回的第一个List<Map<String, Object>>中1作为另一列。查询设置为正确排序,只需要在同一索引级别合并。

4)将List输出为JSON。

我的问题是#3,我不知道如何合并数据。

这是我到目前为止所拥有的:

GenericSelectCommand graphData = new GenericSelectCommand(graphDataQuery);
GenericSelectCommand backSeriesData = new GenericSelectCommand(backSeriesQuery);

List<Map<String, Object>> graphDataList;
List<Map<String, Object>> backSeriesList;

try
{
    Persistor myPersistor = new Persistor();

    // 1) GET THE INITIAL LINE CHART SERIES
    myPersistor.executeTransact(graphData);
    graphDataList = graphData.getRows();

    // 2) LOOK FOR ANY ADDITIONAL SERIES THAT SHOULD BE ON THE LINE CHART
    myPersistor.executeTransact(backSeriesData);
    backSeriesList = backSeriesData.getRows();

    // 3) FOR EACH ADDITIONAL SERIES FOUND, RUN A QUERY AND APPEND THE DATA TO THE INITIAL LINE CHART SERIES (graphDataList)
    for (int i = 0; i < backSeriesList.size(); i++)
    {
        Map<String, Object> backSeriesBean = backSeriesList.get(i);

        // THIS QUERY RETURNS ONE COLUMN OF INT VALUES (THE LINE CHART DATA) WITH THE EXACT SAME NUMBER OF ROWS AS THE INITIAL LINE CHART SERIES (graphDataList)
        String backDataQuery = "exec runQuery 'getBackData', '" + backSeriesBean.get("series_id") + "'";

        GenericSelectCommand backData = new GenericSelectCommand(backDataQuery);
        myPersistor.executeTransact(backData);
        List<Map<String, Object>> backDataList = backData.getRows();

        // FOR EACH RECORD IN THE BACK DATA (Map<String, Object>)
        for (int i = 0; i < backDataList.size(); i++)
        {
            Map<String, Object> backDataBean = backDataList.get(i);
            // HOW DO I ADD IT TO THE RECORD AT THE SAME INDEX LEVEL IN graphDataList (List<Map<String, Object>>)
        }

    }


}
catch (Throwable e)
{
    System.err.println("Error: ");
    System.err.println(e.getCause());
}
finally
{
    myPersistor.closeSession();
}

// 4) RETURN THE DATA AS JSON NOW THAT IT IS MERGED
for (int i = 0; i < graphDataList.size(); i++)
{
    Map<String, Object> graphDataBean = graphDataList.get(i);
    out.println(/*JSON FORMAT + graphDataBean.get('data') + JSON FORMAT*/)
}

SOLUTION:

GenericSelectCommand graphData = new GenericSelectCommand(graphDataQuery);
GenericSelectCommand backSeries = new GenericSelectCommand(backSeriesQuery);

List<Map<String, Object>> graphDataList = Collections.emptyList();
List<Map<String, Object>> backSeriesList = Collections.emptyList();
List backDataListArray = new ArrayList();

try
{

    // GET THE INITIAL LINE CHART SERIES
    Persistor.instance().executeTransact(graphData);
    graphDataList = graphData.getRows();

    // LOOK FOR ANY ADDITIONAL SERIES THAT SHOULD BE ON THE LINE CHART
    Persistor.instance().executeTransact(backSeries);
    backSeriesList = backSeries.getRows();

    // FOR EACH ADDITIONAL SERIES FOUND, RUN THE QUERY AND ADD IT TO backDataListArray
    for (int i = 0; i < backSeriesList.size(); i++)
    {
        Map<String, Object> backSeriesBean = backSeriesList.get(i);

        String backDataQuery = "exec runQuery 'getBackData', " + backSeriesBean.get("series_id");
        GenericSelectCommand backData = new GenericSelectCommand(backDataQuery);
        Persistor.instance().executeTransact(backData);
        List<Map<String, Object>> backDataList = backData.getRows();
        backDataListArray.add(backDataList);
    }
}
catch (Throwable e)
{
    System.err.println("Error: ");
    System.err.println(e.getCause());
}
finally
{
    Persistor.instance().closeSession();
}

// FOR EACH RECORD IN THE ORIGINAL QUERY, WRITE THE JSON STRING
for (int i = 0; i < graphDataList.size(); i++)
{

    StringBuilder backDataString = new StringBuilder();

    // BUILD THE BACK DATA STRING (IF THERE IS ANY)
    for (int j = 0; j < backDataListArray.size(); j++)
    {
        List<Map<String, Object>> backDataList = (List<Map<String, Object>>) backDataListArray.get(j);
        Map<String, Object> backDataBean = backDataList.get(i);
        Map<String, Object> backSeriesBean = backSeriesList.get(j);

        backDataString.append(backSeriesBean.get("the_series") + ": " + backDataBean.get("the_count") + ", ");
    }

    Map<String, Object> graphDataBean = graphDataList.get(i);

    out.println("{the_quota: " + graphDataBean.get("the_quota") + ", " + "count_pt_year: " + graphDataBean.get("count_pt_year") + ", " + backDataString + "date_string: '" + graphDataBean.get("date_string") + "'}" + (i + 1 == graphDataList.size() ? "" : "," ));
}

1 个答案:

答案 0 :(得分:3)

我不会合并列表。我只想为每个查询创建一个外部列表,然后浏览外部列表并返回每个系列列表。您可以将外部列表创建为:

List outerList = new ArrayList();

我不担心指定外部列表的类型,因为它只是使它变得更复杂而没什么好处。