2011-12-31 119 views
2

我想在服務器端使用JSP執行可變數量的查詢,並將所有這些查詢的結果作爲ExtJS折線圖的單個JSON數據塊輸出。ExtJS圖表的動態數據存儲

查詢數量變化的原因是因爲每個圖表在折線圖上表示不同的系列(不同的行),並且系列數量根據用戶選擇的折線圖而不同。

我正在使用hibernate,我的持久化類將每個查詢數據返回爲: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*/) 
} 

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

回答

3

我不會合並列表。我只是爲每個查詢創建一個外部列表,然後通過外部列表並返回每個系列列表。你可以創建外列表爲:

List outerList = new ArrayList(); 

我就不會擔心了外列表中指定的類型,因爲它只是使它成爲小利益較爲複雜。

+0

謝謝弗朗西斯,把它弄直了 – Geronimo 2011-12-31 23:26:45