1# 2# tkextlib/blt/component.rb 3# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) 4# 5 6require 'tk' 7require 'tkextlib/blt.rb' 8 9module Tk::BLT 10 module PlotComponent 11 include TkItemConfigMethod 12 13 module OptKeys 14 def __item_font_optkeys(id) 15 ['font', 'tickfont', 'titlefont'] 16 end 17 private :__item_font_optkeys 18 19 def __item_numstrval_optkeys(id) 20 ['xoffset', 'yoffset'] 21 end 22 private :__item_numstrval_optkeys 23 24 def __item_boolval_optkeys(id) 25 ['hide', 'under', 'descending', 'logscale', 'loose', 'showticks', 26 'titlealternate', 'scalesymbols', 'minor', 'raised', 27 'center', 'decoration', 'landscape', 'maxpect'] 28 end 29 private :__item_boolval_optkeys 30 31 def __item_strval_optkeys(id) 32 ['text', 'label', 'limits', 'title', 33 'show', 'file', 'maskdata', 'maskfile', 34 'color', 'titlecolor', 'fill', 'outline', 'offdash'] 35 end 36 private :__item_strval_optkeys 37 38 def __item_listval_optkeys(id) 39 ['bindtags'] 40 end 41 private :__item_listval_optkeys 42 43 def __item_numlistval_optkeys(id) 44 ['dashes', 'majorticks', 'minorticks'] 45 end 46 private :__item_numlistval_optkeys 47 48 def __item_tkvariable_optkeys(id) 49 ['variable', 'textvariable', 'colormap', 'fontmap'] 50 end 51 private :__item_tkvariable_optkeys 52 end 53 54 include OptKeys 55 56 def __item_cget_cmd(id) 57 if id.kind_of?(Array) 58 # id := [ type, name ] 59 [self.path, id[0], 'cget', id[1]] 60 else 61 [self.path, id, 'cget'] 62 end 63 end 64 private :__item_cget_cmd 65 66 def __item_config_cmd(id) 67 if id.kind_of?(Array) 68 # id := [ type, name, ... ] 69 type, *names = id 70 [self.path, type, 'configure'].concat(names) 71 else 72 [self.path, id, 'configure'] 73 end 74 end 75 private :__item_config_cmd 76 77 def __item_pathname(id) 78 if id.kind_of?(Array) 79 id = tagid(id[1]) 80 end 81 [self.path, id].join(';') 82 end 83 private :__item_pathname 84 85 def axis_cget_tkstring(id, option) 86 ret = itemcget_tkstring(['axis', tagid(id)], option) 87 end 88 def axis_cget(id, option) 89 ret = itemcget(['axis', tagid(id)], option) 90 end 91 def axis_cget_strict(id, option) 92 ret = itemcget_strict(['axis', tagid(id)], option) 93 end 94 def axis_configure(*args) 95 slot = args.pop 96 if slot.kind_of?(Hash) 97 value = None 98 slot = _symbolkey2str(slot) 99 if cmd = slot.delete('command') 100 slot['command'] = proc{|w, tick| 101 cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) 102 } 103 end 104 else 105 value = slot 106 slot = args.pop 107 if slot == :command || slot == 'command' 108 cmd = value 109 value = proc{|w, tick| 110 cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) 111 } 112 end 113 end 114 id_list = args.flatten.collect!{|id| tagid(id)}.unshift('axis') 115 itemconfigure(id_list, slot, value) 116 end 117 def axis_configinfo(id, slot=nil) 118 itemconfiginfo(['axis', tagid(id)], slot) 119 end 120 def current_axis_configinfo(id, slot=nil) 121 current_itemconfiginfo(['axis', tagid(id)], slot) 122 end 123 124 def crosshairs_cget_tkstring(option) 125 itemcget_tkstring('crosshairs', option) 126 end 127 def crosshairs_cget(option) 128 itemcget('crosshairs', option) 129 end 130 def crosshairs_cget_strict(option) 131 itemcget_strict('crosshairs', option) 132 end 133 def crosshairs_configure(slot, value=None) 134 itemconfigure('crosshairs', slot, value) 135 end 136 def crosshairs_configinfo(slot=nil) 137 itemconfiginfo('crosshairs', slot) 138 end 139 def current_crosshairs_configinfo(slot=nil) 140 current_itemconfiginfo('crosshairs', slot) 141 end 142 143 def element_cget_tkstring(id, option) 144 itemcget_tkstring(['element', tagid(id)], option) 145 end 146 def element_cget(id, option) 147 itemcget(['element', tagid(id)], option) 148 end 149 def element_cget_strict(id, option) 150 itemcget_strict(['element', tagid(id)], option) 151 end 152 def element_configure(*args) 153 slot = args.pop 154 if slot.kind_of?(Hash) 155 value = None 156 else 157 value = slot 158 slot = args.pop 159 end 160 id_list = args.flatten.collect!{|id| tagid(id)}.unshift('element') 161 itemconfigure(id_list, slot, value) 162 end 163 def element_configinfo(id, slot=nil) 164 itemconfiginfo(['element', tagid(id)], slot) 165 end 166 def current_element_configinfo(id, slot=nil) 167 current_itemconfiginfo(['element', tagid(id)], slot) 168 end 169 170 def bar_cget_tkstring(id, option) 171 itemcget_tkstring(['bar', tagid(id)], option) 172 end 173 def bar_cget(id, option) 174 itemcget(['bar', tagid(id)], option) 175 end 176 def bar_cget_strict(id, option) 177 itemcget_strict(['bar', tagid(id)], option) 178 end 179 def bar_configure(*args) 180 slot = args.pop 181 if slot.kind_of?(Hash) 182 value = None 183 else 184 value = slot 185 slot = args.pop 186 end 187 id_list = args.flatten.collect!{|id| tagid(id)}.unshift('bar') 188 itemconfigure(id_list, slot, value) 189 end 190 def bar_configinfo(id, slot=nil) 191 itemconfiginfo(['bar', tagid(id)], slot) 192 end 193 def current_bar_configinfo(id, slot=nil) 194 current_itemconfiginfo(['bar', tagid(id)], slot) 195 end 196 197 def line_cget_tkstring(id, option) 198 itemcget_tkstring(['line', tagid(id)], option) 199 end 200 def line_cget(id, option) 201 itemcget(['line', tagid(id)], option) 202 end 203 def line_cget_strict(id, option) 204 itemcget_strict(['line', tagid(id)], option) 205 end 206 def line_configure(*args) 207 slot = args.pop 208 if slot.kind_of?(Hash) 209 value = None 210 else 211 value = slot 212 slot = args.pop 213 end 214 id_list = args.flatten.collect!{|id| tagid(id)}.unshift('line') 215 itemconfigure(id_list, slot, value) 216 end 217 def line_configinfo(id, slot=nil) 218 itemconfiginfo(['line', tagid(id)], slot) 219 end 220 def current_line_configinfo(id, slot=nil) 221 current_itemconfiginfo(['line', tagid(id)], slot) 222 end 223 224 def gridline_cget_tkstring(option) 225 itemcget_tkstring('grid', option) 226 end 227 def gridline_cget(option) 228 itemcget('grid', option) 229 end 230 def gridline_cget_strict(option) 231 itemcget_strict('grid', option) 232 end 233 def gridline_configure(slot, value=None) 234 itemconfigure('grid', slot, value) 235 end 236 def gridline_configinfo(slot=nil) 237 itemconfiginfo('grid', slot) 238 end 239 def current_gridline_configinfo(slot=nil) 240 current_itemconfiginfo('grid', slot) 241 end 242 243 def legend_cget_tkstring(option) 244 itemcget_tkstring('legend', option) 245 end 246 def legend_cget(option) 247 itemcget('legend', option) 248 end 249 def legend_cget_strict(option) 250 itemcget_strict('legend', option) 251 end 252 def legend_configure(slot, value=None) 253 itemconfigure('legend', slot, value) 254 end 255 def legend_configinfo(slot=nil) 256 itemconfiginfo('legend', slot) 257 end 258 def current_legend_configinfo(slot=nil) 259 current_itemconfiginfo('legend', slot) 260 end 261 262 def pen_cget_tkstring(id, option) 263 itemcget_tkstring(['pen', tagid(id)], option) 264 end 265 def pen_cget(id, option) 266 itemcget(['pen', tagid(id)], option) 267 end 268 def pen_cget_strict(id, option) 269 itemcget_strict(['pen', tagid(id)], option) 270 end 271 def pen_configure(*args) 272 slot = args.pop 273 if slot.kind_of?(Hash) 274 value = None 275 else 276 value = slot 277 slot = args.pop 278 end 279 id_list = args.flatten.collect!{|id| tagid(id)}.unshift('pen') 280 itemconfigure(id_list, slot, value) 281 end 282 def pen_configinfo(id, slot=nil) 283 itemconfiginfo(['pen', tagid(id)], slot) 284 end 285 def current_pen_configinfo(id, slot=nil) 286 current_itemconfiginfo(['pen', tagid(id)], slot) 287 end 288 289 def postscript_cget_tkstring(option) 290 itemcget_tkstring('postscript', option) 291 end 292 def postscript_cget(option) 293 itemcget('postscript', option) 294 end 295 def postscript_cget_strict(option) 296 itemcget_strict('postscript', option) 297 end 298 def postscript_configure(slot, value=None) 299 itemconfigure('postscript', slot, value) 300 end 301 def postscript_configinfo(slot=nil) 302 itemconfiginfo('postscript', slot) 303 end 304 def current_postscript_configinfo(slot=nil) 305 current_itemconfiginfo('postscript', slot) 306 end 307 308 def marker_cget_tkstring(id, option) 309 itemcget_tkstring(['marker', tagid(id)], option) 310 end 311 def marker_cget(id, option) 312 itemcget(['marker', tagid(id)], option) 313 end 314 def marker_cget_strict(id, option) 315 itemcget_strict(['marker', tagid(id)], option) 316 end 317 def marker_configure(*args) 318 slot = args.pop 319 if slot.kind_of?(Hash) 320 value = None 321 else 322 value = slot 323 slot = args.pop 324 end 325 id_list = args.flatten.collect!{|id| tagid(id)}.unshift('marker') 326 itemconfigure(id_list, slot, value) 327 end 328 def marker_configinfo(id, slot=nil) 329 itemconfiginfo(['marker', tagid(id)], slot) 330 end 331 def current_marker_configinfo(id, slot=nil) 332 current_itemconfiginfo(['marker', tagid(id)], slot) 333 end 334 335 alias __itemcget_tkstring itemcget_tkstring 336 alias __itemcget itemcget 337 alias __itemcget_strict itemcget_strict 338 alias __itemconfiginfo itemconfiginfo 339 alias __current_itemconfiginfo current_itemconfiginfo 340 private :__itemcget_tkstring, :__itemcget, :__itemconfiginfo, :__current_itemconfiginfo 341 342 def itemcget_tkstring(tagOrId, option) 343 __itemcget_tkstring(tagid(tagOrId), option) 344 end 345 def itemcget_strict(tagOrId, option) 346 ret = __itemcget(tagid(tagOrId), option) 347 if option == 'bindtags' || option == :bindtags 348 ret.collect{|tag| TkBindTag.id2obj(tag)} 349 else 350 ret 351 end 352 end 353 def itemcget(tagOrId, option) 354 unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ 355 itemcget_strict(tagOrId, option) 356 else 357 begin 358 itemcget_strict(tagOrId, option) 359 rescue => e 360 begin 361 if current_itemconfiginfo(tagOrId).has_key?(option.to_s) 362 # error on known option 363 fail e 364 else 365 # unknown option 366 nil 367 end 368 rescue 369 fail e # tag error 370 end 371 end 372 end 373 end 374 def itemconfiginfo(tagOrId, slot = nil) 375 ret = __itemconfiginfo(tagid(tagOrId), slot) 376 377 if TkComm::GET_CONFIGINFO_AS_ARRAY 378 if slot 379 if slot == 'bindtags' || slot == :bindtags 380 ret[-2] = ret[-2].collect{|tag| TkBindTag.id2obj(tag)} 381 ret[-1] = ret[-1].collect{|tag| TkBindTag.id2obj(tag)} 382 end 383 else 384 if (inf = ret.assoc('bindtags')) 385 inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)} 386 inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)} 387 end 388 end 389 390 else # ! TkComm::GET_CONFIGINFO_AS_ARRAY 391 if (inf = ret['bindtags']) 392 inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)} 393 inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)} 394 ret['bindtags'] = inf 395 end 396 end 397 398 ret 399 end 400 def current_itemconfiginfo(tagOrId, slot = nil) 401 ret = __current_itemconfiginfo(tagid(tagOrId), slot) 402 403 if (val = ret['bindtags']) 404 ret['bindtags'] = val.collect{|tag| TkBindTag.id2obj(tag)} 405 end 406 407 ret 408 end 409 410 private :itemcget_tkstring, :itemcget, :itemcget_strict 411 private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo 412 413 ################# 414 415 class Axis < TkObject 416 (OBJ_ID = ['blt_chart_axis'.freeze, TkUtil.untrust('00000')]).instance_eval{ 417 @mutex = Mutex.new 418 def mutex; @mutex; end 419 freeze 420 } 421 422 AxisID_TBL = TkCore::INTERP.create_table 423 424 TkCore::INTERP.init_ip_env{ 425 AxisID_TBL.mutex.synchronize{ AxisID_TBL.clear } 426 } 427 428 def self.id2obj(chart, id) 429 cpath = chart.path 430 AxisID_TBL.mutex.synchronize{ 431 return id unless AxisID_TBL[cpath] 432 AxisID_TBL[cpath][id]? AxisID_TBL[cpath][id]: id 433 } 434 end 435 436 def self.new(chart, axis=nil, keys={}) 437 if axis.kind_of?(Hash) 438 keys = axis 439 axis = nil 440 end 441 if keys 442 keys = _symbolkey2str(keys) 443 not_create = keys.delete('without_creating') 444 else 445 not_create = false 446 end 447 448 obj = nil 449 AxisID_TBL.mutex.synchronize{ 450 chart_path = chart.path 451 AxisID_TBL[chart_path] ||= {} 452 if axis && AxisID_TBL[chart_path][axis] 453 obj = AxisID_TBL[chart_path][axis] 454 else 455 (obj = self.allocate).instance_eval{ 456 if axis 457 @axis = @id = axis.to_s 458 else 459 OBJ_ID.mutex.synchronize{ 460 @axis = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze 461 OBJ_ID[1].succ! 462 } 463 end 464 @path = @id 465 @parent = @chart = chart 466 @cpath = @chart.path 467 Axis::AxisID_TBL[@cpath][@axis] = self 468 unless not_create 469 tk_call(@chart, 'axis', 'create', @axis, keys) 470 return obj 471 end 472 } 473 end 474 } 475 476 obj.configure(keys) if obj && ! keys.empty? 477 obj 478 end 479 480 def initialize(chart, axis=nil, keys={}) 481 # dummy:: not called by 'new' method 482 483 if axis.kind_of?(Hash) 484 keys = axis 485 axis = nil 486 end 487 if axis 488 @axis = @id = axis.to_s 489 else 490 OBJ_ID.mutex.synchronize{ 491 @axis = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze 492 OBJ_ID[1].succ! 493 } 494 end 495 @path = @id 496 @parent = @chart = chart 497 @cpath = @chart.path 498 # Axis::AxisID_TBL[@cpath][@axis] = self 499 keys = _symbolkey2str(keys) 500 unless keys.delete('without_creating') 501 # @chart.axis_create(@axis, keys) 502 tk_call(@chart, 'axis', 'create', @axis, keys) 503 end 504 end 505 506 def id 507 @id 508 end 509 510 def to_eval 511 @id 512 end 513 514 def cget_tkstring(option) 515 @chart.axis_cget_tkstring(@id, option) 516 end 517 def cget(option) 518 @chart.axis_cget(@id, option) 519 end 520 def cget_strict(option) 521 @chart.axis_cget_strict(@id, option) 522 end 523 def configure(key, value=None) 524 @chart.axis_configure(@id, key, value) 525 self 526 end 527 def configinfo(key=nil) 528 @chart.axis_configinfo(@id, key) 529 end 530 def current_configinfo(key=nil) 531 @chart.current_axis_configinfo(@id, key) 532 end 533 534 def command(cmd=nil, &b) 535 if cmd 536 configure('command', cmd) 537 elsif b 538 configure('command', Proc.new(&b)) 539 else 540 cget('command') 541 end 542 end 543 544 def delete 545 @chart.axis_delete(@id) 546 self 547 end 548 549 def invtransform(val) 550 @chart.axis_invtransform(@id, val) 551 end 552 553 def limits 554 @chart.axis_limits(@id) 555 end 556 557 def name 558 @axis 559 end 560 561 def transform(val) 562 @chart.axis_transform(@id, val) 563 end 564 565 def view 566 @chart.axis_view(@id) 567 self 568 end 569 570 def use(name=None) # if @id == xaxis | x2axis | yaxis | y2axis 571 @chart.axis_use(@id, name) 572 end 573 574 def use_as(axis) # axis := xaxis | x2axis | yaxis | y2axis 575 @chart.axis_use(axis, @id) 576 end 577 end 578 579 ################# 580 581 class Crosshairs < TkObject 582 CrosshairsID_TBL = TkCore::INTERP.create_table 583 584 TkCore::INTERP.init_ip_env{ 585 CrosshairsID_TBL.mutex.synchronize{ CrosshairsID_TBL.clear } 586 } 587 588 def self.new(chart, keys={}) 589 obj = nil 590 CrosshairsID_TBL.mutex.synchronize{ 591 unless (obj = CrosshairsID_TBL[chart.path]) 592 (obj = self.allocate).instance_eval{ 593 @parent = @chart = chart 594 @cpath = @chart.path 595 @path = @id = 'crosshairs' 596 Crosshairs::CrosshairsID_TBL[@cpath] = self 597 } 598 end 599 } 600 chart.crosshair_configure(keys) if obj && ! keys.empty? 601 obj 602 end 603 604 def initialize(chart, keys={}) 605 # dummy:: not called by 'new' method 606 607 @parent = @chart = chart 608 @cpath = @chart.path 609 # Crosshairs::CrosshairsID_TBL[@cpath] = self 610 @chart.crosshair_configure(keys) unless keys.empty? 611 @path = @id = 'crosshairs' 612 end 613 614 def id 615 @id 616 end 617 618 def to_eval 619 @id 620 end 621 622 def cget_tkstring(option) 623 @chart.crosshair_cget_tkstring(option) 624 end 625 def cget(option) 626 @chart.crosshair_cget(option) 627 end 628 def cget_strict(option) 629 @chart.crosshair_cget_strict(option) 630 end 631 def configure(key, value=None) 632 @chart.crosshair_configure(key, value) 633 self 634 end 635 def configinfo(key=nil) 636 @chart.crosshair_configinfo(key) 637 end 638 def current_configinfo(key=nil) 639 @chart.current_crosshair_configinfo(key) 640 end 641 642 def off 643 @chart.crosshair_off 644 self 645 end 646 def on 647 @chart.crosshair_on 648 self 649 end 650 def toggle 651 @chart.crosshair_toggle 652 self 653 end 654 end 655 656 ################# 657 658 class Element < TkObject 659 extend Tk 660 extend TkItemFontOptkeys 661 extend TkItemConfigOptkeys 662 663 extend Tk::BLT::PlotComponent::OptKeys 664 665 ElementTypeName = 'element' 666 ElementTypeToClass = { ElementTypeName=>self } 667 668 ElementID_TBL = TkCore::INTERP.create_table 669 670 TkCore::INTERP.init_ip_env{ 671 ElementID_TBL.mutex.synchronize{ ElementID_TBL.clear } 672 } 673 674 (OBJ_ID = ['blt_chart_element'.freeze, TkUtil.untrust('00000')]).instance_eval{ 675 @mutex = Mutex.new 676 def mutex; @mutex; end 677 freeze 678 } 679 680 def Element.type2class(type) 681 ElementTypeToClass[type] 682 end 683 684 def Element.id2obj(chart, id) 685 cpath = chart.path 686 ElementID_TBL.mutex.synchronize{ 687 return id unless ElementID_TBL[cpath] 688 ElementID_TBL[cpath][id]? ElementID_TBL[cpath][id]: id 689 } 690 end 691 692 def self.new(chart, element=nil, keys={}) 693 if element.kind_of?(Hash) 694 keys = element 695 element = nil 696 end 697 if keys 698 keys = _symbolkey2str(keys) 699 not_create = keys.delete('without_creating') 700 else 701 not_create = false 702 end 703 704 obj = nil 705 ElementID_TBL.mutex.synchronize{ 706 chart_path = chart.path 707 ElementID_TBL[chart_path] ||= {} 708 if element && ElementID_TBL[chart_path][element] 709 obj = ElementID_TBL[chart_path][element] 710 else 711 (obj = self.allocate).instance_eval{ 712 if element 713 @element = @id = element.to_s 714 else 715 OBJ_ID.mutex.synchronize{ 716 @element = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze 717 OBJ_ID[1].succ! 718 } 719 end 720 @path = @id 721 @parent = @chart = chart 722 @cpath = @chart.path 723 @typename = self.class::ElementTypeName 724 Element::ElementID_TBL[@cpath][@element] = self 725 unless not_create 726 tk_call(@chart, @typename, 'create', @element, keys) 727 return obj 728 end 729 } 730 end 731 } 732 733 obj.configure(keys) if obj && ! keys.empty? 734 obj 735 end 736 737 def initialize(chart, element=nil, keys={}) 738 # dummy:: not called by 'new' method 739 740 if element.kind_of?(Hash) 741 keys = element 742 element = nil 743 end 744 if element 745 @element = @id = element.to_s 746 else 747 OBJ_ID.mutex.synchronize{ 748 @element = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze 749 OBJ_ID[1].succ! 750 } 751 end 752 @path = @id 753 @parent = @chart = chart 754 @cpath = @chart.path 755 @typename = self.class::ElementTypeName 756 # Element::ElementID_TBL[@cpath][@element] = self 757 keys = _symbolkey2str(keys) 758 unless keys.delete('without_creating') 759 # @chart.element_create(@element, keys) 760 tk_call(@chart, @typename, 'create', @element, keys) 761 end 762 end 763 764 def id 765 @id 766 end 767 768 def to_eval 769 @id 770 end 771 772 def cget_tkstring(option) 773 # @chart.element_cget(@id, option) 774 @chart.__send__(@typename + '_cget_tkstring', @id, option) 775 end 776 def cget(option) 777 # @chart.element_cget(@id, option) 778 @chart.__send__(@typename + '_cget', @id, option) 779 end 780 def cget_strict(option) 781 @chart.__send__(@typename + '_cget_strict', @id, option) 782 end 783 def configure(key, value=None) 784 # @chart.element_configure(@id, key, value) 785 @chart.__send__(@typename + '_configure', @id, key, value) 786 self 787 end 788 def configinfo(key=nil) 789 # @chart.element_configinfo(@id, key) 790 @chart.__send__(@typename + '_configinfo', @id, key) 791 end 792 def current_configinfo(key=nil) 793 # @chart.current_element_configinfo(@id, key) 794 @chart.__send__('current_' << @typename << '_configinfo', @id, key) 795 end 796 797 def activate(*args) 798 @chart.element_activate(@id, *args) 799 end 800 801 def closest(x, y, var, keys={}) 802 # @chart.element_closest(x, y, var, @id, keys) 803 @chart.__send__(@typename + '_closest', x, y, var, @id, keys) 804 end 805 806 def deactivate 807 @chart.element_deactivate(@id) 808 self 809 end 810 811 def delete 812 @chart.element_delete(@id) 813 self 814 end 815 816 def exist? 817 @chart.element_exist?(@id) 818 end 819 820 def name 821 @element 822 end 823 824 def type 825 @chart.element_type(@id) 826 end 827 end 828 829 class Bar < Element 830 ElementTypeName = 'bar'.freeze 831 ElementTypeToClass[ElementTypeName] = self 832 end 833 class Line < Element 834 ElementTypeName = 'line'.freeze 835 ElementTypeToClass[ElementTypeName] = self 836 end 837 838 ################# 839 840 class GridLine < TkObject 841 GridLineID_TBL = TkCore::INTERP.create_table 842 TkCore::INTERP.init_ip_env{ 843 GridLineID_TBL.mutex.synchronize{ GridLineID_TBL.clear } 844 } 845 846 def self.new(chart, keys={}) 847 obj = nil 848 GridLineID_TBL.mutex.synchronize{ 849 unless (obj = GridLineID_TBL[chart.path]) 850 (obj = self.allocate).instance_eval{ 851 @parent = @chart = chart 852 @cpath = @chart.path 853 @path = @id = 'grid' 854 GridLine::GridLineID_TBL[@cpath] = self 855 } 856 end 857 } 858 chart.gridline_configure(keys) if obj && ! keys.empty? 859 obj 860 end 861 862 def initialize(chart, keys={}) 863 # dummy:: not called by 'new' method 864 865 @parent = @chart = chart 866 @cpath = @chart.path 867 # GridLine::GridLineID_TBL[@cpath] = self 868 @chart.gridline_configure(keys) unless keys.empty? 869 @path = @id = 'grid' 870 end 871 872 def id 873 @id 874 end 875 876 def to_eval 877 @id 878 end 879 880 def cget_tkstring(option) 881 @chart.gridline_cget_tkstring(option) 882 end 883 def cget(option) 884 @chart.gridline_cget(option) 885 end 886 def cget_strict(option) 887 @chart.gridline_cget_strict(option) 888 end 889 def configure(key, value=None) 890 @chart.gridline_configure(key, value) 891 self 892 end 893 def configinfo(key=nil) 894 @chart.gridline_configinfo(key) 895 end 896 def current_configinfo(key=nil) 897 @chart.current_gridline_configinfo(key) 898 end 899 900 def off 901 @chart.gridline_off 902 self 903 end 904 def on 905 @chart.gridline_on 906 self 907 end 908 def toggle 909 @chart.gridline_toggle 910 self 911 end 912 end 913 914 ################# 915 916 class Legend < TkObject 917 LegendID_TBL = TkCore::INTERP.create_table 918 919 TkCore::INTERP.init_ip_env{ 920 LegendID_TBL.mutex.synchronize{ LegendID_TBL.clear } 921 } 922 923 def self.new(chart, keys={}) 924 obj = nil 925 LegenedID_TBL.mutex.synchronize{ 926 unless (obj = LegenedID_TBL[chart.path]) 927 (obj = self.allocate).instance_eval{ 928 @parent = @chart = chart 929 @cpath = @chart.path 930 @path = @id = 'crosshairs' 931 Legend::LegenedID_TBL[@cpath] = self 932 } 933 end 934 } 935 chart.legend_configure(keys) if obj && ! keys.empty? 936 obj 937 end 938 939 def initialize(chart, keys={}) 940 # dummy:: not called by 'new' method 941 942 @parent = @chart = chart 943 @cpath = @chart.path 944 # Legend::LegendID_TBL[@cpath] = self 945 @chart.legend_configure(keys) unless keys.empty? 946 @path = @id = 'legend' 947 end 948 949 def id 950 @id 951 end 952 953 def to_eval 954 @id 955 end 956 957 def cget_tkstring(option) 958 @chart.legend_cget_tkstring(option) 959 end 960 def cget(option) 961 @chart.legend_cget(option) 962 end 963 def cget_strict(option) 964 @chart.legend_cget_strict(option) 965 end 966 def configure(key, value=None) 967 @chart.legend_configure(key, value) 968 self 969 end 970 def configinfo(key=nil) 971 @chart.legend_configinfo(key) 972 end 973 def current_configinfo(key=nil) 974 @chart.current_legend_configinfo(key) 975 end 976 977 def activate(*args) 978 @chart.legend_activate(*args) 979 end 980 981 def deactivate(*args) 982 @chart.legend_deactivate(*args) 983 end 984 985 def get(pos, y=nil) 986 @chart.legend_get(pos, y) 987 end 988 end 989 990 ################# 991 992 class Pen < TkObject 993 (OBJ_ID = ['blt_chart_pen'.freeze, TkUtil.untrust('00000')]).instance_eval{ 994 @mutex = Mutex.new 995 def mutex; @mutex; end 996 freeze 997 } 998 999 PenID_TBL = TkCore::INTERP.create_table 1000 1001 TkCore::INTERP.init_ip_env{ 1002 PenID_TBL.mutex.synchronize{ PenID_TBL.clear } 1003 } 1004 1005 def self.id2obj(chart, id) 1006 cpath = chart.path 1007 PenID_TBL.mutex.synchronize{ 1008 return id unless PenID_TBL[cpath] 1009 PenID_TBL[cpath][id]? PenID_TBL[cpath][id]: id 1010 } 1011 end 1012 1013 def self.new(chart, pen=nil, keys={}) 1014 if pen.kind_of?(Hash) 1015 keys = pen 1016 pen = nil 1017 end 1018 if keys 1019 keys = _symbolkey2str(keys) 1020 not_create = keys.delete('without_creating') 1021 else 1022 not_create = false 1023 end 1024 1025 obj = nil 1026 PenID_TBL.mutex.synchronize{ 1027 chart_path = chart.path 1028 PenID_TBL[chart_path] ||= {} 1029 if pen && PenID_TBL[chart_path][pen] 1030 obj = PenID_TBL[chart_path][pen] 1031 else 1032 (obj = self.allocate).instance_eval{ 1033 if pen 1034 @pen = @id = pen.to_s 1035 else 1036 OBJ_ID.mutex.synchronize{ 1037 @pen = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze 1038 OBJ_ID[1].succ! 1039 } 1040 end 1041 @path = @id 1042 @parent = @chart = chart 1043 @cpath = @chart.path 1044 Pen::PenID_TBL[@cpath][@pen] = self 1045 unless not_create 1046 tk_call(@chart, 'pen', 'create', @pen, keys) 1047 return obj 1048 end 1049 } 1050 end 1051 } 1052 1053 obj.configure(keys) if obj && ! keys.empty? 1054 obj 1055 end 1056 1057 def initialize(chart, pen=nil, keys={}) 1058 if pen.kind_of?(Hash) 1059 keys = pen 1060 pen = nil 1061 end 1062 if pen 1063 @pen = @id = pen.to_s 1064 else 1065 OBJ_ID.mutex.synchronize{ 1066 @pen = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze 1067 OBJ_ID[1].succ! 1068 } 1069 end 1070 @path = @id 1071 @parent = @chart = chart 1072 @cpath = @chart.path 1073 Pen::PenID_TBL[@cpath][@pen] = self 1074 keys = _symbolkey2str(keys) 1075 unless keys.delete('without_creating') 1076 # @chart.pen_create(@pen, keys) 1077 tk_call(@chart, 'pen', 'create', @pen, keys) 1078 end 1079 end 1080 1081 def id 1082 @id 1083 end 1084 1085 def to_eval 1086 @id 1087 end 1088 1089 def cget_tkstring(option) 1090 @chart.pen_cget_tkstring(@id, option) 1091 end 1092 def cget(option) 1093 @chart.pen_cget(@id, option) 1094 end 1095 def cget_strict(option) 1096 @chart.pen_cget_strict(@id, option) 1097 end 1098 def configure(key, value=None) 1099 @chart.pen_configure(@id, key, value) 1100 self 1101 end 1102 def configinfo(key=nil) 1103 @chart.pen_configinfo(@id, key) 1104 end 1105 def current_configinfo(key=nil) 1106 @chart.current_pen_configinfo(@id, key) 1107 end 1108 1109 def delete 1110 @chart.pen_delete(@id) 1111 self 1112 end 1113 1114 def name 1115 @pen 1116 end 1117 end 1118 1119 ################# 1120 1121 class Postscript < TkObject 1122 PostscriptID_TBL = TkCore::INTERP.create_table 1123 1124 TkCore::INTERP.init_ip_env{ 1125 PostscriptID_TBL.mutex.synchronize{ PostscriptID_TBL.clear } 1126 } 1127 1128 def self.new(chart, keys={}) 1129 obj = nil 1130 PostscriptID_TBL.mutex.synchronize{ 1131 unless (obj = PostscriptID_TBL[chart.path]) 1132 (obj = self.allocate).instance_eval{ 1133 @parent = @chart = chart 1134 @cpath = @chart.path 1135 @path = @id = 'postscript' 1136 Postscript::PostscriptID_TBL[@cpath] = self 1137 } 1138 end 1139 } 1140 chart.postscript_configure(keys) if obj && ! keys.empty? 1141 obj 1142 end 1143 1144 def initialize(chart, keys={}) 1145 # dummy:: not called by 'new' method 1146 1147 @parent = @chart = chart 1148 @cpath = @chart.path 1149 # Postscript::PostscriptID_TBL[@cpath] = self 1150 @chart.postscript_configure(keys) unless keys.empty? 1151 @path = @id = 'postscript' 1152 end 1153 1154 def id 1155 @id 1156 end 1157 1158 def to_eval 1159 @id 1160 end 1161 1162 def cget_tkstring(option) 1163 @chart.postscript_cget_tkstring(option) 1164 end 1165 def cget(option) 1166 @chart.postscript_cget(option) 1167 end 1168 def cget_strict(option) 1169 @chart.postscript_cget_strict(option) 1170 end 1171 def configure(key, value=None) 1172 @chart.postscript_configure(key, value) 1173 self 1174 end 1175 def configinfo(key=nil) 1176 @chart.postscript_configinfo(key) 1177 end 1178 def current_configinfo(key=nil) 1179 @chart.current_postscript_configinfo(key) 1180 end 1181 1182 def output(file=nil, keys={}) 1183 if file.kind_of?(Hash) 1184 keys = file 1185 file = nil 1186 end 1187 1188 ret = @chart.postscript_output(file, keys) 1189 1190 if file 1191 self 1192 else 1193 ret 1194 end 1195 end 1196 end 1197 1198 ################# 1199 class Marker < TkObject 1200 extend Tk 1201 extend TkItemFontOptkeys 1202 extend TkItemConfigOptkeys 1203 1204 extend Tk::BLT::PlotComponent::OptKeys 1205 1206 MarkerTypeName = nil 1207 MarkerTypeToClass = {} 1208 MarkerID_TBL = TkCore::INTERP.create_table 1209 1210 TkCore::INTERP.init_ip_env{ 1211 MarkerID_TBL.mutex.synchronize{ MarkerID_TBL.clear } 1212 } 1213 1214 def Marker.type2class(type) 1215 MarkerTypeToClass[type] 1216 end 1217 1218 def Marker.id2obj(chart, id) 1219 cpath = chart.path 1220 MarkerID_TBL.mutex.synchronize{ 1221 if MarkerID_TBL[cpath] 1222 MarkerID_TBL[cpath][id]? MarkerID_TBL[cpath][id]: id 1223 else 1224 id 1225 end 1226 } 1227 end 1228 1229 def self._parse_create_args(keys) 1230 fontkeys = {} 1231 methodkeys = {} 1232 if keys.kind_of? Hash 1233 keys = _symbolkey2str(keys) 1234 1235 __item_font_optkeys(nil).each{|key| 1236 fkey = key.to_s 1237 fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) 1238 1239 fkey = "kanji#{key}" 1240 fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) 1241 1242 fkey = "latin#{key}" 1243 fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) 1244 1245 fkey = "ascii#{key}" 1246 fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) 1247 } 1248 1249 __item_optkey_aliases(nil).each{|alias_name, real_name| 1250 alias_name = alias_name.to_s 1251 if keys.has_key?(alias_name) 1252 keys[real_name.to_s] = keys.delete(alias_name) 1253 end 1254 } 1255 1256 __item_methodcall_optkeys(nil).each{|key| 1257 key = key.to_s 1258 methodkeys[key] = keys.delete(key) if keys.key?(key) 1259 } 1260 1261 __item_ruby2val_optkeys(nil).each{|key, method| 1262 key = key.to_s 1263 keys[key] = method.call(keys[key]) if keys.has_key?(key) 1264 } 1265 1266 args = itemconfig_hash_kv(nil, keys) 1267 else 1268 args = [] 1269 end 1270 1271 [args, fontkeys, methodkeys] 1272 end 1273 private_class_method :_parse_create_args 1274 1275 def self.create(chart, keys={}) 1276 unless self::MarkerTypeName 1277 fail RuntimeError, "#{self} is an abstract class" 1278 end 1279 args, fontkeys, methodkeys = _parse_create_args(keys) 1280 idnum = tk_call_without_enc(chart.path, 'marker', 'create', 1281 self::MarkerTypeName, *args) 1282 chart.marker_configure(idnum, fontkeys) unless fontkeys.empty? 1283 chart.marker_configure(idnum, methodkeys) unless methodkeys.empty? 1284 idnum.to_i # 'item id' is an integer number 1285 end 1286 1287 def self.create_type(chart, type, keys={}) 1288 args, fontkeys, methodkeys = _parse_create_args(keys) 1289 idnum = tk_call_without_enc(chart.path, 'marker', 'create', 1290 type, *args) 1291 chart.marker_configure(idnum, fontkeys) unless fontkeys.empty? 1292 chart.marker_configure(idnum, methodkeys) unless methodkeys.empty? 1293 id = idnum.to_i # 'item id' is an integer number 1294 obj = self.allocate 1295 obj.instance_eval{ 1296 @parent = @chart = chart 1297 @cpath = chart.path 1298 @id = id 1299 Tk::BLT::PlotComponent::Marker::MarkerID_TBL.mutex.synchronize{ 1300 Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] ||= {} 1301 Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath][@id] = self 1302 } 1303 } 1304 obj 1305 end 1306 1307 def initialize(parent, *args) 1308 @parent = @chart = parent 1309 @cpath = parent.path 1310 1311 @path = @id = create_self(*args) # an integer number as 'item id' 1312 Tk::BLT::PlotComponent::Marker::MarkerID_TBL.mutex.synchronize{ 1313 Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] ||= {} 1314 Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath][@id] = self 1315 } 1316 end 1317 def create_self(*args) 1318 self.class.create(@chart, *args) # return an integer as 'item id' 1319 end 1320 private :create_self 1321 1322 def id 1323 @id 1324 end 1325 1326 def to_eval 1327 @id 1328 end 1329 1330 def cget_tkstring(option) 1331 @chart.marker_cget_tkstring(@id, option) 1332 end 1333 def cget(option) 1334 @chart.marker_cget(@id, option) 1335 end 1336 def cget_strict(option) 1337 @chart.marker_cget_strict(@id, option) 1338 end 1339 def configure(key, value=None) 1340 @chart.marker_configure(@id, key, value) 1341 self 1342 end 1343 def configinfo(key=nil) 1344 @chart.marker_configinfo(@id, key) 1345 end 1346 def current_configinfo(key=nil) 1347 @chart.current_marker_configinfo(@id, key) 1348 end 1349 1350 def after(target=None) 1351 @chart.marker_after(@id, target) 1352 end 1353 1354 def before(target=None) 1355 @chart.marker_before(@id, target) 1356 end 1357 1358 def delete 1359 @chart.marker_delete(@id) 1360 end 1361 1362 def exist? 1363 @chart.marker_exist(@id) 1364 end 1365 1366 def type 1367 @chart.marker_type(@id) 1368 end 1369 end 1370 1371 class TextMarker < Marker 1372 MarkerTypeName = 'text'.freeze 1373 MarkerTypeToClass[MarkerTypeName] = self 1374 end 1375 class LineMarker < Marker 1376 MarkerTypeName = 'line'.freeze 1377 MarkerTypeToClass[MarkerTypeName] = self 1378 end 1379 class BitmapMarker < Marker 1380 MarkerTypeName = 'bitmap'.freeze 1381 MarkerTypeToClass[MarkerTypeName] = self 1382 end 1383 class ImageMarker < Marker 1384 MarkerTypeName = 'image'.freeze 1385 MarkerTypeToClass[MarkerTypeName] = self 1386 end 1387 class PolygonMarker < Marker 1388 MarkerTypeName = 'polygon'.freeze 1389 MarkerTypeToClass[MarkerTypeName] = self 1390 end 1391 class WindowMarker < Marker 1392 MarkerTypeName = 'window'.freeze 1393 MarkerTypeToClass[MarkerTypeName] = self 1394 end 1395 1396 ################# 1397 1398 def __destroy_hook__ 1399 Axis::AxisID_TBL.delete(@path) 1400 Crosshairs::CrosshairsID_TBL.delete(@path) 1401 Element::ElementID_TBL.delete(@path) 1402 GridLine::GridLineID_TBL.delete(@path) 1403 Legend::LegendID_TBL.delete(@path) 1404 Pen::PenID_TBL.delete(@path) 1405 Postscript::PostscriptID_TBL.delete(@path) 1406 Marker::MarkerID_TBL.delete(@path) 1407 super() 1408 end 1409 1410 ################# 1411 1412 def tagid(tag) 1413 if tag.kind_of?(Axis) || 1414 tag.kind_of?(Crosshairs) || 1415 tag.kind_of?(Element) || 1416 tag.kind_of?(GridLine) || 1417 tag.kind_of?(Legend) || 1418 tag.kind_of?(Pen) || 1419 tag.kind_of?(Postscript) || 1420 tag.kind_of?(Marker) 1421 tag.id 1422 else 1423 tag # maybe an Array of configure paramters 1424 end 1425 end 1426 1427 def _component_bind(target, tag, context, *args) 1428 if TkComm._callback_entry?(args[0]) || !block_given? 1429 cmd = args.shift 1430 else 1431 cmd = Proc.new 1432 end 1433 _bind([path, target, 'bind', tagid(tag)], context, cmd, *args) 1434 self 1435 end 1436 def _component_bind_append(target, tag, context, *args) 1437 if TkComm._callback_entry?(args[0]) || !block_given? 1438 cmd = args.shift 1439 else 1440 cmd = Proc.new 1441 end 1442 _bind_append([path, target, 'bind', tagid(tag)], context, cmd, *args) 1443 self 1444 end 1445 def _component_bind_remove(target, tag, context) 1446 _bind_remove([path, target, 'bind', tagid(tag)], context) 1447 self 1448 end 1449 def _component_bindinfo(target, tag, context=nil) 1450 _bindinfo([path, target, 'bind', tagid(tag)], context) 1451 end 1452 private :_component_bind, :_component_bind_append 1453 private :_component_bind_remove, :_component_bindinfo 1454 1455 def axis_bind(tag, context, *args) 1456 _component_bind('axis', tag, context, *args) 1457 end 1458 def axis_bind_append(tag, context, *args) 1459 _component_bind_append('axis', tag, context, *args) 1460 end 1461 def axis_bind_remove(tag, context) 1462 _component_bind_remove('axis', tag, context) 1463 end 1464 def axis_bindinfo(tag, context=nil) 1465 _component_bindinfo('axis', tag, context) 1466 end 1467 1468 def element_bind(tag, context, *args) 1469 _component_bind('element', tag, context, *args) 1470 end 1471 def element_bind_append(tag, context, *args) 1472 _component_bind_append('element', tag, context, *args) 1473 end 1474 def element_bind_remove(tag, context) 1475 _component_bind_remove('element', tag, context) 1476 end 1477 def element_bindinfo(tag, context=nil) 1478 _component_bindinfo('element', tag, context) 1479 end 1480 1481 def bar_bind(tag, context, *args) 1482 _component_bind('bar', tag, context, *args) 1483 end 1484 def bar_bind_append(tag, context, *args) 1485 _component_bind_append('bar', tag, context, *args) 1486 end 1487 def bar_bind_remove(tag, context) 1488 _component_bind_remove('bar', tag, context) 1489 end 1490 def bar_bindinfo(tag, context=nil) 1491 _component_bindinfo('bar', tag, context) 1492 end 1493 1494 def line_bind(tag, context, *args) 1495 _component_bind('line', tag, context, *args) 1496 end 1497 def line_bind_append(tag, context, *args) 1498 _component_bind_append('line', tag, context, *args) 1499 end 1500 def line_bind_remove(tag, context) 1501 _component_bind_remove('line', tag, context) 1502 end 1503 def line_bindinfo(tag, context=nil) 1504 _component_bindinfo('line', tag, context) 1505 end 1506 1507 def legend_bind(tag, context, *args) 1508 _component_bind('legend', tag, context, *args) 1509 end 1510 def legend_bind_append(tag, context, *args) 1511 _component_bind_append('legend', tag, context, *args) 1512 end 1513 def legend_bind_remove(tag, context) 1514 _component_bind_remove('legend', tag, context) 1515 end 1516 def legend_bindinfo(tag, context=nil) 1517 _component_bindinfo('legend', tag, context) 1518 end 1519 1520 def marker_bind(tag, context, *args) 1521 _component_bind('marker', tag, context, *args) 1522 end 1523 def marker_bind_append(tag, context, *args) 1524 _component_bind_append('marker', tag, context, *args) 1525 end 1526 def marker_bind_remove(tag, context) 1527 _component_bind_remove('marker', tag, context) 1528 end 1529 def marker_bindinfo(tag, context=nil) 1530 _component_bindinfo('marker', tag, context) 1531 end 1532 1533 ################### 1534 1535 def axis_create(id=nil, keys={}) 1536 # tk_send('axis', 'create', tagid(id), keys) 1537 Tk::BLT::PlotComponent::Axis.new(self, tagid(id), keys) 1538 end 1539 def axis_delete(*ids) 1540 tk_send('axis', 'delete', *(ids.collect{|id| tagid(id)})) 1541 self 1542 end 1543 def axis_invtransform(id, val) 1544 list(tk_send('axis', 'invtransform', tagid(id), val)) 1545 end 1546 def axis_limits(id) 1547 list(tk_send('axis', 'limits', tagid(id))) 1548 end 1549 def axis_names(*pats) 1550 simplelist(tk_send('axis', 'names', 1551 *(pats.collect{|pat| tagid(pat)}))).collect{|axis| 1552 Tk::BLT::PlotComponent::Axis.id2obj(self, axis) 1553 } 1554 end 1555 def axis_transform(id, val) 1556 list(tk_send('axis', 'transform', tagid(id), val)) 1557 end 1558 def axis_view(id) 1559 tk_send('axis', 'view', tagid(id)) 1560 self 1561 end 1562 def axis_use(id, target=nil) 1563 if target 1564 Tk::BLT::PlotComponent::Axis.id2obj(self, 1565 tk_send('axis', 'use', 1566 tagid(id), tagid(target))) 1567 else 1568 Tk::BLT::PlotComponent::Axis.id2obj(self, 1569 tk_send('axis', 'use', tagid(id))) 1570 end 1571 end 1572 1573 ################### 1574 1575 def crosshairs_off 1576 tk_send_without_enc('crosshairs', 'off') 1577 self 1578 end 1579 def crosshairs_on 1580 tk_send_without_enc('crosshairs', 'on') 1581 self 1582 end 1583 def crosshairs_toggle 1584 tk_send_without_enc('crosshairs', 'toggle') 1585 self 1586 end 1587 1588 ################### 1589 1590 def element_create(id=nil, keys={}) 1591 # tk_send('element', 'create', tagid(id), keys) 1592 Tk::BLT::PlotComponent::Element.new(self, tagid(id), keys) 1593 end 1594 def element_activate(*args) 1595 if args.empty? 1596 list(tk_send('element', 'activate')).collect{|elem| 1597 Tk::BLT::PlotComponent::Element.id2obj(self, elem) 1598 } 1599 else 1600 # id, *indices 1601 id = args.shift 1602 tk_send('element', 'activate', tagid(id), *args) 1603 end 1604 end 1605 def element_closest(x, y, var, *args) 1606 if args[-1].kind_of?(Hash) 1607 keys = args.pop 1608 bool(tk_send('element', 'closest', x, y, var, 1609 *(hash_kv(keys).concat(args.collect{|id| tagid(id)})))) 1610 else 1611 bool(tk_send('element', 'closest', x, y, var, 1612 *(args.collect{|id| tagid(id)}))) 1613 end 1614 end 1615 def element_deactivate(*ids) 1616 tk_send('element', 'deactivate', *(ids.collect{|id| tagid(id)})) 1617 self 1618 end 1619 def element_delete(*ids) 1620 tk_send('element', 'delete', *(ids.collect{|id| tagid(id)})) 1621 self 1622 end 1623 def element_exist?(id) 1624 bool(tk_send('element', 'exists', tagid(id))) 1625 end 1626 def element_names(*pats) 1627 simplelist(tk_send('element', 'names', 1628 *(pats.collect{|pat| tagid(pat)}))).collect{|elem| 1629 Tk::BLT::PlotComponent::Element.id2obj(self, elem) 1630 } 1631 end 1632 def element_show(*names) 1633 if names.empty? 1634 simplelist(tk_send('element', 'show')) 1635 else 1636 tk_send('element', 'show', *(names.collect{|n| tagid(n)})) 1637 self 1638 end 1639 end 1640 def element_type(id) 1641 tk_send('element', 'type', tagid(id)) 1642 end 1643 1644 ################### 1645 1646 def bar_create(id=nil, keys={}) 1647 # tk_send('bar', 'create', tagid(id), keys) 1648 Tk::BLT::PlotComponent::Bar.new(self, tagid(id), keys) 1649 end 1650 alias bar bar_create 1651 def bar_activate(*args) 1652 if args.empty? 1653 list(tk_send('bar', 'activate')).collect{|elem| 1654 Tk::BLT::PlotComponent::Element.id2obj(self, elem) 1655 } 1656 else 1657 # id, *indices 1658 id = args.shift 1659 tk_send('bar', 'activate', tagid(id), *args) 1660 end 1661 end 1662 def bar_closest(x, y, var, *args) 1663 if args[-1].kind_of?(Hash) 1664 keys = args.pop 1665 bool(tk_send('bar', 'closest', x, y, var, 1666 *(hash_kv(keys).concat(args.collect{|id| tagid(id)})))) 1667 else 1668 bool(tk_send('bar', 'closest', x, y, var, 1669 *(args.collect{|id| tagid(id)}))) 1670 end 1671 end 1672 def bar_deactivate(*ids) 1673 tk_send('bar', 'deactivate', *(ids.collect{|id| tagid(id)})) 1674 self 1675 end 1676 def bar_delete(*ids) 1677 tk_send('bar', 'delete', *(ids.collect{|id| tagid(id)})) 1678 self 1679 end 1680 def bar_exist?(id) 1681 bool(tk_send('bar', 'exists', tagid(id))) 1682 end 1683 def bar_names(*pats) 1684 simplelist(tk_send('bar', 'names', 1685 *(pats.collect{|pat| tagid(pat)}))).collect{|elem| 1686 Tk::BLT::PlotComponent::Element.id2obj(self, elem) 1687 } 1688 end 1689 def bar_show(*names) 1690 if names.empty? 1691 simplelist(tk_send('bar', 'show')) 1692 else 1693 tk_send('bar', 'show', *(names.collect{|n| tagid(n)})) 1694 self 1695 end 1696 end 1697 def bar_type(id) 1698 tk_send('bar', 'type', tagid(id)) 1699 end 1700 1701 ################### 1702 1703 def line_create(id=nil, keys={}) 1704 # tk_send('line', 'create', tagid(id), keys) 1705 Tk::BLT::PlotComponent::Line.new(self, tagid(id), keys) 1706 end 1707 alias bar line_create 1708 def line_activate(*args) 1709 if args.empty? 1710 list(tk_send('line', 'activate')).collect{|elem| 1711 Tk::BLT::PlotComponent::Element.id2obj(self, elem) 1712 } 1713 else 1714 # id, *indices 1715 id = args.shift 1716 tk_send('line', 'activate', tagid(id), *args) 1717 end 1718 end 1719 def line_closest(x, y, var, *args) 1720 if args[-1].kind_of?(Hash) 1721 keys = args.pop 1722 bool(tk_send('line', 'closest', x, y, var, 1723 *(hash_kv(keys).concat(args.collect{|id| tagid(id)})))) 1724 else 1725 bool(tk_send('line', 'closest', x, y, var, 1726 *(args.collect{|id| tagid(id)}))) 1727 end 1728 end 1729 def line_deactivate(*ids) 1730 tk_send('line', 'deactivate', *(ids.collect{|id| tagid(id)})) 1731 self 1732 end 1733 def line_delete(*ids) 1734 tk_send('line', 'delete', *(ids.collect{|id| tagid(id)})) 1735 self 1736 end 1737 def line_exist?(id) 1738 bool(tk_send('line', 'exists', tagid(id))) 1739 end 1740 def line_names(*pats) 1741 simplelist(tk_send('line', 'names', 1742 *(pats.collect{|pat| tagid(pat)}))).collect{|elem| 1743 Tk::BLT::PlotComponent::Element.id2obj(self, elem) 1744 } 1745 end 1746 def line_show(*names) 1747 if names.empty? 1748 simplelist(tk_send('line', 'show')) 1749 else 1750 tk_send('line', 'show', *(names.collect{|n| tagid(n)})) 1751 self 1752 end 1753 end 1754 def line_type(id) 1755 tk_send('line', 'type', tagid(id)) 1756 end 1757 1758 ################### 1759 1760 def gridline_off 1761 tk_send_without_enc('grid', 'off') 1762 self 1763 end 1764 def gridline_on 1765 tk_send_without_enc('grid', 'on') 1766 self 1767 end 1768 def gridline_toggle 1769 tk_send_without_enc('grid', 'toggle') 1770 self 1771 end 1772 1773 ################### 1774 1775 def legend_window_create(parent=nil, keys=nil) 1776 if parent.kind_of?(Hash) 1777 keys = _symbolkey2str(parent) 1778 parent = keys.delete('parent') 1779 widgetname = keys.delete('widgetname') 1780 keys.delete('without_creating') 1781 elsif keys 1782 keys = _symbolkey2str(keys) 1783 widgetname = keys.delete('widgetname') 1784 keys.delete('without_creating') 1785 end 1786 1787 legend = self.class.new(parent, :without_creating=>true, 1788 :widgetname=>widgetname) 1789 class << legend 1790 def __destroy_hook__ 1791 TkCore::INTERP.tk_windows.delete(@path) 1792 end 1793 end 1794 1795 if keys 1796 self.legend_configure(keys.update('position'=>legend)) 1797 else 1798 self.legend_configure('position'=>legend) 1799 end 1800 legend 1801 end 1802 1803 def legend_activate(*pats) 1804 list(tk_send('legend', 'activate', 1805 *(pats.collect{|pat| tagid(pat)}))).collect{|elem| 1806 Tk::BLT::PlotComponent::Element.id2obj(self, elem) 1807 } 1808 end 1809 def legend_deactivate(*pats) 1810 list(tk_send('legend', 'deactivate', 1811 *(pats.collect{|pat| tagid(pat)}))).collect{|elem| 1812 Tk::BLT::PlotComponent::Element.id2obj(self, elem) 1813 } 1814 end 1815 def legend_get(pos, y=nil) 1816 if y 1817 Tk::BLT::PlotComponent::Element.id2obj(self, 1818 tk_send('legend', 'get', 1819 _at(pos, y))) 1820 else 1821 Tk::BLT::PlotComponent::Element.id2obj(self, 1822 tk_send('legend', 'get', pos)) 1823 end 1824 end 1825 1826 ################### 1827 1828 def pen_create(id=nil, keys={}) 1829 # tk_send('pen', 'create', tagid(id), keys) 1830 Tk::BLT::PlotComponent::Pen.new(self, tagid(id), keys) 1831 end 1832 def pen_delete(*ids) 1833 tk_send('pen', 'delete', *(ids.collect{|id| tagid(id)})) 1834 self 1835 end 1836 def pen_names(*pats) 1837 simplelist(tk_send('pen', 'names', 1838 *(pats.collect{|pat| tagid(pat)}))).collect{|pen| 1839 Tk::BLT::PlotComponent::Pen.id2obj(self, pen) 1840 } 1841 end 1842 1843 ################### 1844 1845 def postscript_output(file=nil, keys={}) 1846 if file.kind_of?(Hash) 1847 keys = file 1848 file = nil 1849 end 1850 1851 if file 1852 tk_send('postscript', 'output', file, keys) 1853 self 1854 else 1855 tk_send('postscript', 'output', keys) 1856 end 1857 end 1858 1859 ################### 1860 1861 def marker_create(type, keys={}) 1862 case type 1863 when :text, 'text' 1864 Tk::BLT::PlotComponent::TextMarker.new(self, keys) 1865 when :line, 'line' 1866 Tk::BLT::PlotComponent::LineMarker.new(self, keys) 1867 when :bitmap, 'bitmap' 1868 Tk::BLT::PlotComponent::BitmapMarker.new(self, keys) 1869 when :image, 'image' 1870 Tk::BLT::PlotComponent::ImageMarker.new(self, keys) 1871 when :polygon, 'polygon' 1872 Tk::BLT::PlotComponent::PolygonMarker.new(self, keys) 1873 when :window, 'window' 1874 Tk::BLT::PlotComponent::WindowMarker.new(self, keys) 1875 else 1876 if type.kind_of?(Tk::BLT::PlotComponent::Marker) 1877 type.new(self, keys) 1878 else 1879 Tk::BLT::PlotComponent::Marker.create_type(self, type, keys) 1880 end 1881 end 1882 end 1883 def marker_after(id, target=nil) 1884 if target 1885 tk_send_without_enc('marker', 'after', tagid(id), tagid(target)) 1886 else 1887 tk_send_without_enc('marker', 'after', tagid(id)) 1888 end 1889 self 1890 end 1891 def marker_before(id, target=None) 1892 if target 1893 tk_send_without_enc('marker', 'before', tagid(id), tagid(target)) 1894 else 1895 tk_send_without_enc('marker', 'before', tagid(id)) 1896 end 1897 self 1898 end 1899 def marker_delete(*ids) 1900 tk_send('marker', 'delete', *(ids.collect{|id| tagid(id)})) 1901 self 1902 end 1903 def marker_exist?(id) 1904 bool(tk_send('marker', 'exists', tagid(id))) 1905 end 1906 def marker_names(*pats) 1907 simplelist(tk_send('marker', 'names', 1908 *(pats.collect{|pat| tagid(pat)}))).collect{|id| 1909 Tk::BLT::PlotComponent::Marker.id2obj(self, id) 1910 } 1911 end 1912 def marker_type(id) 1913 tk_send('marker', 'type', tagid(id)) 1914 end 1915 1916 ################### 1917 1918 def xaxis_cget_tkstring(option) 1919 itemcget_tkstring('xaxis', option) 1920 end 1921 def xaxis_cget(option) 1922 itemcget('xaxis', option) 1923 end 1924 def xaxis_cget_strict(option) 1925 itemcget_strict('xaxis', option) 1926 end 1927 def xaxis_configure(slot, value=None) 1928 if slot.kind_of?(Hash) 1929 slot = _symbolkey2str(slot) 1930 if cmd = slot.delete('command') 1931 slot['command'] = proc{|w, tick| 1932 cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) 1933 } 1934 end 1935 elsif slot == :command || slot == 'command' 1936 cmd = value 1937 value = proc{|w, tick| 1938 cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) 1939 } 1940 end 1941 itemconfigure('xaxis', slot, value) 1942 end 1943 def xaxis_configinfo(slot=nil) 1944 itemconfiginfo('xaxis', slot) 1945 end 1946 def current_xaxis_configinfo(slot=nil) 1947 current_itemconfiginfo('xaxis', slot) 1948 end 1949 def xaxis_bind(context, *args) 1950 if TkComm._callback_entry?(args[0]) || !block_given? 1951 cmd = args.shift 1952 else 1953 cmd = Proc.new 1954 end 1955 _bind([path, 'xaxis', 'bind'], context, cmd, *args) 1956 self 1957 end 1958 def xaxis_bind_append(context, *args) 1959 if TkComm._callback_entry?(args[0]) || !block_given? 1960 cmd = args.shift 1961 else 1962 cmd = Proc.new 1963 end 1964 _bind_append([path, 'xaxis', 'bind'], context, cmd, *args) 1965 self 1966 end 1967 def xaxis_bind_remove(context) 1968 _bind_remove([path, 'xaxis', 'bind'], context) 1969 self 1970 end 1971 def xaxis_bindinfo(context=nil) 1972 _bindinfo([path, 'xaxis', 'bind'], context) 1973 end 1974 def xaxis_invtransform(val) 1975 list(tk_send('xaxis', 'invtransform', val)) 1976 end 1977 def xaxis_limits 1978 list(tk_send('xaxis', 'limits')) 1979 end 1980 def xaxis_transform(val) 1981 list(tk_send('xaxis', 'transform', val)) 1982 end 1983 def xaxis_use(target=nil) 1984 if target 1985 Tk::BLT::PlotComponent::Axis.id2obj(self, 1986 tk_send('xaxis', 'use', 1987 tagid(target))) 1988 else 1989 Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('xaxis', 'use')) 1990 end 1991 end 1992 1993 def x2axis_cget_tkstring(option) 1994 itemcget_tkstring('x2axis', option) 1995 end 1996 def x2axis_cget(option) 1997 itemcget('x2axis', option) 1998 end 1999 def x2axis_cget_strict(option) 2000 itemcget_strict('x2axis', option) 2001 end 2002 def x2axis_configure(slot, value=None) 2003 if slot.kind_of?(Hash) 2004 slot = _symbolkey2str(slot) 2005 if cmd = slot.delete('command') 2006 slot['command'] = proc{|w, tick| 2007 cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) 2008 } 2009 end 2010 elsif slot == :command || slot == 'command' 2011 cmd = value 2012 value = proc{|w, tick| 2013 cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) 2014 } 2015 end 2016 itemconfigure('x2axis', slot, value) 2017 end 2018 def x2axis_configinfo(slot=nil) 2019 itemconfiginfo('x2axis', slot) 2020 end 2021 def current_x2axis_configinfo(slot=nil) 2022 current_itemconfiginfo('x2axis', slot) 2023 end 2024 def x2axis_bind(context, *args) 2025 if TkComm._callback_entry?(args[0]) || !block_given? 2026 cmd = args.shift 2027 else 2028 cmd = Proc.new 2029 end 2030 _bind([path, 'x2axis', 'bind'], context, cmd, *args) 2031 self 2032 end 2033 def x2axis_bind_append(context, *args) 2034 if TkComm._callback_entry?(args[0]) || !block_given? 2035 cmd = args.shift 2036 else 2037 cmd = Proc.new 2038 end 2039 _bind_append([path, 'x2axis', 'bind'], context, cmd, *args) 2040 self 2041 end 2042 def x2axis_bind_remove(context) 2043 _bind_remove([path, 'x2axis', 'bind'], context) 2044 self 2045 end 2046 def x2axis_bindinfo(context=nil) 2047 _bindinfo([path, 'x2axis', 'bind'], context) 2048 end 2049 def x2axis_invtransform(val) 2050 list(tk_send('x2axis', 'invtransform', val)) 2051 end 2052 def x2axis_limits 2053 list(tk_send('x2axis', 'limits')) 2054 end 2055 def x2axis_transform(val) 2056 list(tk_send('x2axis', 'transform', val)) 2057 end 2058 def x2axis_use(target=nil) 2059 if target 2060 Tk::BLT::PlotComponent::Axis.id2obj(self, 2061 tk_send('x2axis', 'use', 2062 tagid(target))) 2063 else 2064 Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('x2axis', 'use')) 2065 end 2066 end 2067 2068 def yaxis_cget_tkstring(option) 2069 itemcget_tkstring('yaxis', option) 2070 end 2071 def yaxis_cget(option) 2072 itemcget('yaxis', option) 2073 end 2074 def yaxis_cget_strict(option) 2075 itemcget_strict('yaxis', option) 2076 end 2077 def yaxis_configure(slot, value=None) 2078 if slot.kind_of?(Hash) 2079 slot = _symbolkey2str(slot) 2080 if cmd = slot.delete('command') 2081 slot['command'] = proc{|w, tick| 2082 cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) 2083 } 2084 end 2085 elsif slot == :command || slot == 'command' 2086 cmd = value 2087 value = proc{|w, tick| 2088 cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) 2089 } 2090 end 2091 itemconfigure('yaxis', slot, value) 2092 end 2093 def yaxis_configinfo(slot=nil) 2094 itemconfiginfo('yaxis', slot) 2095 end 2096 def current_yaxis_configinfo(slot=nil) 2097 current_itemconfiginfo('yaxis', slot) 2098 end 2099 def yaxis_bind(context, *args) 2100 if TkComm._callback_entry?(args[0]) || !block_given? 2101 cmd = args.shift 2102 else 2103 cmd = Proc.new 2104 end 2105 _bind([path, 'yaxis', 'bind'], context, cmd, *args) 2106 self 2107 end 2108 def yaxis_bind_append(context, *args) 2109 if TkComm._callback_entry?(args[0]) || !block_given? 2110 cmd = args.shift 2111 else 2112 cmd = Proc.new 2113 end 2114 _bind_append([path, 'yaxis', 'bind'], context, cmd, *args) 2115 self 2116 end 2117 def yaxis_bind_remove(context) 2118 _bind_remove([path, 'yaxis', 'bind'], context) 2119 self 2120 end 2121 def yaxis_bindinfo(context=nil) 2122 _bindinfo([path, 'yaxis', 'bind'], context) 2123 end 2124 def yaxis_invtransform(val) 2125 list(tk_send('yaxis', 'invtransform', val)) 2126 end 2127 def yaxis_limits 2128 list(tk_send('yaxis', 'limits')) 2129 end 2130 def yaxis_transform(val) 2131 list(tk_send('yaxis', 'transform', val)) 2132 end 2133 def yaxis_use(target=nil) 2134 if target 2135 Tk::BLT::PlotComponent::Axis.id2obj(self, 2136 tk_send('yaxis', 'use', 2137 tagid(target))) 2138 else 2139 Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('yaxis', 'use')) 2140 end 2141 end 2142 2143 def y2axis_cget_tkstring(option) 2144 itemcget_tkstring('y2axis', option) 2145 end 2146 def y2axis_cget(option) 2147 itemcget('y2axis', option) 2148 end 2149 def y2axis_cget_strict(option) 2150 itemcget_strict('y2axis', option) 2151 end 2152 def y2axis_configure(slot, value=None) 2153 if slot.kind_of?(Hash) 2154 slot = _symbolkey2str(slot) 2155 if cmd = slot.delete('command') 2156 slot['command'] = proc{|w, tick| 2157 cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) 2158 } 2159 end 2160 elsif slot == :command || slot == 'command' 2161 cmd = value 2162 value = proc{|w, tick| 2163 cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) 2164 } 2165 end 2166 itemconfigure('y2axis', slot, value) 2167 end 2168 def y2axis_configinfo(slot=nil) 2169 axis_configinfo('y2axis', slot) 2170 end 2171 def current_y2axis_configinfo(slot=nil) 2172 current_itemconfiginfo('y2axis', slot) 2173 end 2174 def y2axis_bind(context, *args) 2175 if TkComm._callback_entry?(args[0]) || !block_given? 2176 cmd = args.shift 2177 else 2178 cmd = Proc.new 2179 end 2180 _bind([path, 'y2axis', 'bind'], context, cmd, *args) 2181 self 2182 end 2183 def y2axis_bind_append(context, *args) 2184 if TkComm._callback_entry?(args[0]) || !block_given? 2185 cmd = args.shift 2186 else 2187 cmd = Proc.new 2188 end 2189 _bind_append([path, 'y2axis', 'bind'], context, cmd, *args) 2190 self 2191 end 2192 def y2axis_bind_remove(context) 2193 _bind_remove([path, 'y2axis', 'bind'], context) 2194 self 2195 end 2196 def y2axis_bindinfo(context=nil) 2197 _bindinfo([path, 'y2axis', 'bind'], context) 2198 end 2199 def y2axis_invtransform(val) 2200 list(tk_send('y2axis', 'invtransform', val)) 2201 end 2202 def y2axis_limits 2203 list(tk_send('y2axis', 'limits')) 2204 end 2205 def y2axis_transform(val) 2206 list(tk_send('y2axis', 'transform', val)) 2207 end 2208 def y2axis_use(target=nil) 2209 if target 2210 Tk::BLT::PlotComponent::Axis.id2obj(self, 2211 tk_send('y2axis', 'use', 2212 tagid(target))) 2213 else 2214 Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('y2axis', 'use')) 2215 end 2216 end 2217 end 2218end 2219