~ubuntu-branches/ubuntu/oneiric/ctioga2/oneiric

« back to all changes in this revision

Viewing changes to lib/ctioga2/graphics/elements/parametric2d.rb

  • Committer: Bazaar Package Importer
  • Author(s): Vincent Fourmond
  • Date: 2011-01-24 21:36:06 UTC
  • Revision ID: james.westby@ubuntu.com-20110124213606-9ettx0ugl83z0bzp
Tags: upstream-0.1
ImportĀ upstreamĀ versionĀ 0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: undecided -*-
 
2
# parametric2d.rb: a 2D curve whose parameters depend on Z values
 
3
# copyright (c) 2006, 2007, 2008, 2009, 2010 by Vincent Fourmond
 
4
 
 
5
# This program is free software; you can redistribute it and/or modify
 
6
# it under the terms of the GNU General Public License as published by
 
7
# the Free Software Foundation; either version 2 of the License, or
 
8
# (at your option) any later version.
 
9
 
 
10
# This program is distributed in the hope that it will be useful, but
 
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
13
# General Public License for more details (in the COPYING file).
 
14
 
 
15
require 'ctioga2/utils'
 
16
require 'ctioga2/log'
 
17
 
 
18
require 'Dobjects/Function'
 
19
 
 
20
 
 
21
module CTioga2
 
22
 
 
23
  Version::register_svn_info('$Revision: 229 $', '$Date: 2011-01-17 17:34:57 +0100 (Mon, 17 Jan 2011) $')
 
24
 
 
25
  module Graphics
 
26
 
 
27
    module Elements
 
28
 
 
29
      # This class represents a 3D (or more, to be seen later) dataset
 
30
      # as markers with various parameters parametrized (color,
 
31
      # transparency, marker scale, marker type (discrete), possibly
 
32
      # stroke and fill colors ?
 
33
      #
 
34
      # @todo What would be interesting here would be to have indexed
 
35
      # plots, ie draw one curve for each value of Z, with a color
 
36
      # indexed by Z.
 
37
      class Parametric2D  < TiogaElement
 
38
 
 
39
        include Log
 
40
        include Dobjects
 
41
 
 
42
        # The Data::Dataset object that should get plotted.
 
43
        attr_accessor :dataset
 
44
 
 
45
        # A Styles::CurveStyle object saying how the curve should be
 
46
        # drawn.
 
47
        #
 
48
        # Some of the elements will be overridden.
 
49
        attr_accessor :curve_style
 
50
 
 
51
        # For convenience only: xy functions
 
52
        attr_accessor :function
 
53
 
 
54
        # A hash Z value -> corresponding XY functions.
 
55
        attr_accessor :planes
 
56
 
 
57
 
 
58
 
 
59
        undef :location=, :location
 
60
        
 
61
        # Creates a new Curve2D object with the given _dataset_ and
 
62
        # _style_.
 
63
        def initialize(dataset, style = nil)
 
64
          @dataset = dataset
 
65
          @curve_style = style
 
66
          prepare_data
 
67
        end
 
68
 
 
69
        # Prepares the internal storage of the data, from the @dataset
 
70
        def prepare_data
 
71
          @function = Function.new(@dataset.x.values.dup, 
 
72
                                   @dataset.y.values.dup)
 
73
 
 
74
          ## @todo this should eventually use Dataset::index_on_cols.
 
75
          @planes = {}
 
76
          @dataset.each_values do |i, x,y,*zs|
 
77
            @planes[zs[0]] ||= Function.new(Dvector.new, Dvector.new)
 
78
            @planes[zs[0]].x << x
 
79
            @planes[zs[0]].y << y
 
80
          end
 
81
        end
 
82
        
 
83
        protected :prepare_data
 
84
 
 
85
        # Returns the LocationStyle object of the curve. Returns the
 
86
        # one from #curve_style.
 
87
        def location
 
88
          return @curve_style.location
 
89
        end
 
90
 
 
91
        # Returns the Types::Boundaries of this curve.
 
92
        def get_boundaries
 
93
          return Types::Boundaries.bounds(@function.x, @function.y)
 
94
        end
 
95
 
 
96
        # Draws the markers, if applicable.
 
97
        def draw_path(t)
 
98
          min = @dataset.z.values.min
 
99
          max = @dataset.z.values.max
 
100
          if @curve_style.has_line?
 
101
            # We use a default color map for the lines
 
102
            @curve_style.color_map ||= 
 
103
              Styles::ColorMap.from_text("Red--Green")
 
104
            cmap = @curve_style.color_map
 
105
 
 
106
            for zs in @planes.keys.sort ## \todo have the sort
 
107
                                        ## direction configurable.
 
108
              f = @planes[zs]
 
109
              color = cmap.z_color(zs, min, max)
 
110
              t.context do 
 
111
                @curve_style.line.set_stroke_style(t)
 
112
                t.stroke_color = color
 
113
                t.show_polyline(f.x, f.y)
 
114
              end
 
115
            end
 
116
          end
 
117
        end
 
118
 
 
119
 
 
120
        # Draws the markers, if applicable.
 
121
        def draw_markers(t)
 
122
          min = @dataset.z.values.min
 
123
          max = @dataset.z.values.max
 
124
          if @curve_style.has_marker?
 
125
            # We use a default color map for the markers
 
126
            @curve_style.marker_color_map ||= 
 
127
              Styles::ColorMap.from_text("Red--Green")
 
128
            cmap = @curve_style.marker_color_map
 
129
            for zs in @planes.keys.sort ## \todo have the sort
 
130
                                        ## direction configurable.
 
131
              f = @planes[zs]
 
132
              color = cmap.z_color(zs, min, max)
 
133
              @curve_style.marker.draw_markers_at(t, f.x, f.y, 
 
134
                                                  { 'color' => color})
 
135
            end
 
136
          end
 
137
        end
 
138
        
 
139
        ## Actually draws the curve
 
140
        def real_do(t)
 
141
          debug { "Plotting curve #{inspect}" }
 
142
          t.context do
 
143
            ## \todo allow customization of the order of drawing,
 
144
            ## using a simple user-specificable array of path,
 
145
            ## markers... and use the corresponding #draw_path or
 
146
            ## #draw_markers... Ideally, any string could be used, and
 
147
            ## warnings should be issued on missing symbols.
 
148
 
 
149
            # draw_fill(t)
 
150
            # draw_errorbars(t)
 
151
            draw_path(t)
 
152
            draw_markers(t)
 
153
 
 
154
            if @curve_style.zaxis
 
155
              begin
 
156
                @parent.style.get_axis_style(@curve_style.zaxis).
 
157
                  set_color_map(@curve_style.marker_color_map, 
 
158
                                @dataset.z.values.min,
 
159
                                @dataset.z.values.max)
 
160
              rescue
 
161
                error { "Could not set Z info to non-existent axis #{@curve_style.zaxis}" }
 
162
              end
 
163
            end
 
164
 
 
165
            # draw_error_bars(t) ??
 
166
          end
 
167
        end
 
168
        
 
169
      end
 
170
    end
 
171
  end
 
172
end