├── .gitignore
├── .travis.yml
├── dynamic-plot-gtk
├── COPYING
├── Graphics
│ └── Dynamic
│ │ └── Plot
│ │ └── R2
│ │ └── Gtk.hs
└── dynamic-plot-gtk.cabal
├── dynamic-plot
├── COPYING
├── Graphics
│ ├── Dynamic
│ │ └── Plot
│ │ │ ├── Colour.hs
│ │ │ ├── Internal
│ │ │ └── Types.hs
│ │ │ ├── Internals.hs
│ │ │ ├── R2.hs
│ │ │ └── R2
│ │ │ └── Internal.hs
│ ├── Image
│ │ └── Resample.hs
│ └── Text
│ │ └── Annotation.hs
├── INSTALL
├── README.md
├── Setup.hs
├── dynamic-plot.cabal
└── images
│ └── examples
│ ├── HelloWorld.gif
│ ├── cos-encircle-points-far.png
│ ├── cos-encircle-points.ghci
│ ├── cos-encircle-points.gif
│ ├── cos-encircle-points.png
│ ├── propeller.png
│ ├── sin-ctrd-tangents.ghci
│ └── sin-ctrd-tangents.gif
└── stack.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | cabal-dev
3 | *.o
4 | *.hi
5 | *.chi
6 | *.chs.h
7 | .virthualenv
8 | *~
9 | bin/
10 | *.kate-swp
11 | *.fuse_hidden*
12 | *.#*
13 | *#*#
14 | .stack-work
15 | *.swp
16 | *.lock
17 | dist-newstyle
18 | .ghc.envi*
19 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # This is the simple Travis configuration, which is intended for use
2 | # on applications which do not require cross-platform and
3 | # multiple-GHC-version support. For more information and other
4 | # options, see:
5 | #
6 | # https://docs.haskellstack.org/en/stable/travis_ci/
7 | #
8 | # Copy these contents into the root directory of your Github project in a file
9 | # named .travis.yml
10 |
11 | # Choose a build environment
12 | dist: xenial
13 |
14 | # Do not choose a language; we provide our own build tools.
15 | language: generic
16 |
17 | # Caching so the next build will be fast too.
18 | cache:
19 | directories:
20 | - $HOME/.stack
21 |
22 | # Ensure necessary system libraries are present
23 | addons:
24 | apt:
25 | packages:
26 | - libgmp-dev
27 | - zlib1g-dev
28 | - libcairo2-dev
29 | - libpango1.0-dev
30 | - libgtk2.0-dev
31 |
32 | before_install:
33 | # Download and unpack the stack executable
34 | - mkdir -p ~/.local/bin
35 | - export PATH=$HOME/.local/bin:$PATH
36 | - travis_retry curl -L https://get.haskellstack.org/stable/linux-x86_64.tar.gz | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'
37 |
38 | install:
39 | # Build dependencies
40 | - stack --no-terminal --install-ghc test --only-dependencies
41 |
42 | script:
43 | # Build the package and its docs
44 | - stack --no-terminal build --haddock --no-haddock-deps
45 |
--------------------------------------------------------------------------------
/dynamic-plot-gtk/COPYING:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/dynamic-plot-gtk/Graphics/Dynamic/Plot/R2/Gtk.hs:
--------------------------------------------------------------------------------
1 | -- |
2 | -- Module : Graphics.Dynamic.Plot.R2.Gtk
3 | -- Copyright : (c) Justus Sagemüller 2022-2023
4 | -- License : GPL v3
5 | --
6 | -- Maintainer : (@) jsag $ hvl.no
7 | -- Stability : experimental
8 | -- Portability : requires GHC>6 extensions
9 |
10 |
11 | {-# LANGUAGE NoMonomorphismRestriction #-}
12 | {-# LANGUAGE GADTs #-}
13 | {-# LANGUAGE TypeFamilies #-}
14 | {-# LANGUAGE ScopedTypeVariables #-}
15 | {-# LANGUAGE RecordWildCards #-}
16 | {-# LANGUAGE TupleSections #-}
17 | {-# LANGUAGE TypeOperators #-}
18 | {-# LANGUAGE UnicodeSyntax #-}
19 | {-# LANGUAGE FlexibleInstances #-}
20 | {-# LANGUAGE LiberalTypeSynonyms #-}
21 | {-# LANGUAGE FlexibleContexts #-}
22 | {-# LANGUAGE ConstraintKinds #-}
23 | {-# LANGUAGE UndecidableInstances #-}
24 | {-# LANGUAGE LambdaCase #-}
25 | {-# LANGUAGE NoImplicitPrelude #-}
26 | {-# LANGUAGE RankNTypes #-}
27 | {-# LANGUAGE GeneralizedNewtypeDeriving #-}
28 | {-# LANGUAGE DeriveFunctor #-}
29 | {-# LANGUAGE StandaloneDeriving #-}
30 | {-# LANGUAGE TemplateHaskell #-}
31 | {-# LANGUAGE CPP #-}
32 |
33 | module Graphics.Dynamic.Plot.R2.Gtk (
34 | module Graphics.Dynamic.Plot.R2
35 | -- * Interactive display
36 | , plotWindow, plotWindow'
37 | ) where
38 |
39 | import Graphics.Dynamic.Plot.R2
40 | import Graphics.Dynamic.Plot.Internals
41 |
42 | import qualified Prelude
43 |
44 | import Diagrams.Prelude ((^&), (&), _x, _y)
45 | import qualified Diagrams.Prelude as Dia
46 | import qualified Diagrams.TwoD.Size as Dia
47 | import qualified Diagrams.TwoD.Types as DiaTypes
48 | import Diagrams.TwoD.Types (V2(V2))
49 | import Diagrams.BoundingBox (BoundingBox)
50 | import qualified Diagrams.BoundingBox as DiaBB
51 | import qualified Diagrams.Backend.Cairo as Cairo
52 | import qualified Diagrams.Backend.Cairo.Text as CairoTxt
53 |
54 | import qualified Data.Colour as DCol
55 | import qualified Data.Colour.SRGB as DCol (toSRGB24, RGB(..))
56 | import qualified Data.Colour.Names as DCol
57 | import qualified Codec.Picture as JPix
58 | import qualified Codec.Picture.Types as JPix
59 |
60 | import qualified Diagrams.Backend.Gtk as BGTK
61 | import qualified Graphics.UI.Gtk as GTK
62 | import Graphics.UI.Gtk ( AttrOp((:=)) )
63 | import qualified Graphics.UI.Gtk.Gdk.EventM as Event
64 | import qualified System.Glib.Signals (on)
65 |
66 | import Control.Monad.Trans (liftIO, lift)
67 | import Control.Monad.Trans.State (evalState, get, put)
68 | import Control.Monad.ST
69 | import Control.Applicative ((<|>))
70 | import Data.STRef
71 |
72 | import qualified Control.Category.Hask as Hask
73 | import Control.Category.Constrained.Prelude hiding ((^))
74 | import Control.Arrow.Constrained
75 | import Control.Monad.Constrained
76 |
77 | import Control.Lens hiding ((...), (<.>))
78 | import Control.Lens.TH(makeLenses)
79 |
80 |
81 | import Control.Concurrent (runInBoundThread, threadDelay, ThreadId, forkIO, killThread)
82 | import Control.Concurrent.MVar
83 | import Control.DeepSeq
84 | import Control.Exception (evaluate)
85 |
86 |
87 | import Data.List (foldl', sort, sortBy, partition, zip4)
88 | import qualified Data.List.NonEmpty as NE
89 | import Data.List.NonEmpty (NonEmpty (..))
90 | import qualified Data.Vector as Arr
91 | import Data.Maybe
92 | import Data.Semigroup
93 | import Data.Default
94 | import Data.Foldable (fold, foldMap, minimumBy)
95 | import qualified Data.Foldable as Hask
96 | import Data.Function (on)
97 | import Data.Ord (comparing)
98 |
99 | import Data.VectorSpace
100 | import Math.LinearMap.Category
101 | import Data.Basis
102 | import Data.AffineSpace
103 | import Data.Manifold.PseudoAffine
104 | #if MIN_VERSION_manifolds(0,6,0)
105 | import Data.Manifold.WithBoundary
106 | #endif
107 | import Data.Function.Differentiable
108 | import Data.Manifold.Types
109 | import Data.Manifold.Shade
110 | import Data.Manifold.TreeCover
111 | import Data.Manifold.Web
112 | import Data.Manifold.Riemannian (Geodesic, pointsBarycenter)
113 | import qualified Data.Map.Lazy as Map
114 |
115 | import qualified Data.Colour.Manifold as CSp
116 | import qualified Data.Colour.Manifold.Internal as CSp
117 |
118 | import qualified Data.Random as Random
119 | import qualified System.Random as Random
120 | import qualified Data.Random.Manifold
121 |
122 | import Data.IORef
123 |
124 | import System.IO
125 | import System.Exit
126 | import System.Process
127 | import Data.Time
128 |
129 |
130 | -- | Plot some plot objects to a new interactive GTK window. Useful for a quick
131 | -- preview of some unknown data or real-valued functions; things like selection
132 | -- of reasonable view range and colourisation are automatically chosen.
133 | --
134 | -- Example:
135 | --
136 | -- <>
137 | --
138 | -- The individual objects you want to plot can be evaluated in multiple threads, so
139 | -- a single hard calculatation won't freeze the responsitivity of the whole window.
140 | -- Invoke e.g. from @ghci +RTS -N4@ to benefit from this.
141 | --
142 | -- ATTENTION: the window may sometimes freeze, especially when displaying
143 | -- complicated functions with 'fnPlot` from ghci. This is apparently
144 | -- a kind of deadlock problem with one of the C libraries that are invoked,
145 | -- At the moment, we can recommend no better solution than to abort and restart ghci
146 | -- (or what else you use – iHaskell kernel, process, ...) if this occurs.
147 | plotWindow :: [DynamicPlottable] -> IO GraphWindowSpec
148 | plotWindow = plotWindow' def
149 |
150 | -- | Like 'plotWindow', but with explicit specification how the window is supposed
151 | -- to show up. ('plotWindow' uses the default configuration, i.e. 'def'.)
152 | plotWindow' :: ViewportConfig -> [DynamicPlottable] -> IO GraphWindowSpec
153 | plotWindow' viewportConfig [] = plotWindow' viewportConfig [dynamicAxes]
154 | plotWindow' viewportConfig givenPlotObjs = runInBoundThread $ do
155 |
156 | let defColourScheme = defaultColourScheme
157 | tintedPlotObjs = chooseAutoTints givenPlotObjs
158 |
159 | viewState <- newIORef $ autoDefaultView viewportConfig tintedPlotObjs
160 | viewTgt <- newIORef =<< readIORef viewState
161 | let objAxisLabels = concat $ _axisLabelRequests<$>givenPlotObjs
162 | viewTgtGlobal <- newMVar . (,objAxisLabels) =<< readIORef viewState
163 | screenResolution <- newIORef (viewportConfig^.xResV, viewportConfig^.yResV)
164 | let viewConstraint = flip (foldr _viewportConstraint) givenPlotObjs
165 |
166 | let screenCoordsToData (sx,sy) = do
167 | GraphWindowSpecR2{..} <- readIORef viewState
168 | let snx = sx / fromIntegral xResolution
169 | sny = sy / fromIntegral yResolution
170 | return (lBound + snx*(rBound-lBound), tBound - sny*(tBound-bBound))
171 |
172 | dgStore <- newIORef mempty
173 |
174 | (plotObjs, cancelWorkers) :: ([ObjInPlot], IO ()) <- do
175 | let assignPlObjPropties :: [DynamicPlottable] -> Necessity
176 | -> IO [(ObjInPlot, ThreadId)]
177 | assignPlObjPropties [] axesNeed
178 | | axesNeed > 0 = assignPlObjPropties [tint Dia.grey dynamicAxes] (-1)
179 | | otherwise = return []
180 | assignPlObjPropties (o:os) axn = do
181 | newDia <- newEmptyMVar
182 | newMouseEvs <- newEmptyMVar
183 | workerId <- forkIO $ objectPlotterThread o viewTgtGlobal newMouseEvs newDia
184 | stableView <- newIORef Nothing
185 | ((ObjInPlot stableView newDia newMouseEvs cl o, workerId) :)
186 | <$> assignPlObjPropties os (axn + o^.axesNecessity)
187 | where cl | TrueColour c₀:_ <- o^.inherentColours
188 | = Just $ Dia.opaque c₀
189 | | SymbolicColour c₀:_ <- o^.inherentColours
190 | = Just $ defColourScheme c₀
191 | | otherwise = Nothing
192 | (pObs, workerId) <- unzip <$> assignPlObjPropties tintedPlotObjs 0
193 | return ( sortBy (comparing $ _occlusiveness . _originalPlotObject) pObs
194 | , forM_ workerId killThread )
195 |
196 |
197 | GTK.initGUI
198 | window <- GTK.windowNew
199 |
200 | mouseAnchor <- newIORef Nothing
201 | mousePressedAt <- newIORef Nothing
202 |
203 | refreshDraw <- do
204 | drawA <- GTK.drawingAreaNew
205 | GTK.onExpose drawA $ \_ -> do
206 | (canvasX,canvasY) <- GTK.widgetGetSize drawA
207 | modifyIORef viewTgt
208 | $ \view -> viewConstraint $ view{ xResolution = fromIntegral canvasX
209 | , yResolution = fromIntegral canvasY }
210 |
211 | dia <- readIORef dgStore
212 |
213 | let scaledDia = Dia.bg (case viewportConfig^.plotBackground of
214 | Just bgc -> bgc
215 | Nothing -> Dia.black)
216 | . Dia.scaleX (fromInt canvasX / 2)
217 | . Dia.scaleY (-fromInt canvasY / 2)
218 | . Dia.translate (1 ^& (-1))
219 | . Dia.withEnvelope (Dia.rect 2 2 :: PlainGraphicsR2)
220 | . (viewportConfig^.graphicsPostprocessing)
221 | $ dia
222 | drawWindow <- GTK.widgetGetDrawWindow drawA
223 | BGTK.renderToGtk drawWindow $ scaledDia
224 | return True
225 |
226 | GTK.on drawA GTK.buttonPressEvent . Event.tryEvent $ do
227 | Event.eventButton >>= guard.(==defaultDragButton)
228 | anchXY <- Event.eventCoordinates
229 | liftIO . writeIORef mouseAnchor $ Just anchXY
230 | GTK.on drawA GTK.buttonReleaseEvent . Event.tryEvent $ do
231 | Event.eventButton >>= guard.(==defaultDragButton)
232 | liftIO . writeIORef mouseAnchor $ Nothing
233 |
234 | GTK.on drawA GTK.buttonPressEvent . Event.tryEvent $ do
235 | Event.eventButton >>= guard.(==defaultEditButton)
236 | (pressX,pressY) <- liftIO . screenCoordsToData =<< Event.eventCoordinates
237 | liftIO . writeIORef mousePressedAt $ Just (pressX,pressY)
238 | let event = MouseEvent (pressX^&pressY) (pressX^&pressY)
239 | liftIO . forM_ plotObjs $ _mouseEventsForObj >>> \mevs -> do
240 | tryTakeMVar mevs >>= \case
241 | Nothing -> putMVar mevs $ Interactions [] (Just event)
242 | Just (Interactions qe _)
243 | -> putMVar mevs $ Interactions qe (Just event)
244 | GTK.on drawA GTK.buttonReleaseEvent . Event.tryEvent $ do
245 | Event.eventButton >>= guard.(==defaultEditButton)
246 | (relX,relY) <- liftIO . screenCoordsToData =<< Event.eventCoordinates
247 | liftIO (readIORef mousePressedAt) >>= \case
248 | Just (pressX,pressY) -> liftIO $ do
249 | let event = MouseEvent (pressX^&pressY) (relX^&relY)
250 | forM_ plotObjs $ _mouseEventsForObj >>> \mevs -> do
251 | tryTakeMVar mevs >>= \case
252 | Nothing -> putMVar mevs $ Interactions [event] Nothing
253 | Just (Interactions qe _)
254 | -> putMVar mevs $ Interactions (event:qe) Nothing
255 | Nothing -> mzero
256 | liftIO . writeIORef mouseAnchor $ Nothing
257 |
258 | GTK.on drawA GTK.motionNotifyEvent . Event.tryEvent $ do
259 | liftIO (readIORef mouseAnchor) >>= \case
260 | Just (oldX,oldY) -> do
261 | (mvX,mvY) <- Event.eventCoordinates
262 | (canvasX,canvasY) <- liftIO $ GTK.widgetGetSize drawA
263 | let ηX = (oldX-mvX) / fromIntegral canvasX
264 | ηY = (mvY-oldY) / fromIntegral canvasY
265 | liftIO . modifyIORef viewTgt $ \view@GraphWindowSpecR2{..} ->
266 | let w = rBound - lBound
267 | h = tBound - bBound
268 | in view{ lBound = lBound + w * ηX
269 | , rBound = rBound + w * ηX
270 | , tBound = tBound + h * ηY
271 | , bBound = bBound + h * ηY
272 | }
273 | liftIO . modifyIORef mouseAnchor . fmap $ const (mvX,mvY)
274 | Nothing -> liftIO (readIORef mousePressedAt) >>= \case
275 | Just (pressX,pressY) -> do
276 | (curX,curY) <- liftIO . screenCoordsToData =<< Event.eventCoordinates
277 | let event = MouseEvent (pressX^&pressY) (curX^&curY)
278 | liftIO . forM_ plotObjs $ _mouseEventsForObj >>> \mevs -> do
279 | tryTakeMVar mevs >>= \case
280 | Nothing -> putMVar mevs $ Interactions [] (Just event)
281 | Just (Interactions qe _)
282 | -> putMVar mevs $ Interactions qe (Just event)
283 | Nothing -> mzero
284 | GTK.widgetAddEvents drawA [GTK.ButtonMotionMask]
285 |
286 | GTK.on drawA GTK.scrollEvent . Event.tryEvent $ do
287 | (canvasX,canvasY) <- liftIO $ GTK.widgetGetSize drawA
288 | (scrollX,scrollY) <- Event.eventCoordinates
289 | let (rcX,rcY) = ( scrollX*2 / fromIntegral canvasX - 1
290 | , 1 - scrollY*2 / fromIntegral canvasY )
291 | scrollD <- Event.eventScrollDirection
292 | liftIO . modifyIORef viewTgt $ \view@GraphWindowSpecR2{..} ->
293 | let w = rBound - lBound
294 | h = tBound - bBound
295 | ηl = (rcX + 1)^2/4; ηr = (rcX - 1)^2/4
296 | ηb = (rcY + 1)^2/4; ηt = (rcY - 1)^2/4
297 | ηh = (1-ηt) * (1-ηb) + ηl + ηr
298 | ηv = (1-ηl) * (1-ηr) + ηt + ηb
299 | in case defaultScrollBehaviour scrollD of
300 | ScrollZoomIn -> view{
301 | lBound = lBound + w * ηl * ηh * scrollZoomStrength
302 | , rBound = rBound - w * ηr * ηh * scrollZoomStrength
303 | , tBound = tBound - h * ηt * ηv * scrollZoomStrength
304 | , bBound = bBound + h * ηb * ηv * scrollZoomStrength
305 | }
306 | ScrollZoomOut -> view{
307 | lBound = lBound - w * ηr * ηh * scrollZoomStrength
308 | , rBound = rBound + w * ηl * ηh * scrollZoomStrength
309 | , tBound = tBound + h * ηb * ηv * scrollZoomStrength
310 | , bBound = bBound - h * ηt * ηv * scrollZoomStrength
311 | }
312 |
313 |
314 |
315 | GTK.set window [ GTK.windowTitle := "Plot"
316 | , GTK.windowDefaultWidth := viewportConfig^.xResV
317 | , GTK.windowDefaultHeight := viewportConfig^.yResV
318 | , GTK.containerChild := drawA
319 | ]
320 |
321 | GTK.widgetShowAll window
322 |
323 | return $ GTK.widgetQueueDraw drawA
324 |
325 |
326 | t₀ <- getCurrentTime
327 | lastFrameTime <- newIORef t₀
328 |
329 |
330 | let refreshScreen = do
331 | currentView@(GraphWindowSpecR2{..}) <- readIORef viewState
332 | let textTK txSiz asp = TextTK defaultTxtStyle txSiz asp 0.2 0.2
333 | renderComp plotObj = do
334 | plt <- tryTakeMVar (plotObj^.newPlotView) >>= \case
335 | Nothing -> fmap snd <$> readIORef (plotObj^.lastStableView)
336 | newDia -> do
337 | writeIORef (plotObj^.lastStableView) newDia
338 | return $ snd <$> newDia
339 | case plt of
340 | Nothing -> return mempty
341 | Just (Plot{..}, objLegend) -> do
342 | renderedAnnot
343 | <- renderAnnotationsForView currentView _plotAnnotations
344 | return (normaliseView currentView
345 | $ renderedAnnot <> _getPlot, objLegend)
346 |
347 | (thisPlots, thisLegends)
348 | <- unzip . reverse <$> mapM renderComp (reverse plotObjs)
349 | let thePlot = mconcat thisPlots
350 | theLegend <- prerenderLegend (textTK 10 1) colourScheme
351 | (LegendDisplayConfig Dia.absolute)
352 | $ concat (fst<$>thisLegends)
353 |
354 | writeIORef dgStore $ maybe mempty
355 | (\l -> l & Dia.scaleX (0.1 / sqrt (fromIntegral xResolution))
356 | & Dia.scaleY (0.1 / sqrt (fromIntegral yResolution))
357 | & (`Dia.place`(0.75^&0.75)) ) theLegend
358 | <> thePlot
359 |
360 | refreshDraw
361 |
362 | let mainLoop = do
363 | t <- getCurrentTime
364 | δt <- fmap (diffUTCTime t) $ readIORef lastFrameTime
365 | writeIORef lastFrameTime t
366 |
367 | do vt <- readIORef viewTgt
368 | modifyMVar_ viewTgtGlobal $ return . first (const vt)
369 | modifyIORef viewState $ \vo ->
370 | let a%b = let η = min 1 $ 2 * realToFrac δt in η*a + (1-η)*b
371 | in GraphWindowSpecR2 (lBound vt % lBound vo) (rBound vt % rBound vo)
372 | (bBound vt % bBound vo) (tBound vt % tBound vo)
373 | (xResolution vt) (yResolution vt)
374 | defColourScheme
375 | -- GTK.sleep 0.01
376 | refreshScreen
377 | -- GTK.pollEvents
378 | return True
379 |
380 | GTK.onDestroy window $ do
381 | cancelWorkers
382 | GTK.mainQuit
383 |
384 |
385 | GTK.timeoutAdd mainLoop 50
386 |
387 |
388 | GTK.mainGUI
389 |
390 | readIORef viewState
391 |
392 |
393 |
394 |
395 | data ScrollAction = ScrollZoomIn | ScrollZoomOut
396 |
397 | defaultScrollBehaviour :: Event.ScrollDirection -> ScrollAction
398 | defaultScrollBehaviour Event.ScrollUp = ScrollZoomIn
399 | defaultScrollBehaviour Event.ScrollDown = ScrollZoomOut
400 |
401 | defaultDragButton :: Event.MouseButton
402 | defaultDragButton = Event.MiddleButton
403 |
404 | defaultEditButton :: Event.MouseButton
405 | defaultEditButton = Event.LeftButton
406 |
407 | scrollZoomStrength :: Double
408 | scrollZoomStrength = 1/20
409 |
410 |
411 |
412 |
--------------------------------------------------------------------------------
/dynamic-plot-gtk/dynamic-plot-gtk.cabal:
--------------------------------------------------------------------------------
1 | Name: dynamic-plot-gtk
2 | Version: 0.4.2.0
3 | Category: graphics
4 | Synopsis: Interactive diagram windows
5 | Description: Showing and manipulating plots, diagrams etc. in GTK.
6 | License: GPL-3
7 | License-file: COPYING
8 | Author: Justus Sagemüller
9 | Maintainer: (@) jsag $ hvl.no
10 | Homepage: https://github.com/leftaroundabout/dynamic-plot
11 | Build-Type: Simple
12 | Cabal-Version: 1.18
13 |
14 | Source-Repository head
15 | type: git
16 | location: git://github.com/leftaroundabout/dynamic-plot.git
17 |
18 | Library
19 | Build-Depends: base>=4.5 && <6
20 | , dynamic-plot ==0.4.2.0
21 | , transformers
22 | , mtl
23 | , vector-space>=0.8
24 | , MemoTrie
25 | , vector
26 | , tagged
27 | , containers
28 | , semigroups
29 | , data-default
30 | , random, random-fu
31 | , time
32 | , deepseq
33 | , process
34 | , constrained-categories >= 0.2
35 | , free-vector-spaces >= 0.1 && < 0.3
36 | , linearmap-category >=0.3.5
37 | , diagrams-core
38 | , diagrams-lib >= 1.3 && < 1.5
39 | , diagrams-cairo
40 | , diagrams-gtk
41 | , gtk > 0.10 && < 0.16
42 | , glib
43 | , colour >= 2 && < 3
44 | , manifolds >= 0.4.2 && < 0.7
45 | , manifold-random
46 | , colour-space >=0.2
47 | , JuicyPixels > 3 && < 4
48 | , lens < 6.0
49 | ghc-options: -O2
50 | default-language: Haskell2010
51 | Exposed-modules: Graphics.Dynamic.Plot.R2.Gtk
52 |
--------------------------------------------------------------------------------
/dynamic-plot/COPYING:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/dynamic-plot/Graphics/Dynamic/Plot/Colour.hs:
--------------------------------------------------------------------------------
1 | -- |
2 | -- Module : Graphics.Dynamic.Plot.Colour
3 | -- Copyright : (c) Justus Sagemüller 2013
4 | -- License : GPL v3
5 | --
6 | -- Maintainer : (@) jsag $ hvl.no
7 | -- Stability : experimental
8 | -- Portability : requires GHC>6 extensions
9 |
10 | {-# LANGUAGE FlexibleInstances #-}
11 |
12 | module Graphics.Dynamic.Plot.Colour ( module Graphics.Dynamic.Plot.Colour
13 | , Colour, AColour, FColour, PColour, ColourScheme
14 | ) where
15 |
16 |
17 | import qualified Data.Colour as DCol
18 | import Data.Colour (opaque)
19 | import qualified Data.Colour.Names as N
20 | import Data.Colour.CIE hiding (Colour)
21 | import qualified Data.Colour.CIE.Illuminant as Illum
22 |
23 | import Graphics.Dynamic.Plot.Internal.Types
24 |
25 |
26 |
27 | neutral, contrast, grey
28 | , magenta, red, orange, yellow, green, cyan, blue, violet :: Colour
29 | neutral = BaseColour Neutral
30 | contrast= Contrast Neutral
31 | grey = paler contrast
32 | magenta = Contrast Green
33 | red = BaseColour Red
34 | orange = Contrast Blue
35 | yellow = BaseColour Yellow
36 | green = BaseColour Green
37 | cyan = Contrast Red
38 | blue = BaseColour Blue
39 | violet = Contrast Yellow
40 |
41 | paler, opposite :: Colour -> Colour
42 | paler = Paler
43 | opposite (BaseColour c) = Contrast c
44 | opposite (Contrast c) = BaseColour c
45 | opposite (Paler c) = Paler $ opposite c
46 | opposite (CustomColour c) = CustomColour $ hueInvert c
47 |
48 |
49 | defaultColourScheme :: ColourScheme
50 | defaultColourScheme (BaseColour Neutral) = opaque N.black
51 | defaultColourScheme (BaseColour Red ) = opaque N.red
52 | defaultColourScheme (BaseColour Yellow ) = opaque N.yellow
53 | defaultColourScheme (BaseColour Green ) = opaque N.green
54 | defaultColourScheme (BaseColour Blue ) = opaque N.blue
55 | defaultColourScheme (Contrast Neutral) = opaque N.white
56 | defaultColourScheme (Contrast Red ) = opaque N.cyan
57 | defaultColourScheme (Contrast Yellow ) = opaque N.violet
58 | defaultColourScheme (Contrast Green ) = opaque N.magenta
59 | defaultColourScheme (Contrast Blue ) = opaque N.orange
60 | defaultColourScheme (Paler c) = DCol.dissolve 0.5 $ defaultColourScheme c
61 | defaultColourScheme (CustomColour c) = opaque c
62 |
63 |
64 | defaultColourSeq :: [Colour]
65 | defaultColourSeq = cycle [blue, red, green, orange, cyan, magenta, yellow, violet]
66 |
67 |
68 |
69 | hueInvert :: FColour -> FColour
70 | hueInvert c = let (l,a,b) = cieLABView i c
71 | in cieLAB i l (1-a) (1-b)
72 | where i = Illum.a
73 |
74 |
75 |
76 |
77 | class HasColour c where
78 | asAColourWith :: ColourScheme -> c -> AColour
79 |
80 | instance HasColour AColour where asAColourWith _ = id
81 | instance HasColour FColour where asAColourWith _ = DCol.opaque
82 | instance HasColour Colour where asAColourWith = ($)
83 | instance HasColour PColour where
84 | asAColourWith sch (TrueColour c) = asAColourWith sch c
85 | asAColourWith sch (SymbolicColour c) = asAColourWith sch c
86 |
87 | instance (HasColour a) => HasColour (Maybe a) where
88 | asAColourWith sch Nothing = sch $ paler contrast
89 | asAColourWith sch (Just c) = asAColourWith sch c
90 |
--------------------------------------------------------------------------------
/dynamic-plot/Graphics/Dynamic/Plot/Internal/Types.hs:
--------------------------------------------------------------------------------
1 | -- |
2 | -- Module : Graphics.Dynamic.Plot.Internal.Types
3 | -- Copyright : (c) Justus Sagemüller 2015
4 | -- License : GPL v3
5 | --
6 | -- Maintainer : (@) jsag $ hvl.no
7 | -- Stability : experimental
8 | -- Portability : requires GHC>6 extensions
9 |
10 |
11 | {-# LANGUAGE NoMonomorphismRestriction #-}
12 | {-# LANGUAGE GADTs #-}
13 | {-# LANGUAGE TypeFamilies #-}
14 | {-# LANGUAGE MultiParamTypeClasses #-}
15 | {-# LANGUAGE ScopedTypeVariables #-}
16 | {-# LANGUAGE RecordWildCards #-}
17 | {-# LANGUAGE TupleSections #-}
18 | {-# LANGUAGE TypeOperators #-}
19 | {-# LANGUAGE FlexibleInstances #-}
20 | {-# LANGUAGE FlexibleContexts #-}
21 | {-# LANGUAGE ConstraintKinds #-}
22 | {-# LANGUAGE UndecidableInstances #-}
23 | {-# LANGUAGE LambdaCase #-}
24 | {-# LANGUAGE NoImplicitPrelude #-}
25 | {-# LANGUAGE RankNTypes #-}
26 | {-# LANGUAGE GeneralizedNewtypeDeriving #-}
27 | {-# LANGUAGE DeriveFunctor #-}
28 | {-# LANGUAGE StandaloneDeriving #-}
29 | {-# LANGUAGE TemplateHaskell #-}
30 |
31 | module Graphics.Dynamic.Plot.Internal.Types where
32 |
33 |
34 | import qualified Prelude
35 |
36 | import Diagrams.Prelude ((^&), (&), _x, _y)
37 | import qualified Diagrams.Prelude as Dia
38 | import qualified Diagrams.TwoD.Size as Dia
39 | import qualified Diagrams.TwoD.Types as DiaTypes
40 | import Diagrams.BoundingBox (BoundingBox)
41 | import qualified Diagrams.BoundingBox as DiaBB
42 | import qualified Diagrams.Backend.Cairo as Cairo
43 | import qualified Diagrams.Backend.Cairo.Text as CairoTxt
44 |
45 | import qualified Data.Colour as DCol
46 |
47 | import qualified Control.Category.Hask as Hask
48 | import Control.Category.Constrained.Prelude hiding ((^))
49 | import Control.Arrow.Constrained
50 | import Control.Monad.Constrained
51 |
52 | import Control.Lens hiding ((...), (<.>))
53 | import Control.Lens.TH
54 |
55 | import qualified Data.Vector as Arr
56 | import Data.List (sort)
57 | import Data.List.NonEmpty (NonEmpty(..))
58 |
59 | import Data.VectorSpace
60 | import Data.Basis
61 | import Math.LinearMap.Category
62 | import Data.AffineSpace
63 | import Data.VectorSpace.Free ()
64 | import Data.Manifold.PseudoAffine
65 | import Data.Manifold.TreeCover
66 | import Data.Semigroup
67 | import Data.Tagged
68 |
69 | import Data.Default
70 |
71 | type R2 = Dia.V2 Double
72 | type P2 = Dia.P2 Double
73 |
74 |
75 |
76 | (^) :: Num n => n -> Int -> n
77 | (^) = (Prelude.^)
78 |
79 |
80 | type R = Double
81 |
82 | -- | Use 'Graphics.Dynamic.Plot.R2.plot' to directly include any 'Dia.Diagram'.
83 | -- (All 'Graphics.Dynamic.Plot.R2.DynamicPlottable'
84 | -- is internally rendered to that type.)
85 | --
86 | -- The exact type may change in the future: we'll probably stay with @diagrams@,
87 | -- but when document output is introduced the backend might become variable
88 | -- or something else but 'Cairo.Cairo'.
89 | type PlainGraphicsR2 = Dia.Diagram Cairo.B
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | data Pair p = Pair !p !p
98 | deriving (Hask.Functor, Show, Eq, Ord)
99 | data Triple p = Triple !p !p !p
100 | deriving (Hask.Functor, Show, Eq, Ord)
101 |
102 | data DiffList a = DiffList { getDiffList :: [a]->[a], diffListLen :: Int }
103 | diffList :: Arr.Vector a -> DiffList a
104 | diffList l = DiffList (Arr.toList l++) (Arr.length l)
105 |
106 | instance Semigroup (DiffList a) where
107 | DiffList dl n <> DiffList dl' n' = DiffList (dl . dl') (n+n')
108 | instance Monoid (DiffList a) where
109 | mappend = (<>); mempty = DiffList id 0
110 |
111 |
112 | newtype SplitList a = SplitList { getSplList :: Arr.Vector a }
113 | deriving (Hask.Functor, Monoid)
114 | presplitList :: [a] -> SplitList a
115 | presplitList = SplitList . Arr.fromList
116 |
117 | splitEvenly :: Int -> SplitList a -> Either (Arr.Vector a) [SplitList a]
118 | splitEvenly k _ | k < 1 = error "Can't split a list to less than one part."
119 | splitEvenly k (SplitList v)
120 | | k >= n = Left v
121 | | otherwise = Right $ splits splitIs 0
122 | where splitIs = take k . map round . tail
123 | $ iterate (+ (fromIntegral n/fromIntegral k :: Double)) 0
124 | splits [_] i₀ = [SplitList $ Arr.drop i₀ v]
125 | splits (i:is) i₀ = SplitList (Arr.slice i₀ (i-i₀) v) : splits is i
126 | n = Arr.length v
127 |
128 | instance Semigroup (SplitList a) where
129 | SplitList l <> SplitList l' = SplitList (l Arr.++ l')
130 |
131 | fromDiffList :: DiffList a -> SplitList a
132 | fromDiffList (DiffList f _) = SplitList . Arr.fromList $ f[]
133 |
134 |
135 |
136 |
137 | data LinFitParams y = LinFitParams { constCoeff :: y
138 | , linCoeff :: Diff y }
139 | deriving instance (AffineSpace y, Show y, Show (Diff y)) => Show (LinFitParams y)
140 |
141 |
142 | linFitMeanInCtrdUnitIntv ::
143 | (AffineSpace y, v~Diff y, VectorSpace v, Fractional (Scalar v))
144 | => LinFitParams y -> y
145 | linFitMeanInCtrdUnitIntv (LinFitParams{..}) = constCoeff
146 |
147 |
148 |
149 | data DevBoxes y = DevBoxes { deviations :: Metric' y
150 | , maxDeviation :: Scalar (Diff y) }
151 |
152 |
153 |
154 |
155 |
156 | data PCMRange x = PCMRange { pcmStart, pcmSampleDuration :: x } deriving (Show)
157 |
158 | data RecursiveSamples' n x y t
159 | = RecursivePCM { rPCMlinFit :: LinFitParams y
160 | , details :: Either (Pair (RecursiveSamples' n x y t))
161 | (Arr.Vector (y,t))
162 | , pFitDeviations :: DevBoxes y
163 | , samplingSpec :: PCMRange x
164 | , splIdLen :: Int
165 | , rPCMNodeInfo :: n
166 | }
167 | instance Hask.Functor (RecursiveSamples' n x y) where
168 | fmap f (RecursivePCM l d v s n i) = RecursivePCM l d' v s n i
169 | where d' = case d of Left rs' -> Left (fmap (fmap f) rs')
170 | Right ps -> Right $ fmap (second f) ps
171 |
172 | fmapRPCMNodeInfo :: (n->n') -> RecursivePCM n x y -> RecursivePCM n' x y
173 | fmapRPCMNodeInfo f (RecursivePCM l d v s n i) = RecursivePCM l d' v s n $ f i
174 | where d' = case d of Left rs' -> Left (fmap (fmapRPCMNodeInfo f) rs')
175 | Right ps -> Right ps
176 |
177 | type RecursiveSamples = RecursiveSamples' ()
178 | type RecursivePCM n x y = RecursiveSamples' n x y ()
179 | type (x-.^>y) = RecursivePCM () x y
180 |
181 | recursiveSamples' :: forall x y v t .
182 | ( VectorSpace x, Real (Scalar x)
183 | , AffineManifold y, v~Needle y, HilbertSpace v, RealFloat (Scalar v) )
184 | => PCMRange x -> [(y,t)] -> RecursiveSamples x y t
185 | recursiveSamples' xrng_g ys = calcDeviations . go xrng_g $ presplitList ys
186 | where go :: PCMRange x -> SplitList (y,t) -> RecursiveSamples' (Arr.Vector y) x y t
187 | go xrng@(PCMRange xl wsp) l@(SplitList arr) = case splitEvenly 2 l of
188 | Right sps
189 | | [sp1, sp2] <- lIndThru xl sps
190 | -> let pFit = solveToLinFit
191 | $ (linFitMeanInCtrdUnitIntv.rPCMlinFit) <$> [sp1,sp2]
192 | in RecursivePCM pFit
193 | (Left $ Pair sp1 sp2)
194 | (undefined)
195 | xrng (Arr.length arr)
196 | (fmap fst arr)
197 | Right _ -> evenSplitErr
198 | Left pSpls -> RecursivePCM (solveToLinFit $ Arr.toList (fmap fst pSpls))
199 | (Right $ pSpls)
200 | (undefined)
201 | xrng (Arr.length arr)
202 | (fmap fst arr)
203 | where lIndThru _ [] = []
204 | lIndThru x₀₁ (sp₁@(SplitList arr₁):sps)
205 | = let x₀₂ = x₀₁ ^+^ fromIntegral (Arr.length arr₁) *^ wsp
206 | in go (PCMRange x₀₁ wsp) sp₁ : lIndThru x₀₂ sps
207 | evenSplitErr = error "'splitEvenly' returned wrong number of slices."
208 |
209 | calcDeviations :: RecursiveSamples' (Arr.Vector y) x y t
210 | -> RecursiveSamples x y t
211 | calcDeviations = cdvs Nothing Nothing
212 | where cdvs lPFits rPFits
213 | rPCM@( RecursivePCM pFit dtls _ sSpc@(PCMRange xl wsp) slLn pts )
214 | = RecursivePCM pFit dtls' (DevBoxes stdDev maxDev) sSpc slLn ()
215 | where stdDev = scaleNorm (1/ fromIntegral slLn) $ spanNorm msqs
216 | maxDev = sqrt . maximum $ magnitudeSq <$> msqs
217 | msqs = [ (y .-. ff x)
218 | | (x,y) <- normlsdIdd $ SplitList pts ]
219 | ff = l₀splineRep (Pair lPFits rPFits) rPCM
220 | dtls' = case dtls of
221 | Left (Pair r₁ r₂)
222 | -> let r₁' = cdvs (rRoute=< Right pSpls
226 | (LinFitParams b a) = pFit
227 | lRoute, rRoute :: RecursiveSamples' n x y t -> Maybe (RecursiveSamples' n x y t)
228 | lRoute (RecursivePCM {details = Right _}) = Nothing
229 | lRoute (RecursivePCM {details = Left (Pair l _)}) = Just l
230 | rRoute (RecursivePCM {details = Right _}) = Nothing
231 | rRoute (RecursivePCM {details = Left (Pair _ r)}) = Just r
232 |
233 |
234 | recursiveSamples ::
235 | ( AffineManifold y, v~Needle y, HilbertSpace v, RealFloat (Scalar v) )
236 | => [(y,t)] -> RecursiveSamples Int y t
237 | recursiveSamples = recursiveSamples' (PCMRange 0 1)
238 |
239 | recursivePCM :: ( VectorSpace x, Real (Scalar x)
240 | , AffineManifold y, v~Needle y, HilbertSpace v, RealFloat (Scalar v) )
241 | => PCMRange x -> [y] -> x-.^>y
242 | recursivePCM xrng_g = recursiveSamples' xrng_g . fmap (,())
243 |
244 |
245 | splineRep :: ( AffineSpace y, v~Diff y, InnerSpace v, Floating (Scalar v), Ord (Scalar v) )
246 | => Int -- ^ Number of subdivisions to \"go down\".
247 | -> (R-.^>y) -> R -> y
248 | splineRep n₀ rPCM@(RecursivePCM _ _ _ (PCMRange xl wsp) slLn ())
249 | = go n₀ Nothing Nothing rPCM . normaliseR
250 | where go n lPFits rPFits (RecursivePCM _ (Left (Pair r₁ r₂)) _ _ slLn ())
251 | | n>0, f₁ <- go (n-1) (rRoute=< if x<0.5 then f₁ $ x*2
254 | else f₂ $ x*2 - 1
255 | go _ lPFits rPFits rPCM = l₀splineRep (Pair lPFits rPFits) rPCM
256 |
257 | normaliseR x = (x - xl)/(wsp * fromIntegral slLn)
258 |
259 | l₀splineRep ::
260 | ( VectorSpace x, Num (Scalar x)
261 | , AffineSpace y, v~Diff y, VectorSpace v, Floating (Scalar v), Ord (Scalar v) )
262 | => Pair (Maybe (RecursiveSamples' n x y t'))
263 | -> (RecursiveSamples' n x y t)
264 | -> R{-Sample position normalised to [0,1]-} -> y
265 | l₀splineRep (Pair lPFits rPFits)
266 | (RecursivePCM{ rPCMlinFit=LinFitParams b a
267 | , samplingSpec=PCMRange x₀ wsp
268 | , splIdLen = n })
269 | = f
270 | where f x | x < 0.5, t <- realToFrac $ 0.5 - x
271 | , Just(RecursivePCM{rPCMlinFit=LinFitParams b'l a'l}) <- lPFits
272 | = b .+^ (b'l.-.b) ^* h₀₁ t
273 | .-^ a ^* h₁₀ t
274 | .-^ a'l ^* h₁₁ t
275 | | x > 0.5, t <- realToFrac $ x - 0.5
276 | , Just(RecursivePCM{rPCMlinFit=LinFitParams b'r a'r}) <- rPFits
277 | = b .+^ (b'r.-.b) ^* h₀₁ t
278 | .+^ a ^* h₁₀ t
279 | .+^ a'r ^* h₁₁ t
280 | | t <- realToFrac $ x-0.5
281 | = b .+^ t*^a
282 | h₀₀ t = (1 + 2*t) * (1 - t)^2 -- Cubic Hermite splines
283 | h₀₁ t = t^2 * (3 - 2*t)
284 | h₁₀ t = t * (1 - t)^2
285 | h₁₁ t = t^2 * (t - 1)
286 |
287 |
288 |
289 | rPCMSample :: (AffineManifold y, v~Needle y, HilbertSpace v, RealFloat (Scalar v))
290 | => Interval R -> R -> (R->y) -> R-.^>y
291 | rPCMSample (Interval l r) δx f = recursivePCM (PCMRange l δx) [f x | x<-[l, l+δx .. r]]
292 |
293 |
294 | type R2Box = Dia.BoundingBox Dia.V2 Double
295 |
296 | rPCM_R2_boundingBox :: (RecursiveSamples x P2 t) -> R2Box
297 | rPCM_R2_boundingBox rPCM@(RecursivePCM pFit _ (DevBoxes dev _) _ _ ())
298 | = Interval (xl - ux*2) (xr + ux*2)
299 | -*| Interval (yb - uy*2) (yt + uy*2)
300 | where pm = constCoeff pFit
301 | p₀ = pm .-^ linCoeff pFit; pe = pm .+^ linCoeff pFit
302 | ux = dev |$| 1^&0; uy = dev |$| 0^&1
303 | [xl,xr] = sort[p₀^._x, pe^._x]; [yb,yt] = sort[p₀^._y, pe^._y]
304 |
305 |
306 |
307 |
308 |
309 | rPCMLinFitRange :: (R-.^>R) -> Interval R -> Interval R
310 | rPCMLinFitRange rPCM@(RecursivePCM _ _ (DevBoxes _ δ) _ _ ()) ix
311 | = let (Interval b t) = rppm rPCM ix in Interval (b-δ) (t+δ)
312 | where rppm rPCM@(RecursivePCM (LinFitParams b a) _ _ _ _ ()) (Interval l r)
313 | | r < (-1) = spInterval $ b - a
314 | | l > 1 = spInterval $ b + a
315 | | l < (-1) = rppm rPCM $ Interval (-1) r
316 | | r > 1 = rppm rPCM $ Interval l 1
317 | | otherwise = (b + l*a) ... (b + r*a)
318 |
319 |
320 | solveToLinFit :: (AffineSpace y, v~Diff y, VectorSpace v, Floating (Scalar v))
321 | => [y] -> LinFitParams y
322 | solveToLinFit [] = error
323 | "LinFit solve under-specified (need at least one reference point)."
324 | solveToLinFit [y] = LinFitParams { constCoeff=y, linCoeff=zeroV }
325 | solveToLinFit [y₁,y₂] -- @[x₁, x₂] ≡ [-½, ½]@, and @f(½) = (y₁+y₂)/2 + ½·(y₂-y₁) = y₂@.
326 | -- (Likewise for @f(-½) = y₁@).
327 | = LinFitParams { constCoeff = alerp y₁ y₂ 0.5
328 | , linCoeff = y₂ .-. y₁ }
329 | solveToLinFit _ = error "LinFit solve over-specified (can't solve more than two points)."
330 |
331 |
332 | normlsdIdd :: Fractional x => SplitList y -> [(x, y)]
333 | normlsdIdd (SplitList l) = zip [ (k+1/2)/fromIntegral (Arr.length l)
334 | | k<-iterate(+1)0] $ Arr.toList l
335 |
336 |
337 | type FColour = DCol.Colour Double
338 | type AColour = DCol.AlphaColour Double
339 |
340 | -- | Unlike the typical types such as 'Draw.Color', this one has /semantic/
341 | -- more than physical meaning.
342 | data Colour = BaseColour BaseColour
343 | | Contrast BaseColour
344 | | Paler Colour
345 | | CustomColour FColour
346 | deriving (Eq)
347 | data BaseColour = Neutral -- ^ Either black or white, depending on the context.
348 | | Red -- ^ Contrast cyan.
349 | | Yellow -- ^ Contrast violet.
350 | | Green -- ^ Contrast magenta.
351 | | Blue -- ^ Contrast orange.
352 | deriving (Eq, Show, Enum)
353 |
354 | type ColourScheme = Colour -> AColour
355 |
356 | data PColour = TrueColour FColour | SymbolicColour Colour
357 |
358 |
359 | data GraphWindowSpecR2 = GraphWindowSpecR2 {
360 | lBound, rBound, bBound, tBound :: R
361 | , xResolution, yResolution :: Int
362 | , colourScheme :: ColourScheme
363 | }
364 | instance Show GraphWindowSpecR2 where
365 | show (GraphWindowSpecR2{..}) = "GraphWindowSpecR2{\
366 | \lBound="++show lBound++", \
367 | \rBound="++show rBound++", \
368 | \bBound="++show bBound++", \
369 | \tBound="++show tBound++", \
370 | \xResolution="++show xResolution++", \
371 | \yResolution="++show yResolution++"}"
372 |
373 | windowCenter :: Lens' GraphWindowSpecR2 (R,R)
374 | windowCenter = lens
375 | (\(GraphWindowSpecR2 l r b t _ _ _) -> ((l+r)/2, (b+t)/2))
376 | (\(GraphWindowSpecR2 l r b t xRes yRes colSch) (cx, cy)
377 | -> let rx = (r-l)/2; ry = (t-b)/2
378 | in GraphWindowSpecR2 (cx - rx) (cx + rx) (cy - ry) (cy + ry)
379 | xRes yRes colSch
380 | )
381 | windowDiameter :: Lens' GraphWindowSpecR2 R
382 | windowDiameter = lens
383 | (\(GraphWindowSpecR2 l r b t _ _ _) -> sqrt $ (r-l)^2 + (t-b)^2)
384 | (\(GraphWindowSpecR2 l r b t xRes yRes colSch) dNew
385 | -> let cx = (l+r)/2; rx = (r-l)/2
386 | cy = (b+t)/2; ry = (t-b)/2
387 | dOld = 2 * sqrt (rx^2 + ry^2)
388 | η = dNew / dOld
389 | in GraphWindowSpecR2 (cx - η*rx) (cx + η*rx) (cy - η*ry) (cy + η*ry)
390 | xRes yRes colSch
391 | )
392 | windowDataAspect :: Lens' GraphWindowSpecR2 R
393 | windowDataAspect = lens
394 | (\(GraphWindowSpecR2 l r b t xRes yRes _) -> (r-l)/(t-b)
395 | * fromIntegral yRes/fromIntegral xRes)
396 | (\(GraphWindowSpecR2 l r b t xRes yRes colSch) βNew
397 | -> let cx = (l+r)/2; rx = (r-l)/2
398 | cy = (b+t)/2; ry = (t-b)/2
399 | βOld = (r-l)/(t-b) * fromIntegral yRes/fromIntegral xRes
400 | ψ = sqrt $ βNew / βOld
401 | in GraphWindowSpecR2 (cx - rx*ψ) (cx + rx*ψ) (cy - ry/ψ) (cy + ry/ψ)
402 | xRes yRes colSch
403 | )
404 |
405 |
406 |
407 | data Interval r = Interval !r !r deriving (Show)
408 | instance (Ord r) => Semigroup (Interval r) where -- WRT closed hull of the union.
409 | Interval l₁ u₁ <> Interval l₂ u₂ = Interval (min l₁ l₂) (max u₁ u₂)
410 |
411 | realInterval :: Real r => Interval r -> Interval R
412 | realInterval (Interval a b) = Interval (realToFrac a) (realToFrac b)
413 |
414 | onInterval :: ((R,R) -> (R,R)) -> Interval R -> Interval R
415 | onInterval f (Interval l r) = uncurry Interval $ f (l, r)
416 |
417 | infixl 6 ...
418 | -- | Build an interval from specified boundary points. No matter which of these
419 | -- points is higher, the result will always be the interval in between (i.e.,
420 | -- @3 '...' 1@ will yield the interval [1,3], not an empty set or some \"oriented
421 | -- interval\" [3,1]).
422 | -- The fixity @infixl 6@ was chosen so you can write 2D bounding-boxes as e.g.
423 | -- @-1...4 -*| -1...1@.
424 | (...) :: (Ord r) => r -> r -> Interval r
425 | x1...x2 | x1 < x2 = Interval x1 x2
426 | | otherwise = Interval x2 x1
427 |
428 | infixl ±
429 | (±) :: Real v => v -> v -> Interval v
430 | c ± δ | δ>0 = Interval (c-δ) (c+δ)
431 | | otherwise = Interval (c+δ) (c-δ)
432 |
433 | spInterval :: r -> Interval r
434 | spInterval x = Interval x x
435 |
436 | intersects :: Ord r => Interval r -> Interval r -> Bool
437 | intersects (Interval a b) (Interval c d) = a<=d && b>=c
438 |
439 | includes :: Ord r => Interval r -> r -> Bool
440 | Interval a b `includes` x = x>=a && x<=b
441 |
442 | infix 5 -*|
443 |
444 | -- | Cartesian product of intervals.
445 | (-*|) :: Interval R -> Interval R -> R2Box
446 | Interval l r -*| Interval b t = DiaBB.fromCorners (l^&b) (r^&t)
447 |
448 | -- | Inverse of @uncurry ('-*|')@. /This is a partial function/, since
449 | -- 'BoundingBox'es can be empty.
450 | xyRanges :: R2Box -> (Interval R, Interval R)
451 | xyRanges bb = let Just (c₁, c₂) = DiaBB.getCorners bb
452 | in (c₁^._x ... c₂^._x, c₁^._y ... c₂^._y)
453 |
454 |
455 |
456 | shadeExtends :: Shade P2 -> (Interval R, Interval R)
457 | shadeExtends shade
458 | = ( (ctr^._x) ± (expa |$| 1^&0)
459 | , (ctr^._y) ± (expa |$| 0^&1) )
460 | where ctr = shade^.shadeCtr; expa = shade^.shadeExpanse
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 | type Necessity = Double
469 | superfluent = -1e+32 :: Necessity
470 |
471 |
472 |
473 |
474 |
475 |
476 | infixl 7 `provided`
477 | provided :: Monoid m => m -> Bool -> m
478 | provided m True = m
479 | provided m False = mempty
480 |
481 |
482 | ceil, flor :: R -> R
483 | ceil = fromInt . ceiling
484 | flor = fromInt . floor
485 |
486 | fromInt :: Num a => Int -> a
487 | fromInt = fromIntegral
488 |
489 |
490 |
491 |
492 |
493 | newtype Latest a = Latest { getLatestOf :: NonEmpty a }
494 | deriving (Hask.Functor)
495 |
496 |
497 |
498 | data PrerenderScaling
499 | = ValuespaceScaling -- ^ The diagram has the original coordinates of
500 | -- the data that's plotted in it. E.g. if you've
501 | -- plotted an oscillation with amplitude 1e-4, the
502 | -- height of the plot will be indicated as only 0.0002.
503 | -- Mostly useful when you want to juxtapose multiple
504 | -- plots with correct scale matching.
505 | | NormalisedScaling -- ^ The diagram is scaled to have a range of @[-1, 1]@
506 | -- in both x- and y-direction.
507 | | OutputCoordsScaling -- ^ Scaled to pixel coordinates, i.e. the x range is
508 | -- @[0, xResV-1]@ and the y range @[0, yResV-1]@.
509 |
510 | data ViewportConfig = ViewportConfig {
511 | _xResV, _yResV :: Int
512 | , _prerenderScaling :: PrerenderScaling
513 | , _plotContentZoomFactor :: Double
514 | , _plotBackground :: Maybe (Dia.Colour Double)
515 | , _graphicsPostprocessing :: PlainGraphicsR2 -> PlainGraphicsR2
516 | }
517 | makeLenses ''ViewportConfig
518 |
519 | instance Default ViewportConfig where
520 | def = ViewportConfig 640 480 ValuespaceScaling (6/7) Nothing id
521 |
522 | setSolidBackground :: Dia.Colour Double -> ViewportConfig -> ViewportConfig
523 | setSolidBackground c = plotBackground .~ Just c
524 |
525 |
526 | data LegendDisplayConfig = LegendDisplayConfig {
527 | _legendPrerenderSize :: Dia.SizeSpec Dia.V2 Double
528 | }
529 | makeLenses ''LegendDisplayConfig
530 |
531 | defaultLegendLineHeight :: Double
532 | defaultLegendLineHeight = 16
533 |
534 | instance Default LegendDisplayConfig where
535 | def = LegendDisplayConfig $ Dia.mkSizeSpec2D Nothing (Just defaultLegendLineHeight)
536 |
537 | data MouseEvent x = MouseEvent {
538 | _clickLocation, _releaseLocation :: x
539 | }
540 | deriving (Eq)
541 | makeLenses ''MouseEvent
542 |
--------------------------------------------------------------------------------
/dynamic-plot/Graphics/Dynamic/Plot/Internals.hs:
--------------------------------------------------------------------------------
1 | -- |
2 | -- Module : Graphics.Dynamic.Plot.Internals
3 | -- Copyright : (c) Justus Sagemüller 2023
4 | -- License : GPL v3
5 | --
6 | -- Maintainer : (@) jsag $ hvl.no
7 | -- Stability : experimental
8 | -- Portability : requires GHC>6 extensions
9 |
10 |
11 | module Graphics.Dynamic.Plot.Internals (
12 | module Graphics.Dynamic.Plot.R2.Internal
13 | , module Graphics.Dynamic.Plot.Internal.Types
14 | , module Graphics.Dynamic.Plot.Colour
15 | , module Graphics.Text.Annotation
16 | , module Graphics.Image.Resample
17 | ) where
18 |
19 | import Graphics.Dynamic.Plot.R2.Internal
20 | import Graphics.Dynamic.Plot.Internal.Types
21 | import Graphics.Dynamic.Plot.Colour
22 | import Graphics.Text.Annotation
23 | import Graphics.Image.Resample
24 |
25 |
--------------------------------------------------------------------------------
/dynamic-plot/Graphics/Dynamic/Plot/R2.hs:
--------------------------------------------------------------------------------
1 | -- |
2 | -- Module : Graphics.Dynamic.Plot.R2
3 | -- Copyright : (c) Justus Sagemüller 2013-2019
4 | -- License : GPL v3
5 | --
6 | -- Maintainer : (@) jsag $ hvl.no
7 | -- Stability : experimental
8 | -- Portability : requires GHC>6 extensions
9 |
10 |
11 | {-# LANGUAGE NoMonomorphismRestriction #-}
12 | {-# LANGUAGE GADTs #-}
13 | {-# LANGUAGE TypeFamilies #-}
14 | {-# LANGUAGE ScopedTypeVariables #-}
15 | {-# LANGUAGE RecordWildCards #-}
16 | {-# LANGUAGE TupleSections #-}
17 | {-# LANGUAGE TypeOperators #-}
18 | {-# LANGUAGE UnicodeSyntax #-}
19 | {-# LANGUAGE FlexibleInstances #-}
20 | {-# LANGUAGE LiberalTypeSynonyms #-}
21 | {-# LANGUAGE FlexibleContexts #-}
22 | {-# LANGUAGE ConstraintKinds #-}
23 | {-# LANGUAGE UndecidableInstances #-}
24 | {-# LANGUAGE LambdaCase #-}
25 | {-# LANGUAGE NoImplicitPrelude #-}
26 | {-# LANGUAGE RankNTypes #-}
27 | {-# LANGUAGE GeneralizedNewtypeDeriving #-}
28 | {-# LANGUAGE DeriveFunctor #-}
29 | {-# LANGUAGE StandaloneDeriving #-}
30 | {-# LANGUAGE TemplateHaskell #-}
31 | {-# LANGUAGE CPP #-}
32 |
33 | module Graphics.Dynamic.Plot.R2 (
34 | -- * Display
35 | -- ** Static
36 | plotPrerender
37 | -- ** Interactive
38 | --
39 | -- $gtkPlotting
40 | --
41 | -- * Plottable objects
42 | -- ** Class
43 | , Plottable(..)
44 | -- ** Simple function plots
45 | , fnPlot, paramPlot
46 | , continFnPlot
47 | , tracePlot
48 | , lineSegPlot
49 | , linregressionPlot
50 | , colourPaintPlot
51 | , PlainGraphicsR2
52 | , shapePlot
53 | , diagramPlot
54 | -- ** Multiple objects in one plot
55 | , plotMultiple
56 | -- ** Computation in progress
57 | , plotLatest
58 | -- * Plot-object attributes
59 | -- ** Colour
60 | , tint, autoTint
61 | -- ** Legend captions
62 | , legendName
63 | , plotLegendPrerender
64 | -- ** Animation
65 | , plotDelay, freezeAnim, startFrozen
66 | -- * Viewport
67 | -- ** View selection
68 | , xInterval, yInterval, forceXRange, forceYRange
69 | , unitAspect, ignoreExtent
70 | -- ** Interactive content
71 | -- $interactiveExplanation
72 | -- *** Mouse
73 | , MousePressed (..), MousePress(..), MouseClicks(..)
74 | , clickThrough, withDraggablePoints, mouseInteractive
75 | , MouseEvent, clickLocation, releaseLocation
76 | -- *** Displayed range
77 | , ViewXCenter(..), ViewYCenter(..), ViewWidth(..), ViewHeight(..)
78 | -- *** Resolution
79 | , ViewXResolution(..), ViewYResolution(..)
80 | -- * Auxiliary plot objects
81 | , dynamicAxes, noDynamicAxes, xAxisLabel, yAxisLabel
82 | -- * Types
83 | -- ** The plot type
84 | , DynamicPlottable
85 | , tweakPrerendered
86 | -- ** Viewport choice
87 | , ViewportConfig
88 | -- *** Resolution
89 | , xResV, yResV
90 | -- *** Background
91 | , setSolidBackground
92 | -- *** Output scaling
93 | , prerenderScaling
94 | , PrerenderScaling(..)
95 | , LegendDisplayConfig
96 | , legendPrerenderSize
97 | -- *** General
98 | , graphicsPostprocessing
99 | ) where
100 |
101 | import Graphics.Dynamic.Plot.R2.Internal
102 |
103 | import Graphics.Dynamic.Plot.Internal.Types
104 |
105 |
106 | -- $gtkPlotting
107 | --
108 | -- The module contains
109 | -- @plotWindow@, which can be used for displaying data in an
110 | -- interactive window.
111 | --
112 | -- Example:
113 | --
114 | -- <>
115 |
--------------------------------------------------------------------------------
/dynamic-plot/Graphics/Image/Resample.hs:
--------------------------------------------------------------------------------
1 | -- |
2 | -- Module : Graphics.Image.Resample
3 | -- Copyright : (c) Justus Sagemüller 2018
4 | -- License : GPL v3
5 | --
6 | -- Maintainer : (@) sagemuej $ smail.uni-koeln.de
7 | -- Stability : experimental
8 | -- Portability : requires GHC>6 extensions
9 |
10 | {-# LANGUAGE FlexibleInstances #-}
11 | {-# LANGUAGE TypeFamilies #-}
12 | {-# LANGUAGE NoMonomorphismRestriction #-}
13 |
14 | module Graphics.Image.Resample where
15 |
16 | import qualified Codec.Picture as JPix
17 | import qualified Codec.Picture.Types as JPix
18 |
19 | import qualified Data.Vector.Storable as SArr
20 |
21 | import Control.Monad
22 | import Control.Monad.ST
23 | import Data.STRef
24 |
25 |
26 | scaleX2Bilinear :: JPix.Image JPix.PixelRGBA8 -> JPix.Image JPix.PixelRGBA8
27 | scaleX2Bilinear img@(JPix.Image _ _ imgData) = runST $ do
28 | buf@(JPix.MutableImage _ _ bufData) <- JPix.newMutableImage wScaled hScaled
29 |
30 | let pbc = JPix.componentCount (undefined :: JPix.PixelRGBA8)
31 |
32 | forM_ [0 .. hOrig-2] $ \j -> do
33 | forM_ [0 .. wOrig-2] $ \k -> do
34 | let linIndex = JPix.pixelBaseIndex img k j
35 | orig₀₀ = JPix.unsafePixelAt imgData linIndex
36 | orig₀₁ = JPix.unsafePixelAt imgData (linIndex+pbc)
37 | orig₁₀ = JPix.unsafePixelAt imgData (linIndex+pbc*wOrig)
38 | linIndexScaled = JPix.mutablePixelBaseIndex buf (k*2) (j*2)
39 | JPix.unsafeWritePixel bufData linIndexScaled
40 | $ orig₀₀
41 | JPix.unsafeWritePixel bufData (linIndexScaled+pbc)
42 | $ between orig₀₀ orig₀₁
43 | JPix.unsafeWritePixel bufData (linIndexScaled+pbc*wScaled)
44 | $ between orig₀₀ orig₁₀
45 | JPix.unsafeWritePixel bufData (linIndexScaled+pbc+pbc*wScaled)
46 | $ between orig₁₀ orig₀₁
47 |
48 | forM_ [0 .. hOrig-2] $ \j -> do
49 | forM_ [wOrig-1] $ \k -> do
50 | let orig₀₀ = JPix.pixelAt img k j
51 | orig₁₀ = JPix.pixelAt img k (j+1)
52 | JPix.writePixel buf (k*2) (j*2) $ orig₀₀
53 | JPix.writePixel buf (k*2) (j*2+1) $ between orig₀₀ orig₁₀
54 |
55 | forM_ [hOrig-1] $ \j -> do
56 | forM_ [0 .. wOrig-2] $ \k -> do
57 | let orig₀₀ = JPix.pixelAt img k j
58 | orig₀₁ = JPix.pixelAt img (k+1) j
59 | JPix.writePixel buf (k*2) (j*2) $ orig₀₀
60 | JPix.writePixel buf (k*2+1) (j*2) $ between orig₀₀ orig₀₁
61 |
62 | forM_ [hOrig-1] $ \j -> do
63 | forM_ [wOrig-1] $ \k -> do
64 | let orig₀₀ = JPix.pixelAt img k j
65 | JPix.writePixel buf (k*2) (j*2) $ orig₀₀
66 |
67 | JPix.unsafeFreezeImage buf
68 |
69 | where wOrig = JPix.imageWidth img
70 | wScaled = 2 * wOrig - 1
71 | hOrig = JPix.imageHeight img
72 | hScaled = 2 * hOrig - 1
73 |
74 | refiningScaleX2Bilinear ::
75 | [(Int,Int)] -> ((Int,Int) -> JPix.PixelRGBA8)
76 | -> JPix.Image JPix.PixelRGBA8 -> (JPix.Image JPix.PixelRGBA8, [(Int,Int)])
77 | refiningScaleX2Bilinear hotSpots refineFn loRes = runST (do
78 | intermediate <- JPix.unsafeThawImage $ scaleX2Bilinear loRes
79 |
80 | alreadyDone <- JPix.unsafeThawImage
81 | $ JPix.generateImage (\_ _ -> 0::JPix.Pixel8)
82 | renderWidth renderHeight
83 |
84 | alterations <- newSTRef []
85 |
86 | let refineAt (ix,iy) = do
87 | roughVal <- JPix.readPixel intermediate ix iy
88 | let refinedVal = refineFn (ix,iy)
89 | JPix.writePixel intermediate ix iy refinedVal
90 | JPix.writePixel alreadyDone ix iy 1
91 | notablyDifferent refinedVal roughVal ==> modifySTRef alterations ((ix,iy):)
92 | refineBack (ix,iy) = do
93 | doneBefore <- JPix.readPixel alreadyDone ix iy
94 | doneBefore==0 ==> refineAt (ix,iy)
95 |
96 | forM_ hotSpots $ \(irx,iry) -> do
97 | irx > 0 ==> do
98 | refineBack (2*irx - 1, 2*iry)
99 | iry > 0 ==> refineBack (2*irx - 1, 2*iry - 1)
100 | iry < loResHeight-1 ==> refineBack (2*irx - 1, 2*iry + 1)
101 | irx < loResWidth-1 ==> do
102 | refineAt (2*irx + 1, 2*iry)
103 | iry > 0 ==> refineBack (2*irx + 1, 2*iry - 1)
104 | iry < loResHeight-1 ==> refineAt (2*irx + 1, 2*iry + 1)
105 | iry > 0 ==> refineBack (2*irx, 2*iry - 1)
106 | iry < loResHeight-1 ==> refineAt (2*irx, 2*iry + 1)
107 |
108 | alterationsDone <- readSTRef alterations
109 |
110 | result <- JPix.unsafeFreezeImage intermediate
111 |
112 | return (result, alterationsDone)
113 | )
114 | where loResWidth = JPix.imageWidth loRes
115 | loResHeight = JPix.imageHeight loRes
116 | renderWidth = loResWidth * 2 - 1
117 | renderHeight = loResHeight * 2 - 1
118 | infixr 1 ==>
119 | (==>) = when
120 |
121 |
122 | notablyDifferent :: JPix.PixelRGBA8 -> JPix.PixelRGBA8 -> Bool
123 | notablyDifferent (JPix.PixelRGBA8 r₀ g₀ b₀ a₀) (JPix.PixelRGBA8 r₁ g₁ b₁ a₁)
124 | = ( abs (fromIntegral r₀ - fromIntegral r₁)
125 | + abs (fromIntegral g₀ - fromIntegral g₁)
126 | + abs (fromIntegral b₀ - fromIntegral b₁)
127 | + abs (fromIntegral a₀ - fromIntegral a₁) :: Int )
128 | > 16
129 |
130 |
131 | between :: JPix.PixelRGBA8 -> JPix.PixelRGBA8 -> JPix.PixelRGBA8
132 | between (JPix.PixelRGBA8 r₀ g₀ b₀ a₀) (JPix.PixelRGBA8 r₁ g₁ b₁ a₁)
133 | = JPix.PixelRGBA8 (r₀`quot`2 + r₁`quot`2)
134 | (g₀`quot`2 + g₁`quot`2)
135 | (b₀`quot`2 + b₁`quot`2)
136 | (a₀`quot`2 + a₁`quot`2)
137 |
--------------------------------------------------------------------------------
/dynamic-plot/Graphics/Text/Annotation.hs:
--------------------------------------------------------------------------------
1 | -- |
2 | -- Module : Graphics.Text.Annotation
3 | -- Copyright : (c) Justus Sagemüller 2015
4 | -- License : GPL v3
5 | --
6 | -- Maintainer : (@) jsage $ hvl.no
7 | -- Stability : experimental
8 | -- Portability : requires GHC>6 extensions
9 |
10 |
11 | {-# LANGUAGE NoMonomorphismRestriction #-}
12 | {-# LANGUAGE GADTs #-}
13 | {-# LANGUAGE TypeFamilies #-}
14 | {-# LANGUAGE ScopedTypeVariables #-}
15 | {-# LANGUAGE RecordWildCards #-}
16 | {-# LANGUAGE TupleSections #-}
17 | {-# LANGUAGE TypeOperators #-}
18 | {-# LANGUAGE FlexibleInstances #-}
19 | {-# LANGUAGE FlexibleContexts #-}
20 | {-# LANGUAGE ConstraintKinds #-}
21 | {-# LANGUAGE UndecidableInstances #-}
22 | {-# LANGUAGE LambdaCase #-}
23 | {-# LANGUAGE NoImplicitPrelude #-}
24 | {-# LANGUAGE RankNTypes #-}
25 | {-# LANGUAGE GeneralizedNewtypeDeriving #-}
26 | {-# LANGUAGE DeriveFunctor #-}
27 | {-# LANGUAGE StandaloneDeriving #-}
28 | {-# LANGUAGE TemplateHaskell #-}
29 |
30 | module Graphics.Text.Annotation where
31 |
32 | import Graphics.Dynamic.Plot.Colour
33 | import Graphics.Dynamic.Plot.Internal.Types
34 |
35 |
36 | import qualified Prelude
37 |
38 | import Diagrams.Prelude ((^&), (&), _x, _y, (|||), (===))
39 | import qualified Diagrams.Prelude as Dia
40 | import qualified Diagrams.TwoD.Size as Dia
41 | import qualified Diagrams.TwoD.Types as DiaTypes
42 | import qualified Diagrams.TwoD.Text as DiaTxt
43 | import Diagrams.BoundingBox (BoundingBox)
44 | import qualified Diagrams.BoundingBox as DiaBB
45 | import qualified Diagrams.Backend.Cairo as Cairo
46 | import qualified Diagrams.Backend.Cairo.Text as CairoTxt
47 |
48 | import Control.Monad.Trans (liftIO)
49 |
50 | import qualified Control.Category.Hask as Hask
51 | import Control.Category.Constrained.Prelude hiding ((^))
52 | import Control.Arrow.Constrained hiding ((|||))
53 | import Control.Monad.Constrained
54 |
55 | import Control.Lens hiding ((...), (<.>))
56 | import Control.Lens.TH
57 |
58 |
59 | import Data.List (foldl', sort, intercalate, isPrefixOf, isInfixOf, find, zip4)
60 | import qualified Data.Vector as Arr
61 | import Data.Maybe
62 | import Data.Semigroup
63 | import Data.Foldable (fold, foldMap)
64 | import Data.Function (on)
65 |
66 | import Data.VectorSpace
67 | import Data.Basis
68 | import Data.AffineSpace
69 | import Data.Manifold.PseudoAffine
70 | import Data.Manifold.TreeCover
71 | import qualified Data.Map.Lazy as Map
72 |
73 | import Data.Tagged
74 |
75 | import Text.Printf
76 |
77 |
78 |
79 |
80 | prettyFloatShow :: Int -> Double -> String
81 | prettyFloatShow _ 0 = "0"
82 | prettyFloatShow preci x
83 | | preci >= 0, preci < 4 = show $ round x
84 | | preci < 0, preci > -2 = printf "%.1f" x
85 | | otherwise = case ceiling (0.01 + lg (abs x/10^^(preci+1))) + preci of
86 | 0 | preci < 0 -> printf "%.*f"
87 | (-preci)
88 | x
89 | expn | expn>preci -> printf "%.*f×₁₀%s"
90 | (expn-preci)
91 | (x/10^^expn)
92 | (showExponentAsSuperscript expn)
93 | | otherwise -> printf "%i×₁₀%s"
94 | (round $ x/10^^expn :: Int)
95 | (showExponentAsSuperscript expn)
96 |
97 | showExponentAsSuperscript :: Int -> String
98 | showExponentAsSuperscript = map sup . show
99 | where sup ch = case lookup ch $ zip "0123456789-"
100 | "⁰¹²³⁴⁵⁶⁷⁸⁹⁻" of
101 | Just ch -> ch
102 |
103 | maybeRead :: Read a => String -> Maybe a
104 | maybeRead = fmap fst . listToMaybe . reads
105 |
106 | data Annotation = Annotation {
107 | getAnnotation :: AnnotationObj
108 | , placement :: AnnotationPlace
109 | , isOptional :: Bool
110 | }
111 | data AnnotationObj = TextAnnotation TextObj TextAlignment
112 | data AnnotationPlace = ExactPlace R2
113 |
114 | data TextObj = PlainText String
115 | fromPlaintextObj :: TextObj -> String
116 | fromPlaintextObj (PlainText t) = t
117 |
118 | data TextAlignment = TextAlignment { hAlign, vAlign :: Alignment } -- , blockSpread :: Bool }
119 | data Alignment = AlignBottom | AlignMid | AlignTop
120 |
121 | type TxtStyle = Dia.Style Dia.V2 R
122 |
123 | data DiagramTK = DiagramTK { textTools :: TextTK, viewScope :: GraphWindowSpecR2 }
124 | data TextTK = TextTK { txtCairoStyle :: TxtStyle
125 | , txtSize, xAspect, padding, extraTopPad :: R }
126 |
127 | defaultTxtStyle :: TxtStyle
128 | defaultTxtStyle = mempty & Dia.fontSizeO 9
129 | & Dia.fc Dia.grey
130 | & Dia.lc Dia.grey
131 |
132 |
133 | prerenderAnnotation :: DiagramTK -> Annotation -> IO PlainGraphicsR2
134 | prerenderAnnotation (DiagramTK{ textTools = TextTK{..}, viewScope = GraphWindowSpecR2{..} })
135 | (Annotation{..})
136 | | TextAnnotation (PlainText str) (TextAlignment{..}) <- getAnnotation
137 | , ExactPlace p₀ <- placement = do
138 | let dtxAlign = DiaTxt.BoxAlignedText
139 | (case hAlign of {AlignBottom -> 0; AlignMid -> 0.5; AlignTop -> 1})
140 | (case vAlign of {AlignBottom -> 0; AlignMid -> 0.5; AlignTop -> 1})
141 |
142 | rnTextLines <- mapM (CairoTxt.textVisualBoundedIO txtCairoStyle
143 | . DiaTxt.Text mempty dtxAlign )
144 | $ lines str
145 | let lineWidths = map ((/6 {- Magic number ??? -}) .
146 | Dia.width) rnTextLines
147 | nLines = length lineWidths
148 | lineHeight = 1 + extraTopPad + 2*padding
149 | ζx = ζy * xAspect
150 | ζy = txtSize -- / lineHeight
151 | width = (maximum $ 0 : lineWidths) + 2*padding
152 | height = fromIntegral nLines * lineHeight
153 | y₀ = case vAlign of
154 | AlignBottom -> padding
155 | AlignMid -> 0
156 | AlignTop -> - padding
157 | fullText = mconcat $ zipWith3 ( \n w ->
158 | let y = n' * lineHeight
159 | n' = n - case vAlign of
160 | AlignTop -> 0
161 | AlignMid -> fromIntegral nLines / 2
162 | AlignBottom -> fromIntegral nLines
163 | in (Dia.translate $ Dia.r2 (case hAlign of
164 | AlignBottom -> ( padding, y₀-y )
165 | AlignMid -> ( 0 , y₀-y )
166 | AlignTop -> (-padding, y₀-y )
167 | ) ) ) [0..] lineWidths rnTextLines
168 | p = px ^& py
169 | where px = max l' . min r' $ p₀^._x
170 | py = max b' . min t' $ p₀^._y
171 | (l', r') = case hAlign of
172 | AlignBottom -> (lBound , rBound - w )
173 | AlignMid -> (lBound + w/2, rBound - w/2)
174 | AlignTop -> (lBound + w , rBound )
175 | (b', t') = case vAlign of
176 | AlignBottom -> (bBound' , tBound - 2*h )
177 | AlignMid -> (bBound' + h/2, tBound - 3*h/2)
178 | AlignTop -> (bBound' + h , tBound - h )
179 | w = ζx * width; h = 1.5 * ζy * height
180 | bBound' = bBound + lineHeight*ζy
181 | return . Dia.translate p . Dia.scaleX ζx . Dia.scaleY ζy
182 | $ Dia.lc Dia.grey fullText
183 |
184 |
185 |
186 |
187 |
188 | lg :: Floating a => a -> a
189 | lg = logBase 10
190 |
191 |
192 |
193 |
194 | data LegendEntry = LegendEntry {
195 | _plotObjectTitle :: TextObj
196 | , _plotObjRepresentativeColour :: Maybe PColour
197 | , _customLegendObject :: Maybe ()
198 | }
199 | makeLenses ''LegendEntry
200 |
201 | instance HasColour LegendEntry where
202 | asAColourWith sch = asAColourWith sch . _plotObjRepresentativeColour
203 |
204 |
205 | prerenderLegend :: TextTK -> ColourScheme -> LegendDisplayConfig
206 | -> [LegendEntry] -> IO (Maybe PlainGraphicsR2)
207 | prerenderLegend _ _ _ [] = return mempty
208 | prerenderLegend TextTK{..} cscm layoutSpec l = do
209 | let bgColour = cscm neutral
210 | lRends <- forM l `id`\legEntry -> do
211 | txtR <- CairoTxt.textVisualBoundedIO txtCairoStyle
212 | $ DiaTxt.Text mempty (DiaTxt.BoxAlignedText 0 0.5)
213 | (fromPlaintextObj $ legEntry^.plotObjectTitle)
214 | let h = Dia.height txtR
215 | return $ Dia.hsep 5 [ Dia.rect h h & Dia.fcA
216 | (asAColourWith cscm legEntry)
217 | , txtR
218 | ] & Dia.centerXY
219 | & Dia.frame 2
220 | & Dia.alignL
221 | let szSpec = Dia.getSpec (layoutSpec ^. legendPrerenderSize)
222 | hLine = maximum $ Dia.height <$> lRends
223 | nLines = case szSpec of
224 | DiaTypes.V2 _ Nothing -> length l
225 | DiaTypes.V2 _ (Just hMax) -> max 1 . floor $ hMax / hLine
226 | lRends2D = Dia.hsep (txtSize*2) $ Dia.vcat <$> takes nLines lRends
227 | w = case szSpec of
228 | DiaTypes.V2 Nothing _ -> Dia.width lRends2D
229 | DiaTypes.V2 (Just wM) _ -> wM
230 | h = Dia.height lRends2D
231 | return . pure
232 | $ ( lRends2D & Dia.centerXY & Dia.translate (3^&3) )
233 | <> ( Dia.rect (w+1) (h+1) & Dia.fcA (cscm $ paler grey) )
234 | where takes :: Int -> [a] -> [[a]]
235 | takes n [] = []
236 | takes n l = case splitAt n l of
237 | (h,r) -> h : takes n r
238 |
239 |
--------------------------------------------------------------------------------
/dynamic-plot/INSTALL:
--------------------------------------------------------------------------------
1 | On a fresh Ubuntu-18.04 station:
2 |
3 | $ sudo apt install zlib1g-dev libcairo2-dev libpango1.0-dev libgtk2.0-dev
4 | $ stack setup
5 | $ stack build
6 |
--------------------------------------------------------------------------------
/dynamic-plot/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 | [](https://travis-ci.org/leftaroundabout/dynamic-plot)
5 |
6 |
--------------------------------------------------------------------------------
/dynamic-plot/Setup.hs:
--------------------------------------------------------------------------------
1 | module Main (main) where
2 |
3 | import Distribution.Simple
4 |
5 | main :: IO ()
6 | main = defaultMain
7 |
--------------------------------------------------------------------------------
/dynamic-plot/dynamic-plot.cabal:
--------------------------------------------------------------------------------
1 | Name: dynamic-plot
2 | Version: 0.4.2.0
3 | Category: graphics
4 | Synopsis: Interactive plots / diagrams
5 | Description: Haskell excels at handling data like continuous functions
6 | in a nice way, i.e. without discretising anything to finite arrays as
7 | is typically done in languages like Matlab. Instead, you can simply pass
8 | around functions or infinite data structures (or /very/ high-resolution data
9 | that would be infeasible to handle in a strict language).
10 | .
11 | However when you want to /view/ the data, it will eventually need to be exported out of Haskell
12 | in some finite form. The purpose of this library is to delay this discretisation
13 | as long as possible: it implements an interactive plotting window that accepts continuous/recursive
14 | data and only “flattens” it according to the specific view configuration.
15 | You can then zoom in to a shown diagram and it will automatically calculate
16 | the features more detailedly, or zoom out and discover previosly unexpected
17 | features. You don't need to worry about specifying the range and/or resolution beforehand:
18 | the program will try to find a suitable default view based on /all/ data you're displaying,
19 | and you can always still zoom, resize or move later.
20 | .
21 | are used as the “pre-rendered” type. This
22 | makes the output usable in a very wide range of applications, though at the moment only the GTK
23 | window view is implemented.
24 | License: GPL-3
25 | License-file: COPYING
26 | Author: Justus Sagemüller
27 | Maintainer: (@) jsag $ hvl.no
28 | Homepage: https://github.com/leftaroundabout/dynamic-plot
29 | Build-Type: Simple
30 | Cabal-Version: 1.18
31 | Extra-Doc-Files: images/examples/*.png
32 | , images/examples/*.gif
33 |
34 | Source-Repository head
35 | type: git
36 | location: git://github.com/leftaroundabout/dynamic-plot.git
37 |
38 | Library
39 | Build-Depends: base>=4.5 && <6
40 | , transformers
41 | , mtl
42 | , vector-space>=0.8
43 | , MemoTrie
44 | , vector
45 | , tagged
46 | , containers
47 | , semigroups
48 | , data-default
49 | , random, random-fu >=0.2 && <0.4, rvar >=0.2 && <0.4
50 | , time
51 | , deepseq
52 | , constrained-categories >= 0.2
53 | , free-vector-spaces >= 0.1 && < 0.3
54 | , linearmap-category >=0.3.5
55 | , diagrams-core
56 | , diagrams-lib >= 1.3 && < 1.5
57 | , diagrams-cairo
58 | , colour >= 2 && < 3
59 | , manifolds >= 0.4.2 && < 0.7
60 | , manifold-random
61 | , colour-space >=0.2
62 | , JuicyPixels > 3 && < 4
63 | , lens < 6.0
64 | Other-Extensions: FlexibleInstances
65 | , TypeFamilies
66 | , FlexibleContexts
67 | , GADTs
68 | , RankNTypes
69 | , ConstraintKinds
70 | , PatternGuards
71 | , ScopedTypeVariables
72 | , RecordWildCards
73 | , TupleSections
74 | ghc-options: -O2
75 | default-language: Haskell2010
76 | Exposed-modules: Graphics.Dynamic.Plot.R2
77 | Graphics.Dynamic.Plot.Internals
78 | Other-modules: Graphics.Dynamic.Plot.R2.Internal
79 | Graphics.Dynamic.Plot.Colour
80 | Graphics.Dynamic.Plot.Internal.Types
81 | Graphics.Text.Annotation
82 | Graphics.Image.Resample
83 |
--------------------------------------------------------------------------------
/dynamic-plot/images/examples/HelloWorld.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leftaroundabout/dynamic-plot/38f49e201480de308b5b7b574a1485b21dccad0d/dynamic-plot/images/examples/HelloWorld.gif
--------------------------------------------------------------------------------
/dynamic-plot/images/examples/cos-encircle-points-far.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leftaroundabout/dynamic-plot/38f49e201480de308b5b7b574a1485b21dccad0d/dynamic-plot/images/examples/cos-encircle-points-far.png
--------------------------------------------------------------------------------
/dynamic-plot/images/examples/cos-encircle-points.ghci:
--------------------------------------------------------------------------------
1 | plotWindow [fnPlot cos, tracePlot [(x,y) | x<-[-1,-0.96..1], y<-[0,0.01..1], abs (x^2 + y^2 - 1) < 0.01 ]]
2 |
--------------------------------------------------------------------------------
/dynamic-plot/images/examples/cos-encircle-points.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leftaroundabout/dynamic-plot/38f49e201480de308b5b7b574a1485b21dccad0d/dynamic-plot/images/examples/cos-encircle-points.gif
--------------------------------------------------------------------------------
/dynamic-plot/images/examples/cos-encircle-points.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leftaroundabout/dynamic-plot/38f49e201480de308b5b7b574a1485b21dccad0d/dynamic-plot/images/examples/cos-encircle-points.png
--------------------------------------------------------------------------------
/dynamic-plot/images/examples/propeller.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leftaroundabout/dynamic-plot/38f49e201480de308b5b7b574a1485b21dccad0d/dynamic-plot/images/examples/propeller.png
--------------------------------------------------------------------------------
/dynamic-plot/images/examples/sin-ctrd-tangents.ghci:
--------------------------------------------------------------------------------
1 | plotWindow [fnPlot sin, plot $ \(ViewXCenter xc) x -> sin xc + (x-xc) * cos xc]
2 |
--------------------------------------------------------------------------------
/dynamic-plot/images/examples/sin-ctrd-tangents.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leftaroundabout/dynamic-plot/38f49e201480de308b5b7b574a1485b21dccad0d/dynamic-plot/images/examples/sin-ctrd-tangents.gif
--------------------------------------------------------------------------------
/stack.yaml:
--------------------------------------------------------------------------------
1 | flags: {}
2 | packages:
3 | - './dynamic-plot'
4 | extra-deps:
5 | - number-show-0.1.0.0
6 | - pragmatic-show-0.1.2.1
7 | - constrained-categories-0.4.1.0
8 | - trivial-constraint-0.7.0.0
9 | - free-vector-spaces-0.1.5.1
10 | - linearmap-category-0.4.2.0
11 | - vector-space-0.16
12 | - spatial-rotations-0.1.0.1
13 | - manifolds-core-0.6.0.0
14 | - manifolds-0.6.0.0
15 | - manifold-random-0.6.0.0
16 | - half-space-0.1.0.0
17 | - colour-space-0.2.0.0
18 | - cairo-0.13.8.2
19 | - pango-0.13.8.2
20 | - diagrams-core-1.5.0
21 | - diagrams-lib-1.4.5.1
22 | - diagrams-cairo-1.4.2
23 | - diagrams-gtk-1.4
24 | - statestack-0.3.1
25 | - dual-tree-0.2.3.0
26 | - monoid-extras-0.6.1
27 | - active-0.2.0.15
28 | - glib-0.13.8.0
29 | - gio-0.13.8.2
30 | - gtk-0.15.7
31 | - gtk2hs-buildtools-0.13.8.3
32 | resolver: lts-18.28
33 | allow-newer: true
34 |
--------------------------------------------------------------------------------