├── .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 | ![Short demo of the interactive features this library offers](images/examples/HelloWorld.gif) 2 | 3 | 4 | [![Build Status](https://travis-ci.org/leftaroundabout/dynamic-plot.svg?branch=master)](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 | --------------------------------------------------------------------------------