# DrawComponent

## DrawComponent

可以視為 GXT 的 canvas，更正確地說是 canvas container / wrapper。 實際上的 canvas 是 `Surface`，會用 deferred binding 的方法抽換實做， 目前大抵上預設是 `SVG`，遇到 IE6～8 會替換成 `VML`， 另外還有隱藏實驗版（JavaDoc 找不到）的 `Canvas2d` 版。 因為 wrapper 過，所以基本上可以不用理會底層實做，GXT 會提供一個一致的 API。

目前建議都作 DrawComponent.setBackground(Color.NONE)， 真的要 background 再自己指定一個 `RectangleSprite`。 不然（似乎是在） resize 的時候，background 的 sprite 會莫名其妙跑到前面去， 讓某些 sprite 被蓋掉、即使那些 sprite 給了很大的 z-index。

`ImageSprite` 沒設定過座標，在視覺上會等同於在 (0, 0)。 不過這會影響 `getBBox()` 回傳的座標仍然是 (Double.NaN, Double.NaN)， 導致 `DrawComponent` 的 sprite handler 會無法觸發。 其他 sprite 應該大同小異，所以簡單地說就是：「`Sprite` 都要設定座標」。

### 判斷游標離開 DrawComponent

雖然游標仍然在 `DrawComponent` 上，不過如果上頭有多個 sprite， 游標在離開 sprite 就會呼叫 `DrawComponent.onMouseOut()`。 所以，要真正判斷游標是否離開 DrawCompont 的方法是

```java
@Override
public void onMouseOut(Event event) {
    super.onMouseOut(event);

    if (getElement().getBounds().contains(event.getClientX(), event.getClientY())) {
        //表示還在 DrawComponent 內
    }
}
```

## Chart

`chart.redrawChart()` 之類的繪圖時刻如果炸 `java.lang.NegativeArraySizeException` 之類狀況， 先檢查一下 chart 的大小是否合理。如果 chart 沒有大小（1 \* 1），那麼炸 exception 好像也很合理。

`NumericAxis.clear()`（實際是 `CartesianAxis.clear()`）不會清 fields， 但是不清 fields 好像也不會怎樣？細節不明 Orz

如果做了 `NumericAxis.setMaximum()` 等動作， 則相關的 series 必須要設定正確的 `setYAxisPosition()`， 否則會出現 series 跟 axis 對不上的各種靈異狀況。 反之如果 axis 沒做、series 不用設定也不會出問題。

### TimerAxis

如果用 `TimeAxis` 作 X 軸（不確定作 Y 軸會怎樣 XD）， 直接設定 `setStartDate()` 跟 `setEndDate()` 就會幫你過濾掉不在時間範圍內的 data， 不用自己整理 store。

`TimerAxis` 的時間區間過濾機制會影響 chart 的 `getCurrentStore()`（`substore`）的值。 這在「清空 / 重塞 store、又變更其他 axis」的前提下，`chart.redrawChart()` 會炸。 因為 render 實際處理的是 `getCurrentStore()`，如果舊的 store 格式跟新的 axis 格式對不上，就會出錯。 解法是在變更其他 axis 之後作 `TimerAxis.drawAxis(false)`（傳入 true / false 好像沒差）， 在 `drawAxis()` 裡頭的 `applyData()`（`TimeAxis` 有 override）會重新計算 / 設定 `currentStore`。 當然這有點浪費，因為在 `chart.render()` 裡頭其實會對各個 axis 作 `drawAxis(false)`， 只能說理論上沒辦法控制 `TimerAxis` 一定要先作，`applyData()` 是 protected 所以沒辦法直接呼叫 前提觸發的條件又不是很 general，只好覆蓋新鮮的肝臟，結束這一回合 T\_\_T。

### LineSeries

預設情況下，若第 n 個點的值為 `Double.NaN`， 則會直接連起 n - 1 跟 n + 1。 設定 `setGapless(false)` 就會斷掉形成 gap。

### Legend

`Legend` 的資料來源是從 `Series.setYField()` 傳入的 `ValueProvider` 的 `getPath()`。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gwt.dontcareabout.us/gxt/drawcomponent.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
