【问题标题】:Dynamic data store for ExtJS chartExtJS 图表的动态数据存储
【发布时间】:2012-01-31 04:38:49
【问题描述】:

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

查询数之所以可变,是因为每个查询在折线图上代表不同的系列(不同的线),而系列的数量根据用户选择的折线图而有所不同。

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

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

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

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

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

4) 将该列表输出为 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*/)
}

解决方案:

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() ? "" : "," ));
}

【问题讨论】:

    标签: java json list jsp extjs


    【解决方案1】:

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

    List outerList = new ArrayList();
    

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

    【讨论】:

    • 谢谢弗朗西斯,把它理顺了
    猜你喜欢
    • 2013-04-16
    • 2013-03-31
    • 2014-04-14
    • 1970-01-01
    • 2017-12-18
    • 2018-03-16
    • 1970-01-01
    • 2015-05-30
    • 2015-12-10
    相关资源
    最近更新 更多