diff --git a/LICENSES/LGPL-2.1-only.txt b/LICENSES/LGPL-2.1-only.txt
new file mode 100644
index 0000000..130dffb
--- /dev/null
+++ b/LICENSES/LGPL-2.1-only.txt
@@ -0,0 +1,467 @@
+GNU LESSER GENERAL PUBLIC LICENSE
+
+Version 2.1, February 1999
+
+Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts as the
+successor of the GNU Library Public License, version 2, hence the version
+number 2.1.]
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it. By contrast, the GNU General Public Licenses are intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users.
+
+This license, the Lesser General Public License, applies to some specially
+designated software packages--typically libraries--of the Free Software Foundation
+and other authors who decide to use it. You can use it too, but we suggest
+you first think carefully about whether this license or the ordinary General
+Public License is the better strategy to use in any particular case, based
+on the explanations below.
+
+When we speak of free software, we are referring to freedom of use, not price.
+Our General Public Licenses are designed to make sure that you have the freedom
+to distribute copies of free software (and charge for this service if you
+wish); that you receive source code or can get it if you want it; that you
+can change the software and use pieces of it in new free programs; and that
+you are informed that you can do these things.
+
+To protect your rights, we need to make restrictions that forbid distributors
+to deny you these rights or to ask you to surrender these rights. These restrictions
+translate to certain responsibilities for you if you distribute copies of
+the library or if you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for
+a fee, you must give the recipients all the rights that we gave you. You must
+make sure that they, too, receive or can get the source code. If you link
+other code with the library, you must provide complete object files to the
+recipients, so that they can relink them with the library after making changes
+to the library and recompiling it. And you must show them these terms so they
+know their rights.
+
+We protect your rights with a two-step method: (1) we copyright the library,
+and (2) we offer you this license, which gives you legal permission to copy,
+distribute and/or modify the library.
+
+To protect each distributor, we want to make it very clear that there is no
+warranty for the free library. Also, if the library is modified by someone
+else and passed on, the recipients should know that what they have is not
+the original version, so that the original author's reputation will not be
+affected by problems that might be introduced by others.
+
+Finally, software patents pose a constant threat to the existence of any free
+program. We wish to make sure that a company cannot effectively restrict the
+users of a free program by obtaining a restrictive license from a patent holder.
+Therefore, we insist that any patent license obtained for a version of the
+library must be consistent with the full freedom of use specified in this
+license.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU
+General Public License. This license, the GNU Lesser General Public License,
+applies to certain designated libraries, and is quite different from the ordinary
+General Public License. We use this license for certain libraries in order
+to permit linking those libraries into non-free programs.
+
+When a program is linked with a library, whether statically or using a shared
+library, the combination of the two is legally speaking a combined work, a
+derivative of the original library. The ordinary General Public License therefore
+permits such linking only if the entire combination fits its criteria of freedom.
+The Lesser General Public License permits more lax criteria for linking other
+code with the library.
+
+We call this license the "Lesser" General Public License because it does Less
+to protect the user's freedom than the ordinary General Public License. It
+also provides other free software developers Less of an advantage over competing
+non-free programs. These disadvantages are the reason we use the ordinary
+General Public License for many libraries. However, the Lesser license provides
+advantages in certain special circumstances.
+
+For example, on rare occasions, there may be a special need to encourage the
+widest possible use of a certain library, so that it becomes a de-facto standard.
+To achieve this, non-free programs must be allowed to use the library. A more
+frequent case is that a free library does the same job as widely used non-free
+libraries. In this case, there is little to gain by limiting the free library
+to free software only, so we use the Lesser General Public License.
+
+In other cases, permission to use a particular library in non-free programs
+enables a greater number of people to use a large body of free software. For
+example, permission to use the GNU C Library in non-free programs enables
+many more people to use the whole GNU operating system, as well as its variant,
+the GNU/Linux operating system.
+
+Although the Lesser General Public License is Less protective of the users'
+freedom, it does ensure that the user of a program that is linked with the
+Library has the freedom and the wherewithal to run that program using a modified
+version of the Library.
+
+The precise terms and conditions for copying, distribution and modification
+follow. Pay close attention to the difference between a "work based on the
+library" and a "work that uses the library". The former contains code derived
+from the library, whereas the latter must be combined with the library in
+order to run.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License Agreement applies to any software library or other program
+which contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Lesser General
+Public License (also called "this License"). Each licensee is addressed as
+"you".
+
+A "library" means a collection of software functions and/or data prepared
+so as to be conveniently linked with application programs (which use some
+of those functions and data) to form executables.
+
+The "Library", below, refers to any such software library or work which has
+been distributed under these terms. A "work based on the Library" means either
+the Library or any derivative work under copyright law: that is to say, a
+work containing the Library or a portion of it, either verbatim or with modifications
+and/or translated straightforwardly into another language. (Hereinafter, translation
+is included without limitation in the term "modification".)
+
+"Source code" for a work means the preferred form of the work for making modifications
+to it. For a library, complete source code means all the source code for all
+modules it contains, plus any associated interface definition files, plus
+the scripts used to control compilation and installation of the library.
+
+Activities other than copying, distribution and modification are not covered
+by this License; they are outside its scope. The act of running a program
+using the Library is not restricted, and output from such a program is covered
+only if its contents constitute a work based on the Library (independent of
+the use of the Library in a tool for writing it). Whether that is true depends
+on what the Library does and what the program that uses the Library does.
+
+1. You may copy and distribute verbatim copies of the Library's complete source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and disclaimer
+of warranty; keep intact all the notices that refer to this License and to
+the absence of any warranty; and distribute a copy of this License along with
+the Library.
+
+You may charge a fee for the physical act of transferring a copy, and you
+may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Library or any portion of it,
+thus forming a work based on the Library, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all
+of these conditions:
+
+ a) The modified work must itself be a software library.
+
+b) You must cause the files modified to carry prominent notices stating that
+you changed the files and the date of any change.
+
+c) You must cause the whole of the work to be licensed at no charge to all
+third parties under the terms of this License.
+
+d) If a facility in the modified Library refers to a function or a table of
+data to be supplied by an application program that uses the facility, other
+than as an argument passed when the facility is invoked, then you must make
+a good faith effort to ensure that, in the event an application does not supply
+such function or table, the facility still operates, and performs whatever
+part of its purpose remains meaningful.
+
+(For example, a function in a library to compute square roots has a purpose
+that is entirely well-defined independent of the application. Therefore, Subsection
+2d requires that any application-supplied function or table used by this function
+must be optional: if the application does not supply it, the square root function
+must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Library, and can be reasonably
+considered independent and separate works in themselves, then this License,
+and its terms, do not apply to those sections when you distribute them as
+separate works. But when you distribute the same sections as part of a whole
+which is a work based on the Library, the distribution of the whole must be
+on the terms of this License, whose permissions for other licensees extend
+to the entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise
+the right to control the distribution of derivative or collective works based
+on the Library.
+
+In addition, mere aggregation of another work not based on the Library with
+the Library (or with a work based on the Library) on a volume of a storage
+or distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may opt to apply the terms of the ordinary GNU General Public License
+instead of this License to a given copy of the Library. To do this, you must
+alter all the notices that refer to this License, so that they refer to the
+ordinary GNU General Public License, version 2, instead of to this License.
+(If a newer version than version 2 of the ordinary GNU General Public License
+has appeared, then you can specify that version instead if you wish.) Do not
+make any other change in these notices.
+
+Once this change is made in a given copy, it is irreversible for that copy,
+so the ordinary GNU General Public License applies to all subsequent copies
+and derivative works made from that copy.
+
+This option is useful when you wish to copy part of the code of the Library
+into a program that is not a library.
+
+4. You may copy and distribute the Library (or a portion or derivative of
+it, under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you accompany it with the complete corresponding
+machine-readable source code, which must be distributed under the terms of
+Sections 1 and 2 above on a medium customarily used for software interchange.
+
+If distribution of object code is made by offering access to copy from a designated
+place, then offering equivalent access to copy the source code from the same
+place satisfies the requirement to distribute the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+5. A program that contains no derivative of any portion of the Library, but
+is designed to work with the Library by being compiled or linked with it,
+is called a "work that uses the Library". Such a work, in isolation, is not
+a derivative work of the Library, and therefore falls outside the scope of
+this License.
+
+However, linking a "work that uses the Library" with the Library creates an
+executable that is a derivative of the Library (because it contains portions
+of the Library), rather than a "work that uses the library". The executable
+is therefore covered by this License. Section 6 states terms for distribution
+of such executables.
+
+When a "work that uses the Library" uses material from a header file that
+is part of the Library, the object code for the work may be a derivative work
+of the Library even though the source code is not. Whether this is true is
+especially significant if the work can be linked without the Library, or if
+the work is itself a library. The threshold for this to be true is not precisely
+defined by law.
+
+If such an object file uses only numerical parameters, data structure layouts
+and accessors, and small macros and small inline functions (ten lines or less
+in length), then the use of the object file is unrestricted, regardless of
+whether it is legally a derivative work. (Executables containing this object
+code plus portions of the Library will still fall under Section 6.)
+
+Otherwise, if the work is a derivative of the Library, you may distribute
+the object code for the work under the terms of Section 6. Any executables
+containing that work also fall under Section 6, whether or not they are linked
+directly with the Library itself.
+
+6. As an exception to the Sections above, you may also combine or link a "work
+that uses the Library" with the Library to produce a work containing portions
+of the Library, and distribute that work under terms of your choice, provided
+that the terms permit modification of the work for the customer's own use
+and reverse engineering for debugging such modifications.
+
+You must give prominent notice with each copy of the work that the Library
+is used in it and that the Library and its use are covered by this License.
+You must supply a copy of this License. If the work during execution displays
+copyright notices, you must include the copyright notice for the Library among
+them, as well as a reference directing the user to the copy of this License.
+Also, you must do one of these things:
+
+a) Accompany the work with the complete corresponding machine-readable source
+code for the Library including whatever changes were used in the work (which
+must be distributed under Sections 1 and 2 above); and, if the work is an
+executable linked with the Library, with the complete machine-readable "work
+that uses the Library", as object code and/or source code, so that the user
+can modify the Library and then relink to produce a modified executable containing
+the modified Library. (It is understood that the user who changes the contents
+of definitions files in the Library will not necessarily be able to recompile
+the application to use the modified definitions.)
+
+b) Use a suitable shared library mechanism for linking with the Library. A
+suitable mechanism is one that (1) uses at run time a copy of the library
+already present on the user's computer system, rather than copying library
+functions into the executable, and (2) will operate properly with a modified
+version of the library, if the user installs one, as long as the modified
+version is interface-compatible with the version that the work was made with.
+
+c) Accompany the work with a written offer, valid for at least three years,
+to give the same user the materials specified in Subsection 6a, above, for
+a charge no more than the cost of performing this distribution.
+
+d) If distribution of the work is made by offering access to copy from a designated
+place, offer equivalent access to copy the above specified materials from
+the same place.
+
+e) Verify that the user has already received a copy of these materials or
+that you have already sent this user a copy.
+
+For an executable, the required form of the "work that uses the Library" must
+include any data and utility programs needed for reproducing the executable
+from it. However, as a special exception, the materials to be distributed
+need not include anything that is normally distributed (in either source or
+binary form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component itself
+accompanies the executable.
+
+It may happen that this requirement contradicts the license restrictions of
+other proprietary libraries that do not normally accompany the operating system.
+Such a contradiction means you cannot use both them and the Library together
+in an executable that you distribute.
+
+7. You may place library facilities that are a work based on the Library side-by-side
+in a single library together with other library facilities not covered by
+this License, and distribute such a combined library, provided that the separate
+distribution of the work based on the Library and of the other library facilities
+is otherwise permitted, and provided that you do these two things:
+
+a) Accompany the combined library with a copy of the same work based on the
+Library, uncombined with any other library facilities. This must be distributed
+under the terms of the Sections above.
+
+b) Give prominent notice with the combined library of the fact that part of
+it is a work based on the Library, and explaining where to find the accompanying
+uncombined form of the same work.
+
+8. You may not copy, modify, sublicense, link with, or distribute the Library
+except as expressly provided under this License. Any attempt otherwise to
+copy, modify, sublicense, link with, or distribute the Library is void, and
+will automatically terminate your rights under this License. However, parties
+who have received copies, or rights, from you under this License will not
+have their licenses terminated so long as such parties remain in full compliance.
+
+9. You are not required to accept this License, since you have not signed
+it. However, nothing else grants you permission to modify or distribute the
+Library or its derivative works. These actions are prohibited by law if you
+do not accept this License. Therefore, by modifying or distributing the Library
+(or any work based on the Library), you indicate your acceptance of this License
+to do so, and all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+10. Each time you redistribute the Library (or any work based on the Library),
+the recipient automatically receives a license from the original licensor
+to copy, distribute, link with or modify the Library subject to these terms
+and conditions. You may not impose any further restrictions on the recipients'
+exercise of the rights granted herein. You are not responsible for enforcing
+compliance by third parties with this License.
+
+11. If, as a consequence of a court judgment or allegation of patent infringement
+or for any other reason (not limited to patent issues), conditions are imposed
+on you (whether by court order, agreement or otherwise) that contradict the
+conditions of this License, they do not excuse you from the conditions of
+this License. If you cannot distribute so as to satisfy simultaneously your
+obligations under this License and any other pertinent obligations, then as
+a consequence you may not distribute the Library at all. For example, if a
+patent license would not permit royalty-free redistribution of the Library
+by all those who receive copies directly or indirectly through you, then the
+only way you could satisfy both it and this License would be to refrain entirely
+from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents
+or other property right claims or to contest validity of any such claims;
+this section has the sole purpose of protecting the integrity of the free
+software distribution system which is implemented by public license practices.
+Many people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose
+that choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+12. If the distribution and/or use of the Library is restricted in certain
+countries either by patents or by copyrighted interfaces, the original copyright
+holder who places the Library under this License may add an explicit geographical
+distribution limitation excluding those countries, so that distribution is
+permitted only in or among countries not thus excluded. In such case, this
+License incorporates the limitation as if written in the body of this License.
+
+13. The Free Software Foundation may publish revised and/or new versions of
+the Lesser General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to address
+new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library specifies
+a version number of this License which applies to it and "any later version",
+you have the option of following the terms and conditions either of that version
+or of any later version published by the Free Software Foundation. If the
+Library does not specify a license version number, you may choose any version
+ever published by the Free Software Foundation.
+
+14. If you wish to incorporate parts of the Library into other free programs
+whose distribution conditions are incompatible with these, write to the author
+to ask for permission. For software which is copyrighted by the Free Software
+Foundation, write to the Free Software Foundation; we sometimes make exceptions
+for this. Our decision will be guided by the two goals of preserving the free
+status of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
+"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
+OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
+THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
+OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
+OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
+OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
+HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Libraries
+
+If you develop a new library, and you want it to be of the greatest possible
+use to the public, we recommend making it free software that everyone can
+redistribute and change. You can do so by permitting redistribution under
+these terms (or, alternatively, under the terms of the ordinary General Public
+License).
+
+To apply these terms, attach the following notices to the library. It is safest
+to attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the "copyright"
+line and a pointer to where the full notice is found.
+
+< one line to give the library's name and an idea of what it does. >
+
+Copyright (C) < year > < name of author >
+
+This library is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free
+Software Foundation; either version 2.1 of the License, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this library; if not, write to the Free Software Foundation, Inc., 51
+Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information
+on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the library, if necessary. Here
+is a sample; alter the names:
+
+Yoyodyne, Inc., hereby disclaims all copyright interest in
+
+the library `Frob' (a library for tweaking knobs) written
+
+by James Random Hacker.
+
+< signature of Ty Coon > , 1 April 1990
+
+Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/LICENSES/LGPL-3.0-only.txt b/LICENSES/LGPL-3.0-only.txt
new file mode 100644
index 0000000..bd405af
--- /dev/null
+++ b/LICENSES/LGPL-3.0-only.txt
@@ -0,0 +1,163 @@
+GNU LESSER GENERAL PUBLIC LICENSE
+
+Version 3, 29 June 2007
+
+Copyright (C) 2007 Free Software Foundation, Inc.
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+This version of the GNU Lesser General Public License incorporates the terms
+and conditions of version 3 of the GNU General Public License, supplemented
+by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+
+
+As used herein, "this License" refers to version 3 of the GNU Lesser General
+Public License, and the "GNU GPL" refers to version 3 of the GNU General Public
+License.
+
+
+
+"The Library" refers to a covered work governed by this License, other than
+an Application or a Combined Work as defined below.
+
+
+
+An "Application" is any work that makes use of an interface provided by the
+Library, but which is not otherwise based on the Library. Defining a subclass
+of a class defined by the Library is deemed a mode of using an interface provided
+by the Library.
+
+
+
+A "Combined Work" is a work produced by combining or linking an Application
+with the Library. The particular version of the Library with which the Combined
+Work was made is also called the "Linked Version".
+
+
+
+The "Minimal Corresponding Source" for a Combined Work means the Corresponding
+Source for the Combined Work, excluding any source code for portions of the
+Combined Work that, considered in isolation, are based on the Application,
+and not on the Linked Version.
+
+
+
+The "Corresponding Application Code" for a Combined Work means the object
+code and/or source code for the Application, including any data and utility
+programs needed for reproducing the Combined Work from the Application, but
+excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+You may convey a covered work under sections 3 and 4 of this License without
+being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+If you modify a copy of the Library, and, in your modifications, a facility
+refers to a function or data to be supplied by an Application that uses the
+facility (other than as an argument passed when the facility is invoked),
+then you may convey a copy of the modified version:
+
+a) under this License, provided that you make a good faith effort to ensure
+that, in the event an Application does not supply the function or data, the
+facility still operates, and performs whatever part of its purpose remains
+meaningful, or
+
+b) under the GNU GPL, with none of the additional permissions of this License
+applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+The object code form of an Application may incorporate material from a header
+file that is part of the Library. You may convey such object code under terms
+of your choice, provided that, if the incorporated material is not limited
+to numerical parameters, data structure layouts and accessors, or small macros,
+inline functions and templates (ten or fewer lines in length), you do both
+of the following:
+
+a) Give prominent notice with each copy of the object code that the Library
+is used in it and that the Library and its use are covered by this License.
+
+b) Accompany the object code with a copy of the GNU GPL and this license document.
+
+ 4. Combined Works.
+
+You may convey a Combined Work under terms of your choice that, taken together,
+effectively do not restrict modification of the portions of the Library contained
+in the Combined Work and reverse engineering for debugging such modifications,
+if you also do each of the following:
+
+a) Give prominent notice with each copy of the Combined Work that the Library
+is used in it and that the Library and its use are covered by this License.
+
+b) Accompany the Combined Work with a copy of the GNU GPL and this license
+document.
+
+c) For a Combined Work that displays copyright notices during execution, include
+the copyright notice for the Library among these notices, as well as a reference
+directing the user to the copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+0) Convey the Minimal Corresponding Source under the terms of this License,
+and the Corresponding Application Code in a form suitable for, and under terms
+that permit, the user to recombine or relink the Application with a modified
+version of the Linked Version to produce a modified Combined Work, in the
+manner specified by section 6 of the GNU GPL for conveying Corresponding Source.
+
+1) Use a suitable shared library mechanism for linking with the Library. A
+suitable mechanism is one that (a) uses at run time a copy of the Library
+already present on the user's computer system, and (b) will operate properly
+with a modified version of the Library that is interface-compatible with the
+Linked Version.
+
+e) Provide Installation Information, but only if you would otherwise be required
+to provide such information under section 6 of the GNU GPL, and only to the
+extent that such information is necessary to install and execute a modified
+version of the Combined Work produced by recombining or relinking the Application
+with a modified version of the Linked Version. (If you use option 4d0, the
+Installation Information must accompany the Minimal Corresponding Source and
+Corresponding Application Code. If you use option 4d1, you must provide the
+Installation Information in the manner specified by section 6 of the GNU GPL
+for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+You may place library facilities that are a work based on the Library side
+by side in a single library together with other library facilities that are
+not Applications and are not covered by this License, and convey such a combined
+library under terms of your choice, if you do both of the following:
+
+a) Accompany the combined library with a copy of the same work based on the
+Library, uncombined with any other library facilities, conveyed under the
+terms of this License.
+
+b) Give prominent notice with the combined library that part of it is a work
+based on the Library, and explaining where to find the accompanying uncombined
+form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+The Free Software Foundation may publish revised and/or new versions of the
+GNU Lesser General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to address
+new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library as you
+received it specifies that a certain numbered version of the GNU Lesser General
+Public License "or any later version" applies to it, you have the option of
+following the terms and conditions either of that published version or of
+any later version published by the Free Software Foundation. If the Library
+as you received it does not specify a version number of the GNU Lesser General
+Public License, you may choose any version of the GNU Lesser General Public
+License ever published by the Free Software Foundation.
+
+If the Library as you received it specifies that a proxy can decide whether
+future versions of the GNU Lesser General Public License shall apply, that
+proxy's public statement of acceptance of any version is permanent authorization
+for you to choose that version for the Library.
diff --git a/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt b/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt
new file mode 100644
index 0000000..232b3c5
--- /dev/null
+++ b/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt
@@ -0,0 +1,12 @@
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 3 of the license or (at your option) any later version
+that is accepted by the membership of KDE e.V. (or its successor
+approved by the membership of KDE e.V.), which shall act as a
+proxy as defined in Section 6 of version 3 of the license.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt
new file mode 100644
index 0000000..204b93d
--- /dev/null
+++ b/LICENSES/MIT.txt
@@ -0,0 +1,19 @@
+MIT License Copyright (c)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/autotests/ArraySourceTest.cpp b/autotests/ArraySourceTest.cpp
index 237172c..737557b 100644
--- a/autotests/ArraySourceTest.cpp
+++ b/autotests/ArraySourceTest.cpp
@@ -1,115 +1,101 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include
#include "datasource/ArraySource.h"
class ArraySourceTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testCreate()
{
// Basic creation should create an empty source.
auto source = new ArraySource{};
QCOMPARE(source->itemCount(), 0);
QCOMPARE(source->item(0), QVariant{});
QCOMPARE(source->minimum(), QVariant{});
QCOMPARE(source->maximum(), QVariant{});
}
void testWithArray_data()
{
QTest::addColumn("array");
QTest::addColumn("itemCount");
QTest::addColumn("firstItem");
QTest::addColumn("lastItem");
QTest::addColumn("minimum");
QTest::addColumn("maximum");
QTest::newRow("simple ints") << QVariantList{0, 1, 2, 3, 4} << 5 << QVariant{0} << QVariant{4} << QVariant{0} << QVariant{4};
QTest::newRow("random ints") << QVariantList{-3, 6, 4, 9, 4} << 5 << QVariant{-3} << QVariant{4} << QVariant{-3} << QVariant{9};
QTest::newRow("floats") << QVariantList{2.56, 4.45, 2.5, 5.3} << 4 << QVariant{2.56} << QVariant{5.3} << QVariant{2.5} << QVariant{5.3};
}
void testWithArray()
{
auto source = new ArraySource{};
QFETCH(QVariantList, array);
source->setArray(array);
QFETCH(int, itemCount);
QCOMPARE(source->itemCount(), itemCount);
QFETCH(QVariant, firstItem);
QCOMPARE(source->item(0), firstItem);
QFETCH(QVariant, lastItem);
QCOMPARE(source->item(itemCount - 1), lastItem);
QCOMPARE(source->item(itemCount), QVariant{});
QFETCH(QVariant, minimum);
QCOMPARE(source->minimum(), minimum);
QFETCH(QVariant, maximum);
QCOMPARE(source->maximum(), maximum);
}
void testWrap_data()
{
QTest::addColumn("array");
QTest::addColumn("itemCount");
QTest::addColumn("firstItem");
QTest::addColumn("lastItem");
QTest::newRow("simple ints") << QVariantList{0, 1, 2, 3, 4} << 5 << QVariant{0} << QVariant{4};
QTest::newRow("random ints") << QVariantList{-3, 6, 4, 9, 4} << 5 << QVariant{-3} << QVariant{4};
QTest::newRow("floats") << QVariantList{2.56, 4.45, 2.5, 5.3} << 4 << QVariant{2.56} << QVariant{5.3};
}
void testWrap()
{
auto source = new ArraySource{};
QFETCH(QVariantList, array);
source->setArray(array);
source->setWrap(true);
QFETCH(int, itemCount);
QFETCH(QVariant, firstItem);
QFETCH(QVariant, lastItem);
QCOMPARE(source->item(0), firstItem);
QCOMPARE(source->item(itemCount - 1), lastItem);
QCOMPARE(source->item(itemCount), firstItem);
QCOMPARE(source->item(itemCount * 2 - 1), lastItem);
QCOMPARE(source->item(itemCount * 99), firstItem);
}
};
QTEST_GUILESS_MAIN(ArraySourceTest)
#include "ArraySourceTest.moc"
diff --git a/autotests/qmltest.cpp b/autotests/qmltest.cpp
index 50f14d8..6d09aff 100644
--- a/autotests/qmltest.cpp
+++ b/autotests/qmltest.cpp
@@ -1,23 +1,9 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include
QUICK_TEST_MAIN(Charts)
diff --git a/autotests/tst_BarChart.qml b/autotests/tst_BarChart.qml
index b66a993..a1818d8 100644
--- a/autotests/tst_BarChart.qml
+++ b/autotests/tst_BarChart.qml
@@ -1,66 +1,52 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.11
import QtTest 1.11
import org.kde.quickcharts 1.0 as Charts
TestCase {
id: testCase
name: "Bar Chart Tests"
width: 400
height: 400
visible: true
when: windowShown
Component {
id: minimal
Charts.BarChart { }
}
Component {
id: simple
Charts.BarChart {
width: 200
height: 200
nameSource: Charts.ArraySource { array: ["Test 1", "Test 2", "Test 3"] }
colorSource: Charts.ArraySource { array: ["red", "green", "blue"] }
valueSources: Charts.ArraySource { array: [1, 2, 3, 4, 5] }
}
}
function test_create_data() {
return [
{ tag: "minimal", component: minimal },
{ tag: "simple", component: simple }
]
}
function test_create(data) {
var item = createTemporaryObject(data.component, testCase)
verify(item)
verify(waitForRendering(item))
}
}
diff --git a/autotests/tst_LineChart.qml b/autotests/tst_LineChart.qml
index 68de153..a59526b 100644
--- a/autotests/tst_LineChart.qml
+++ b/autotests/tst_LineChart.qml
@@ -1,64 +1,50 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.11
import QtTest 1.11
import org.kde.quickcharts 1.0 as Charts
TestCase {
id: testCase
name: "Line Chart Tests"
width: 400
height: 400
visible: true
when: windowShown
Component {
id: minimal
Charts.LineChart { }
}
Component {
id: simple
Charts.LineChart {
width: 200
height: 200
nameSource: Charts.ArraySource { array: ["Test 1", "Test 2", "Test 3"] }
colorSource: Charts.ArraySource { array: ["red", "green", "blue"] }
valueSources: Charts.ArraySource { array: [1, 2, 3, 4, 5] }
}
}
function test_create_data() {
return [
{ tag: "minimal", component: minimal },
{ tag: "simple", component: simple }
]
}
function test_create(data) {
var item = createTemporaryObject(data.component, testCase)
verify(item)
verify(waitForRendering(item))
}
}
diff --git a/autotests/tst_PieChart.qml b/autotests/tst_PieChart.qml
index 1a651f5..bd09056 100644
--- a/autotests/tst_PieChart.qml
+++ b/autotests/tst_PieChart.qml
@@ -1,106 +1,92 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.11
import QtTest 1.11
import org.kde.quickcharts 1.0 as Charts
TestCase {
id: testCase
name: "Pie Chart Tests"
width: 400
height: 400
visible: true
when: windowShown
Component {
id: minimal
Charts.PieChart { }
}
Component {
id: simple
Charts.PieChart {
width: 200
height: 200
nameSource: Charts.ArraySource { array: ["Test 1", "Test 2", "Test 3"] }
colorSource: Charts.ArraySource { array: ["red", "green", "blue"] }
valueSources: Charts.ArraySource { array: [1, 2, 3, 4, 5] }
}
}
Component {
id: multiValue
Charts.PieChart {
width: 200
height: 200
nameSource: Charts.ArraySource { array: ["Test 1", "Test 2", "Test 3"] }
colorSource: Charts.ArraySource { array: ["red", "green", "blue"] }
valueSources: [
Charts.ArraySource { array: [1, 2, 3, 4, 5] },
Charts.ArraySource { array: [1, 2, 3, 4, 5] },
Charts.ArraySource { array: [1, 2, 3, 4, 5] }
]
}
}
Component {
id: model
Charts.PieChart {
width: 200
height: 200
valueSources: [
Charts.ModelSource {
model: ListModel {
id: listModel
ListElement { name: "Test 1"; color: "red"; value: 1 }
ListElement { name: "Test 2"; color: "green"; value: 2 }
ListElement { name: "Test 3"; color: "blue"; value: 3 }
ListElement { name: "Test 4"; color: "cyan"; value: 4 }
ListElement { name: "Test 5"; color: "magenta"; value: 5 }
ListElement { name: "Test 6"; color: "yellow"; value: 6 }
}
}
]
nameSource: Charts.ModelSource { model: listModel; roleName: "name" }
colorSource: Charts.ModelSource { model: listModel; roleName: "color" }
}
}
function test_create_data() {
return [
{ tag: "minimal", component: minimal },
{ tag: "simple", component: simple },
{ tag: "multiValue", component: multiValue },
{ tag: "model", component: model }
]
}
function test_create(data) {
var item = createTemporaryObject(data.component, testCase)
verify(item)
verify(waitForRendering(item))
}
}
diff --git a/controls/ChartsControlsPlugin.cpp b/controls/ChartsControlsPlugin.cpp
index 3e2b068..4fb9f4f 100644
--- a/controls/ChartsControlsPlugin.cpp
+++ b/controls/ChartsControlsPlugin.cpp
@@ -1,59 +1,45 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "ChartsControlsPlugin.h"
#include
#include
#include
#include
#include
ChartsControlsPlugin::ChartsControlsPlugin(QObject *parent)
: QQmlExtensionPlugin(parent)
{
}
void ChartsControlsPlugin::registerTypes(const char *uri)
{
Q_ASSERT(QString::fromLatin1(uri) == QLatin1String("org.kde.quickcharts.controls"));
m_styleName = QQuickStyle::name();
qmlRegisterSingletonType(componentUrl(QStringLiteral("Theme.qml")), uri, 1, 0, "Theme");
qmlRegisterType(componentUrl(QStringLiteral("Legend.qml")), uri, 1, 0, "Legend");
qmlRegisterType(componentUrl(QStringLiteral("LegendDelegate.qml")), uri, 1, 0, "LegendDelegate");
qmlRegisterType(componentUrl(QStringLiteral("LineChartControl.qml")), uri, 1, 0, "LineChartControl");
qmlRegisterType(componentUrl(QStringLiteral("PieChartControl.qml")), uri, 1, 0, "PieChartControl");
}
QUrl ChartsControlsPlugin::componentUrl(const QString &fileName)
{
auto url = baseUrl();
url.setPath(url.path() % QLatin1Char('/'));
auto styled = url.resolved(QUrl{QStringLiteral("styles/") % m_styleName % QLatin1Char('/') % fileName});
if (QFile::exists(styled.toLocalFile())) {
return styled;
}
return url.resolved(QUrl{fileName});
}
diff --git a/controls/ChartsControlsPlugin.h b/controls/ChartsControlsPlugin.h
index fe1c79d..7656d4a 100644
--- a/controls/ChartsControlsPlugin.h
+++ b/controls/ChartsControlsPlugin.h
@@ -1,42 +1,28 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef CHARTSCONTROLSPLUGIN_H
#define CHARTSCONTROLSPLUGIN_H
#include
class ChartsControlsPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
explicit ChartsControlsPlugin(QObject *parent = nullptr);
void registerTypes(const char *uri) override;
private:
QUrl componentUrl(const QString &fileName);
QUrl styledComponentUrl(const QString &fileName);
QString m_styleName;
};
#endif // CHARTSCONTROLSPLUGIN_H
diff --git a/controls/Legend.qml b/controls/Legend.qml
index ba5488f..044dba2 100644
--- a/controls/Legend.qml
+++ b/controls/Legend.qml
@@ -1,112 +1,98 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.9
import QtQuick.Layouts 1.2
import QtQuick.Controls 2.2
import org.kde.quickcharts 1.0 as Charts
import org.kde.quickcharts.controls 1.0
/**
* A pre-made legend control that displays a legend for charts.
*/
Control {
id: control
/**
* The chart to display the legend for.
*/
property Charts.Chart chart
property alias model: legendRepeater.model
property alias delegate: legendRepeater.delegate
property alias flow: legend.flow
property int sourceIndex: -1
property var formatValue: function(input, index) { return input }
property bool valueVisible: false
property real valueWidth: -1
property bool colorVisible: true
property real colorWidth: Theme.smallSpacing
property string nameRole: "name"
property string colorRole: "color"
property string valueRole: "value"
property Component indicator: null
default property alias extraItems: legend.children
leftPadding: 0
rightPadding: 0
topPadding: 0
bottomPadding: 0
implicitWidth: legend.implicitWidth
implicitHeight: legend.implicitHeight
contentItem: GridLayout {
id: legend
columns: flow == GridLayout.TopToBottom ? 1 : -1
rows: flow == GridLayout.TopToBottom ? -1 : 1
rowSpacing: control.spacing
columnSpacing: rowSpacing
Repeater {
id: legendRepeater
model: Charts.LegendModel { id: legendModel; chart: control.chart; sourceIndex: control.sourceIndex }
delegate: LegendDelegate {
Layout.preferredWidth: implicitWidth
property var itemData: typeof modelData !== "undefined" ? modelData : model
name: itemData[control.nameRole] !== undefined ? itemData[control.nameRole] : ""
color: itemData[control.colorRole] !== undefined ? itemData[control.colorRole] : "white"
value: {
if (itemData[control.valueRole] !== undefined) {
if (control.formatValue.length == 2) {
return control.formatValue(itemData[control.valueRole], index)
} else {
return control.formatValue(itemData[control.valueRole])
}
}
return ""
}
colorVisible: control.colorVisible
colorWidth: control.colorWidth
valueVisible: control.valueVisible
valueWidth: control.valueWidth
indicator: control.indicator
font: control.font
layoutWidth: legend.flow == GridLayout.TopToBottom ? control.Layout.maximumWidth
: control.Layout.maximumWidth / legendRepeater.count - control.spacing
}
}
}
}
diff --git a/controls/LegendDelegate.qml b/controls/LegendDelegate.qml
index 759022b..aa0e437 100644
--- a/controls/LegendDelegate.qml
+++ b/controls/LegendDelegate.qml
@@ -1,131 +1,117 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.9
import QtQuick.Layouts 1.2
import QtQuick.Controls 2.2
import org.kde.quickcharts 1.0 as Charts
import org.kde.quickcharts.controls 1.0
/**
* A delegate that can be used as part of a Legend.
*/
RowLayout {
id: delegate
Layout.fillHeight: false
Layout.preferredWidth: 0
property string name
property color color
property string value
property color valueColor: name.color
property real colorWidth: Theme.smallSpacing
property real valueWidth: -1
property bool colorVisible: true
property bool valueVisible: true
property alias font: name.font
property Component indicator: null
property real layoutWidth: -1
spacing: Theme.smallSpacing
opacity: parent.height >= y + height // This will hide the item if it is out of bounds
Loader {
Layout.preferredHeight: name.contentHeight
Layout.preferredWidth: delegate.colorWidth
visible: delegate.colorVisible
property color delegateColor: delegate.color
sourceComponent: delegate.indicator != null ? delegate.indicator : defaultIndicator
MouseArea {
id: mouse
anchors.fill: parent
hoverEnabled: true
ToolTip.visible: mouse.containsMouse && (!name.visible || !value.visible)
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
ToolTip.text: "%1: %2".arg(delegate.name).arg(delegate.value)
}
}
Label {
id: name
Layout.fillWidth: true
Layout.fillHeight: true
text: delegate.name
visible: {
if (delegate.layoutWidth < 0) {
return true;
}
return delegate.layoutWidth - delegate.colorWidth - delegate.spacing * 2 >= contentWidth
}
verticalAlignment: Qt.AlignVCenter
}
Label {
id: value
Layout.fillHeight: true
Layout.preferredWidth: delegate.valueWidth
text: delegate.value;
font: name.font
color: delegate.valueColor
verticalAlignment: Qt.AlignVCenter
horizontalAlignment: Qt.AlignRight
visible: {
if (!delegate.valueVisible) {
return false;
}
if (delegate.layoutWidth < 0) {
return true;
}
var remainingWidth = delegate.layoutWidth - delegate.spacing * 2
if (delegate.colorVisible) {
remainingWidth -= delegate.colorWidth - delegate.spacing
}
if (name.visible) {
remainingWidth -= name.contentWidth - delegate.spacing
}
return remainingWidth >= delegate.valueWidth
}
}
Component { id: defaultIndicator; Rectangle { color: delegateColor } }
}
diff --git a/controls/LineChartControl.qml b/controls/LineChartControl.qml
index b7bb1e9..fbde2cb 100644
--- a/controls/LineChartControl.qml
+++ b/controls/LineChartControl.qml
@@ -1,150 +1,136 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.9
import QtQuick.Controls 2.2
import org.kde.quickcharts 1.0 as Charts
import org.kde.quickcharts.controls 1.0
/**
* A line chart with legend, grid and axis labels.
*/
Control {
property alias valueSources: lineChart.valueSources
property alias names: nameSource.array
property alias color: colorSource.baseColor
property alias lineWidth: lineChart.lineWidth
property alias fillOpacity: lineChart.fillOpacity
property alias stacked: lineChart.stacked
property alias chart: lineChart
property alias legend: legend
property alias xLabels: xAxisLabels
property alias yLabels: yAxisLabels
property alias verticalLinesVisible: verticalLines.visible
property alias horizontalLinesVisible: horizontalLines.visible
property alias xRange: lineChart.xRange
property alias yRange: lineChart.yRange
property alias xAxisSource: xAxisLabels.source
property alias yAxisSource: yAxisLabels.source
background: Rectangle { color: Theme.backgroundColor }
contentItem: Item {
anchors.fill: parent;
Charts.GridLines {
id: horizontalLines
anchors.fill: lineChart
chart: lineChart
major.frequency: 2
major.lineWidth: 2
major.color: Qt.rgba(0.8, 0.8, 0.8, 1.0)
minor.frequency: 1
minor.lineWidth: 1
minor.color: Qt.rgba(0.8, 0.8, 0.8, 1.0)
}
Charts.GridLines {
id: verticalLines
anchors.fill: lineChart
chart: lineChart
direction: Charts.GridLines.Vertical;
major.count: 1
major.lineWidth: 2
major.color: Qt.rgba(0.8, 0.8, 0.8, 1.0)
minor.count: 3
minor.lineWidth: 1
minor.color: Qt.rgba(0.8, 0.8, 0.8, 1.0)
}
Charts.AxisLabels {
id: yAxisLabels
anchors {
left: parent.left
top: parent.top
bottom: xAxisLabels.top
}
direction: Charts.AxisLabels.VerticalBottomTop
delegate: Label { text: Charts.AxisLabels.label }
source: Charts.ChartAxisSource { chart: lineChart; axis: Charts.ChartAxisSource.YAxis; itemCount: 5 }
}
Charts.AxisLabels {
id: xAxisLabels
anchors {
left: yAxisLabels.visible ? yAxisLabels.right : parent.left
right: parent.right
bottom: legend.top
}
delegate: Label { text: Charts.AxisLabels.label }
source: Charts.ChartAxisSource { chart: lineChart; axis: Charts.ChartAxisSource.XAxis; itemCount: 5 }
}
Legend {
id: legend
anchors {
left: yAxisLabels.visible ? yAxisLabels.right : parent.left
right: parent.right
bottom: parent.bottom
bottomMargin: Theme.smallSpacing
}
chart: lineChart
}
Charts.LineChart {
id: lineChart
anchors {
top: parent.top
left: yAxisLabels.visible ? yAxisLabels.right : parent.left
right: parent.right
bottom: xAxisLabels.visible ? xAxisLabels.top : legend.top
}
xRange.automatic: true
yRange.automatic: true
colorSource: Charts.ColorGradientSource { id: colorSource; baseColor: Theme.highlightColor; itemCount: lineChart.valueSources.length }
nameSource: Charts.ArraySource { id: nameSource; array: ["1", "2", "3", "4", "5"] }
}
}
}
diff --git a/controls/PieChartControl.qml b/controls/PieChartControl.qml
index 8855f8d..eb296d5 100644
--- a/controls/PieChartControl.qml
+++ b/controls/PieChartControl.qml
@@ -1,62 +1,48 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.9
import QtQuick.Controls 2.2
import org.kde.quickcharts 1.0 as Charts
import org.kde.quickcharts.controls 1.0
/**
* A pie chart with text in the middle.
*/
Control {
property alias valueSources: pie.valueSources
property alias names: nameSource.array
property alias color: colorSource.baseColor
property alias range: pie.range
property alias chart: pie
property alias text: centerText.text
implicitWidth: Theme.gridUnit * 5
implicitHeight: Theme.gridUnit * 5
contentItem: Item {
Charts.PieChart {
id: pie
anchors.fill: parent
nameSource: Charts.ArraySource { id: nameSource; array: [ ] }
colorSource: Charts.ColorGradientSource { id: colorSource; baseColor: Theme.highlightColor; itemCount: pie.valueSources.length }
}
Label {
id: centerText
anchors.centerIn: parent;
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
}
}
}
diff --git a/controls/Theme.qml b/controls/Theme.qml
index b8a27ef..b7b6650 100644
--- a/controls/Theme.qml
+++ b/controls/Theme.qml
@@ -1,33 +1,19 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.9
pragma Singleton;
QtObject {
property real gridUnit: 20
property real smallSpacing: 5
property real largeSpacing: 10
property color highlightColor: "blue"
property color backgroundColor: "white"
}
diff --git a/controls/styles/org.kde.desktop/Theme.qml b/controls/styles/org.kde.desktop/Theme.qml
index b96e494..e576fe2 100644
--- a/controls/styles/org.kde.desktop/Theme.qml
+++ b/controls/styles/org.kde.desktop/Theme.qml
@@ -1,37 +1,23 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.9
import org.kde.kirigami 2.4 as Kirigami
pragma Singleton;
QtObject {
property real gridUnit: Kirigami.Units.gridUnit
property real smallSpacing: Kirigami.Units.smallSpacing
property real largeSpacing: Kirigami.Units.largeSpacing
property color highlightColor: Kirigami.Theme.highlightColor
property color backgroundColor: Kirigami.Theme.backgroundColor
Kirigami.Theme.colorSet: Kirigami.Theme.View
}
diff --git a/examples/charts/BarChart.qml b/examples/charts/BarChart.qml
index c61097e..f1203af 100644
--- a/examples/charts/BarChart.qml
+++ b/examples/charts/BarChart.qml
@@ -1,223 +1,209 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.2
import org.kde.kirigami 2.4 as Kirigami
import org.kde.kquickcontrols 2.0
import org.kde.quickcharts 1.0 as Charts
import org.kde.quickcharts.controls 1.0 as ChartsControls
Kirigami.Page {
title: "Bar Chart"
ListModel {
id: barModel;
dynamicRoles: true;
Component.onCompleted: {
append({label: "Item 1", value1: 0, value2: 15, value3: 20})
append({label: "Item 2", value1: 10, value2: 25, value3: 25})
append({label: "Item 3", value1: 15, value2: 20, value3: 30})
append({label: "Item 4", value1: 10, value2: 10, value3: 35})
append({label: "Item 5", value1: 20, value2: 5, value3: 40})
}
}
ColumnLayout {
anchors.fill: parent
anchors.margins: Kirigami.Units.largeSpacing
spacing: Kirigami.Units.largeSpacing
Kirigami.AbstractCard {
Layout.fillHeight: false
Layout.preferredHeight: 400
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Charts.GridLines {
anchors.fill: barChart
chart: barChart
major.visible: false
minor.count: 4
minor.lineWidth: 1
minor.color: Qt.rgba(0.8, 0.8, 0.8, 1.0)
}
Charts.GridLines {
anchors.fill: barChart
chart: barChart
direction: Charts.GridLines.Vertical;
major.count: 1
major.lineWidth: 2
major.color: Qt.rgba(0.8, 0.8, 0.8, 1.0)
minor.count: 3
minor.lineWidth: 1
minor.color: Qt.rgba(0.8, 0.8, 0.8, 1.0)
}
Charts.AxisLabels {
id: yAxisLabels
anchors {
left: parent.left
top: parent.top
bottom: xAxisLabels.top
}
direction: Charts.AxisLabels.VerticalBottomTop
delegate: Label { text: Charts.AxisLabels.label }
source: Charts.ChartAxisSource { chart: barChart; axis: Charts.ChartAxisSource.YAxis; itemCount: 5 }
}
Charts.AxisLabels {
id: xAxisLabels
anchors {
left: yAxisLabels.right
right: parent.right
bottom: legend.top
}
delegate: Label { text: Charts.AxisLabels.label }
source: Charts.ModelSource { model: barModel; roleName: "label" }
}
ChartsControls.Legend {
id: legend
anchors {
left: yAxisLabels.right
right: parent.right
bottom: parent.bottom
bottomMargin: Kirigami.Units.smallSpacing
}
chart: barChart
}
Charts.BarChart {
id: barChart
anchors {
top: parent.top
left: yAxisLabels.right
right: parent.right
bottom: xAxisLabels.top
}
xRange {
from: 0
to: 10
automatic: true
}
yRange {
from: 0
to: 10
automatic: true
}
valueSources: [
Charts.ModelSource { roleName: "value1"; model: barModel },
Charts.ModelSource { roleName: "value2"; model: barModel },
Charts.ModelSource { roleName: "value3"; model: barModel }
]
barWidth: 10
spacing: 2
colorSource: Charts.ArraySource { array: ["red", "green", "blue"] }
nameSource: Charts.ArraySource { array: ["Example 1", "Example 2", "Example 3"] }
}
}
RangeEditor { label: "X Axis"; range: barChart.xRange }
RangeEditor { label: "Y Axis"; range: barChart.yRange }
RowLayout {
Button { text: "Add Item"; onClicked: barModel.append({label: "New", value1: 0, value2: 0, value3: 0}) }
Button { text: "Remove Item"; onClicked: barModel.remove(barModel.count - 1)}
Label { text: "Bar Width" }
SpinBox { from: -1; to: 1000; value: barChart.barWidth; onValueModified: barChart.barWidth = value; }
Label { text: "Bar Spacing" }
SpinBox { from: 0; to: 100; value: barChart.spacing; onValueModified: barChart.spacing = value; }
CheckBox { text: "Stacked"; checked: barChart.stacked; onToggled: barChart.stacked = checked }
}
Frame {
Layout.fillWidth: true
Layout.fillHeight: true
ScrollView {
anchors.fill: parent
ListView {
model: barModel;
delegate: Kirigami.BasicListItem {
width: ListView.view.width
height: Kirigami.Units.gridUnit * 2 + Kirigami.Units.smallSpacing
contentItem: RowLayout {
Label { text: "Label" }
TextField {
Layout.preferredWidth: 75
text: model.label;
onEditingFinished: barModel.setProperty(index, "label", text)
}
Label { text: "Value 1" }
SpinBox {
Layout.preferredWidth: 75
from: -10000; to: 10000;
stepSize: 1;
value: model.value1;
onValueModified: barModel.setProperty(index, "value1", value)
}
Label { text: "Value 2" }
SpinBox {
Layout.preferredWidth: 75
from: -10000; to: 10000;
stepSize: 1;
value: model.value2;
onValueModified: barModel.setProperty(index, "value2", value)
}
Label { text: "Value 3" }
SpinBox {
Layout.preferredWidth: 75
from: -10000; to: 10000;
stepSize: 1;
value: model.value3;
onValueModified: barModel.setProperty(index, "value3", value)
}
}
}
}
}
}
}
}
diff --git a/examples/charts/ContinuousLineChart.qml b/examples/charts/ContinuousLineChart.qml
index ef238d3..67b2813 100644
--- a/examples/charts/ContinuousLineChart.qml
+++ b/examples/charts/ContinuousLineChart.qml
@@ -1,102 +1,88 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.2
import org.kde.kirigami 2.4 as Kirigami
import org.kde.kquickcontrols 2.0
import org.kde.quickcharts 1.0 as Charts
Kirigami.Page {
title: "Line Chart"
ListModel {
id: lineModel;
dynamicRoles: true;
}
Timer {
id: updateTimer
running: true
repeat: true
interval: 16
property real lastValue: 0.0
onTriggered: {
var value = Math.max(0.0, Math.min(1.0, lastValue + (-0.05 + Math.random() / 10)))
lastValue = value;
lineModel.insert(0, {"value": value})
var distance = chart.xRange.to - chart.xRange.from
if(!chart.xRange.automatic && lineModel.count > distance) {
var toRemove = lineModel.count - distance;
lineModel.remove(lineModel.count - toRemove, toRemove)
}
}
}
ColumnLayout {
anchors.fill: parent
anchors.margins: Kirigami.Units.largeSpacing
spacing: Kirigami.Units.largeSpacing
Kirigami.AbstractCard {
Layout.fillHeight: false
Layout.preferredHeight: 400
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Charts.LineChart {
id: chart
anchors.fill: parent
xRange {
from: 0
to: 500
automatic: false
}
yRange {
from: 0
to: 1
automatic: false
}
valueSources: Charts.ModelSource { roleName: "value"; model: lineModel }
colorSource: Charts.SingleValueSource { value: "darkRed" }
lineWidth: 2
fillOpacity: 0.2
}
}
RowLayout {
RangeEditor { label: "X Axis"; range: chart.xRange }
Item { Layout.fillWidth: true }
Button { icon.name: "media-playback-start"; enabled: !updateTimer.running; onClicked: updateTimer.start() }
Button { icon.name: "media-playback-stop"; enabled: updateTimer.running; onClicked: updateTimer.stop() }
Item { Layout.fillWidth: true }
RangeEditor { label: "Y Axis"; range: chart.yRange }
}
}
}
diff --git a/examples/charts/LineChart.qml b/examples/charts/LineChart.qml
index 3a7d255..4527453 100644
--- a/examples/charts/LineChart.qml
+++ b/examples/charts/LineChart.qml
@@ -1,134 +1,120 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.2
import org.kde.kirigami 2.4 as Kirigami
import org.kde.kquickcontrols 2.0
import org.kde.quickcharts 1.0 as Charts
import org.kde.quickcharts.controls 1.0 as ChartsControls
Kirigami.Page {
title: "Line Chart"
ListModel {
id: lineModel;
dynamicRoles: true;
Component.onCompleted: {
append({label: "Item 1", value1: 10, value2: 15, value3: 20})
append({label: "Item 2", value1: 15, value2: 25, value3: 25})
append({label: "Item 3", value1: 15, value2: 20, value3: 30})
append({label: "Item 4", value1: 10, value2: 10, value3: 35})
append({label: "Item 5", value1: 20, value2: 5, value3: 40})
}
}
ColumnLayout {
anchors.fill: parent
anchors.margins: Kirigami.Units.largeSpacing
spacing: Kirigami.Units.largeSpacing
Kirigami.AbstractCard {
Layout.fillHeight: false
Layout.preferredHeight: 400
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
ChartsControls.LineChartControl {
id: lineChart
anchors.fill: parent
valueSources: [
Charts.ModelSource { roleName: "value1"; model: lineModel },
Charts.ModelSource { roleName: "value2"; model: lineModel },
Charts.ModelSource { roleName: "value3"; model: lineModel }
]
names: ["Example 1", "Example 2", "Example 3"]
}
}
RangeEditor { label: "X Axis"; range: lineChart.xRange }
RangeEditor { label: "Y Axis"; range: lineChart.yRange }
RowLayout {
Button { text: "Add Item"; onClicked: lineModel.append({label: "New", value1: 0, value2: 0, value3: 0}) }
Button { text: "Remove Item"; onClicked: lineModel.remove(lineModel.count - 1)}
Label { text: "Line Width" }
SpinBox { from: 0; to: 1000; value: lineChart.lineWidth; onValueModified: lineChart.lineWidth = value; }
Label { text: "Fill Opacity" }
SpinBox { from: 0; to: 100; value: lineChart.fillOpacity * 100; onValueModified: lineChart.fillOpacity = value / 100; }
CheckBox { text: "Stacked"; checked: lineChart.stacked; onToggled: lineChart.stacked = checked }
}
Frame {
Layout.fillWidth: true
Layout.fillHeight: true
ScrollView {
anchors.fill: parent
ListView {
model: lineModel;
delegate: Kirigami.BasicListItem {
width: ListView.view.width
height: Kirigami.Units.gridUnit * 2 + Kirigami.Units.smallSpacing
contentItem: RowLayout {
Label { text: "Label" }
TextField {
Layout.preferredWidth: 75
text: model.label;
onEditingFinished: lineModel.setProperty(index, "label", text)
}
Label { text: "Value 1" }
SpinBox {
Layout.preferredWidth: 75
from: -10000; to: 10000;
stepSize: 1;
value: model.value1;
onValueModified: lineModel.setProperty(index, "value1", value)
}
Label { text: "Value 2" }
SpinBox {
Layout.preferredWidth: 75
from: -10000; to: 10000;
stepSize: 1;
value: model.value2;
onValueModified: lineModel.setProperty(index, "value2", value)
}
Label { text: "Value 3" }
SpinBox {
Layout.preferredWidth: 75
from: -10000; to: 10000;
stepSize: 1;
value: model.value3;
onValueModified: lineModel.setProperty(index, "value3", value)
}
}
}
}
}
}
}
}
diff --git a/examples/charts/PieChart.qml b/examples/charts/PieChart.qml
index 13f3334..1fdafc2 100644
--- a/examples/charts/PieChart.qml
+++ b/examples/charts/PieChart.qml
@@ -1,123 +1,109 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.2
import org.kde.kirigami 2.4 as Kirigami
import org.kde.kquickcontrols 2.0
import org.kde.quickcharts 1.0 as Charts
Kirigami.Page {
title: "Pie Chart"
ListModel {
id: pieModel;
dynamicRoles: true;
Component.onCompleted: {
append({ data: 50, data2: 30, color: "red" })
append({ data: 50, data2: 60, color: "green" })
append({ data: 50, data2: 60, color: "blue" })
}
}
ColumnLayout {
anchors.fill: parent
anchors.margins: Kirigami.Units.largeSpacing
spacing: Kirigami.Units.largeSpacing
Kirigami.AbstractCard {
Layout.fillWidth: false
Layout.fillHeight: false
Layout.preferredWidth: 600
Layout.preferredHeight: 400
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Charts.PieChart {
id: chart
anchors.fill: parent
anchors.margins: Kirigami.Units.smallSpacing;
range.to: 150
valueSources: Charts.ModelSource { roleName: "data"; model: pieModel }
colorSource: Charts.ModelSource { roleName: "color"; model: pieModel }
thickness: 20;
filled: false;
backgroundColor: "gray"
}
}
RangeEditor { label: "Range"; range: chart.range }
RowLayout {
Button { text: "Add Item"; onClicked: pieModel.append({data: 50, color: Qt.rgba(1.0, 1.0, 1.0)}) }
Button { text: "Remove Item"; onClicked: pieModel.remove(pieModel.count - 1)}
Label { text: "Thickness" }
SpinBox { from: 0; to: chart.width / 2; value: chart.thickness; onValueModified: chart.thickness = value; }
CheckBox { text: "Filled"; checked: chart.filled; onCheckedChanged: chart.filled = checked }
}
RowLayout {
CheckBox { text: "Smooth Ends"; checked: chart.smoothEnds; onCheckedChanged: chart.smoothEnds = checked }
Label { text: "From Angle" }
SpinBox { from: -360; to: 360; value: chart.fromAngle; onValueModified: chart.fromAngle = value; }
Label { text: "To Angle" }
SpinBox { from: -360; to: 360; value: chart.toAngle; onValueModified: chart.toAngle = value; }
}
Frame {
Layout.fillWidth: true
Layout.fillHeight: true
ScrollView {
anchors.fill: parent
ListView {
model: pieModel;
delegate: Kirigami.BasicListItem {
width: ListView.view.width
height: Kirigami.Units.gridUnit * 2 + Kirigami.Units.smallSpacing
contentItem: RowLayout {
Label { text: "Value" }
SpinBox {
Layout.preferredWidth: parent.width * 0.15
from: 0; to: 10000;
stepSize: 1;
value: model.data;
onValueModified: pieModel.setProperty(index, "data", value)
}
Label { text: "Color" }
ColorButton {
color: model.color;
showAlphaChannel: true;
onColorChanged: pieModel.setProperty(index, "color", color)
}
}
}
}
}
}
}
}
diff --git a/examples/charts/RangeEditor.qml b/examples/charts/RangeEditor.qml
index 01a7283..7f0566d 100644
--- a/examples/charts/RangeEditor.qml
+++ b/examples/charts/RangeEditor.qml
@@ -1,86 +1,72 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.2
import org.kde.kirigami 2.4 as Kirigami
import org.kde.quickcharts 1.0 as Charts
RowLayout {
property alias label: labelItem.text;
property Charts.Range range;
spacing: Kirigami.Units.smallSpacing
Label {
id: labelItem;
}
CheckBox {
id: automaticCheckbox;
checked: range.automatic;
text: "Automatic";
onToggled: range.automatic = checked
}
Label {
text: "From"
}
SpinBox {
from: -10000;
to: 10000;
value: range.from;
editable: true;
enabled: !automaticCheckbox.checked;
onValueModified: range.from = value;
}
Label {
text: "To"
}
SpinBox {
from: -10000;
to: 10000;
value: range.to;
editable: true;
enabled: !automaticCheckbox.checked;
onValueModified: range.to = value;
}
Label {
text: "Minimum"
}
SpinBox {
from: 0
to: 10000
value: range.minimum
editable: true
onValueModified: range.minimum = value
}
Label {
text: "Increment"
}
SpinBox {
from: 0
to: 10000
value: range.increment
editable: true
onValueModified: range.increment = value
}
}
diff --git a/examples/charts/main.cpp b/examples/charts/main.cpp
index 8eaac1e..fdb9fc5 100644
--- a/examples/charts/main.cpp
+++ b/examples/charts/main.cpp
@@ -1,71 +1,57 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QCommandLineParser parser;
parser.addOption({QStringLiteral("page"), QStringLiteral("The page to show."), QStringLiteral("page")});
parser.addOption({QStringLiteral("api"),
QStringLiteral("The graphics API to use. Can be one of 'default', 'core45', 'compat45', 'compat21' or 'es'."),
QStringLiteral("api"),
QStringLiteral("default")});
parser.addHelpOption();
parser.process(app);
QSurfaceFormat format;
auto api = parser.value(QStringLiteral("api"));
if (api == QStringLiteral("core45")) {
format.setProfile(QSurfaceFormat::CoreProfile);
format.setVersion(4, 5);
} else if (api == QStringLiteral("compat45")) {
format.setProfile(QSurfaceFormat::CompatibilityProfile);
format.setVersion(4, 5);
} else if (api == QStringLiteral("es")) {
format.setRenderableType(QSurfaceFormat::OpenGLES);
} else if (api == QStringLiteral("default") || api == QStringLiteral("compat20")) {
format.setVersion(2, 1);
} else {
qWarning() << "Unknown API option" << api << "\n";
parser.showHelp(1);
}
QSurfaceFormat::setDefaultFormat(format);
QQmlApplicationEngine engine;
if (parser.isSet(QStringLiteral("page"))) {
engine.rootContext()->setContextProperty(QStringLiteral("__commandLinePage"), parser.value(QStringLiteral("page")));
} else {
engine.rootContext()->setContextProperty(QStringLiteral("__commandLinePage"), nullptr);
}
engine.load(QStringLiteral("qrc:/main.qml"));
return app.exec();
}
diff --git a/examples/charts/main.qml b/examples/charts/main.qml
index 8bfeaff..adcda27 100644
--- a/examples/charts/main.qml
+++ b/examples/charts/main.qml
@@ -1,62 +1,48 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
import QtQuick 2.9
import QtQuick.Controls 2.2
import org.kde.kirigami 2.2 as Kirigami
Kirigami.ApplicationWindow {
id: window
title: "Charts Example"
pageStack.initialPage: Kirigami.ScrollablePage {
title: "Charts"
ListView {
model: ListModel {
id: pagesModel
ListElement { label: "Pie Chart"; file: "qrc:/PieChart.qml"; identifier: "pie" }
ListElement { label: "Line Chart"; file: "qrc:/LineChart.qml"; identifier: "line" }
ListElement { label: "Continuous Line Chart"; file: "qrc:/ContinuousLineChart.qml"; identifier: "continuous" }
ListElement { label: "Bar Chart"; file: "qrc:/BarChart.qml"; identifier: "bar" }
}
delegate: Kirigami.BasicListItem {
label: model.label
onClicked: applicationWindow().pageStack.push(model.file);
}
}
}
Component.onCompleted: {
if (__commandLinePage !== null) {
for (var i = 0; i < pagesModel.count; ++i) {
var item = pagesModel.get(i);
if (item.identifier == __commandLinePage || item.label == __commandLinePage) {
window.pageStack.push(item.file);
return;
}
}
}
}
}
diff --git a/examples/snippets/barchart.qml b/examples/snippets/barchart.qml
index cb94e3f..e56429e 100644
--- a/examples/snippets/barchart.qml
+++ b/examples/snippets/barchart.qml
@@ -1,55 +1,41 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
//! [example]
import QtQuick 2.11
import QtQuick.Controls 2.11
import org.kde.quickcharts 1.0 as Charts
Charts.BarChart {
id: barChart
width: 400
height: 300
valueSources: [
Charts.ModelSource { roleName: "value1"; model: listModel },
Charts.ModelSource { roleName: "value2"; model: listModel },
Charts.ModelSource { roleName: "value3"; model: listModel }
]
colorSource: Charts.ArraySource { array: ["red", "green", "blue"] }
nameSource: Charts.ArraySource { array: ["Example 1", "Example 2", "Example 3"] }
barWidth: 20
ListModel {
id: listModel
ListElement { value1: 19; value2: 2; value3: 6 }
ListElement { value1: 14; value2: 20; value3: 17 }
ListElement { value1: 4; value2: 10; value3: 11 }
ListElement { value1: 5; value2: 11; value3: 9 }
ListElement { value1: 20; value2: 7; value3: 13 }
}
}
//! [example]
diff --git a/examples/snippets/linechart.qml b/examples/snippets/linechart.qml
index 37ac58e..fdccbd3 100644
--- a/examples/snippets/linechart.qml
+++ b/examples/snippets/linechart.qml
@@ -1,50 +1,36 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
//! [example]
import QtQuick 2.11
import QtQuick.Controls 2.11
import org.kde.quickcharts 1.0 as Charts
Charts.LineChart {
width: 400
height: 300
valueSources: [
Charts.ModelSource { roleName: "value1"; model: listModel },
Charts.ModelSource { roleName: "value2"; model: listModel },
Charts.ModelSource { roleName: "value3"; model: listModel }
]
colorSource: Charts.ArraySource { array: ["red", "green", "blue"] }
nameSource: Charts.ArraySource { array: ["Example 1", "Example 2", "Example 3"]}
ListModel {
id: listModel
ListElement { value1: 19; value2: 2; value3: 6 }
ListElement { value1: 14; value2: 20; value3: 17 }
ListElement { value1: 4; value2: 10; value3: 11 }
ListElement { value1: 5; value2: 11; value3: 9 }
ListElement { value1: 20; value2: 7; value3: 13 }
}
}
//! [example]
diff --git a/examples/snippets/minimal.qml b/examples/snippets/minimal.qml
index f1a5592..1ef26dd 100644
--- a/examples/snippets/minimal.qml
+++ b/examples/snippets/minimal.qml
@@ -1,52 +1,38 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
//! [example]
import QtQuick 2.11
import QtQuick.Controls 2.11
import org.kde.quickcharts 1.0 as Charts
ApplicationWindow {
width: 500
height: 500
Rectangle {
anchors.centerIn: parent
width: 300
height: 200
border.width: 2
Charts.LineChart {
anchors.fill: parent
colorSource: Charts.ArraySource { array: ["red", "green", "blue"] }
nameSource: Charts.ArraySource { array: ["First", "Second", "Third"] }
valueSources: [
Charts.ArraySource { array: [1, 2, 2, 1] },
Charts.ArraySource { array: [2, 5, 2, 5] },
Charts.ArraySource { array: [5, 4, 3, 4] }
]
}
}
}
//! [example]
diff --git a/examples/snippets/piechart.qml b/examples/snippets/piechart.qml
index c6577eb..a62e743 100644
--- a/examples/snippets/piechart.qml
+++ b/examples/snippets/piechart.qml
@@ -1,48 +1,34 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
//! [example]
import QtQuick 2.11
import QtQuick.Controls 2.11
import org.kde.quickcharts 1.0 as Charts
Charts.PieChart {
width: 400
height: 300
valueSources: Charts.ModelSource {
roleName: "data";
model: ListModel {
id: listModel
ListElement { data: 12 }
ListElement { data: 19 }
ListElement { data: 10 }
ListElement { data: 13 }
ListElement { data: 13 }
}
}
colorSource: Charts.ArraySource { array: ["red", "green", "blue", "yellow", "cyan"] }
nameSource: Charts.ArraySource { array: ["Red", "Green", "Blue", "Yellow", "Cyan"] }
thickness: 50
}
//! [example]
diff --git a/src/BarChart.cpp b/src/BarChart.cpp
index 33244b1..6638b52 100644
--- a/src/BarChart.cpp
+++ b/src/BarChart.cpp
@@ -1,197 +1,183 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "BarChart.h"
#include
#include
#include "datasource/ChartDataSource.h"
#include "scenegraph/BarChartNode.h"
#include "RangeGroup.h"
BarChart::BarChart(QQuickItem *parent)
: XYChart(parent)
{
connect(this, &BarChart::computedRangeChanged, this, &BarChart::onDataChanged);
}
qreal BarChart::spacing() const
{
return m_spacing;
}
void BarChart::setSpacing(qreal newSpacing)
{
if (newSpacing == m_spacing) {
return;
}
m_spacing = newSpacing;
update();
Q_EMIT spacingChanged();
}
qreal BarChart::barWidth() const
{
return m_barWidth;
}
void BarChart::setBarWidth(qreal newBarWidth)
{
if (newBarWidth == m_barWidth) {
return;
}
m_barWidth = newBarWidth;
update();
Q_EMIT barWidthChanged();
}
QSGNode *BarChart::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *)
{
if (!node) {
node = new BarChartNode{};
}
QVector> values;
// TODO: Find some way to clean this up and simplify it, since this is pretty ugly.
auto w = m_barWidth;
if (w < 0.0) {
if (stacked()) {
auto totalItemCount = m_values.size();
w = width() / totalItemCount - m_spacing;
auto x = float(m_spacing / 2);
auto itemSpacing = w + m_spacing;
for (const auto &items : qAsConst(m_values)) {
for (int i = items.count() - 1; i >= 0; --i) {
auto entry = items.at(i);
values << QPair{QVector2D{x, float(entry.first)}, entry.second};
}
x += itemSpacing;
}
} else {
auto totalItemCount = m_values.size() * valueSources().count();
w = width() / totalItemCount - m_spacing;
auto x = float(m_spacing / 2);
auto itemSpacing = w + m_spacing;
for (const auto &items : qAsConst(m_values)) {
for (const auto &entry : items) {
values << QPair{QVector2D{x, float(entry.first)}, entry.second};
x += itemSpacing;
}
}
}
} else {
auto itemSpacing = width() / m_values.size();
if (stacked()) {
auto x = float(itemSpacing / 2 - m_barWidth / 2);
for (const auto &items : qAsConst(m_values)) {
for (int i = items.count() - 1; i >= 0; --i) {
auto entry = items.at(i);
values << QPair{QVector2D{x, float(entry.first)}, entry.second};
}
x += itemSpacing;
}
} else {
auto totalWidth = m_barWidth * valueSources().count() + m_spacing * (valueSources().count() - 1);
auto x = float(itemSpacing / 2 - totalWidth / 2);
for (const auto &items : qAsConst(m_values)) {
for (int i = 0; i < items.count(); ++i) {
auto entry = items.at(i);
values << QPair{QVector2D{float(x + i * (m_barWidth + m_spacing)), float(entry.first)}, entry.second};
}
x += itemSpacing;
}
}
}
auto barNode = static_cast(node);
barNode->setRect(boundingRect());
barNode->setValues(values);
barNode->setBarWidth(w);
barNode->update();
return barNode;
}
void BarChart::onDataChanged()
{
m_values.clear();
updateComputedRange();
const auto range = computedRange();
const auto sources = valueSources();
auto colors = colorSource();
auto indexMode = indexingMode();
auto colorIndex = 0;
m_values.fill(QVector>{}, range.distanceX);
auto generator = [&, i = range.startX]() mutable -> QVector> {
QVector> values;
for (int j = 0; j < sources.count(); ++j) {
auto value = (sources.at(j)->item(i).toReal() - range.startY) / range.distanceY;
values << QPair(value, colors->item(colorIndex).value());
if (indexMode != Chart::IndexSourceValues) {
colorIndex++;
}
}
if (stacked()) {
auto previous = 0.0;
for (auto &value : values) {
value.first += previous;
previous = value.first;
}
}
if (indexMode == Chart::IndexSourceValues) {
colorIndex++;
} else if (indexMode == Chart::IndexEachSource) {
colorIndex = 0;
}
i++;
return values;
};
if (direction() == Direction::ZeroAtStart) {
std::generate_n(m_values.begin(), range.distanceX, generator);
} else {
std::generate_n(m_values.rbegin(), range.distanceX, generator);
}
update();
}
diff --git a/src/BarChart.h b/src/BarChart.h
index e897862..0065fb4 100644
--- a/src/BarChart.h
+++ b/src/BarChart.h
@@ -1,89 +1,75 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef BARCHART_H
#define BARCHART_H
#include "XYChart.h"
/**
* An item to render a bar chart.
*
* This chart renders
*
* ## Usage example
*
* \snippet snippets/barchart.qml example
*
* \image html barchart.png "The resulting bar chart."
*/
class BarChart : public XYChart
{
Q_OBJECT
/**
* The spacing between bars for each value source.
*
* Note that spacing between each X axis value is determined automatically
* based on barWidth, spacing and total chart width. The default is 0.
*/
Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
/**
* The width of individual bars in the chart.
*
* If set to WidthMode::AutoWidth (also the default), the width will be
* calculated automatically based on total chart width and item count.
*/
Q_PROPERTY(qreal barWidth READ barWidth WRITE setBarWidth NOTIFY barWidthChanged)
public:
/**
* Helper enum to provide an easy way to set barWidth to auto.
*/
enum WidthMode { AutoWidth = -2 };
Q_ENUM(WidthMode)
explicit BarChart(QQuickItem *parent = nullptr);
qreal spacing() const;
void setSpacing(qreal newSpacing);
Q_SIGNAL void spacingChanged();
qreal barWidth() const;
void setBarWidth(qreal newBarWidth);
Q_SIGNAL void barWidthChanged();
protected:
/**
* Reimplemented from QQuickItem.
*/
QSGNode *updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *) override;
/**
* Reimplemented from Chart.
*/
void onDataChanged() override;
private:
qreal m_spacing = 0.0;
qreal m_barWidth = AutoWidth;
QVector>> m_values;
};
#endif // BARCHART_H
diff --git a/src/Chart.cpp b/src/Chart.cpp
index aadbd12..1ec4d4e 100644
--- a/src/Chart.cpp
+++ b/src/Chart.cpp
@@ -1,150 +1,136 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "Chart.h"
#include "datasource/ChartDataSource.h"
Chart::Chart(QQuickItem *parent)
: QQuickItem(parent)
{
setFlag(ItemHasContents, true);
}
ChartDataSource *Chart::nameSource() const
{
return m_nameSource;
}
void Chart::setNameSource(ChartDataSource *nameSource)
{
if (m_nameSource == nameSource) {
return;
}
m_nameSource = nameSource;
Q_EMIT nameSourceChanged();
}
ChartDataSource *Chart::colorSource() const
{
return m_colorSource;
}
void Chart::setColorSource(ChartDataSource *colorSource)
{
if (m_colorSource == colorSource) {
return;
}
m_colorSource = colorSource;
Q_EMIT colorSourceChanged();
}
Chart::DataSourcesProperty Chart::valueSourcesProperty()
{
return DataSourcesProperty{this, this, &Chart::appendSource, &Chart::sourceCount, &Chart::source, &Chart::clearSources};
}
QVector Chart::valueSources() const
{
return m_valueSources;
}
void Chart::insertValueSource(int index, ChartDataSource *source)
{
if (index < 0) {
return;
}
m_valueSources.insert(index, source);
connect(source, &QObject::destroyed, this, qOverload(&Chart::removeValueSource));
connect(source, &ChartDataSource::dataChanged, this, &Chart::onDataChanged);
onDataChanged();
Q_EMIT valueSourcesChanged();
}
void Chart::removeValueSource(int index)
{
if (index < 0 || index >= m_valueSources.count()) {
return;
}
m_valueSources.at(index)->disconnect(this);
m_valueSources.remove(index);
onDataChanged();
Q_EMIT valueSourcesChanged();
}
void Chart::removeValueSource(QObject *source)
{
removeValueSource(m_valueSources.indexOf(qobject_cast(source)));
}
Chart::IndexingMode Chart::indexingMode() const
{
return m_indexingMode;
}
void Chart::setIndexingMode(IndexingMode newIndexingMode)
{
if (newIndexingMode == m_indexingMode) {
return;
}
m_indexingMode = newIndexingMode;
onDataChanged();
Q_EMIT indexingModeChanged();
}
void Chart::componentComplete()
{
QQuickItem::componentComplete();
onDataChanged();
}
void Chart::appendSource(Chart::DataSourcesProperty *list, ChartDataSource *source)
{
auto chart = reinterpret_cast(list->data);
chart->m_valueSources.append(source);
QObject::connect(source, &ChartDataSource::dataChanged, chart, &Chart::onDataChanged);
chart->onDataChanged();
}
int Chart::sourceCount(Chart::DataSourcesProperty *list)
{
return reinterpret_cast(list->data)->m_valueSources.count();
}
ChartDataSource *Chart::source(Chart::DataSourcesProperty *list, int index)
{
return reinterpret_cast(list->data)->m_valueSources.at(index);
}
void Chart::clearSources(Chart::DataSourcesProperty *list)
{
auto chart = reinterpret_cast(list->data);
std::for_each(chart->m_valueSources.cbegin(), chart->m_valueSources.cend(), [chart](ChartDataSource *source) { source->disconnect(chart); });
chart->m_valueSources.clear();
chart->onDataChanged();
}
diff --git a/src/Chart.h b/src/Chart.h
index 410cacd..eaf3f75 100644
--- a/src/Chart.h
+++ b/src/Chart.h
@@ -1,111 +1,97 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef CHART_H
#define CHART_H
#include
class ChartDataSource;
/**
* Abstract base class for all charts.
*/
class Chart : public QQuickItem
{
Q_OBJECT
/**
* The data source to use for names of chart items.
*/
Q_PROPERTY(ChartDataSource *nameSource READ nameSource WRITE setNameSource NOTIFY nameSourceChanged)
/**
* The data source to use for colors of chart items.
*/
Q_PROPERTY(ChartDataSource *colorSource READ colorSource WRITE setColorSource NOTIFY colorSourceChanged)
/**
* The data sources providing the data this chart needs to render.
*/
Q_PROPERTY(QQmlListProperty valueSources READ valueSourcesProperty NOTIFY valueSourcesChanged)
/**
* The indexing mode used for indexing colors and names.
*/
Q_PROPERTY(IndexingMode indexingMode READ indexingMode WRITE setIndexingMode NOTIFY indexingModeChanged)
public:
using DataSourcesProperty = QQmlListProperty;
/**
* How to index color and name sources relative to the different value sources.
*/
enum IndexingMode {
IndexSourceValues = 1, ///< Index each value, restart indexing for each value source.
IndexEachSource, ///< Index each value source, never index individual values.
IndexAllValues ///< Index each value, continuing with the index for each value source.
};
Q_ENUM(IndexingMode)
explicit Chart(QQuickItem *parent = nullptr);
~Chart() override = default;
ChartDataSource *nameSource() const;
void setNameSource(ChartDataSource *nameSource);
Q_SIGNAL void nameSourceChanged();
ChartDataSource *colorSource() const;
void setColorSource(ChartDataSource *colorSource);
Q_SIGNAL void colorSourceChanged();
DataSourcesProperty valueSourcesProperty();
QVector valueSources() const;
Q_SIGNAL void valueSourcesChanged();
Q_INVOKABLE void insertValueSource(int index, ChartDataSource *source);
Q_INVOKABLE void removeValueSource(int index);
Q_INVOKABLE void removeValueSource(QObject *source);
IndexingMode indexingMode() const;
void setIndexingMode(IndexingMode newIndexingMode);
Q_SIGNAL void indexingModeChanged();
protected:
/**
* Called when the data of a value source changes.
*
* This method should be reimplemented by subclasses. It is called whenever
* the data of one of the value sources changes. Subclasses should use this
* to make sure that they update whatever internal state they use for
* rendering, then call update() to schedule rendering the item.
*/
virtual void onDataChanged() = 0;
void componentComplete() override;
private:
static void appendSource(DataSourcesProperty *list, ChartDataSource *source);
static int sourceCount(DataSourcesProperty *list);
static ChartDataSource *source(DataSourcesProperty *list, int index);
static void clearSources(DataSourcesProperty *list);
ChartDataSource *m_nameSource = nullptr;
ChartDataSource *m_colorSource = nullptr;
QVector m_valueSources;
IndexingMode m_indexingMode = IndexEachSource;
};
#endif // CHART_H
diff --git a/src/ChartsPlugin.cpp b/src/ChartsPlugin.cpp
index 7b989e7..f037ed0 100644
--- a/src/ChartsPlugin.cpp
+++ b/src/ChartsPlugin.cpp
@@ -1,82 +1,68 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "ChartsPlugin.h"
#include "BarChart.h"
#include "Chart.h"
#include "LineChart.h"
#include "PieChart.h"
#include "RangeGroup.h"
#include "XYChart.h"
#include "decorations/AxisLabels.h"
#include "decorations/GridLines.h"
#include "decorations/LegendModel.h"
#include "datasource/ArraySource.h"
#include "datasource/ChartAxisSource.h"
#include "datasource/ColorGradientSource.h"
#include "datasource/ModelHistorySource.h"
#include "datasource/ModelSource.h"
#include "datasource/SingleValueSource.h"
#include "datasource/ValueHistorySource.h"
QuickChartsPlugin::QuickChartsPlugin(QObject *parent)
: QQmlExtensionPlugin(parent)
{
}
void QuickChartsPlugin::registerTypes(const char *uri)
{
Q_ASSERT(QString::fromLatin1(uri) == QLatin1String("org.kde.quickcharts"));
Q_INIT_RESOURCE(shaders);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
qmlRegisterAnonymousType(uri, 1);
#else
qmlRegisterType();
#endif
qmlRegisterType(uri, 1, 0, "PieChart");
qmlRegisterType(uri, 1, 0, "LineChart");
qmlRegisterType(uri, 1, 0, "BarChart");
qmlRegisterUncreatableType(uri, 1, 0, "XYChart", QStringLiteral("Just a base class"));
qmlRegisterUncreatableType(uri, 1, 0, "Chart", QStringLiteral("Just a base class"));
qmlRegisterUncreatableType(uri, 1, 0, "ChartDataSource", QStringLiteral("Just a base class"));
qmlRegisterType(uri, 1, 0, "ModelSource");
qmlRegisterType(uri, 1, 0, "SingleValueSource");
qmlRegisterType(uri, 1, 0, "ArraySource");
qmlRegisterType(uri, 1, 0, "ModelHistorySource");
qmlRegisterType(uri, 1, 0, "ChartAxisSource");
qmlRegisterType(uri, 1, 0, "ValueHistorySource");
qmlRegisterType(uri, 1, 0, "ColorGradientSource");
qmlRegisterUncreatableType(uri, 1, 0, "Range", QStringLiteral("Used as a grouped property"));
qmlRegisterType(uri, 1, 0, "GridLines");
qmlRegisterUncreatableType(uri, 1, 0, "LinePropertiesGroup", QStringLiteral("Used as a grouped property"));
qmlRegisterType(uri, 1, 0, "AxisLabels");
qmlRegisterUncreatableType(uri, 1, 0, "AxisLabelsAttached", QStringLiteral("Attached property"));
qmlRegisterType(uri, 1, 0, "LegendModel");
}
diff --git a/src/ChartsPlugin.h b/src/ChartsPlugin.h
index b57365f..8480de8 100644
--- a/src/ChartsPlugin.h
+++ b/src/ChartsPlugin.h
@@ -1,37 +1,23 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef CHARTSPLUGIN_H
#define CHARTSPLUGIN_H
#include
class QuickChartsPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
explicit QuickChartsPlugin(QObject *parent = nullptr);
void registerTypes(const char *uri) override;
};
#endif // CHARTSPLUGIN_H
diff --git a/src/LineChart.cpp b/src/LineChart.cpp
index 12d5aed..8816bc7 100644
--- a/src/LineChart.cpp
+++ b/src/LineChart.cpp
@@ -1,250 +1,236 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "LineChart.h"
#include
#include
#include
#include "RangeGroup.h"
#include "datasource/ChartDataSource.h"
#include "scenegraph/LineChartNode.h"
#include "scenegraph/LineGridNode.h"
QVector interpolate(const QVector &points, qreal start, qreal end, qreal height);
LineChart::LineChart(QQuickItem *parent)
: XYChart(parent)
{
}
bool LineChart::smooth() const
{
return m_smooth;
}
qreal LineChart::lineWidth() const
{
return m_lineWidth;
}
qreal LineChart::fillOpacity() const
{
return m_fillOpacity;
}
void LineChart::setSmooth(bool smooth)
{
if (smooth == m_smooth) {
return;
}
m_smooth = smooth;
update();
Q_EMIT smoothChanged();
}
void LineChart::setLineWidth(qreal width)
{
if (qFuzzyCompare(m_lineWidth, width)) {
return;
}
m_lineWidth = width;
update();
Q_EMIT lineWidthChanged();
}
void LineChart::setFillOpacity(qreal opacity)
{
if (qFuzzyCompare(m_fillOpacity, opacity)) {
return;
}
m_fillOpacity = opacity;
update();
Q_EMIT fillOpacityChanged();
}
QSGNode *LineChart::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *data)
{
Q_UNUSED(data);
if (!node) {
node = new QSGNode();
}
if (m_rangeInvalid) {
updateComputedRange();
m_rangeInvalid = false;
}
if (stacked()) {
m_previousValues.clear();
}
const auto sources = valueSources();
for (int i = 0; i < sources.size(); ++i) {
int childIndex = sources.size() - 1 - i;
while (childIndex >= node->childCount()) {
node->appendChildNode(new LineChartNode{});
}
auto lineNode = static_cast(node->childAtIndex(childIndex));
auto color = colorSource() ? colorSource()->item(i).value() : Qt::black;
updateLineNode(lineNode, color, sources.at(i));
}
while (node->childCount() > sources.size()) {
node->removeChildNode(node->childAtIndex(node->childCount() - 1));
}
return node;
}
void LineChart::onDataChanged()
{
m_rangeInvalid = true;
update();
}
void LineChart::updateLineNode(LineChartNode *node, const QColor &lineColor, ChartDataSource *valueSource)
{
auto fillColor = lineColor;
fillColor.setRedF(fillColor.redF() * m_fillOpacity);
fillColor.setGreenF(fillColor.greenF() * m_fillOpacity);
fillColor.setBlueF(fillColor.blueF() * m_fillOpacity);
fillColor.setAlphaF(m_fillOpacity);
node->setRect(boundingRect());
node->setLineColor(lineColor);
node->setFillColor(fillColor);
node->setLineWidth(m_lineWidth);
auto range = computedRange();
float stepSize = width() / (range.distanceX - 1);
QVector values(range.distanceX);
auto generator = [&, i = range.startX]() mutable -> QVector2D {
float value = 0;
if (range.distanceY != 0) {
value = (valueSource->item(i).toFloat() - range.startY) / range.distanceY;
}
auto result = QVector2D{direction() == Direction::ZeroAtStart ? i * stepSize : float(boundingRect().right()) - i * stepSize,
value};
i++;
return result;
};
if (direction() == Direction::ZeroAtStart) {
std::generate_n(values.begin(), range.distanceX, generator);
} else {
std::generate_n(values.rbegin(), range.distanceX, generator);
}
if (stacked() && !m_previousValues.isEmpty()) {
if (values.size() != m_previousValues.size()) {
qWarning() << "Value source" << valueSource->objectName()
<< "has a different number of elements from the previuous source. Ignoring stacking for this source.";
} else {
std::for_each(
values.begin(), values.end(), [this, i = 0](QVector2D &point) mutable { point.setY(point.y() + m_previousValues.at(i++).y()); });
}
}
m_previousValues = values;
if (m_smooth) {
values = interpolate(values, 0.0, width(), height());
}
node->setValues(values);
}
QVector interpolate(const QVector &points, qreal start, qreal end, qreal height)
{
QPainterPath path;
if (points.size() < 4)
return points;
const auto sixth = 1.f / 6.f;
const qreal xDelta = (end - start) / (points.count() - 3);
qreal x = start - xDelta;
path.moveTo(start, points[0].y() * height);
for (int i = 1; i < points.count() - 2; i++) {
// This code was:
//
// QMatrix4x4 matrix( 0, 1, 0, 0,
// -1/6, 1, 1/6, 0,
// 0, 1/6, 1, -1/6,
// 0, 0, 1, 0);
// QMatrix4x4 p(x + xDelta * 0, points[i - 1].y() * height, 0, 0,
// x + xDelta * 1, points[i + 0].y() * height, 0, 0,
// x + xDelta * 2, points[i + 1].y() * height, 0, 0,
// x + xDelta * 3, points[i + 2].y() * height, 0, 0)
// QMatrix4x4 res = matrix * p;
// path.cubicTo(res(1,0), res(1, 1), res(2, 0), res(2, 1), res(3, 0), res(3, 1))
//
// The below calculations calculate the used elements from the matrix directly, avoiding
// most of an expensive matrix multiplication.
auto p0 = points[i - 1].y() * height;
auto p1 = points[i].y() * height;
auto p2 = points[i + 1].y() * height;
auto p3 = points[i + 2].y() * height;
//res(1, 0) = (-1/6, 1, 1/6, 0) dot (x, x + xDelta, x + xDelta * 2, x + xDelta * 3)
auto res10 = (3 * x + 4 * xDelta) / 3.f;
//res(1, 1) = (-1/6, 1, 1/6, 0) dot (p[i-1].y, p[i].y, p[i+1].y, p[i+2].y)
auto res11 = -sixth * p0 + p1 + sixth * p2;
//res(2, 0) = (0, 1/6, 1, -1/6) dot (x, x + xDelta, x + xDelta * 2, x + xDelta * 3)
auto res20 = (3 * x + 5 * xDelta) / 3.f;
//res(2, 1) = (0, 1/6, 1, -1/6) dot (p[i-1].y, p[i].y, p[i+1].y, p[i+2].y)
auto res21 = sixth * p1 + p2 + -sixth * p3;
//res(3, 0) = (0, 0, 1, 0) dot (x, x + xDelta, x + xDelta * 2, x + xDelta * 3)
auto res30 = x + 2 * xDelta;
//res(3, 1) = (0, 0, 1, 0) dot (p[i-1].y, p[i].y, p[i+1].y, p[i+2].y)
auto res31 = p2;
path.cubicTo(res10, res11, res20, res21, res30, res31);
x += xDelta;
}
QVector result;
const auto polygons = path.toSubpathPolygons();
auto pointCount = std::accumulate(polygons.begin(), polygons.end(), 0, [](int current, const QPolygonF &polygon) {
return current + polygon.size();
});
result.reserve(pointCount);
for (const auto &polygon : polygons) {
for (auto point : polygon) {
result.append(QVector2D{float(point.x()), float(point.y() / height)});
}
}
return result;
}
diff --git a/src/LineChart.h b/src/LineChart.h
index 14cfb92..b18e7c6 100644
--- a/src/LineChart.h
+++ b/src/LineChart.h
@@ -1,86 +1,72 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef LINECHART_H
#define LINECHART_H
#include
#include "XYChart.h"
class LineChartNode;
/**
* A line chart.
*
* ## Usage example
*
* \snippet snippets/linechart.qml example
*
* \image html linechart.png "The resulting bar chart."
*/
class LineChart : public XYChart
{
Q_OBJECT
/**
* Smooth the lines in the chart instead of making hard corners.
*/
Q_PROPERTY(bool smooth READ smooth WRITE setSmooth NOTIFY smoothChanged)
/**
* The width of a line in the chart.
*/
Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged)
/**
* The opacity of the area below a line.
*/
Q_PROPERTY(qreal fillOpacity READ fillOpacity WRITE setFillOpacity NOTIFY fillOpacityChanged)
public:
explicit LineChart(QQuickItem *parent = nullptr);
bool smooth() const;
void setSmooth(bool smooth);
Q_SIGNAL void smoothChanged();
qreal lineWidth() const;
void setLineWidth(qreal width);
Q_SIGNAL void lineWidthChanged();
qreal fillOpacity() const;
void setFillOpacity(qreal opacity);
Q_SIGNAL void fillOpacityChanged();
protected:
QSGNode *updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *data) override;
void onDataChanged() override;
private:
void updateLineNode(LineChartNode *node, const QColor &lineColor, ChartDataSource *valueSource);
bool m_smooth = false;
qreal m_lineWidth = 1.0;
qreal m_fillOpacity = 0.0;
bool m_rangeInvalid = true;
QVector m_previousValues;
};
#endif // LINECHART_H
diff --git a/src/PieChart.cpp b/src/PieChart.cpp
index 026ff99..340d9da 100644
--- a/src/PieChart.cpp
+++ b/src/PieChart.cpp
@@ -1,273 +1,259 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "PieChart.h"
#include
#include
#include "RangeGroup.h"
#include "datasource/ChartDataSource.h"
#include "scenegraph/PieChartNode.h"
PieChart::PieChart(QQuickItem *parent)
: Chart(parent)
{
setIndexingMode(Chart::IndexSourceValues);
m_range = std::make_unique();
connect(m_range.get(), &RangeGroup::rangeChanged, this, &PieChart::onDataChanged);
}
RangeGroup *PieChart::range() const
{
return m_range.get();
}
bool PieChart::filled() const
{
return m_filled;
}
void PieChart::setFilled(bool newFilled)
{
if (newFilled == m_filled) {
return;
}
m_filled = newFilled;
update();
Q_EMIT filledChanged();
}
qreal PieChart::thickness() const
{
return m_thickness;
}
void PieChart::setThickness(qreal newThickness)
{
if (newThickness == m_thickness) {
return;
}
m_thickness = newThickness;
update();
Q_EMIT thicknessChanged();
}
qreal PieChart::spacing() const
{
return m_spacing;
}
void PieChart::setSpacing(qreal newSpacing)
{
if (newSpacing == m_spacing) {
return;
}
m_spacing = newSpacing;
update();
Q_EMIT spacingChanged();
}
QColor PieChart::backgroundColor() const
{
return m_backgroundColor;
}
void PieChart::setBackgroundColor(const QColor &color)
{
if (color == m_backgroundColor) {
return;
}
m_backgroundColor = color;
update();
Q_EMIT backgroundColorChanged();
}
qreal PieChart::fromAngle() const
{
return m_fromAngle;
}
void PieChart::setFromAngle(qreal newFromAngle)
{
if (qFuzzyCompare(newFromAngle, m_fromAngle)) {
return;
}
m_fromAngle = newFromAngle;
update();
Q_EMIT fromAngleChanged();
}
qreal PieChart::toAngle() const
{
return m_toAngle;
}
void PieChart::setToAngle(qreal newToAngle)
{
if (qFuzzyCompare(newToAngle, m_toAngle)) {
return;
}
m_toAngle = newToAngle;
update();
Q_EMIT toAngleChanged();
}
bool PieChart::smoothEnds() const
{
return m_smoothEnds;
}
void PieChart::setSmoothEnds(bool newSmoothEnds)
{
if (newSmoothEnds == m_smoothEnds) {
return;
}
m_smoothEnds = newSmoothEnds;
update();
Q_EMIT smoothEndsChanged();
}
QSGNode *PieChart::updatePaintNode(QSGNode *node, UpdatePaintNodeData *data)
{
Q_UNUSED(data);
if (!node) {
node = new QSGNode{};
}
auto sourceCount = valueSources().size();
if (m_sections.count() < sourceCount) {
return node;
}
auto minDimension = std::min(width(), height());
float outerRadius = minDimension;
for (int i = 0; i < sourceCount; ++i) {
float innerRadius = i == sourceCount - 1 && m_filled ? 0.0 : outerRadius - m_thickness;
if (node->childCount() <= i) {
node->appendChildNode(new PieChartNode{});
}
auto pieNode = static_cast(node->childAtIndex(i));
pieNode->setRect(boundingRect());
pieNode->setInnerRadius(innerRadius);
pieNode->setOuterRadius(outerRadius);
pieNode->setSections(m_sections.at(i));
pieNode->setBackgroundColor(m_backgroundColor);
pieNode->setColors(m_colors.at(i));
pieNode->setFromAngle(m_fromAngle);
pieNode->setToAngle(m_toAngle);
pieNode->setSmoothEnds(m_smoothEnds);
outerRadius = outerRadius - m_thickness - m_spacing;
}
while (node->childCount() > sourceCount) {
node->removeChildNode(node->childAtIndex(node->childCount() - 1));
}
return node;
}
void PieChart::onDataChanged()
{
m_sections.clear();
m_colors.clear();
const auto sources = valueSources();
const auto colors = colorSource();
if (!colors || sources.isEmpty() || !m_range->isValid()) {
return;
}
auto maximum = [](ChartDataSource* source) {
qreal result = 0.0;
for (int i = 0; i < source->itemCount(); ++i) {
result += source->item(i).toDouble();
}
return std::max(result, source->maximum().toDouble());
};
auto indexMode = indexingMode();
auto colorIndex = 0;
auto range = m_range->calculateRange(valueSources(),
[](ChartDataSource*) { return 0.0; },
maximum);
for (auto source : sources) {
qreal threshold = range.start;
qreal total = 0.0;
QVector sections;
QVector sectionColors;
for (int i = 0; i < source->itemCount(); ++i) {
auto value = source->item(i).toReal();
auto limited = value - threshold;
if (limited > 0.0) {
if (total + limited >= range.end) {
limited = range.end - total;
}
sections << limited;
total += limited;
auto color = colors->item(colorIndex).value();
sectionColors << color;
}
threshold = std::max(0.0, threshold - value);
if (indexMode != IndexEachSource) {
colorIndex++;
}
}
if (qFuzzyCompare(total, 0.0)) {
m_sections << QVector{0.0};
m_colors << QVector{colors->item(colorIndex).value()};
}
for (auto &value : sections) {
value = value / range.end;
}
m_sections << sections;
m_colors << sectionColors;
if (indexMode == IndexEachSource) {
colorIndex++;
} else if (indexMode == IndexSourceValues) {
colorIndex = 0;
}
}
update();
}
diff --git a/src/PieChart.h b/src/PieChart.h
index 69a95e1..0f36277 100644
--- a/src/PieChart.h
+++ b/src/PieChart.h
@@ -1,182 +1,168 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef PIECHART_H
#define PIECHART_H
#include
#include "Chart.h"
class ChartDataSource;
class RangeGroup;
/**
* An item to render a pie chart.
*
* This item will render a Pie chart based on the [valueSources] supplied to it.
* By default it will set [indexingMode] to [IndexSourceValues], meaning that it
* will use the individual values of the valueSources to render sections of the
* chart.
*
* [valueSources]: \ref Chart::valueSources
* [indexingMode]: \ref Chart::indexingMode
* [IndexSourceValues]: \ref Chart::IndexingMode
*
* ### Usage example
*
* \snippet snippets/piechart.qml example
*
* \image html piechart.png "The resulting pie chart."
*
* ### Multiple Value Sources
*
* Multiple valueSources are rendered as consecutive pie charts in the same
* item. The first valueSource will become the outermost circle and consecutive
* valueSources will be rendered as continuously smaller circles. When rendering
* multiple value sources, [filled] will only affect the last value source. All
* other value sources will be rendered according to [thickness], with [spacing]
* amount of space between them.
*
* [filled]: \ref PieChart::filled
* [thickness]: \ref PieChart::thickness
* [spacing]: \ref PieChart::spacing
*
*/
class PieChart : public Chart
{
Q_OBJECT
/**
* The range of values to display in this PieChart.
*
* When set to "automatic", the values will be divided across the entire
* chart.
*
* \sa RangeGroup
*/
Q_PROPERTY(RangeGroup *range READ range CONSTANT)
/**
* Whether to use a filled pie or not.
*
* If true, the last pie rendered will be rendered as a filled circle.
* The default is false.
*/
Q_PROPERTY(bool filled READ filled WRITE setFilled NOTIFY filledChanged)
/**
* The thickness of an individual pie, in pixels.
*
* If filled is set, this is ignored for the last pie. The default is 10px.
*/
Q_PROPERTY(qreal thickness READ thickness WRITE setThickness NOTIFY thicknessChanged)
/**
* The amount of spacing between pies when rendering multiple value sources.
*
* The default is 0.
*/
Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
/**
* Sets a colour to use to fill remaining space on the pie.
*
* The default is transparent.
*/
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
/**
* The starting angle of the arc used for the entire pie.
*
* When set, instead of rendering a full circle, the pie will be rendered as
* an arc. The default is 0.
*/
Q_PROPERTY(qreal fromAngle READ fromAngle WRITE setFromAngle NOTIFY fromAngleChanged)
/**
* The end angle of the arc used for the entire pie. When set, instead of
* rendering a full circle, the pie will be rendered as an arc. The default
* is 360.
*/
Q_PROPERTY(qreal toAngle READ toAngle WRITE setToAngle NOTIFY toAngleChanged)
/**
* Smooth the ends of pie sections.
*
* When true, this will try to smooth the ends of sections. This works best
* when [filled] is false. The default is false.
*
* [filled]: \ref PieChart::filled
*/
Q_PROPERTY(bool smoothEnds READ smoothEnds WRITE setSmoothEnds NOTIFY smoothEndsChanged)
public:
explicit PieChart(QQuickItem *parent = nullptr);
RangeGroup *range() const;
bool filled() const;
void setFilled(bool newFilled);
Q_SIGNAL void filledChanged();
qreal thickness() const;
void setThickness(qreal newThickness);
Q_SIGNAL void thicknessChanged();
qreal spacing() const;
void setSpacing(qreal newSpacing);
Q_SIGNAL void spacingChanged();
QColor backgroundColor() const;
void setBackgroundColor(const QColor &color);
Q_SIGNAL void backgroundColorChanged();
qreal fromAngle() const;
void setFromAngle(qreal newFromAngle);
Q_SIGNAL void fromAngleChanged();
qreal toAngle() const;
void setToAngle(qreal newToAngle);
Q_SIGNAL void toAngleChanged();
bool smoothEnds() const;
void setSmoothEnds(bool newSmoothEnds);
Q_SIGNAL void smoothEndsChanged();
protected:
/**
* Reimplemented from QQuickItem.
*/
QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data) override;
/**
* Reimplemented from Chart.
*/
void onDataChanged() override;
private:
std::unique_ptr m_range;
bool m_filled = false;
qreal m_thickness = 10.0;
qreal m_spacing = 0.0;
QColor m_backgroundColor = Qt::transparent;
qreal m_fromAngle = 0.0;
qreal m_toAngle = 360.0;
bool m_smoothEnds = false;
QVector> m_sections;
QVector> m_colors;
};
#endif // PIECHART_H
diff --git a/src/RangeGroup.cpp b/src/RangeGroup.cpp
index 07fb9f4..d68bd4a 100644
--- a/src/RangeGroup.cpp
+++ b/src/RangeGroup.cpp
@@ -1,152 +1,138 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "RangeGroup.h"
#include
#include
RangeGroup::RangeGroup(QObject *parent)
: QObject(parent)
{
connect(this, &RangeGroup::fromChanged, this, &RangeGroup::rangeChanged);
connect(this, &RangeGroup::toChanged, this, &RangeGroup::rangeChanged);
connect(this, &RangeGroup::automaticChanged, this, &RangeGroup::rangeChanged);
connect(this, &RangeGroup::minimumChanged, this, &RangeGroup::rangeChanged);
connect(this, &RangeGroup::incrementChanged, this, &RangeGroup::rangeChanged);
}
qreal RangeGroup::from() const
{
return m_from;
}
void RangeGroup::setFrom(qreal from)
{
if (qFuzzyCompare(m_from, from)) {
return;
}
m_from = from;
Q_EMIT fromChanged();
}
qreal RangeGroup::to() const
{
return m_to;
}
void RangeGroup::setTo(qreal to)
{
if (qFuzzyCompare(m_to, to)) {
return;
}
m_to = to;
Q_EMIT toChanged();
}
bool RangeGroup::automatic() const
{
return m_automatic;
}
void RangeGroup::setAutomatic(bool automatic)
{
if (m_automatic == automatic) {
return;
}
m_automatic = automatic;
Q_EMIT automaticChanged();
}
qreal RangeGroup::distance() const
{
return m_to - m_from;
}
qreal RangeGroup::minimum() const
{
return m_minimum;
}
void RangeGroup::setMinimum(qreal newMinimum)
{
if (newMinimum == m_minimum) {
return;
}
m_minimum = newMinimum;
Q_EMIT minimumChanged();
}
qreal RangeGroup::increment() const
{
return m_increment;
}
void RangeGroup::setIncrement(qreal newIncrement)
{
if (newIncrement == m_increment) {
return;
}
m_increment = newIncrement;
Q_EMIT incrementChanged();
}
bool RangeGroup::isValid() const
{
return m_automatic || (m_to > m_from);
}
RangeGroup::RangeResult RangeGroup::calculateRange(const QVector &sources,
std::function minimumCallback,
std::function maximumCallback)
{
RangeResult result;
auto min = std::numeric_limits::max();
auto max = std::numeric_limits::min();
if (!m_automatic) {
min = m_from;
max = m_to;
} else {
std::for_each(sources.begin(), sources.end(), [&](ChartDataSource *source) {
min = std::min(min, minimumCallback(source));
max = std::max(max, maximumCallback(source));
});
}
max = std::max(max, m_minimum);
if (m_increment > 0.0) {
max = m_increment * std::ceil(max / m_increment);
}
result.start = min;
result.end = max;
result.distance = max - min;
return result;
}
diff --git a/src/RangeGroup.h b/src/RangeGroup.h
index abd9d16..8d588fa 100644
--- a/src/RangeGroup.h
+++ b/src/RangeGroup.h
@@ -1,125 +1,111 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef RANGEGROUP_H
#define RANGEGROUP_H
#include
#include
class ChartDataSource;
/**
* An object that can be used as a grouped property to provide a value range for charts.
*
*/
class RangeGroup : public QObject
{
Q_OBJECT
/**
* The start of this range.
*
* The default is 0.
*/
Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
/**
* The end of this range.
*
* The default is 100.
*/
Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
/**
* Whether to determine the range based on values of a chart.
*
* If true (the default), `from` and `to` are ignored and instead calculated
* from the minimum and maximum values of a chart's valueSources.
*/
Q_PROPERTY(bool automatic READ automatic WRITE setAutomatic NOTIFY automaticChanged)
/**
* The distance between from and to.
*/
Q_PROPERTY(qreal distance READ distance NOTIFY rangeChanged)
/**
* The minimum size of the range.
*
* This is mostly relevant when automatic is true. Setting this value will
* ensure that the range will never be smaller than this value. The default
* is `std::numeric_limits::min`, which means minimum is disabled.
*/
Q_PROPERTY(qreal minimum READ minimum WRITE setMinimum NOTIFY minimumChanged)
/**
* The amount with which the range increases.
*
* The total range will be limited to a multiple of this value. This is
* mostly useful when automatic is true. The default is 0.0, which means do
* not limit the range increment.
*/
Q_PROPERTY(qreal increment READ increment WRITE setIncrement NOTIFY incrementChanged)
public:
struct RangeResult {
qreal start = 0.0;
qreal end = 0.0;
qreal distance = 0.0;
};
explicit RangeGroup(QObject *parent = nullptr);
qreal from() const;
void setFrom(qreal from);
Q_SIGNAL void fromChanged();
qreal to() const;
void setTo(qreal to);
Q_SIGNAL void toChanged();
bool automatic() const;
void setAutomatic(bool newAutomatic);
Q_SIGNAL void automaticChanged();
qreal distance() const;
qreal minimum() const;
void setMinimum(qreal newMinimum);
Q_SIGNAL void minimumChanged();
qreal increment() const;
void setIncrement(qreal newIncrement);
Q_SIGNAL void incrementChanged();
bool isValid() const;
Q_SIGNAL void rangeChanged();
RangeResult calculateRange(const QVector &sources,
std::function minimumCallback,
std::function maximumCallback);
private:
qreal m_from = 0.0;
qreal m_to = 100.0;
bool m_automatic = true;
qreal m_minimum = std::numeric_limits::min();
qreal m_increment = 0.0;
};
#endif // RANGEGROUP_H
diff --git a/src/XYChart.cpp b/src/XYChart.cpp
index 719484f..a0ebf0d 100644
--- a/src/XYChart.cpp
+++ b/src/XYChart.cpp
@@ -1,145 +1,131 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "XYChart.h"
#include "RangeGroup.h"
#include "datasource/ChartDataSource.h"
bool operator==(const ComputedRange &first, const ComputedRange &second)
{
return first.startX == second.startX && first.endX == second.endX && qFuzzyCompare(first.startY, second.startY)
&& qFuzzyCompare(first.endY, second.endY);
}
XYChart::XYChart(QQuickItem *parent)
: Chart(parent)
{
m_xRange = new RangeGroup{this};
connect(m_xRange, &RangeGroup::rangeChanged, this, &XYChart::updateComputedRange);
m_yRange = new RangeGroup{this};
connect(m_yRange, &RangeGroup::rangeChanged, this, &XYChart::updateComputedRange);
}
RangeGroup *XYChart::xRange() const
{
return m_xRange;
}
RangeGroup *XYChart::yRange() const
{
return m_yRange;
}
XYChart::Direction XYChart::direction() const
{
return m_direction;
}
void XYChart::setDirection(XYChart::Direction newDirection)
{
if (newDirection == m_direction) {
return;
}
m_direction = newDirection;
onDataChanged();
Q_EMIT directionChanged();
}
bool XYChart::stacked() const
{
return m_stacked;
}
void XYChart::setStacked(bool newStacked)
{
if (newStacked == m_stacked) {
return;
}
m_stacked = newStacked;
onDataChanged();
Q_EMIT stackedChanged();
}
ComputedRange XYChart::computedRange() const
{
return m_computedRange;
}
void XYChart::updateComputedRange()
{
if (valueSources().count() == 0) {
return;
}
ComputedRange result;
auto xRange = m_xRange->calculateRange(valueSources(),
[](ChartDataSource *) { return 0; },
[](ChartDataSource *source) { return source->itemCount(); });
result.startX = xRange.start;
result.endX = xRange.end;
result.distanceX = xRange.distance;
auto maximumY = [this, xRange](ChartDataSource *source) {
if (!m_stacked) {
return source->maximum().toDouble();
} else {
qreal max = std::numeric_limits::min();
for (int i = xRange.start; i < xRange.end; ++i) {
qreal yDistance = 0.0;
for (auto source : valueSources()) {
yDistance += source->item(i).toDouble();
}
max = std::max(max, yDistance);
}
return max;
}
};
auto yRange = m_yRange->calculateRange(valueSources(),
[](ChartDataSource *source) { return std::min(0.0, source->minimum().toDouble()); },
maximumY);
result.startY = yRange.start;
result.endY = yRange.end;
result.distanceY = yRange.distance;
setComputedRange(result);
}
void XYChart::setComputedRange(ComputedRange range)
{
if (range == m_computedRange) {
return;
}
m_computedRange = range;
Q_EMIT computedRangeChanged();
}
QDebug operator<<(QDebug debug, const ComputedRange &range)
{
debug << "Range: startX" << range.startX << "endX" << range.endX << "distance" << range.distanceX << "startY" << range.startY << "endY"
<< range.endY << "distance" << range.distanceY;
return debug;
}
diff --git a/src/XYChart.h b/src/XYChart.h
index a20f972..9c25a06 100644
--- a/src/XYChart.h
+++ b/src/XYChart.h
@@ -1,144 +1,130 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef XYCHART_H
#define XYCHART_H
#include "Chart.h"
class RangeGroup;
/**
* A helper containing the calculated X and Y ranges of a chart.
*/
struct ComputedRange
{
int startX = 0;
int endX = 0;
int distanceX = 0;
float startY = 0.0;
float endY = 0.0;
float distanceY = 0.0;
};
bool operator==(const ComputedRange &first, const ComputedRange &second);
/**
* A base class for Charts that are based on an X/Y grid.
*/
class XYChart : public Chart
{
Q_OBJECT
/**
* The range of values on the X axis.
*/
Q_PROPERTY(RangeGroup *xRange READ xRange CONSTANT)
/**
* The range of values on the Y axis.
*/
Q_PROPERTY(RangeGroup *yRange READ yRange CONSTANT)
/**
* Which direction this chart's X axis runs.
*/
Q_PROPERTY(Direction direction READ direction WRITE setDirection NOTIFY directionChanged)
/**
* Whether the values of each value source should be stacked.
*
* When true, Y values will be added on top of each other. The precise
* meaning of this property depends on the specific chart. The default is
* false.
*/
Q_PROPERTY(bool stacked READ stacked WRITE setStacked NOTIFY stackedChanged)
public:
/**
* The direction of values on the X axis.
*
* "Start" is defined as the starting direction of the chart, when using a
* left-to-right language it will be the left side, with a right-to-left
* language it will be right.
*/
enum class Direction {
ZeroAtStart, ///< Zero is at the beginning of the chart, values run from begin to end.
ZeroAtEnd ///< Zero is at the end of the chart, values run from end to begin.
};
Q_ENUM(Direction)
/**
* Constructor
*
* @param parent The QObject parent.
*/
explicit XYChart(QQuickItem *parent = nullptr);
/**
* Destructor
*/
~XYChart() override = default;
virtual RangeGroup *xRange() const;
virtual RangeGroup *yRange() const;
virtual XYChart::Direction direction() const;
virtual void setDirection(XYChart::Direction newDirection);
Q_SIGNAL void directionChanged();
bool stacked() const;
void setStacked(bool newStacked);
Q_SIGNAL void stackedChanged();
/**
* Get the complete, calculated range for this chart.
*/
ComputedRange computedRange() const;
/**
* Emitted whenever the complete range is recalculated.
*/
Q_SIGNAL void computedRangeChanged();
protected:
/**
* Re-calculate the chart's range.
*
* By default, this will make use of the xRange/yRange properties and
* calculate a proper range. This method can be overridden by subclasses if
* some special calculation is needed.
*/
virtual void updateComputedRange();
/**
* Set the computed range.
*
* \param range The new range.
*/
void setComputedRange(ComputedRange range);
private:
RangeGroup *m_xRange = nullptr;
RangeGroup *m_yRange = nullptr;
Direction m_direction = Direction::ZeroAtStart;
bool m_stacked = false;
ComputedRange m_computedRange;
};
QDebug operator<<(QDebug debug, const ComputedRange &range);
#endif // XYCHART_H
diff --git a/src/datasource/ArraySource.cpp b/src/datasource/ArraySource.cpp
index 72f485c..5928640 100644
--- a/src/datasource/ArraySource.cpp
+++ b/src/datasource/ArraySource.cpp
@@ -1,88 +1,74 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "ArraySource.h"
ArraySource::ArraySource(QObject *parent)
: ChartDataSource(parent)
{
}
int ArraySource::itemCount() const
{
return m_array.count();
}
QVariant ArraySource::item(int index) const
{
if (!m_wrap && (index < 0 || index > m_array.count() - 1))
return QVariant{};
return m_array.at(index % m_array.count());
}
QVariant ArraySource::minimum() const
{
auto itr = std::min_element(m_array.cbegin(), m_array.cend());
if (itr != m_array.cend()) {
return *itr;
}
return QVariant{};
}
QVariant ArraySource::maximum() const
{
auto itr = std::max_element(m_array.cbegin(), m_array.cend());
if (itr != m_array.cend()) {
return *itr;
}
return QVariant{};
}
QVariantList ArraySource::array() const
{
return m_array;
}
bool ArraySource::wrap() const
{
return m_wrap;
}
void ArraySource::setArray(const QVariantList &array)
{
if (m_array == array) {
return;
}
m_array = array;
Q_EMIT dataChanged();
}
void ArraySource::setWrap(bool wrap)
{
if (m_wrap == wrap) {
return;
}
m_wrap = wrap;
Q_EMIT dataChanged();
}
diff --git a/src/datasource/ArraySource.h b/src/datasource/ArraySource.h
index 7c10b9f..f5ee981 100644
--- a/src/datasource/ArraySource.h
+++ b/src/datasource/ArraySource.h
@@ -1,62 +1,48 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef ARRAYSOURCE_H
#define ARRAYSOURCE_H
#include
#include "ChartDataSource.h"
/**
* A data source that provides entries of an array as data.
*/
class ArraySource : public ChartDataSource
{
Q_OBJECT
Q_PROPERTY(QVariantList array READ array WRITE setArray NOTIFY dataChanged)
Q_PROPERTY(bool wrap READ wrap WRITE setWrap NOTIFY dataChanged)
public:
/**
* Constructor
*
* @param parent TODO
*/
explicit ArraySource(QObject *parent = nullptr);
virtual int itemCount() const override;
virtual QVariant item(int index) const override;
QVariant minimum() const override;
QVariant maximum() const override;
QVariantList array() const;
void setArray(const QVariantList &array);
bool wrap() const;
void setWrap(bool wrap);
private:
QVariantList m_array;
bool m_wrap = false;
};
#endif // ARRAYSOURCE_H
diff --git a/src/datasource/ChartAxisSource.cpp b/src/datasource/ChartAxisSource.cpp
index 2c7fdc1..a6b2d06 100644
--- a/src/datasource/ChartAxisSource.cpp
+++ b/src/datasource/ChartAxisSource.cpp
@@ -1,124 +1,110 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "ChartAxisSource.h"
#include
#include
#include "XYChart.h"
ChartAxisSource::ChartAxisSource(QObject *parent)
: ChartDataSource(parent)
{
connect(this, &ChartAxisSource::itemCountChanged, this, &ChartAxisSource::dataChanged);
connect(this, &ChartAxisSource::chartChanged, this, &ChartAxisSource::dataChanged);
connect(this, &ChartAxisSource::axisChanged, this, &ChartAxisSource::dataChanged);
}
QVariant ChartAxisSource::item(int index) const
{
if (!m_chart || index < 0 || index > m_itemCount)
return QVariant{};
auto range = m_chart->computedRange();
if (m_axis == Axis::XAxis) {
return range.startX + (range.distanceX / (m_itemCount - 1)) * index;
} else {
return range.startY + (range.distanceY / (m_itemCount - 1)) * index;
}
}
QVariant ChartAxisSource::minimum() const
{
if (!m_chart)
return QVariant{};
if (m_axis == Axis::XAxis) {
return m_chart->computedRange().startX;
} else {
return m_chart->computedRange().startY;
}
}
QVariant ChartAxisSource::maximum() const
{
if (!m_chart)
return QVariant{};
if (m_axis == Axis::XAxis) {
return m_chart->computedRange().endX;
} else {
return m_chart->computedRange().endY;
}
}
XYChart *ChartAxisSource::chart() const
{
return m_chart;
}
void ChartAxisSource::setChart(XYChart *newChart)
{
if (newChart == m_chart) {
return;
}
if (m_chart) {
disconnect(m_chart, &XYChart::computedRangeChanged, this, &ChartAxisSource::dataChanged);
}
m_chart = newChart;
if (m_chart) {
connect(m_chart, &XYChart::computedRangeChanged, this, &ChartAxisSource::dataChanged);
}
Q_EMIT chartChanged();
}
ChartAxisSource::Axis ChartAxisSource::axis() const
{
return m_axis;
}
void ChartAxisSource::setAxis(ChartAxisSource::Axis newAxis)
{
if (newAxis == m_axis) {
return;
}
m_axis = newAxis;
Q_EMIT axisChanged();
}
int ChartAxisSource::itemCount() const
{
return m_itemCount;
}
void ChartAxisSource::setItemCount(int newItemCount)
{
if (newItemCount == m_itemCount) {
return;
}
m_itemCount = newItemCount;
Q_EMIT itemCountChanged();
}
diff --git a/src/datasource/ChartAxisSource.h b/src/datasource/ChartAxisSource.h
index 6149cc7..1bb0a44 100644
--- a/src/datasource/ChartAxisSource.h
+++ b/src/datasource/ChartAxisSource.h
@@ -1,72 +1,58 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef CHARTAXISSOURCE_H
#define CHARTAXISSOURCE_H
#include "ChartDataSource.h"
class XYChart;
/**
* A data source that provides values from a chart's axis as data.
*/
class ChartAxisSource : public ChartDataSource
{
Q_OBJECT
Q_PROPERTY(XYChart *chart READ chart WRITE setChart NOTIFY chartChanged)
Q_PROPERTY(ChartAxisSource::Axis axis READ axis WRITE setAxis NOTIFY axisChanged)
Q_PROPERTY(int itemCount READ itemCount WRITE setItemCount NOTIFY itemCountChanged)
public:
enum class Axis { XAxis, YAxis };
Q_ENUM(Axis)
/**
* Constructor
*
* @param parent TODO
*/
ChartAxisSource(QObject *parent = nullptr);
virtual QVariant item(int index) const override;
QVariant minimum() const override;
QVariant maximum() const override;
XYChart *chart() const;
Q_SLOT void setChart(XYChart *newChart);
Q_SIGNAL void chartChanged();
ChartAxisSource::Axis axis() const;
Q_SLOT void setAxis(ChartAxisSource::Axis newAxis);
Q_SIGNAL void axisChanged();
virtual int itemCount() const override;
Q_SLOT void setItemCount(int newItemCount);
Q_SIGNAL void itemCountChanged();
private:
XYChart *m_chart = nullptr;
Axis m_axis = Axis::XAxis;
int m_itemCount = 2;
};
#endif // ARRAYSOURCE_H
diff --git a/src/datasource/ChartDataSource.cpp b/src/datasource/ChartDataSource.cpp
index 0e061ff..1fba2cf 100644
--- a/src/datasource/ChartDataSource.cpp
+++ b/src/datasource/ChartDataSource.cpp
@@ -1,27 +1,13 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "ChartDataSource.h"
ChartDataSource::ChartDataSource(QObject *parent)
: QObject(parent)
{
}
diff --git a/src/datasource/ChartDataSource.h b/src/datasource/ChartDataSource.h
index 0535c05..5bb6f39 100644
--- a/src/datasource/ChartDataSource.h
+++ b/src/datasource/ChartDataSource.h
@@ -1,46 +1,32 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef DATASOURCE_H
#define DATASOURCE_H
#include
/**
* Abstract base class for data sources.
*/
class ChartDataSource : public QObject
{
Q_OBJECT
public:
explicit ChartDataSource(QObject *parent = nullptr);
virtual ~ChartDataSource() = default;
virtual int itemCount() const = 0;
virtual QVariant item(int index) const = 0;
virtual QVariant minimum() const = 0;
virtual QVariant maximum() const = 0;
Q_SIGNAL void dataChanged();
};
#endif // DATASOURCE_H
diff --git a/src/datasource/ColorGradientSource.cpp b/src/datasource/ColorGradientSource.cpp
index 6ca4e26..8bc3dbf 100644
--- a/src/datasource/ColorGradientSource.cpp
+++ b/src/datasource/ColorGradientSource.cpp
@@ -1,111 +1,97 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Marco Martin
- * Copyright 2019 David Edmundson
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Marco Martin
+ * SPDX-FileCopyrightText: 2019 David Edmundson
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "ColorGradientSource.h"
#include
#include
ColorGradientSource::ColorGradientSource(QObject *parent)
: ChartDataSource(parent)
{
}
int ColorGradientSource::itemCount() const
{
return m_itemCount;
}
QVariant ColorGradientSource::item(int index) const
{
if (index < 0 || index >= m_colors.size()) {
return QVariant{};
}
return m_colors.at(index);
}
QVariant ColorGradientSource::minimum() const
{
return QVariant{};
}
QVariant ColorGradientSource::maximum() const
{
return QVariant{};
}
QColor ColorGradientSource::baseColor() const
{
return m_baseColor;
}
void ColorGradientSource::setBaseColor(const QColor &newBaseColor)
{
if (newBaseColor == m_baseColor) {
return;
}
m_baseColor = newBaseColor;
regenerateColors();
Q_EMIT baseColorChanged();
}
void ColorGradientSource::setItemCount(int newItemCount)
{
if (newItemCount == m_itemCount) {
return;
}
m_itemCount = newItemCount;
regenerateColors();
Q_EMIT itemCountChanged();
}
QVariantList ColorGradientSource::colors() const
{
QVariantList colorsVariant;
colorsVariant.reserve(m_colors.count());
for (const QColor &color : qAsConst(m_colors)) {
colorsVariant.append(color);
}
return colorsVariant;
}
void ColorGradientSource::regenerateColors()
{
if (!m_baseColor.isValid() || m_itemCount <= 0) {
return;
}
m_colors.clear();
for (int i = 0; i < m_itemCount; ++i) {
auto newHue = m_baseColor.hsvHueF() + i * (1.0 / m_itemCount);
newHue = newHue - int(newHue);
m_colors.append(QColor::fromHsvF(newHue, m_baseColor.saturationF(), m_baseColor.valueF(), m_baseColor.alphaF()));
}
Q_EMIT dataChanged();
}
diff --git a/src/datasource/ColorGradientSource.h b/src/datasource/ColorGradientSource.h
index 604c36b..f889edb 100644
--- a/src/datasource/ColorGradientSource.h
+++ b/src/datasource/ColorGradientSource.h
@@ -1,67 +1,53 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Marco Martin
- * Copyright 2019 David Edmundson
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Marco Martin
+ * SPDX-FileCopyrightText: 2019 David Edmundson
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef COLORGRADIENTSOURCE_H
#define COLORGRADIENTSOURCE_H
#include
#include
#include "ChartDataSource.h"
/**
* A data source that provides a hue-shifted color as data.
*/
class ColorGradientSource : public ChartDataSource
{
Q_OBJECT
Q_PROPERTY(QColor baseColor READ baseColor WRITE setBaseColor NOTIFY baseColorChanged)
Q_PROPERTY(int itemCount READ itemCount WRITE setItemCount NOTIFY itemCountChanged)
Q_PROPERTY(QVariantList colors READ colors NOTIFY dataChanged)
public:
explicit ColorGradientSource(QObject *parent = nullptr);
int itemCount() const override;
QVariant item(int index) const override;
QVariant minimum() const override;
QVariant maximum() const override;
QColor baseColor() const;
void setBaseColor(const QColor &newBaseColor);
Q_SIGNAL void baseColorChanged();
void setItemCount(int newItemCount);
Q_SIGNAL void itemCountChanged();
QVariantList colors() const;
private:
void regenerateColors();
QColor m_baseColor = Qt::blue;
int m_itemCount = 0;
QVector m_colors;
};
#endif // COLORGRADIENTSOURCE_H
diff --git a/src/datasource/ModelHistorySource.cpp b/src/datasource/ModelHistorySource.cpp
index ef13c4a..4c60c00 100644
--- a/src/datasource/ModelHistorySource.cpp
+++ b/src/datasource/ModelHistorySource.cpp
@@ -1,174 +1,160 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "ModelHistorySource.h"
#include
#include
#include
#include
ModelHistorySource::ModelHistorySource(QObject *parent)
: ModelSource(parent)
{
connect(this, &ModelHistorySource::modelChanged, this, &ModelHistorySource::onModelChanged);
}
int ModelHistorySource::itemCount() const
{
return m_history.size();
}
QVariant ModelHistorySource::item(int index) const
{
if (index < 0 || index >= m_history.size())
return QVariant{};
return m_history.at(index);
}
QVariant ModelHistorySource::minimum() const
{
if (m_history.isEmpty())
return QVariant{};
return *std::min_element(m_history.begin(), m_history.end());
}
QVariant ModelHistorySource::maximum() const
{
if (m_history.isEmpty())
return QVariant{};
return *std::max_element(m_history.begin(), m_history.end());
}
int ModelHistorySource::row() const
{
return m_row;
}
void ModelHistorySource::setRow(int row)
{
if (m_row == row) {
return;
}
m_row = row;
Q_EMIT rowChanged();
}
int ModelHistorySource::maximumHistory() const
{
return m_maximumHistory;
}
void ModelHistorySource::setMaximumHistory(int maximumHistory)
{
if (m_maximumHistory == maximumHistory) {
return;
}
m_maximumHistory = maximumHistory;
Q_EMIT maximumHistoryChanged();
}
int ModelHistorySource::interval() const
{
return m_updateTimer ? m_updateTimer->interval() : -1;
}
void ModelHistorySource::setInterval(int newInterval)
{
if (m_updateTimer && newInterval == m_updateTimer->interval()) {
return;
}
if (newInterval > 0) {
if (!m_updateTimer) {
m_updateTimer = std::make_unique();
// We need precise timers to avoid missing updates when dealing with semi-constantly
// updating model. That is, if the model updates at 500ms and we also update at that
// rate, a drift of 2ms can cause us to miss updates.
m_updateTimer->setTimerType(Qt::PreciseTimer);
connect(m_updateTimer.get(), &QTimer::timeout, this, [this]() {
if (!model()) {
return;
}
auto index = model()->index(m_row, column());
onDataChanged(index, index, {role()});
});
if (model()) {
disconnect(model(), &QAbstractItemModel::dataChanged, this, &ModelHistorySource::onDataChanged);
}
}
m_updateTimer->setInterval(newInterval);
m_updateTimer->start();
} else {
m_updateTimer.reset();
onModelChanged();
}
Q_EMIT intervalChanged();
}
void ModelHistorySource::clear()
{
m_history.clear();
Q_EMIT dataChanged();
}
void ModelHistorySource::onModelChanged()
{
if (model() && !m_updateTimer) {
connect(model(), &QAbstractItemModel::dataChanged, this, &ModelHistorySource::onDataChanged);
}
}
void ModelHistorySource::onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles)
{
if (!model()) {
return;
}
if (!roles.isEmpty() && !roles.contains(role())) {
return;
}
if (topLeft.row() > m_row || bottomRight.row() < m_row) {
return;
}
if (topLeft.column() > column() || bottomRight.column() < column()) {
return;
}
auto entry = model()->data(model()->index(m_row, column()), role());
m_history.prepend(entry);
while (m_history.size() > m_maximumHistory) {
m_history.pop_back();
}
Q_EMIT dataChanged();
}
diff --git a/src/datasource/ModelHistorySource.h b/src/datasource/ModelHistorySource.h
index 1d0041c..355f314 100644
--- a/src/datasource/ModelHistorySource.h
+++ b/src/datasource/ModelHistorySource.h
@@ -1,78 +1,64 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef MODELHISTORYSOURCE_H
#define MODELHISTORYSOURCE_H
#include
#include
#include "ModelSource.h"
/**
* A data source that watches a QAbstractItemModel cell and provides the history of that cell as data.
*/
class ModelHistorySource : public ModelSource
{
Q_OBJECT
// The row to read data from. The items of this source will be the values of
// that row, using the column and role from ModelSource.
Q_PROPERTY(int row READ row WRITE setRow NOTIFY rowChanged)
// The maximum amount of history to keep.
Q_PROPERTY(int maximumHistory READ maximumHistory WRITE setMaximumHistory NOTIFY maximumHistoryChanged)
// The update interval. If not set or set to a value < 0, a new item will be
// added whenever the underlying model changes. Otherwise, the source will
// sample the underlying model every interval milliseconds and add a new item
// with whatever value the model has at that point - even if it did not change.
Q_PROPERTY(int interval READ interval WRITE setInterval NOTIFY intervalChanged)
public:
explicit ModelHistorySource(QObject *parent = nullptr);
virtual int itemCount() const override;
virtual QVariant item(int index) const override;
virtual QVariant minimum() const override;
virtual QVariant maximum() const override;
int row() const;
void setRow(int row);
Q_SIGNAL void rowChanged();
int maximumHistory() const;
void setMaximumHistory(int maximumHistory);
Q_SIGNAL void maximumHistoryChanged();
int interval() const;
void setInterval(int newInterval);
Q_SIGNAL void intervalChanged();
Q_INVOKABLE void clear();
private:
void onModelChanged();
void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles);
int m_row;
int m_maximumHistory;
QVariantList m_history;
std::unique_ptr m_updateTimer;
};
#endif // MODELHISTORYSOURCE_H
diff --git a/src/datasource/ModelSource.cpp b/src/datasource/ModelSource.cpp
index e6c58e7..f1e7627 100644
--- a/src/datasource/ModelSource.cpp
+++ b/src/datasource/ModelSource.cpp
@@ -1,205 +1,191 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "ModelSource.h"
#include
ModelSource::ModelSource(QObject *parent)
: ChartDataSource(parent)
{
connect(this, &ModelSource::modelChanged, this, &ModelSource::dataChanged);
connect(this, &ModelSource::columnChanged, this, &ModelSource::dataChanged);
connect(this, &ModelSource::roleChanged, this, &ModelSource::dataChanged);
connect(this, &ModelSource::indexColumnsChanged, this, &ModelSource::dataChanged);
}
int ModelSource::role() const
{
if (m_role < 0 && !m_roleName.isEmpty())
m_role = m_model->roleNames().key(m_roleName.toLatin1(), -1);
return m_role;
}
QString ModelSource::roleName() const
{
return m_roleName;
}
int ModelSource::column() const
{
return m_column;
}
QAbstractItemModel *ModelSource::model() const
{
return m_model;
}
bool ModelSource::indexColumns() const
{
return m_indexColumns;
}
int ModelSource::itemCount() const
{
if (!m_model)
return 0;
return m_indexColumns ? m_model->columnCount() : m_model->rowCount();
}
QVariant ModelSource::item(int index) const
{
if (!m_model)
return QVariant{};
// For certain model (QML ListModel for example), the roleNames() are more
// dynamic and may only be valid when this method gets called. So try and
// lookup the role first before anything else.
if (m_role < 0 && !m_roleName.isEmpty())
m_role = m_model->roleNames().key(m_roleName.toLatin1(), -1);
if (m_role < 0) {
qWarning() << "ModelSource: Invalid role " << m_role << m_roleName;
return QVariant{};
}
if (!m_indexColumns && (m_column < 0 || m_column > m_model->columnCount())) {
qWarning() << "ModelSource: Invalid column" << m_column;
return QVariant{};
}
auto modelIndex = m_indexColumns ? m_model->index(0, index) : m_model->index(index, m_column);
if (modelIndex.isValid()) {
return m_model->data(modelIndex, m_role);
}
return QVariant{};
}
QVariant ModelSource::minimum() const
{
if (itemCount() <= 0)
return QVariant{};
auto minProperty = m_model->property("minimum");
auto maxProperty = m_model->property("maximum");
if (minProperty.isValid() && minProperty != maxProperty) {
return minProperty;
}
QVariant result = std::numeric_limits::max();
for (int i = 0; i < itemCount(); ++i) {
result = qMin(result, item(i));
}
return result;
}
QVariant ModelSource::maximum() const
{
if (itemCount() <= 0)
return QVariant{};
auto minProperty = m_model->property("minimum");
auto maxProperty = m_model->property("maximum");
if (maxProperty.isValid() && maxProperty != minProperty) {
return maxProperty;
}
QVariant result = std::numeric_limits::min();
for (int i = 0; i < itemCount(); ++i) {
result = qMax(result, item(i));
}
return result;
}
void ModelSource::setRole(int role)
{
if (role == m_role) {
return;
}
m_role = role;
if (m_model) {
m_roleName = QString::fromLatin1(m_model->roleNames().value(role));
Q_EMIT roleNameChanged();
}
Q_EMIT roleChanged();
}
void ModelSource::setRoleName(const QString &name)
{
if (name == m_roleName) {
return;
}
m_roleName = name;
if (m_model) {
m_role = m_model->roleNames().key(m_roleName.toLatin1(), -1);
Q_EMIT roleChanged();
}
Q_EMIT roleNameChanged();
}
void ModelSource::setColumn(int column)
{
if (column == m_column) {
return;
}
m_column = column;
Q_EMIT columnChanged();
}
void ModelSource::setIndexColumns(bool index)
{
if (index == m_indexColumns) {
return;
}
m_indexColumns = index;
Q_EMIT indexColumnsChanged();
}
void ModelSource::setModel(QAbstractItemModel *model)
{
if (m_model == model) {
return;
}
if (m_model) {
m_model->disconnect(this);
}
m_model = model;
if (m_model) {
connect(m_model, &QAbstractItemModel::rowsInserted, this, &ModelSource::dataChanged);
connect(m_model, &QAbstractItemModel::rowsRemoved, this, &ModelSource::dataChanged);
connect(m_model, &QAbstractItemModel::rowsMoved, this, &ModelSource::dataChanged);
connect(m_model, &QAbstractItemModel::modelReset, this, &ModelSource::dataChanged);
connect(m_model, &QAbstractItemModel::dataChanged, this, &ModelSource::dataChanged);
connect(m_model, &QAbstractItemModel::layoutChanged, this, &ModelSource::dataChanged);
}
Q_EMIT modelChanged();
}
diff --git a/src/datasource/ModelSource.h b/src/datasource/ModelSource.h
index bb35464..d5a2207 100644
--- a/src/datasource/ModelSource.h
+++ b/src/datasource/ModelSource.h
@@ -1,79 +1,65 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef MODELSOURCE_H
#define MODELSOURCE_H
#include "ChartDataSource.h"
#include
/**
* A data source that reads data from a QAbstractItemModel.
*
*
*/
class ModelSource : public ChartDataSource
{
Q_OBJECT
Q_PROPERTY(int role READ role WRITE setRole NOTIFY roleChanged)
Q_PROPERTY(QString roleName READ roleName WRITE setRoleName NOTIFY roleNameChanged)
Q_PROPERTY(int column READ column WRITE setColumn NOTIFY columnChanged)
Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelChanged)
Q_PROPERTY(bool indexColumns READ indexColumns WRITE setIndexColumns NOTIFY indexColumnsChanged)
public:
explicit ModelSource(QObject *parent = nullptr);
int role() const;
void setRole(int role);
Q_SIGNAL void roleChanged();
QString roleName() const;
void setRoleName(const QString &name);
Q_SIGNAL void roleNameChanged();
int column() const;
void setColumn(int column);
Q_SIGNAL void columnChanged();
QAbstractItemModel *model() const;
void setModel(QAbstractItemModel *model);
Q_SIGNAL void modelChanged();
bool indexColumns() const;
void setIndexColumns(bool index);
Q_SIGNAL void indexColumnsChanged();
virtual int itemCount() const override;
virtual QVariant item(int index) const override;
virtual QVariant minimum() const override;
virtual QVariant maximum() const override;
private:
mutable int m_role = -1;
QString m_roleName;
int m_column = 0;
bool m_indexColumns = false;
QAbstractItemModel *m_model = nullptr;
};
#endif // MODELSOURCE_H
diff --git a/src/datasource/SingleValueSource.cpp b/src/datasource/SingleValueSource.cpp
index 06e8ace..5808901 100644
--- a/src/datasource/SingleValueSource.cpp
+++ b/src/datasource/SingleValueSource.cpp
@@ -1,63 +1,49 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "SingleValueSource.h"
SingleValueSource::SingleValueSource(QObject *parent)
: ChartDataSource(parent)
{
}
QVariant SingleValueSource::item(int index) const
{
Q_UNUSED(index);
return m_value;
}
int SingleValueSource::itemCount() const
{
return 1;
}
QVariant SingleValueSource::minimum() const
{
return m_value;
}
QVariant SingleValueSource::maximum() const
{
return m_value;
}
QVariant SingleValueSource::value() const
{
return m_value;
}
void SingleValueSource::setValue(const QVariant &value)
{
if (m_value == value) {
return;
}
m_value = value;
Q_EMIT dataChanged();
}
diff --git a/src/datasource/SingleValueSource.h b/src/datasource/SingleValueSource.h
index 6107f7a..fa3fd95 100644
--- a/src/datasource/SingleValueSource.h
+++ b/src/datasource/SingleValueSource.h
@@ -1,52 +1,38 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see .
+ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef SINGLEVALUESOURCE_H
#define SINGLEVALUESOURCE_H
#include
#include "ChartDataSource.h"
/**
* A data source that provides a single value as data.
*/
class SingleValueSource : public ChartDataSource
{
Q_OBJECT
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY dataChanged)
public:
explicit SingleValueSource(QObject *parent = nullptr);
virtual int itemCount() const override;
virtual QVariant item(int index) const override;
QVariant minimum() const override;
QVariant maximum() const override;
QVariant value() const;
void setValue(const QVariant &value);
private:
QVariant m_value;
};
#endif // SINGLEVALUESOURCE_H
diff --git a/src/datasource/ValueHistorySource.cpp b/src/datasource/ValueHistorySource.cpp
index 92e366a..be6cc46 100644
--- a/src/datasource/ValueHistorySource.cpp
+++ b/src/datasource/ValueHistorySource.cpp
@@ -1,138 +1,124 @@
/*
* This file is part of KQuickCharts
- * Copyright 2019 Arjen Hiemstra
+ * SPDX-FileCopyrightText: 2019 Arjen Hiemstra
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see