ずいぶんと *古い* ネタである.
あの 後,けっきょく 2 回作り直した.
- 素直に Morph バージョン
- Form バージョン
- FormCanvas バージョン
1) やっぱ要素数が増えると重くて動かん例題があるというのがネック.じゃぁってんで代替えでひねり出したのが, 2) いつもの Form を使うヤツ.一度 aForm に書き出して anImageMorph に変換して持つというもの.ボルヘス流に言えば縮尺 1:1 の投影地図である.これだと,モデルが元々持ってる displayOn: がそのまま使えるというメリットがある.が,表示用のウィンドウを作る際に一度作るだけなんだが,途中でグラフの大きさが変わると,その都度作り直すことになる.動きは随分と軽くなるが,それでも横 2000,縦 75000 みたいなデカい aForm は Display depth ではメモリ不足で作れん.メモリが足りんときは表示深度を落とし,書き出せんときは分割して,みたいなことをやらざるを得ん.あと,状態更新にも弱い.
で,次いでひねくり出したのが 3) FormCanvas を使うバージョン.これは Morph の表示用メカニズム drawOn:[こんとき,個々の aMorph で呼び出される drawOn: のパラメータである aCanvas は WorlsState が作って渡す FormCanvas のインスタンス.ディスプレイ] を使うもの.これは中身の実体を持っていない. aFormCanvas は内部的に form を抱え込んでいる.表示用にからっぽの Morph を作り drawOn: を再定義して,そんままモデルに渡すもの.渡すときに drawOn: の引数である aCanvas から form を取得して渡せば,モデルの displayOn: がそんまま使えるが,今回は新規に drawOn:at: を定義している.もし自前で aFormCanvas を作った場合は,描き終えた後で showAt: しなければならない.元ネタは古い Goodies for Squeak (Smalltalk-80) の DisplayView
以下は樹状整列とスクローリングをアニメーションで表示する例題の実行時間を計測したもの.現在のトップウィンドウの領域に上書き描画するプログラムなので 2) と 3) ではほとんど同じ速度で動く.描画領域は全部 768 @ 571 で統一してある.
examples | Squeak3.10.2-7179web09.07.1 | VWNC7.7 + Jun786 | ||
---|---|---|---|---|
Morph pattern | Form pattern | FormCanvas pattern | ||
example30 (exampleTree) | 29 | 48 | ||
25.81 (0.54 sec/node) | 10.56 (0.36 sec/node) | 10.31 (0.36 sec/node) | 25.29 (0.53 sec/node) | |
example31 (exampleForest) | 173 | 244 | ||
52.81 (0.31 sec/node) | 37.49 (0.22 sec/node) | 38.10 (0.22 sec/node) | 83.69 (0.34 sec/node) | |
example32 (exampleSmalltalk) | 4449 | 3071 | ||
1080.90 (18min 0.9sec) (0.24 sec/node) | 227.45 (3min 47.5sec) (0.05 sec/node) | 229.09 (3min 49.1sec) (0.05 sec/node) | 188.22 (3min 8.2sec) (0.06 sec/node) |
同心円状整列 (arrangeFormat: #concentric) の例.あ,そうそう,前回の重み付きのグラフ:京都 or 東京では連結されてないノードを表示してなかったので,直した.
同心円状整列グラフの鳥瞰画像の例.
4449 個のノードを持つグラフの俯瞰.赤い線のように見えるのは,鳥瞰描画に入る前に,このウィンドウに描画していた領域↓.
鳥瞰図から,この系統がいちばん深い継承を持っていることが判る.この末端は "Polymorph-Widgets-Windows" パッケージに含まれる CustomQuestionDialogWindow クラスで,スーパークラスは 12 個ある.
ProtoObject Object Morph BorderedMorph MorphicModel SystemWindow StandardWindow (ここから下は "Polymorph-*" パッケージ) DialogWindow MessageDialogWindow ProceedDialogWindow QuestionDialogWindow QuestionWithoutCancelDialogWindow CustomQuestionDialogWindow
ノード数が多いグラフで鳥瞰モードに入ると,やはり重い.何か工夫せんと使い難くてかなわん.とりあえず思い付くのは,ダメージ領域だけを再描画する,か.鳥瞰図を保存するには,例えば以下のような感じでモルフ化してエクスポートする.
| aGrapher window aNode view scaleFactor aCanvas previousBox aBox | aGrapher :=NshGrapherJunGrapher exampleSmalltalk. window := aGrapher open. window extent: 600 @ 400. aNode := aGrapher graph labelStringAt: 'CustomQuestionDialogWindow'. aNode ifNotNil: [aGrapher scrollFor: aNode]. view := aGrapher getView. view scrollAmount: view scrollAmount + (200 @ 0). aGrapher changed. scaleFactor := (view bounds extent - (2 @ 2)) / aGrapher boundingBox extent. aCanvas := Display defaultCanvasClass extent: view bounds extent. previousBox := ((view bounds translateBy: view bounds origin negated - aGrapher boundingBox origin - view scrollAmount) scaleBy: scaleFactor) rounded. aCanvas fillColor: aGrapher graph class defaultWorldColor. aGrapher drawOn: aCanvas at: 0 @ 0 - view model boundingBox origin scaledBy: scaleFactor. aCanvas frameRectangle: previousBox width: 2 color: Color blue darker darker. aBox := ((view bounds translateBy: view bounds origin negated - aGrapher boundingBox origin - view scrollAmount) scaleBy: scaleFactor) rounded. aGrapher selectionBorderWidth timesRepeat: [aCanvas frameAndFillRectangle: aBox fillColor: Color transparent borderWidth: 1 borderColor: aGrapher selectionBorderColor. aBox := aBox insetBy: (1 @ 1 corner: 1 @ 1)]. "aCanvas showAt: 0 @ 0." aCanvas form asMorph openInWindow
表示のタイミングで書き出した画像を束ねてアニメーションにしたので,実際の動きとは異なる.
0 件のコメント:
コメントを投稿