ソフトウェア/tchart.rb のバックアップソース(No.6)
更新[[公開メモ]] #contents * テキストファイルのソースを与えてタイミング図を作成するスクリプトです [#yf72bb15] "Timing chart formatter by kumagai" ~ http://www.mech.tohoku-gakuin.ac.jp/rde/contents/library/tchart/indexframe.html を参考にして、svg を出力するように ruby で作りました。 svg の使い方はこちらのサイトを参考にさせていただきました。~ http://www.h2.dion.ne.jp/~defghi/svgMemo/svgMemo.htm かなり走り書き的なところがありますが、ご容赦下さい。 * 使用例 [#ya5f8236] 次のようなテキストから、 # AXI4 fundamental protocol clock _~_~_~_~_~_~_~_~_~_~_ data =?====X=DATA========X=?==== valid _____~~~~~~~~~~______ ready _____________[~~]______ このようなタイミング図を SVG として出力します。 &tchart( # AXI4 fundamental protocol clock _~_~_~_~_~_~_~_~_~_~_ data =?====X=DATA========X=?==== valid _____~~~~~~~~~~______ ready _____________[~~]______ ); * こちらのアドレスで試すことができます [#ba570c1c] オンラインで変換結果を得られます(svn形式 or png形式):~ http://output.jsbin.com/nirugenabu/1 こちらは javascript で書かれており、サーバーに負荷は掛かりませんので、 そのままタイミングチャートの作成用として、ご利用いただけます。 * タイミング記述テキストの文法 [#g7420e8f] ** # から始まる行はコメント行です [#ld750e11] # test test clk _~_~_~_~_~ signal ___~~~~___ &tchart( # test test clk _~_~_~_~_~ signal ___~~~~___ ); ** @ から始まる行で設定を変更できます [#q06c69eb] 形式は次の通りです。 @[設定値の名称][スペース][設定値] [[設定可能な値としてどんな物があるかについてはこちらです。>#rd2a2e82]] @signal_style stroke-linecap="round" stroke-width="2" stroke="green" fill="none" clk _~_~_~_~_~ signal ___~~~~___ &tchart( @signal_style stroke-linecap="round" stroke-width="2" stroke="green" fill="none" clk _~_~_~_~_~ signal ___~~~~___ ); ** % から始まる行で自由な位置に文字列を追加できます [#z209ee2f] 与えるパラメータは、次の通りです。 %[x座標][スペース][y座標][スペース][文字列] @margin 20 %100 -7 test! clk _~_~_~_~_~ signal ___~~~~___ &tchart( @margin 20 %100 -7 test! clk _~_~_~_~_~ signal ___~~~~___ ); ** 空行があれば1行分だけ空白が空きます [#le587f61] clk1 _~_~_~_~_~ clk2 __~~__~~__ signal ___~~_____ &tchart( clk1 _~_~_~_~_~ clk2 __~~__~~__ signal ___~~_____ ); ** その他の文字から始まる行が信号になります [#e6c10712] フォーマットは 信号名 [空白] タイミング定義 の形です。 * 信号定義の文法と用例 [#qdaa4e35] ** _ と ~ で 0 と 1 を表します。 [#dd9965b7] ** - がハイインピーダンス状態です。 [#x82e48ed] clk _~_~_~_~_~_~_~_~_~ data ___~~~~__~~____~~_ enable ___~~~~~~~~~~_____ output ---~~~~__~~__----- &tchart( clk _~_~_~_~_~_~_~_~_~ data ___~~~~__~~____~~_ enable ___~~~~~~~~~~_____ output ---~~~~__~~__----- ); ** バス信号や不定値を表すのに = を使えます。 [#r60d0319] ** X で値の切り替えを表せます。 [#uad781ca] X は時間が進みます。イメージ的には X= のように働きます。 clk _~_~_~_~_~ data =X=X=X=X=X &tchart( clk _~_~_~_~_~ data =X=X=X=X=X ); ** 信号定義に文字列を書き入れることができます。 [#f601e0b1] ** ? を一文字だけ書くと不定値を表すために色が付きます。 [#dc4c5057] 文字列を書いても時間は進みません。 clk _~_~_~_~_~_~_~_~_~ enable ___~~~~~~~~~~_____ output ---=D0=X=D1X=D2X=D3X=D4----- &tchart( clk _~_~_~_~_~_~_~_~_~ enable ___~~~~~~~~~~_____ output ---=D0=X=D1X=D2X=D3X=D4----- ); clk _~_~_~_~_~_~ data =?==XDATA=====X=?= valid ___~~~~~~___ &tchart( clk _~_~_~_~_~_~ data =?==XDATA=====X=?= valid ___~~~~~~___ ); ** : を入れると空白を入れ、途切れさせることができます。 [#yb67ee5a] clk _~_~_~_:...:~_~_~_~_~ data ___~~~~:...:~~____~~_ &tchart( clk _~_~_~_:...:~_~_~_~_~ data ___~~~~:...:~~____~~_ ); ** 不定値部分を表すのに、/ \ * が使えます。 [#b5b09f01] clk _~_~_~_~_~_~_~ rising ___==/=/=~~~~~ falling ~~~==\=\=_____ transition ___=D0=*=D1*=D2*=D3___ &tchart( clk _~_~_~_~_~_~_~ rising ___==/=/=~~~~~ falling ~~~==\=\=_____ transition ___=D0=*=D1*=D2*=D3___ ); ** | を入れるとグリッド線を引けます。 [#d1263d2a] ** [ ] でくくるとハイライトできます。 [#d41e1c81] clk _~_~_~_~_~_~_~_~_~ data ___~~~~~~~~|____~~_ enable ___[~~~~~~~~~~]_____ output ---~~~~~~~~__----- &tchart( clk _~_~_~_~_~_~_~_~_~ data ___~~~~~~~~|____~~_ enable ___[~~~~~~~~~~]_____ output ---~~~~~~~~__----- ); ** 全ての組み合わせを試してみます [#f93875da] # :-~_=/\X* 0 _~_~_~_~_~_~_[~_~_]~_ 1 :::-:~:_:=:/:\:X:*: 2 -:---~-_-=-/-\-X-*- 3 ~:~-~~~_~=~/~\~X~*~ 4 _:_-_~___=_/_\_X_*_ 5 =:=-=|~=_===/=\=X=*= 6 /:/-/~/_/=///\/X/*/ 7 \:\-\~\_\=\/\\\X\*\ 8 X:X-X~X_X=X/X\XXX*X 9 *:*-*~*_*=*/*\*X*** &tchart( # :-~_=/\X* 0 _~_~_~_~_~_~_[~_~_]~_ 1 :::-:~:_:=:/:\:X:*: 2 -:---~-_-=-/-\-X-*- 3 ~:~-~~~_~=~/~\~X~*~ 4 _:_-_~___=_/_\_X_*_ 5 =:=-=|~=_===/=\=X=*= 6 /:/-/~/_/=///\/X/*/ 7 \:\-\~\_\=\/\\\X\*\ 8 X:X-X~X_X=X/X\XXX*X 9 *:*-*~*_*=*/*\*X*** ); ** 不定値の塗り分けをテスト。 [#h695f4bc] @h_line 30 @h_skip 20 @w_transient 5 @w_caption 60 test =/=?\=\=?/=X=?X=*?=*=X=?-=?= =?X &tchart( @h_line 30 @h_skip 20 @w_transient 5 @w_caption 60 test =/=?\=\=?/=X=?X=*?=*=X=?-=?= =?X ); ** 遷移の傾きをなくすには @w_transient 0 とします [#l5475a84] @w_transient 0 clk _~_~_~_~_~_~_~ data ___|~~~~|_______ &tchart( @w_transient 0 clk _~_~_~_~_~_~_~ data ___|~~~~|_______ ); ** svg の特殊文字も正しくエスケープされます [#b0b8f714] clk _~_~_~_~_~_~_~ data ---|===<D1>=X=<D2>==|--- &tchart( clk _~_~_~_~_~_~_~ data ---|===<D1>=X=<D2>==|--- ); ** 生成された svg には変換元のソースコードが埋め込まれます。 [#c058d952] 下記の CDATA の部分です。ソースコードに CDATA の終了を示す ]]> が現れる場合には、 ]]> にエンコードされます。 LANG:xml <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="240pt" height="60pt" viewBox="-10 -10 220 40" version="1.1"> <![CDATA[ clk _~_~_~_~_~_~_~ data ---|===<D1>=X=<D2>==|--- ]]> <g> <text x="35" y="8.5" text-anchor="end" font-size="10" fill="black" font-family="Helvetica">clk</text> <path stroke-linecap="round" stroke-width="0.6" stroke="black" fill="none" d="M42,10H52L54,0H64L66,10H76L78,0H88L90,10H100L102,0H112L114,10H124L126,0H136L138,10H148L150,0H160L162,10H172L174,0H184L186,10H196L198,0H208" /> <text x="35" y="28.5" text-anchor="end" font-size="10" fill="black" font-family="Helvetica">data</text> <text x="101.0" y="28.5" text-anchor="middle" font-size="10" fill="black" font-family="Helvetica"><D1></text> <text x="149.0" y="28.5" text-anchor="middle" font-size="10" fill="black" font-family="Helvetica"><D2></text><path stroke-linecap="round" stroke-width="0.6" stroke="black" fill="none" d="M42,25H52H54H64H66H76L78,20H88H90H100H102H112H114H124L126,30H136H138H148H150H160H162H172L174,25H184H186H196H198H208M76,25L78,30H88H90H100H102H112H114H124L126,20H136H138H148H150H160H162H172L174,25" /> <path d="M77,-10V40" stroke-linecap="round" stroke-width="0.6" stroke="red" fill="none" /> <path d="M173,-10V40" stroke-linecap="round" stroke-width="0.6" stroke="red" fill="none" /> </g> </svg> * 設定値 [#rd2a2e82] ** scale (= 1.0) [#k3b33db2] 図のサイズを拡大・縮小します。 複数指定した場合、最後の値だけが意味を持ちます。 @scale 1.4 clk _~_~_~_~_~_~_~_~ data ==?=X=D0X=D1X=D2X=D3X=?=== &tchart( @scale 1.4 clk _~_~_~_~_~_~_~_~ data ==?=X=D0X=D1X=D2X=D3X=?=== ); @scale 0.7 clk _~_~_~_~_~_~_~_~ data ==?=X=D0X=D1X=D2X=D3X=?=== &tchart( @scale 0.7 clk _~_~_~_~_~_~_~_~ data ==?=X=D0X=D1X=D2X=D3X=?=== ); ** margin (= 10) [#b7fe0b8a] チャートの周囲の余白の幅を指定します。 ** w_caption (= 40) [#ge8b8cec] 信号名称部分の幅を指定します。 long_signal_name _~~~~__~~~~______~~___ &tchart( long_signal_name _~~~~__~~~~______~~___ ); @w_caption 100 long_signal_name _~~~~__~~~~______~~___ &tchart( @w_caption 100 long_signal_name _~~~~__~~~~______~~___ ); ** w_hold (= 10) [#le7dd0fb] 信号の単位時間から遷移時間を引いた部分の幅を指定します。 途中で変更すれば異なるクロックドメインを表したりできます。 @w_hold 10 clock _~_~_~_~_~_~_~_~_~_~_~ @w_hold 22 clock ~_~_~_~_~_~ @w_hold 16 clock _~_~_~_~_~_~_~_ &tchart( @w_hold 10 clock _~_~_~_~_~_~_~_~_~_~_~ @w_hold 22 clock ~_~_~_~_~_~ @w_hold 16 clock _~_~_~_~_~_~_~_ ); ** w_transient (= 2) [#n3c4fb61] 信号の遷移時間の幅を指定します。 ゼロを指定すると、遷移のエッジは垂直になります。 @w_transient 0 clock _~_~_~_~_~_~_~_~_~_~_~ @w_transient 2 clock _~_~_~_~_~_~_~_~_~_~_~ @w_transient 4 clock _~_~_~_~_~_~_~_~_~_~_~ &tchart( @w_transient 0 clock _~_~_~_~_~_~_~_~_~_~_~ @w_transient 2 clock _~_~_~_~_~_~_~_~_~_~_~ @w_transient 4 clock _~_~_~_~_~_~_~_~_~_~_~ ); ** h_line (= 10) [#p7e6f34c] 1行の高さを指定します。信号名のフォントサイズもこの値に等しくなります。 @h_line 10 clock _~_~_~_~_~_~_~_~_~_~_~ @h_line 16 clock _~_~_~_~_~_~_~_~_~_~_~ &tchart( @h_line 10 clock _~_~_~_~_~_~_~_~_~_~_~ @h_line 16 clock _~_~_~_~_~_~_~_~_~_~_~ ); ** h_space (= 10) [#teb7c9f7] 行間のスペースを指定します。 clock _~_~_~_~_~_~_~_~_~_~_~ data1 _~~~~__~~~~______~~___ @h_space 20 data2 _~~~~__~~~~______~~___ data3 _~~~~__~~~~______~~___ &tchart( clock _~_~_~_~_~_~_~_~_~_~_~ data1 _~~~~__~~~~______~~___ @h_space 20 data2 _~~~~__~~~~______~~___ data3 _~~~~__~~~~______~~___ ); ** signal_style [#v5ac38b6] 信号線のスタイルを svg の path の属性値の形で与えます。 規定値は次の通りです。 stroke-linecap="round" stroke-width="0.6" stroke="black" fill="none" data1 _~~~~__~~~~______~~___ @signal_style stroke-linecap="round" stroke-width="2" stroke="green" fill="none" data2 _~~~~__~~~~______~~___ &tchart( data1 _~~~~__~~~~______~~___ @signal_style stroke-linecap="round" stroke-width="2" stroke="green" fill="none" data2 _~~~~__~~~~______~~___ ); ** grid_style [#ra37b0f5] グリッド線のスタイルを svg の path の属性値の形で与えます。 規定値は次の通りです。 stroke-linecap="round" stroke-width="0.6" stroke="red" fill="none" @grid_style stroke-linecap="round" stroke-width="0.6" stroke="black" fill="none" data1 _~~~~__|~~~~______~~___ @grid_style stroke-linecap="round" stroke-width="0.6" stroke="#0CC" fill="none" data2 _~~~~__~~~~______|~~___ &tchart( @grid_style stroke-linecap="round" stroke-width="0.6" stroke="black" fill="none" data1 _~~~~__|~~~~______~~___ @grid_style stroke-linecap="round" stroke-width="0.6" stroke="#0CC" fill="none" data2 _~~~~__~~~~______|~~___ ); ** highlight_style [#d1714e07] ハイライト部分のスタイルを指定します。 規定値は次の通りです。 stroke="none" fill="#ff8" data1 _~~~~__[~~~~]______~~___ @highlight_style stroke="green" fill="#8f8" stroke-width="1" data2 _~~~~__~~~~______[~~]___ &tchart( data1 _~~~~__[~~~~]______~~___ @highlight_style stroke="green" fill="#8f8" stroke-width="1" data2 _~~~~__~~~~______[~~]___ ); ** notcare_style [#r0fb27ce] 不定値部分のスタイルを指定します。 fill="#ccc" clk _~_~_~_~_~_~_~_~_~_~_~ data1 ====?=*========*=?====== @notcare_style stroke="none" fill="#8f8" data1 ====?=*========*=?====== &tchart( clk _~_~_~_~_~_~_~_~_~_~_~ data1 ====?=*========*=?====== @notcare_style stroke="none" fill="#8f8" data1 ====?=*========*=?====== ); ** caption_font [#z0c3eaff] 信号名のフォントを指定します。 規定値は次の通りです。 fill="black" font-family="Helvetica" clk _~_~_~_~_~_~_~_~_~_~_~ @caption_font fill="red" font-family="Helvetica" @signal_style stroke="red" fill="none" data _~~~~______~~____~~~~~ &tchart( clk _~_~_~_~_~_~_~_~_~_~_~ @caption_font fill="red" font-family="Helvetica" @signal_style stroke="red" fill="none" data _~~~~______~~____~~~~~ ); ** signal_font [#sfe73988] 信号部分で用いるフォントを指定します。 規定値は次の通りです。 fill="black" font-family="Helvetica" clk _~_~_~_~_~_~_~_~ @signal_font fill="red" font-family="Helvetica" data ==?=X=D0X=D1X=D2X=D3X=?=== &tchart( clk _~_~_~_~_~_~_~_~ @signal_font fill="red" font-family="Helvetica" data ==?=X=D0X=D1X=D2X=D3X=?=== ); ** rotate (= 0) [#s041342a] 未実装 * ソースファイル [#u33d6dea] いやほんと、走り書きですみません。 LANGUAGE:ruby(linenumber) #!/usr/bin/ruby #### tchart.rb by osamu@big.jp # # "Timing chart formatter by kumagai" # http://www.mech.tohoku-gakuin.ac.jp/rde/contents/library/tchart/indexframe.html # # を参考に、svg を出力するようにしたものです # # かなり走り書き的なところがありますが、ご容赦下さい。 # ##################################################################### # default config conf = { scale: 1.0, margin: 10, w_caption: 40, w_hold: 10, w_transient: 2, h_line: 10, h_space: 10, signal_style: 'stroke-linecap="round" stroke-width="0.6" stroke="black" fill="none"', grid_style: 'stroke-linecap="round" stroke-width="0.6" stroke="red" fill="none"', highlight_style:'stroke="none" fill="#ff8"', notcare_style: 'fill="#ccc"', rotate: 0, caption_font: 'fill="black" font-family="Helvetica"', signal_font: 'fill="black" font-family="Helvetica"' } ##################################################################### class Line class SubLine def initialize(x,y) @points = [[x,y]] end def accepts?(x,y) @points.last == [x,y] end def add(x,y) @points << [x,y] end def path result = '' last = nil @points.each do |p| if last if last==p next elsif last[0]==p[0] result += 'V%g' % p[1] elsif last[1]==p[1] result += 'H%g' % p[0] else result += "L%g,%g" % p end else result = "M%g,%g" % p end last = p end result end end def initialize(style) @lines = [] @style = style end def draw(x1, y1, x2, y2) unless line = @lines.find {|line| line.accepts?(x1, y1) } line = SubLine.new(x1, y1) @lines << line end line.add(x2, y2) end def svg path = @lines.map{|line| line.path }.join('') %Q[<path #{@style} d="#{path}" />] end end class Timeline # : - ~ _ = @@transitions = [ ' ', # : ' - 1 4 14', # - ' 2 ~ / ~/', # ~ ' 3 ` _ _`', # _ ' 23`~/_= ', # = ' 23`~/_=/', # / ' 23`~/_=`', # \ ' 23`~/_X ', # X ' 23`~/_=X', # * ] @@transition_lines = { ' ' => [], '~' => [[1,1]], '_' => [[0,0]], '=' => [[1,1],[0,0]], 'X' => [[1,0],[0,1]], '`' => [[1,0]], '/' => [[0,1]], '1' => [[1,0.5]], '2' => [[0.5,1]], '3' => [[0.5,0]], '4' => [[0,0.5]], '-' => [[0.5,0.5]], } # : - ~ _ = @@state_lines = [[],[0.5],[1],[0],[0,1]] # @@codes = ':-~_=/\\X*' @@grids = [] def self.grids @@grids end @@highlight = [] def self.highlight @@highlight end def initialize(conf, y) @line = Line.new(conf[:signal_style]) @current = 0 @conf = conf @x = conf[:w_caption] @y = y @crosses = [] @strings = [] end def y(s) @y + (1-s) * @conf[:h_line] end def y0 @y + @conf[:h_line] end def y1 @y end def yz @y + @conf[:h_line]/2.0 end def x @x end def xh @x + @conf[:w_transient]/2.0 end def xt @x + @conf[:w_transient] end def xr @x + @conf[:w_transient] + @conf[:w_hold] end def draw_transition_sub(c) crosses = '' @@transition_lines[c].each do |line| @line.draw(x, y(line[0]), xt, y(line[1])) crosses += c if line[0] != line[1] end crosses end def draw_transition(s) crosses = '' @@transitions[s][2*@current,2].each_char do |c| crosses += draw_transition_sub(c) end crosses end def draw_state(s) @@state_lines[s].each do |line| @line.draw(xt, y(line), xr, y(line)) end end def add(c) s = @@codes.index(c) crosses = draw_transition(s) s = 4 if s > 4 draw_state(s) @crosses << [x, crosses] if crosses!='' if (@current == 0 and s != 0) or (@current != 0 and s == 0) @crosses << [x, '|'] end @current = s @x = xr end def add_string(s) @strings << [@crosses.count, s] end def parse(line) while line != '' if line.sub!(/^\s+/, '') elsif line.sub!(/^\|/, '') @@grids << xh elsif line.sub!(/^\[/, '') if @@highlight.last==nil or @@highlight.last.is_a?(Array) @@highlight << xh end elsif line.sub!(/^\]/, '') if @@highlight.last.is_a?(Numeric) @@highlight[-1] = [@@highlight.last, xh] end elsif line.sub!(/^([:\-~_=\/\\X*])/, '') add($1) elsif line.sub!(/"(([^"]|"")+)"/, '') add_string($1.strip) elsif line.sub!(/([^:\-~_=\/\\X*]+)/, '') add_string($1.strip) end end end def string2svg @crosses << [x,'|'] @strings.map do |string| x1 = @crosses[string[0]-1][0] x1t = x1 + @conf[:w_transient] x1h = x1 + @conf[:w_transient]/2.0 x1r = x1t + @conf[:w_hold] x2 = @crosses[string[0] ][0] x2t = x2 + @conf[:w_transient] x2h = x2 + @conf[:w_transient]/2.0 x2r = x2t + @conf[:w_hold] # sanitized = string[1].gsub(/</, '<').gsub(/>/, '>').gsub(/"/, '"') svg = %Q(<text x="#{(x1h + x2h)/2.0}" y="#{y0-1.5}" text-anchor="middle" font-size="#{@conf[:h_line]}" #{@conf[:signal_font]}>#{sanitized}</text>) if string[1] == '?' line = "M#{x1t},#{y1}H#{x2}" case @crosses[string[0]][1] when '|' ; when 'XX' line += "L#{x2h},#{yz}" when '/' line += "H#{x2t}" when '`' line += "L#{x2t},#{y0}" when '23' line += "H#{x2t}L#{x2},#{yz}L#{x2t},#{y0}" when '14' line += "L#{x2t},#{yz}" when '1' line += "L#{x2t},#{yz}V#{y0}" when '2' line += "H#{x2t}L#{x2},#{yz}" when '3' line += "V#{yz}L#{x2t},#{y0}" when '4' line += "H#{x2t}V#{yz}" end line += "L#{x2},#{y0}H#{x1t}" case @crosses[string[0]-1][1] when '|' ; when 'XX' line += "L#{x1h},#{yz}" when '/' line += "H#{x1}" when '`' line += "L#{x1},#{y1}" when '23' line += "L#{x1},#{yz}" when '14' line += "H#{x1}L#{x1t},#{yz}L#{x1},#{y1}" when '1' line += "V#{yz}L#{x1},#{y1}" when '2' line += "H#{x1}V#{yz}" when '3' line += "L#{x1},#{yz}V{y1}" when '4' line += "H#{x1}L#{xt},#{yz}" end line += "Z" svg = %Q(\n<path stroke="none" d="#{line}" #{@conf[:notcare_style]}/>) + svg end svg end.join("\n") end def svg string2svg + @line.svg end end def caption2svg(conf, y, caption) sanitized = caption.gsub(/</, '<').gsub(/>/, '>').gsub(/"/, '"') %Q(<text x="#{conf[:w_caption]-5}" y="#{y+conf[:h_line]-1.5}" text-anchor="end" font-size="#{conf[:h_line]}" #{conf[:caption_font]}>#{sanitized}</text>) end ##################################################################### svg = [] y = -1 x_max = 0 lines = readlines lines.shift while lines[0] =~ /^\s*$/ lines.pop while lines.last =~ /^\s*$/ lines.each do |line| next if line =~ /^\#/ if line =~ /^@/ #### configuration if line !~ /^@([^\s]+)[\s]+([^\s].*)$/ STDERR.puts "Illegal Line: #{line}" next end if conf[$1.to_sym].is_a?(Numeric) conf[$1.to_sym] = $2.to_f else conf[$1.to_sym] = $2 end next end if line =~ /^%/ #### free string if line !~ /^%([\d\.-]+)[\s]+([\d\.-]+)[\s]+([^\s].*)$/ STDERR.puts "Illegal Line: #{line}" next end svg << %Q(<text x="#{$1}" y="#{$2}" text-anchor="middle" font-size="#{conf[:h_line]}" #{conf[:signal_font]}>#{$3}</text>) next end if y < 0 y = 0 else y += conf[:h_space] end line.sub!(/\s*$/, '') next if line == '' if line !~ /^([^\s]+)[\s]+([^\s].*)$/ STDERR.puts "Illegal Line: #{line}" next end caption_s = $1 timeline_s = $2 svg << caption2svg(conf, y, caption_s) timeline = Timeline.new(conf, y) timeline.parse(timeline_s) x_max = timeline.xr if x_max < timeline.xr svg << timeline.svg y += conf[:h_line] end m = conf[:margin] w = "%g" % ((x_max + 2*m) * conf[:scale]) h = "%g" % ((y + 2*m) * conf[:scale]) l = "%g" % (-m) t = "%g" % (-m) r = "%g" % (x_max+2*m) b = "%g" % (y +2*m) Timeline.grids.each do |g| x = "%g" % g svg << %Q(<path d="M#{x},#{'%g' % (-m/2)}V#{'%g' % (y+m/2)}" #{conf[:grid_style]} />) end Timeline.highlight.each do |h| if h.is_a?(Array) x1 = "%g" % h[0] x2 = "%g" % h[1] svg.unshift %Q(<path d="M#{x1},#{'%g' % (-m/2)}V#{'%g' % (y+m/2)}H#{x2}V#{'%g' % (-m/2)}Z" #{conf[:highlight_style]} />) end end print <<SVG <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="#{w}pt" height="#{h}pt" viewBox="#{l} #{t} #{r} #{b}" version="1.1"> <![CDATA[ #{lines.join("\n").gsub(/\]\]\>/, ']]>')} ]]> <g> #{svg.join("\n")} </g> </svg> SVG * ちょっと疑問 [#sfbfc96d] ハイインピーダンスからの遷移の書き方はこれで良いんだろうか? 他と傾きが違ってしまうけれど・・・ @h_line 30 @h_skip 20 @w_transient 8 @w_caption 100 test1 ___|~~~|___|==|X=|X= test2 ---~~~---==--== &tchart( @h_line 30 @h_skip 20 @w_transient 8 @w_caption 100 test1 ___|~~~|___|==|X=|X= test2 ---~~~---==--== ); * もしかして、javascript で作った方が良かったんじゃないだろうか・・・ [#m8dba977] javascript で実装すればクライアント側の処理だけで図を描画できますし、 最近はそのまま画像として保存することもできるそうで、 http://www.pori2.net/html5/Canvas/150.html ずっと良かったのかもしれません??? 確かに・・・ずっとよさそうです~ http://output.jsbin.com/nirugenabu/1 * コメント・質問 [#jb4548c8] #article_kcaptcha
Counter: 3622 (from 2010/06/03),
today: 3,
yesterday: 1