From 4d4305c7edc19750f3ded7feaf18fbbd15acbf53 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Sat, 24 Jun 2023 18:59:24 +0000 Subject: [PATCH] NiceChart: New package with lightweight chart component. By Priyatna. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8847 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/nicechart/License.txt | 567 ++++++ components/nicechart/Readme.html | 213 +++ components/nicechart/demo/Delphi/Project1.dof | 143 ++ components/nicechart/demo/Delphi/Project1.dpr | 13 + .../nicechart/demo/Delphi/Project1.dproj | 152 ++ components/nicechart/demo/Delphi/Project1.res | Bin 0 -> 876 bytes .../nicechart/demo/Lazarus/Project1.lpi | 84 + .../nicechart/demo/Lazarus/Project1.lpr | 17 + components/nicechart/demo/common/Unit1.dfm | 55 + components/nicechart/demo/common/Unit1.lfm | 50 + components/nicechart/demo/common/Unit1.pas | 187 ++ components/nicechart/images/make_res.bat | 1 + components/nicechart/images/tnicechart.bmp | Bin 0 -> 406 bytes .../Delphi XE11 Alexandria/NiceChartDXE11.dpk | 40 + .../NiceChartDXE11.dproj | 131 ++ .../Delphi XE11 Alexandria/NiceChartDXE11.res | Bin 0 -> 676 bytes .../packages/Delphi7/NiceChartD7.dof | 142 ++ .../packages/Delphi7/NiceChartD7.dpk | 37 + .../packages/Delphi7/NiceChartD7.res | Bin 0 -> 1536 bytes .../packages/Lazarus/nicechartlaz.lpk | 43 + .../packages/Lazarus/nicechartlaz.pas | 22 + components/nicechart/source/BSplines.pas | 875 ++++++++++ components/nicechart/source/NiceChart.dcr | Bin 0 -> 476 bytes components/nicechart/source/NiceChart.pas | 1536 +++++++++++++++++ components/nicechart/source/NiceChart.res | Bin 0 -> 2008 bytes .../nicechart/source/nicechart_images.res | Bin 0 -> 476 bytes 26 files changed, 4308 insertions(+) create mode 100644 components/nicechart/License.txt create mode 100644 components/nicechart/Readme.html create mode 100644 components/nicechart/demo/Delphi/Project1.dof create mode 100644 components/nicechart/demo/Delphi/Project1.dpr create mode 100644 components/nicechart/demo/Delphi/Project1.dproj create mode 100644 components/nicechart/demo/Delphi/Project1.res create mode 100644 components/nicechart/demo/Lazarus/Project1.lpi create mode 100644 components/nicechart/demo/Lazarus/Project1.lpr create mode 100644 components/nicechart/demo/common/Unit1.dfm create mode 100644 components/nicechart/demo/common/Unit1.lfm create mode 100644 components/nicechart/demo/common/Unit1.pas create mode 100644 components/nicechart/images/make_res.bat create mode 100644 components/nicechart/images/tnicechart.bmp create mode 100644 components/nicechart/packages/Delphi XE11 Alexandria/NiceChartDXE11.dpk create mode 100644 components/nicechart/packages/Delphi XE11 Alexandria/NiceChartDXE11.dproj create mode 100644 components/nicechart/packages/Delphi XE11 Alexandria/NiceChartDXE11.res create mode 100644 components/nicechart/packages/Delphi7/NiceChartD7.dof create mode 100644 components/nicechart/packages/Delphi7/NiceChartD7.dpk create mode 100644 components/nicechart/packages/Delphi7/NiceChartD7.res create mode 100644 components/nicechart/packages/Lazarus/nicechartlaz.lpk create mode 100644 components/nicechart/packages/Lazarus/nicechartlaz.pas create mode 100644 components/nicechart/source/BSplines.pas create mode 100644 components/nicechart/source/NiceChart.dcr create mode 100644 components/nicechart/source/NiceChart.pas create mode 100644 components/nicechart/source/NiceChart.res create mode 100644 components/nicechart/source/nicechart_images.res diff --git a/components/nicechart/License.txt b/components/nicechart/License.txt new file mode 100644 index 000000000..18f8109b7 --- /dev/null +++ b/components/nicechart/License.txt @@ -0,0 +1,567 @@ + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + + ---------------------------------------------------------------------- + + AMENDMENTS + + The Netscape Public License Version 1.1 ("NPL") consists of the + Mozilla Public License Version 1.1 with the following Amendments, + including Exhibit A-Netscape Public License. Files identified with + "Exhibit A-Netscape Public License" are governed by the Netscape + Public License Version 1.1. + + Additional Terms applicable to the Netscape Public License. + I. Effect. + These additional terms described in this Netscape Public + License -- Amendments shall apply to the Mozilla Communicator + client code and to all Covered Code under this License. + + II. "Netscape's Branded Code" means Covered Code that Netscape + distributes and/or permits others to distribute under one or more + trademark(s) which are controlled by Netscape but which are not + licensed for use under this License. + + III. Netscape and logo. + This License does not grant any rights to use the trademarks + "Netscape", the "Netscape N and horizon" logo or the "Netscape + lighthouse" logo, "Netcenter", "Gecko", "Java" or "JavaScript", + "Smart Browsing" even if such marks are included in the Original + Code or Modifications. + + IV. Inability to Comply Due to Contractual Obligation. + Prior to licensing the Original Code under this License, Netscape + has licensed third party code for use in Netscape's Branded Code. + To the extent that Netscape is limited contractually from making + such third party code available under this License, Netscape may + choose to reintegrate such code into Covered Code without being + required to distribute such code in Source Code form, even if + such code would otherwise be considered "Modifications" under + this License. + + V. Use of Modifications and Covered Code by Initial Developer. + V.1. In General. + The obligations of Section 3 apply to Netscape, except to + the extent specified in this Amendment, Section V.2 and V.3. + + V.2. Other Products. + Netscape may include Covered Code in products other than the + Netscape's Branded Code which are released by Netscape + during the two (2) years following the release date of the + Original Code, without such additional products becoming + subject to the terms of this License, and may license such + additional products on different terms from those contained + in this License. + + V.3. Alternative Licensing. + Netscape may license the Source Code of Netscape's Branded + Code, including Modifications incorporated therein, without + such Netscape Branded Code becoming subject to the terms of + this License, and may license such Netscape Branded Code on + different terms from those contained in this License. + + VI. Litigation. + Notwithstanding the limitations of Section 11 above, the + provisions regarding litigation in Section 11(a), (b) and (c) of + the License shall apply to all disputes relating to this License. + + EXHIBIT A-Netscape Public License. + + "The contents of this file are subject to the Netscape Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/NPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The Original Code is Mozilla Communicator client code, released + March 31, 1998. + + The Initial Developer of the Original Code is Netscape + Communications Corporation. Portions created by Netscape are + Copyright (C) 1998-1999 Netscape Communications Corporation. All + Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the + terms of the _____ license (the "[___] License"), in which case + the provisions of [______] License are applicable instead of + those above. If you wish to allow use of your version of this + file only under the terms of the [____] License and not to allow + others to use your version of this file under the NPL, indicate + your decision by deleting the provisions above and replace them + with the notice and other provisions required by the [___] + License. If you do not delete the provisions above, a recipient + may use your version of this file under either the NPL or the + [___] License." diff --git a/components/nicechart/Readme.html b/components/nicechart/Readme.html new file mode 100644 index 000000000..4107ae058 --- /dev/null +++ b/components/nicechart/Readme.html @@ -0,0 +1,213 @@ + +NiceChart Component + + + +

NiceChart + v1.10
+ © 2008, Priyatna
+ Bandung - Indonesia

+

http://www.priyatna.org/
+ mailto:me@priyatna.org

+

Introduction
+ Version History
+ License
+ Installation
+ Methods

+ Properties
+ Contacts

+

Version: 1.10
+ Release Date: January 12, 2008

+

+

 

+ +
+

+

Introduction

+

Once I need a chart component that can shows interpolated lines for one of + my project. I don't need a sophisticated + full-featured chart, I just need a simple one with basic functionalities. Don't + find a way to do it with standard Delphi TChart component, I decided to write + my own.

+

Currently it has three graph styles: lines, smooth lines with B-Splines, and + bars. It has multilined title, legend, automatic y-axis, and supports multiple + series. It also can produce a monochrome version of the graph using monochromatic + brushes. Those features are sufficient for my programming needs.

+

I learned a lot from creating this component. I learned the algorithm to pick + axis value range that are aligned to zero from an arbitrary set of values. I + also learned some linear interpolation algoritms, although currently only B-splines + that is accomodated in this component. And finally I understand why there's + only a handful chart component out there.

+

 

+

+

+
+

+

Version History

+

Version 1.1 (January 12nd, 2008)
+ - bug fixed: title not centered
+ - bug fixed: empty series
+ - soft colors
+
+ Version 1.0 (May 26th, 2007)
+ Initial Release

+

 

+

+

+
+

 

+

License

+

This library is released under Mozilla Public License. You can use it in your + freeware, shareware or commercial softwares. You can send your modification + to me, and if I decide to include it in the main distribution, I will add your + name as a contributor. You can read full licensing information here. +

+

 

+ +
+

Installation

+

There is no special process to install it on Delphi. Just open NiceChartD7.dpk + on Delphi IDE and press Install button. I use Delphi 7. If you use another Delphi + version, you may have to make some minor changes.

+

The component will appear in priyatna.org tab.

+

 

+

+

+
+

Methods

+

There are some main methods of the component:

+ +

 

+

+

+
+

Properties

+

There are some main properties of the component:

+ +

 

+

+

+
+

Contacts

+

Don't hesitate to report any bug or whish to me:
+

+

Priyatna
+ Bandung - Indonesia

+

http://www.priyatna.org/
+ mailto:me@priyatna.org

+

 

+ diff --git a/components/nicechart/demo/Delphi/Project1.dof b/components/nicechart/demo/Delphi/Project1.dof new file mode 100644 index 000000000..f4335dc12 --- /dev/null +++ b/components/nicechart/demo/Delphi/Project1.dof @@ -0,0 +1,143 @@ +[FileVersion] +Version=7.0 +[Compiler] +A=8 +B=0 +C=1 +D=1 +E=0 +F=0 +G=1 +H=1 +I=1 +J=1 +K=0 +L=1 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=1 +W=0 +X=1 +Y=1 +Z=1 +ShowHints=1 +ShowWarnings=1 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +NamespacePrefix= +SymbolDeprecated=1 +SymbolLibrary=1 +SymbolPlatform=1 +UnitLibrary=1 +UnitPlatform=1 +UnitDeprecated=1 +HResultCompat=1 +HidingMember=1 +HiddenVirtual=1 +Garbage=1 +BoundsError=1 +ZeroNilCompat=1 +StringConstTruncated=1 +ForLoopVarVarPar=1 +TypedConstVarPar=1 +AsgToTypedConst=1 +CaseLabelRange=1 +ForVariable=1 +ConstructingAbstract=1 +ComparisonFalse=1 +ComparisonTrue=1 +ComparingSignedUnsigned=1 +CombiningSignedUnsigned=1 +UnsupportedConstruct=1 +FileOpen=1 +FileOpenUnitSrc=1 +BadGlobalSymbol=1 +DuplicateConstructorDestructor=1 +InvalidDirective=1 +PackageNoLink=1 +PackageThreadVar=1 +ImplicitImport=1 +HPPEMITIgnored=1 +NoRetVal=1 +UseBeforeDef=1 +ForLoopVarUndef=1 +UnitNameMismatch=1 +NoCFGFileFound=1 +MessageDirective=1 +ImplicitVariants=1 +UnicodeToLocale=1 +LocaleToUnicode=1 +ImagebaseMultiple=1 +SuspiciousTypecast=1 +PrivatePropAccessor=1 +UnsafeType=0 +UnsafeCode=0 +UnsafeCast=0 +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription= +[Directories] +OutputDir= +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath=..\..\source +Packages=Vcl50;Vclx50;VclSmp50;Vcldb50;vclado50;ibevnt50;Vclbde50;vcldbx50;Qrpt50;TeeUI50;TeeDB50;Tee50;Dss50;TeeQR50;VCLIB50;RNMap +Conditionals= +DebugSourceDirs= +UsePackages=0 +[Parameters] +RunParams= +HostApplication= +Launcher= +UseLauncher=0 +DebugCWD= +[Language] +ActiveLang= +ProjectLang= +RootDir=K:\Program Files\Borland\Delphi7\Bin\ +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1049 +CodePage=1251 +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= +[HistoryLists\hlUnitAliases] +Count=1 +Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[HistoryLists\hlSearchPath] +Count=2 +Item0=..\..\source +Item1=D:\My\Comps\Commons diff --git a/components/nicechart/demo/Delphi/Project1.dpr b/components/nicechart/demo/Delphi/Project1.dpr new file mode 100644 index 000000000..74baed530 --- /dev/null +++ b/components/nicechart/demo/Delphi/Project1.dpr @@ -0,0 +1,13 @@ +program Project1; + +uses + Forms, + Unit1 in '..\common\Unit1.pas' {Form1}; + +{$R *.res} + +begin + Application.Initialize; + Application.CreateForm(TForm1, Form1); + Application.Run; +end. diff --git a/components/nicechart/demo/Delphi/Project1.dproj b/components/nicechart/demo/Delphi/Project1.dproj new file mode 100644 index 000000000..e19d169ec --- /dev/null +++ b/components/nicechart/demo/Delphi/Project1.dproj @@ -0,0 +1,152 @@ + + + {534D51BE-D1B2-47D2-AD6E-AF9159060EBD} + Project1.dpr + True + Release + 1 + Application + VCL + 19.5 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + false + false + false + true + false + 00400000 + 1 + true + 1 + ..\..\source;$(DCC_UnitSearchPath) + Vcl50;Vclx50;VclSmp50;Vcldb50;vclado50;ibevnt50;Vclbde50;vcldbx50;Qrpt50;TeeUI50;TeeDB50;Tee50;Dss50;TeeQR50;VCLIB50;RNMap;$(DCC_UsePackage) + Project1 + Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + 1049 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) + 1033 + $(BDS)\bin\default_app.manifest + Project1_Icon.ico + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + + + Project1_Icon.ico + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + + + RELEASE;$(DCC_Define) + 0 + false + 0 + + + PerMonitorV2 + true + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) + + + DEBUG;$(DCC_Define) + false + true + + + PerMonitorV2 + true + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) + + + + MainSource + + +
Form1
+
+ + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + +
+ + Delphi.Personality.12 + + + + + Project1.dpr + + + Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver + Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server + Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclBaseExpert280.bpl nicht gefunden + Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclDebugExpert280.bpl nicht gefunden + Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclProjectAnalysisExpert280.bpl nicht gefunden + Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclFavoriteFoldersExpert280.bpl nicht gefunden + Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclRepositoryExpert280.bpl nicht gefunden + Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclSIMDViewExpert280.bpl nicht gefunden + Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclStackTraceViewerExpert280.bpl nicht gefunden + + + + True + False + + + 12 + + + +
diff --git a/components/nicechart/demo/Delphi/Project1.res b/components/nicechart/demo/Delphi/Project1.res new file mode 100644 index 0000000000000000000000000000000000000000..1e4099ba3d5b244035f1f4e2788cda692b773db3 GIT binary patch literal 876 zcmZuwv1;5v5PdocERb=|5U@KR!r18&p)wFV#5lM}{0|{mZ8(CqOJrO`pu)d$MonNE zrOIyv(zv|NftZZntfb2YGThV7+xKR6*}VmT8KK&P=|6Eh8TF8!z-!a#Ml_n9Fqsj@ zM1WzMHUEza;15;R5BxGEDs){(!8T!o_5;8Dz7$EeZ84?lBaxhut$18FHnHL`mT!-C zpss6?o4?!}GDIgQ!(1cn4WiSs945#!ye^81^4L4-rp+b?Wmy#OJx{1loGadyA6MKt zH&2TTUl7-ld0q|;MDktAqmGdu^nP%GUFTAlroJ9A7r1uw!*%}Uj`F@=54OOZ4Sz>H zw}v~1E`7QfIFDo}b#7k<9yjfDlBP%o19|49(ZGhr6B!J(*nuV@^1=If=roW6tsU=k z&$%w(uOpW>r%_nXEYDeJ+zJ}zBDJ*ENaSn7`(QK!U-XoBWO_1g$cV)PRiHYe3snuv z@Jg3k(B&pRFJm12G5~vq`!)PwP8=Ed_cHA1<<+%T`dz#GP`gio{&?|-(gqO{mqbT= pBYvvt-DB?J8KJs`H+YFNyd_@YoZ}el@4{X~fY~haufkqYfCrhd(P97q literal 0 HcmV?d00001 diff --git a/components/nicechart/demo/Lazarus/Project1.lpi b/components/nicechart/demo/Lazarus/Project1.lpi new file mode 100644 index 000000000..1856963d5 --- /dev/null +++ b/components/nicechart/demo/Lazarus/Project1.lpi @@ -0,0 +1,84 @@ + + + + + + + + + <Scaled Value="True"/> + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <XPManifest> + <DpiAware Value="True"/> + </XPManifest> + <Icon Value="0"/> + </General> + <BuildModes> + <Item Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <RequiredPackages> + <Item> + <PackageName Value="NiceChartLaz"/> + </Item> + <Item> + <PackageName Value="LCL"/> + </Item> + </RequiredPackages> + <Units> + <Unit> + <Filename Value="Project1.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + <Unit> + <Filename Value="..\common\Unit1.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="Form1"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="Project1"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value="..\common"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf3"/> + </Debugging> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/components/nicechart/demo/Lazarus/Project1.lpr b/components/nicechart/demo/Lazarus/Project1.lpr new file mode 100644 index 000000000..f7e8fe823 --- /dev/null +++ b/components/nicechart/demo/Lazarus/Project1.lpr @@ -0,0 +1,17 @@ +program Project1; + +{$MODE ObjFpc}{$H+} + +uses + Interfaces, + Forms, + Unit1 in '..\common\Unit1.pas' {Form1}; + +{$R *.res} + +begin + Application.Scaled:=True; + Application.Initialize; + Application.CreateForm(TForm1, Form1); + Application.Run; +end. diff --git a/components/nicechart/demo/common/Unit1.dfm b/components/nicechart/demo/common/Unit1.dfm new file mode 100644 index 000000000..f141c8040 --- /dev/null +++ b/components/nicechart/demo/common/Unit1.dfm @@ -0,0 +1,55 @@ +object Form1: TForm1 + Left = 169 + Top = 68 + Width = 778 + Height = 596 + Caption = 'NiceChart Demo - priyatna.org' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + Position = poDesktopCenter + OnCreate = FormCreate + OnDestroy = FormDestroy + PixelsPerInch = 96 + TextHeight = 13 + object Label1: TLabel + Left = 376 + Top = 15 + Width = 32 + Height = 13 + Caption = 'Label1' + end + object Button1: TButton + Left = 8 + Top = 9 + Width = 105 + Height = 25 + Caption = 'Monochrome' + TabOrder = 0 + OnClick = Button1Click + end + object Button2: TButton + Left = 120 + Top = 9 + Width = 105 + Height = 25 + Caption = 'Save to WMF' + TabOrder = 1 + OnClick = Button2Click + end + object CheckBox1: TCheckBox + Left = 240 + Top = 12 + Width = 96 + Height = 19 + Caption = 'Thick axis lines' + Checked = True + State = cbChecked + TabOrder = 2 + OnClick = CheckBox1Click + end +end diff --git a/components/nicechart/demo/common/Unit1.lfm b/components/nicechart/demo/common/Unit1.lfm new file mode 100644 index 000000000..09ffb7190 --- /dev/null +++ b/components/nicechart/demo/common/Unit1.lfm @@ -0,0 +1,50 @@ +object Form1: TForm1 + Left = 194 + Height = 596 + Top = 111 + Width = 778 + Caption = 'NiceChart Demo - priyatna.org' + ClientHeight = 596 + ClientWidth = 778 + Color = clBtnFace + OnCreate = FormCreate + OnDestroy = FormDestroy + Position = poDesktopCenter + LCLVersion = '2.3.0.0' + object Label1: TLabel + Left = 352 + Height = 15 + Top = 14 + Width = 34 + Caption = 'Label1' + end + object Button1: TButton + Left = 8 + Height = 25 + Top = 9 + Width = 105 + Caption = 'Monochrome' + OnClick = Button1Click + TabOrder = 0 + end + object Button2: TButton + Left = 120 + Height = 25 + Top = 9 + Width = 105 + Caption = 'Save to WMF' + OnClick = Button2Click + TabOrder = 1 + end + object CheckBox1: TCheckBox + Left = 240 + Height = 19 + Top = 12 + Width = 96 + Caption = 'Thick axis lines' + Checked = True + OnClick = CheckBox1Click + State = cbChecked + TabOrder = 2 + end +end diff --git a/components/nicechart/demo/common/Unit1.pas b/components/nicechart/demo/common/Unit1.pas new file mode 100644 index 000000000..95823210c --- /dev/null +++ b/components/nicechart/demo/common/Unit1.pas @@ -0,0 +1,187 @@ +unit Unit1; + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +interface + +uses + SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, + {$IFNDEF FPC}XPMan,{$ENDIF} + NiceChart; + +type + + { TForm1 } + + TForm1 = class(TForm) + CheckBox1: TCheckBox; + Label1: TLabel; + Button1: TButton; + Button2: TButton; + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); + procedure CheckBox1Click(Sender: TObject); + private + { Private declarations } + procedure ChartMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); + public + { Public declarations } + Chart: TNiceChart; + end; + +var + Form1: TForm1; + +implementation + +{$IFDEF FPC} + {$R *.lfm} +{$ELSE} + {$R *.dfm} +{$ENDIF} + +uses + Math; + +procedure TForm1.ChartMouseMove(Sender: TObject; Shift: TShiftState; + X, Y: Integer); +var + ax, ay: Double; +begin + if Chart.ClientToChart(X, Y, ax, ay) + then Label1.Caption := FormatFloat('Mouse position: 0.##', ax) + '; ' + FormatFloat('0.##', ay / 1000) + else Label1.Caption := 'Out of Chart'; +end; + +procedure TForm1.FormCreate(Sender: TObject); +var + Series: TNiceSeries; +begin + Chart := TNiceChart.Create(Self); + with Chart do + begin + Parent := Self; + Left := 8; + Top := 40; + Width := Self.ClientWidth - 16; + Height := Self.ClientHeight - 48; + Anchors := [akLeft, akTop, akRight, akBottom]; + Title := 'Look at me!'#13'I''m a NiceChart!'; + AxisXOnePerValue := True; + ShowXGrid := False; + AxisYScale := 1000; + //Monochrome := True; + OnMouseMove := ChartMouseMove; + end; + Chart.BeginUpdate; + Series := Chart.AddSeries(skBar); + Series.Caption := 'Revenue'; + with Series do + begin + AddXY( 0, 0); + AddXY(2000, 4904620); + AddXY(2001, 15086420); + AddXY(2002, 14696560); + AddXY(2003, 14263160); + AddXY(2004, 13711080); + AddXY(2005, 13018880); + AddXY(2006, 11901080); + AddXY(2007, 10592340); + AddXY(2008, 9750620); + AddXY(2009, 9007960); + AddXY(2010, 7980940); + AddXY(2011, 6164060); + AddXY(2012, 4182760); + AddXY(2013, 3026420); + AddXY(2014, 1907200); + end; + Series := Chart.AddSeries(skBar); + Series.Caption := 'Cash Flow'; + with Series do + begin + AddXY( 0, -9435276); + AddXY(2000, -12884809.79); + AddXY(2001, 11849628.6); + AddXY(2002, 8676685.24); + AddXY(2003, 3856984.44); + AddXY(2004, 3811447.44); + AddXY(2005, 686684.1); + AddXY(2006, 377060.42); + AddXY(2007, 831488.06); + AddXY(2008, 1517731.99); + AddXY(2009, 1431460.27); + AddXY(2010, 1158463.54); + AddXY(2011, 737914.59); + AddXY(2012, 386103.52); + AddXY(2013, 249675.86); + AddXY(2014, 119973); + end; + Series := Chart.AddSeries(skSmooth); + Series.Caption := 'Cum. Cash Flow'; + with Series do + begin + AddXY( 0, -9435276); + AddXY(2000, -22320085.79); + AddXY(2001, -10470457.19); + AddXY(2002, -1793771.95); + AddXY(2003, 2063212.49); + AddXY(2004, 5874659.93); + AddXY(2005, 6561344.03); + AddXY(2006, 6938404.46); + AddXY(2007, 7769892.52); + AddXY(2008, 9287624.51); + AddXY(2009, 10719084.78); + AddXY(2010, 11877548.32); + AddXY(2011, 12615462.91); + AddXY(2012, 13001566.43); + AddXY(2013, 13251242.29); + AddXY(2014, 13371215.29); + end; + Chart.EndUpdate; + + Label1.Caption := ''; +end; + +procedure TForm1.CheckBox1Click(Sender: TObject); +begin + if Checkbox1.Checked then + Chart.AxisLineWidth := 3 + else + Chart.AxisLineWidth := 1; +end; + +procedure TForm1.FormDestroy(Sender: TObject); +begin + Chart.Free; +end; + +procedure TForm1.Button1Click(Sender: TObject); +begin + Chart.Monochrome := not Chart.Monochrome; + if Chart.Monochrome + then Button1.Caption := 'Color' + else Button1.Caption := 'Monochrome'; +end; + +procedure TForm1.Button2Click(Sender: TObject); +{$IFNDEF FPC} +var + m: TMetafile; +{$ENDIF} +begin + {$IFDEF FPC} + ShowMessage('Function not implemented for Lazarus.'); + {$ELSE} + m := Chart.CreateMetafile; + m.Enhanced := True; + m.SaveToFile('test.emf'); + m.Free; + ShowMessage('Saved to "test.wmf".'); + {$ENDIF} +end; + +end. diff --git a/components/nicechart/images/make_res.bat b/components/nicechart/images/make_res.bat new file mode 100644 index 000000000..b75363f95 --- /dev/null +++ b/components/nicechart/images/make_res.bat @@ -0,0 +1 @@ +lazres ../source/nicechart_images.res tnicechart.bmp \ No newline at end of file diff --git a/components/nicechart/images/tnicechart.bmp b/components/nicechart/images/tnicechart.bmp new file mode 100644 index 0000000000000000000000000000000000000000..17655a1d58184ad8450d2c845433d026321c4526 GIT binary patch literal 406 zcmZ{gF$%&!5Jfj&BM7myv{Vps2Yat$og;{a5SxYVTmoKUv0N5%g4`kPE`jmSm@HUi zvh(NV&rcvZUmk^$x<U`=-PDCziNBxre6tm2mRczsRoA}(1uEwpCND^iB4R@0VhhqQ z6k@r`WXM*@jJ_IX?%K>P*)aPb1l`7Sel*b{GX}6Xx{-YFr}QGLCEs@GPWCvg<^7Q# tx|L51VnH4jMP3r}4Uq;Dv(b?<N1geN_2h%VYz(Ea$RFnq1T6f9{tKS|;XnWY literal 0 HcmV?d00001 diff --git a/components/nicechart/packages/Delphi XE11 Alexandria/NiceChartDXE11.dpk b/components/nicechart/packages/Delphi XE11 Alexandria/NiceChartDXE11.dpk new file mode 100644 index 000000000..163dae671 --- /dev/null +++ b/components/nicechart/packages/Delphi XE11 Alexandria/NiceChartDXE11.dpk @@ -0,0 +1,40 @@ +package NiceChartDXE11; + +{$R *.res} +{$R 'NiceChart.dcr'} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO ON} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS ON} +{$RANGECHECKS ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'priyatna.org - NiceChart'} +{$IMPLICITBUILD OFF} + +requires + rtl, + vcl; + +contains + NiceChart in '..\..\source\NiceChart.pas', + BSplines in '..\..\source\BSplines.pas'; + +end. diff --git a/components/nicechart/packages/Delphi XE11 Alexandria/NiceChartDXE11.dproj b/components/nicechart/packages/Delphi XE11 Alexandria/NiceChartDXE11.dproj new file mode 100644 index 000000000..fd316713e --- /dev/null +++ b/components/nicechart/packages/Delphi XE11 Alexandria/NiceChartDXE11.dproj @@ -0,0 +1,131 @@ +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <ProjectGuid>{8BDB7828-1E5C-4C35-85C7-CFD562CFCF75}</ProjectGuid> + <MainSource>NiceChartDXE11.dpk</MainSource> + <Base>True</Base> + <Config Condition="'$(Config)'==''">Debug</Config> + <TargetedPlatforms>1</TargetedPlatforms> + <AppType>Package</AppType> + <FrameworkType>VCL</FrameworkType> + <ProjectVersion>19.5</ProjectVersion> + <Platform Condition="'$(Platform)'==''">Win32</Platform> + </PropertyGroup> + <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''"> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''"> + <Base_Win32>true</Base_Win32> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''"> + <Cfg_1>true</Cfg_1> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''"> + <Cfg_2>true</Cfg_2> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''"> + <Cfg_2_Win32>true</Cfg_2_Win32> + <CfgParent>Cfg_2</CfgParent> + <Cfg_2>true</Cfg_2> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="'$(Base)'!=''"> + <DCC_E>false</DCC_E> + <DCC_F>false</DCC_F> + <DCC_K>false</DCC_K> + <DCC_N>false</DCC_N> + <DCC_S>false</DCC_S> + <DCC_ImageBase>00400000</DCC_ImageBase> + <GenDll>true</GenDll> + <GenPackage>true</GenPackage> + <SanitizedProjectName>NiceChartDXE11</SanitizedProjectName> + <DCC_DebugInformation>1</DCC_DebugInformation> + <DCC_Description>priyatna.org - NiceChart</DCC_Description> + <DCC_OutputNeverBuildDcps>true</DCC_OutputNeverBuildDcps> + <DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;DUnitX.Loggers.GUI;Winapi;$(DCC_Namespace)</DCC_Namespace> + <VerInfo_Locale>1031</VerInfo_Locale> + <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=</VerInfo_Keys> + <DCC_UnitSearchPath>..\..\source;$(DCC_UnitSearchPath)</DCC_UnitSearchPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_Win32)'!=''"> + <DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace> + <BT_BuildType>Debug</BT_BuildType> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys> + <VerInfo_Locale>1033</VerInfo_Locale> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_1)'!=''"> + <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define> + <DCC_DebugInformation>0</DCC_DebugInformation> + <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols> + <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_2)'!=''"> + <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define> + <DCC_Optimize>false</DCC_Optimize> + <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames> + <DCC_RangeChecking>true</DCC_RangeChecking> + <DCC_IntegerOverflowCheck>true</DCC_IntegerOverflowCheck> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''"> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + <VerInfo_Locale>1033</VerInfo_Locale> + <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=2.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys> + <VerInfo_MajorVer>2</VerInfo_MajorVer> + </PropertyGroup> + <ItemGroup> + <DelphiCompile Include="$(MainSource)"> + <MainSource>MainSource</MainSource> + </DelphiCompile> + <DCCReference Include="NiceChart.dcr"/> + <DCCReference Include="rtl.dcp"/> + <DCCReference Include="vcl.dcp"/> + <DCCReference Include="..\..\source\NiceChart.pas"/> + <DCCReference Include="..\..\source\BSplines.pas"/> + <BuildConfiguration Include="Base"> + <Key>Base</Key> + </BuildConfiguration> + <BuildConfiguration Include="Release"> + <Key>Cfg_1</Key> + <CfgParent>Base</CfgParent> + </BuildConfiguration> + <BuildConfiguration Include="Debug"> + <Key>Cfg_2</Key> + <CfgParent>Base</CfgParent> + </BuildConfiguration> + </ItemGroup> + <ProjectExtensions> + <Borland.Personality>Delphi.Personality.12</Borland.Personality> + <Borland.ProjectType>Package</Borland.ProjectType> + <BorlandProject> + <Delphi.Personality> + <Source> + <Source Name="MainSource">NiceChartDXE11.dpk</Source> + </Source> + <Excluded_Packages> + <Excluded_Packages Name="$(BDSBIN)\dcloffice2k280.bpl">Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver</Excluded_Packages> + <Excluded_Packages Name="$(BDSBIN)\dclofficexp280.bpl">Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server</Excluded_Packages> + <Excluded_Packages Name="C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclBaseExpert280.bpl">Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclBaseExpert280.bpl nicht gefunden</Excluded_Packages> + <Excluded_Packages Name="C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclDebugExpert280.bpl">Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclDebugExpert280.bpl nicht gefunden</Excluded_Packages> + <Excluded_Packages Name="C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclProjectAnalysisExpert280.bpl">Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclProjectAnalysisExpert280.bpl nicht gefunden</Excluded_Packages> + <Excluded_Packages Name="C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclFavoriteFoldersExpert280.bpl">Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclFavoriteFoldersExpert280.bpl nicht gefunden</Excluded_Packages> + <Excluded_Packages Name="C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclRepositoryExpert280.bpl">Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclRepositoryExpert280.bpl nicht gefunden</Excluded_Packages> + <Excluded_Packages Name="C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclSIMDViewExpert280.bpl">Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclSIMDViewExpert280.bpl nicht gefunden</Excluded_Packages> + <Excluded_Packages Name="C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclStackTraceViewerExpert280.bpl">Datei C:\Users\Werner-3\Documents\Embarcadero\Studio\22.0\Bpl\Win32\JclStackTraceViewerExpert280.bpl nicht gefunden</Excluded_Packages> + </Excluded_Packages> + </Delphi.Personality> + <Platforms> + <Platform value="Win32">True</Platform> + <Platform value="Win64">False</Platform> + </Platforms> + </BorlandProject> + <ProjectFileVersion>12</ProjectFileVersion> + </ProjectExtensions> + <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/> + <Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/> +</Project> diff --git a/components/nicechart/packages/Delphi XE11 Alexandria/NiceChartDXE11.res b/components/nicechart/packages/Delphi XE11 Alexandria/NiceChartDXE11.res new file mode 100644 index 0000000000000000000000000000000000000000..f2bbbba9ed09c2b1bb86b4f0e600bbbe977d1cfc GIT binary patch literal 676 zcmaiy!A`<J5QhJf9>j~jfgXA`#q?rgG(^OZC>kWhc+g-$Yy!n#eF5LgxAE>9Sijj) zDPEXncBi}l{QvCiO42@_=Y<olSx_tYcfojWFI3$xK|w7d9Ozb$jOXeRb#$#R{~g9Q zvDv5p{UcdEgw6`C)8(HL7AwmIrVkc8_%bb&DAfeEL{p7nPW7xgm<NXm6)Dsa9#Ml; z)YcBUCB8+@n_|cF3SUBQ>V&$)F}r7a(UAR2E#1M<;4=%gRpA+cT)?!-Khy!3(xnrp zdjo2&k>26X=)zDlGR-#WMNV%$|G#SEPtSCvd+kwUkuyQr)H<BQET)bb_%Y*?J7LT? za_5+{zNsE#@wi#*P1(&=_oYB~bA6|p(wQm9YJcngmv1+IjOY0_RbHwI-rhw|S42(b P3p(ECrVFdSFMAWe&8u2J literal 0 HcmV?d00001 diff --git a/components/nicechart/packages/Delphi7/NiceChartD7.dof b/components/nicechart/packages/Delphi7/NiceChartD7.dof new file mode 100644 index 000000000..9d521a0fd --- /dev/null +++ b/components/nicechart/packages/Delphi7/NiceChartD7.dof @@ -0,0 +1,142 @@ +[FileVersion] +Version=7.0 +[Compiler] +A=8 +B=0 +C=1 +D=1 +E=0 +F=0 +G=1 +H=1 +I=1 +J=0 +K=0 +L=1 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=1 +W=0 +X=1 +Y=1 +Z=1 +ShowHints=1 +ShowWarnings=1 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +NamespacePrefix= +SymbolDeprecated=1 +SymbolLibrary=1 +SymbolPlatform=1 +UnitLibrary=1 +UnitPlatform=1 +UnitDeprecated=1 +HResultCompat=1 +HidingMember=1 +HiddenVirtual=1 +Garbage=1 +BoundsError=1 +ZeroNilCompat=1 +StringConstTruncated=1 +ForLoopVarVarPar=1 +TypedConstVarPar=1 +AsgToTypedConst=1 +CaseLabelRange=1 +ForVariable=1 +ConstructingAbstract=1 +ComparisonFalse=1 +ComparisonTrue=1 +ComparingSignedUnsigned=1 +CombiningSignedUnsigned=1 +UnsupportedConstruct=1 +FileOpen=1 +FileOpenUnitSrc=1 +BadGlobalSymbol=1 +DuplicateConstructorDestructor=1 +InvalidDirective=1 +PackageNoLink=1 +PackageThreadVar=1 +ImplicitImport=1 +HPPEMITIgnored=1 +NoRetVal=1 +UseBeforeDef=1 +ForLoopVarUndef=1 +UnitNameMismatch=1 +NoCFGFileFound=1 +MessageDirective=1 +ImplicitVariants=1 +UnicodeToLocale=1 +LocaleToUnicode=1 +ImagebaseMultiple=1 +SuspiciousTypecast=1 +PrivatePropAccessor=1 +UnsafeType=0 +UnsafeCode=0 +UnsafeCast=0 +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription=priyatna.org - NiceChart +[Directories] +OutputDir= +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath=..\..\source +Packages=vcl;rtl;vclx;vclie;xmlrtl;inetdbbde;inet;inetdbxpress;dbrtl;soaprtl;dsnap;VclSmp;dbexpress;vcldb;dbxcds;inetdb;bdertl;vcldbx;adortl;teeui;teedb;tee;ibxpress;vclactnband;SynEdit_D7;XLSPkg;NiceUI_D7;visualclx;visualdbclx;NicePreviewD6 +Conditionals= +DebugSourceDirs= +UsePackages=0 +[Parameters] +RunParams= +HostApplication= +Launcher= +UseLauncher=0 +DebugCWD= +[Language] +ActiveLang= +ProjectLang= +RootDir=C:\PROGRAM FILES\BORLAND\DELPHI7\BIN\ +[Version Info] +IncludeVerInfo=1 +AutoIncBuild=0 +MajorVer=2 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1033 +CodePage=1252 +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=2.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= +[HistoryLists\hlUnitAliases] +Count=1 +Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[HistoryLists\hlSearchPath] +Count=1 +Item0=..\..\source diff --git a/components/nicechart/packages/Delphi7/NiceChartD7.dpk b/components/nicechart/packages/Delphi7/NiceChartD7.dpk new file mode 100644 index 000000000..2d66d4329 --- /dev/null +++ b/components/nicechart/packages/Delphi7/NiceChartD7.dpk @@ -0,0 +1,37 @@ +package NiceChartD7; + +{$R *.res} +{$R 'NiceChart.dcr'} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO ON} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'priyatna.org - NiceChart'} +{$IMPLICITBUILD OFF} + +requires + rtl, + vcl; + +contains + NiceChart in '..\..\source\NiceChart.pas', + BSplines in '..\..\source\BSplines.pas'; + +end. diff --git a/components/nicechart/packages/Delphi7/NiceChartD7.res b/components/nicechart/packages/Delphi7/NiceChartD7.res new file mode 100644 index 0000000000000000000000000000000000000000..da0b2e57d03a6fb5f64ca5eb06d8ab746cf43da5 GIT binary patch literal 1536 zcmZuw&ubGw6#mjIBqdUF@Z_aIM8tzcTd-bi#aJw;6)U}#Vw-NUCZ$GJS+HADmH`j` zCsN2|VG!cUyMKY82XE$P!Q%M6nVlppKJx9Gx9@vDHv<4Q!Wai0Psz^-?=O;5u)b<_ zGVr9UJk*E<qJaE0W4u)T!RiFy4@u$_pFE=9?^BCInh<52;?wnIQ0dNy4AWJ#qIBzI zTPa1cno(+KgHH0j8;GJv>)yx~!kj|TXyor=-RmJ(Ow;^Dtg|j2gkdvXu#70qy5(k? zhT(>_EA*F@qW>_rdtJ7aHp8Y3C`H=YX`Vo9bxWzH_ru$%<AVk0PgR)nODwQ21(eMP zvELlCz=o{{DUdSZpF?L$!nshXc9z>*$s7rXI>`g#tj>;6$q6M+WIdk1gtXOrof9H0 z3$19K6S#B|XagBXB~fhFO<+HV(wVY$2HoTK87MXbl9*?$BbQn0Eavy1#I};wN6zFo zBA)^B9Frp?1!Fw=MPmemV%H3&U<T)~KPY4VSO825PR8(;XJTGp9Hz}d_k&5y7t=o} zn*O_j`F7_#T_vJO91wltGx6OR^ZNq3kw2F)Q+R~CSi)oC9+s)SjNc2n4F%L{fxQ)S ziwfur?^5-@cd0Wm%T%ja!5W|U@sy_}TVc)CTjW{fQ}BzU$X)ao&FOjT1p;dEj>}j3 zVg()SVH+)MVUc<Vo6Ouo6K#?|T239aob)y^%O0eoOUzc_tZlr+F4oC^%c<9CZ4OIZ zvmBqZLC-5Zx3zXzbDOcPA-9e)*`B*f?jG4A&P`lrbq`-(`s`S4i?w&oba2Jie@Oq9 z^-8z9>{F)QLdZxbuFnzg85!%?VBAaUJ-lEiUL1Eh&mmiry1s9*MjLQDdO~iS*<N$@ z&Y2FuUCP|2IcKN8F`QfG2QJ#V-0r2C?7(-}u#K+TzI|7tuL)eX{{%N-i%~mdj(>~E H;79Ner(Q*{ literal 0 HcmV?d00001 diff --git a/components/nicechart/packages/Lazarus/nicechartlaz.lpk b/components/nicechart/packages/Lazarus/nicechartlaz.lpk new file mode 100644 index 000000000..be086bd99 --- /dev/null +++ b/components/nicechart/packages/Lazarus/nicechartlaz.lpk @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <Package Version="5"> + <PathDelim Value="\"/> + <Name Value="NiceChartLaz"/> + <Type Value="RunAndDesignTime"/> + <Author Value="Priyatna"/> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <SearchPaths> + <OtherUnitFiles Value="..\..\source"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)\"/> + </SearchPaths> + </CompilerOptions> + <Description Value="Light-weight chart component with basic functionality (bar series, line series, smooth spline series)"/> + <License Value="MPL"/> + <Version Major="2"/> + <Files> + <Item> + <Filename Value="..\..\source\BSplines.pas"/> + <UnitName Value="BSplines"/> + </Item> + <Item> + <Filename Value="..\..\source\NiceChart.pas"/> + <HasRegisterProc Value="True"/> + <UnitName Value="NiceChart"/> + </Item> + </Files> + <RequiredPkgs> + <Item> + <PackageName Value="LCL"/> + </Item> + </RequiredPkgs> + <UsageOptions> + <UnitPath Value="$(PkgOutDir)"/> + </UsageOptions> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + </Package> +</CONFIG> diff --git a/components/nicechart/packages/Lazarus/nicechartlaz.pas b/components/nicechart/packages/Lazarus/nicechartlaz.pas new file mode 100644 index 000000000..7507c4de3 --- /dev/null +++ b/components/nicechart/packages/Lazarus/nicechartlaz.pas @@ -0,0 +1,22 @@ +{ This file was automatically created by Lazarus. Do not edit! + This source is only used to compile and install the package. + } + +unit NiceChartLaz; + +{$warn 5023 off : no warning about unused units} +interface + +uses + BSplines, NiceChart, LazarusPackageIntf; + +implementation + +procedure Register; +begin + RegisterUnit('NiceChart', @NiceChart.Register); +end; + +initialization + RegisterPackage('NiceChartLaz', @Register); +end. diff --git a/components/nicechart/source/BSplines.pas b/components/nicechart/source/BSplines.pas new file mode 100644 index 000000000..e321079d7 --- /dev/null +++ b/components/nicechart/source/BSplines.pas @@ -0,0 +1,875 @@ +Unit BSplines; +{------------------------------------------------------------------------------} +{ } +{ This code was written by : M. v. Engeland } +{ } +{ This code is copyright 2000 by } +{ M. v. Engeland } +{ } +{ } +{ This is the followup of the B-splines component posted in 1997. } +{ Some bugs were fixed, and some changes were made. The splines now use } +{ dynamic allocation of memory when needed when adding points to the spline. } +{ If the number of points to be added is known in advance, the the precise } +{ amount of memory can be allocated setting the capacity property. } +{ } +{ The conditions for using this component however are not changed: } +{ You may use this component in any way you want to, whether it is for } +{ commercial purposes or not, as long as you don't hold me responsible for } +{ any disasters it may cause. But I would appreciate it if you would send me } +{ an e-mail (martijn@dutw38.wbmt.tudelft.nl) to tell me what you use it for } +{ because over the last three years I've learned that it has been used for } +{ a wide variaty of interesting applications which it was initially never } +{ intended for. Besides, it's nice to know how your offspring's doing. } +{ Also all comments and/or remarks are welcome. } +{ } +{ See the demo program for how to use the component. } +{ Special attention is payed on the possibility of interpolating the } +{ vertices. As you may or may not know, B-Splines normally do not } +{ interpolate the used controlpoints. Thanks to simple matrix calculation } +{ however it is possible to interpolate the controlpoints by calculating } +{ new vertices in such a way that the spline interpolates the original ones. } +{------------------------------------------------------------------------------} + +{$IFDEF FPC} + {$MODE ObjFPC}{$H+} +{$ENDIF} + +interface + +uses windows, + sysutils, + classes, + Graphics, + dialogs, + Math; + +const MaxFragments = 600; // The maximum of straight line segments allowed for drawing the spline + MaxResults = MaxFragments+10; // Max. number of calculated intersections + MaxInterpolatedVertices = 250; // The maximum number of vertices that can be interpolated, up to 16000 allowed + MaxCalcSteps = 150; // Number of steps for numerical intersection calculating + MaxError = 1e-5;// Max error for intersection calculating + MaxIterations = 80; + VerticesIncrement = 25; // Number of vertices to allocate memory for when the count property exceeds the current capacity + +type TDataType = single; + TVertex = record + X,Y : TDataType; + end; + // The following dynamic array is used to store the desired user-specified controlpoints + T2DPointList = array[1..1] of TVertex; + P2DPointList = ^T2DPointList; + + // The vertexlist is used internally to make the spline interpolate the controlpoints + TVertexList = array[0..0] of TVertex; + P2DVertexList = ^TVertexList; + + // The knuckle list stores a flag to see whether a point is a knuckle or not + TKnuckleList = array[1..1] of Boolean; + PKnuckleList = ^TKnuckleList; + + // T2DResults is a record with calculatedvalues at a specific point when for ex. the x-value is known + T2DResults = record + NumberOfHits : integer; + Parameter : array[1..MaxResults] of TDataType; + Point : array[1..MaxResults] of TVertex; + end; + + // 2D B-spline class: + TBSpline = class // 2D B-Spline object + private + FColor : TColor; + FNoPoints : Integer; + FCapacity : Integer; + FPointList : P2DPointList; + FVertexList : P2DVertexList; + FKnuckleList : PKnuckleList; + FBuild : Boolean; + FNoVertices : Integer; + FInterpolated : boolean; + FMin,FMax : TVertex; + FFragments : Integer; + FShowVertices : Boolean; + procedure FSetBuild(val:boolean); + procedure FSetCapacity(Val:Integer); virtual; + procedure FSetInterpolated(const value:boolean); + procedure FSetFragments(Const value:integer); + function FGetNumberOfPoints:integer; + function FGetPoint(Index:Integer):TVertex; virtual; + procedure FSetPoint(Index:Integer;Value:TVertex); virtual; + function FGetVertex(Index:Integer):TVertex; virtual; + procedure FSetVertex(Index:Integer;Value:TVertex); virtual; + function FGetKnuckle(Index:integer):Boolean; virtual; + procedure FSetKnuckle(Index:integer;Value:Boolean); virtual; + function FGetNumberOfVertices:integer; + procedure FInterpolate; virtual; + procedure FFillMatrix; virtual; + procedure FPhantomPoints; + public + procedure AddPoint(Vertex:TVertex); virtual; + procedure Extents(Var Min,Max : TVertex); virtual; + procedure Clear; virtual; + constructor Create; + destructor Destroy; override; + procedure Draw(Canvas:TCanvas); + procedure DeletePoint(Index:Integer); + function FirstDerive(Parameter:extended):TVertex; virtual; + procedure InsertPoint(Index:Integer;Vertex:TVertex); + procedure Invert;// Inverse the controlpoints, eg the last point first and vice versa + function SecondDerive(Parameter:extended):TVertex; virtual;// second derivative in a point + function KnownX(XValue:TDataType;var Results:T2DResults):Boolean;virtual; + function KnownY(YValue:TDataType;var Results:T2DResults):Boolean;virtual; + function Value(Parameter:extended):TVertex; virtual; + procedure Rebuild; virtual; + property Build : Boolean read FBuild write FSetBuild; + property NumberOfPoints : Integer read FGetNumberOfPoints; + property Capacity : Integer read FCapacity write FSetCapacity; + property Fragments : integer read FFragments write FSetFragments; + property Interpolated : Boolean read FInterpolated write FSetInterpolated; + property NumberOfVertices : Integer read FGetNumberOfVertices; + property Point [Index:Integer] : TVertex read FGetPoint write FSetPoint; + property Vertex[Index:Integer] : TVertex read FGetVertex write FSetVertex; + property Knuckle[Index:integer] : Boolean read FGetKnuckle write FSetKnuckle; + property Min : TVertex read FMin; + property Max : TVertex read FMax; + property ShowVertices : boolean read FShowVertices write FShowVertices; + property Color : TColor read FColor write FColor; + end; + +implementation + +// The following tpes are used for the interpolation routines +Type TMatrixRow = Array[1..1] of TDataType; + PMatrixRow = ^TMatrixRow; + TMatrix = array[1..MaxInterpolatedVertices] of PMatrixRow; + +var Matrix : TMatrix; + + +function DistPP2D(P1,P2:TVertex):TDataType; +begin + Result:=Sqrt(Sqr(P2.X-P1.X)+Sqr(P2.Y-P1.Y)); +end;{DistPP2D} + +{--------------------------------------------------------------------------------------------------} +{ TBSpline } +{--------------------------------------------------------------------------------------------------} +procedure TBSpline.FSetBuild(val:boolean); +begin + if not val then + begin + // Release allocated memory for vertices + if (FVertexList<>nil) and (FBuild) then Freemem(FVertexList,(FNoVertices+2)*SizeOf(TVertex)); + FNoVertices:=0; + FVertexList:=nil; + // Clear extents + FMin.X:=0; + FMin.Y:=0; + FMax.X:=1; + FMax.Y:=1; + end; + FBuild:=Val; +end;{TBSpline.FSetBuild} + +procedure TBSpline.FSetCapacity(Val:Integer); +var CurrentSize : Word; + NewSize : Word; + OldPoints : P2DPointList; + OldKnuckle : PKnuckleList; +begin + if Val<>FCapacity then + begin + CurrentSize:=Capacity*SizeOf(TVertex); + NewSize:=Val*SizeOf(TVertex); + OldPoints:=FPointList; + FPointList:=nil; + OldKnuckle:=FKnuckleList; + FKnuckleList:=Nil; + if Val>0 then + begin + GetMem(FPointList,NewSize); + GetMem(FKnuckleList,Val); + FillChar(FKnuckleList^,Val,0); + if Capacity<>0 then + begin + Move(OldKnuckle^,FKnuckleList^,Capacity); + Move(OldPoints^,FPointList^,CurrentSize); + end; + end; + if CurrentSize<>0 then + begin + Freemem(OldPoints,CurrentSize); + Freemem(OldKnuckle,Capacity); + end; + FCapacity:=Val; + end; +end;{TBSpline.FSetCapacity} + +procedure TBSpline.FSetFragments(Const value:integer); +begin + if FFragments<>value then + begin + FFragments:=value; + if FFragments>MaxFragments then FFragments:=MaxFragments; + end; +end;{TBSpline.FSetFragments} + +procedure TBSpline.FSetInterpolated(const value:boolean); +begin + if Value<>FInterpolated then + begin + FInterpolated:=value; + Build:=false; + end; +end;{TBSpline.FSetInterpolated} + +function TBSpline.FGetNumberOfPoints:integer; +begin + Result:=FNoPoints; +end;{TBSpline.FGetNumberOfPoints} + +function TBSpline.FGetPoint(Index:Integer):TVertex; +begin + if (Index>=1) and (Index<=FNoPoints) then Result:=FPointList^[Index] else + begin + Result.X:=0; + Result.Y:=0; + Result.Y:=0; + Raise Exception.Create('List index out of bounds in '+Self.ClassName+'.FGetPoint. ('+IntToStr(Index)+').'); + end; +end;{TBSpline.FGetPoint} + +procedure TBSpline.FSetPoint(Index:Integer;Value:TVertex); +begin + if (Index>=1) and (Index<=FNoPoints) then + begin + FPointList^[Index]:=Value; + Build:=False; + end else Raise Exception.Create('List index out of bounds in '+Self.ClassName+'.FSetPoint. ('+IntToStr(Index)+').'); +end;{TBSpline.FSetPoint} + +function TBSpline.FGetVertex(Index:Integer):TVertex; +begin + Result.X:=0; + Result.Y:=0; + if FBuild=False then if FNoPoints>1 then Rebuild + else exit; + if (Index>=0) and (Index<=NumberOfVertices+1) then Result:=FVertexList^[Index] + else Raise Exception.Create('List index out of bounds in '+Self.ClassName+'.FGetVertex. ('+IntToStr(Index)+').'); +end;{TBSpline.FGetVertex} + +procedure TBSpline.FSetVertex(Index:Integer;Value:TVertex); +begin + if (Index>=0) and (Index<=NumberOfVertices+1) then FVertexList^[Index]:=Value + else Raise Exception.Create('List index out of bounds in '+Self.ClassName+'.FSetVertex. ('+IntToStr(Index)+').'); +end;{TBSpline.FSetVertex} + +function TBSpline.FGetKnuckle(Index:integer):Boolean; +begin + if (Index=1) or (Index=FNoPoints) then Result:=false else + if (Index>0) and (Index<=FNoPoints) then Result:=FKnuckleList^[Index] + else Raise Exception.Create('List index out of bounds in '+Self.ClassName+'FGetKnuckle. ('+IntToStr(Index)+').'); +end;{TBSpline.FGetKnuckle} + +procedure TBSpline.FSetKnuckle(Index:integer;Value:Boolean); +begin + if (Index>0) and (Index<=FNoPoints) then + begin + FKnuckleList^[Index]:=Value; + Build:=false; + end else Raise Exception.Create('List index out of bounds in '+Self.ClassName+'.FSetKnuckle. ('+IntToStr(Index)+').'); +end;{TBSpline.FSetKnuckle} + +function TBSpline.FGetNumberOfVertices:integer; +begin + if Not FBuild then Rebuild; + Result:=FNoVertices; +end;{TBSpline.FGetNumberOfVertices} + +procedure TBSpline.Rebuild; +var I,J : integer; + Vertex2D : TVertex; +begin + if FNoPoints>1 then + begin + if FVertexList<>nil then + begin + Freemem(FVertexList,(FNoVertices+2)*SizeOf(TVertex)); + FVertexList:=nil; + end; + FNoVertices:=0; + For I:=1 to FNoPoints do if Knuckle[I] then inc(FNoVertices,3) + else inc(FNoVertices,1); + GetMem(FVertexList,(FNoVertices+2)*SizeOf(TVertex)); + J:=0; + For I:=1 to FNoPoints do + begin + Vertex2D:=Point[I]; + if Knuckle[I] then + begin + FVertexList^[J+1]:=Vertex2D; + FVertexList^[J+2]:=Vertex2D; + Inc(J,2); + end; + FVertexList^[J+1]:=FPointList^[I]; + if I=1 then + begin + FMin:=Vertex2D; + FMax:=FMin; + end else + begin + if Vertex2D.X<FMin.X then FMin.X:=Vertex2D.X; + if Vertex2D.Y<FMin.Y then FMin.Y:=Vertex2D.Y; + if Vertex2D.X>FMax.X then FMax.X:=Vertex2D.X; + if Vertex2D.Y>FMax.Y then FMax.Y:=Vertex2D.Y; + end; + + Inc(J); + end; + if Interpolated then + begin + For I:=1 to FNoVertices do + begin + GetMem(Matrix[I],FNovertices*SizeOf(TDatatype)); + FillChar(Matrix[I]^,FNovertices*SizeOf(TDatatype),0); + end; + FFillMatrix; + Finterpolate; + For I:=1 to FNoVertices do + begin + FreeMem(Matrix[I],FNovertices*SizeOf(TDatatype)); + Matrix[I]:=nil; + end; + end; + end; + FBuild:=true; + FPhantomPoints; +end;{TBSpline.Rebuild} + +procedure TBSpline.FInterpolate; +var I,J,K : integer; + Factor : extended; + Tmp : P2DVertexList; +begin + if (FNoVertices<MaxInterpolatedVertices) and (FNoVertices>2) then + begin + GetMem(Tmp,(FNoVertices+2)*SizeOf(TVertex)); + for I:=1 to FNoVertices do + begin + for J:=I+1 to FNoVertices do + begin + factor:=Matrix[J]^[I]/Matrix[I]^[I]; + for K:=1 to FNoVertices do Matrix[J]^[K]:=Matrix[J]^[K]-factor*Matrix[I]^[K]; + FVertexList^[J].x:=FVertexList^[J].x-factor*FVertexList^[J-1].x; + FVertexList^[J].y:=FVertexList^[J].y-factor*FVertexList^[J-1].y; + end; + end; + Tmp^[FNoVertices].x:=FVertexList^[FNoVertices].x/Matrix[FNoVertices]^[FNoVertices]; + Tmp^[FNoVertices].y:=FVertexList^[FNoVertices].y/Matrix[FNoVertices]^[FNoVertices]; + for I:=FNoVertices-1 downto 1 do + begin + Tmp^[I].x:=(1/Matrix[I]^[I])*(FVertexList^[I].x-Matrix[I]^[I+1]*Tmp^[I+1].x); + Tmp^[I].y:=(1/Matrix[I]^[I])*(FVertexList^[I].y-Matrix[I]^[I+1]*Tmp^[I+1].y); + end; + if FVertexList<>nil then + begin + Freemem(FVertexList,(FNoVertices+2)*SizeOf(TVertex)); + FVertexList:=nil; + end; + FVertexList:=Tmp; + end; +end;{TBSpline.FInterpolate} + +function TBSpline.KnownX(XValue:TDataType;var Results:T2DResults):Boolean; +var UpperLimit : integer; + Counter : integer; + mn, mx : extended; + Parameter : extended; + Error : extended; + Finished : boolean; + P1,P2 : TVertex; + Output : TVertex; +begin + Result:=false; + if not FBuild then + begin + Rebuild; + if not FBuild then exit; + end; + Results.NumberOfHits:=0; + if NumberOfPoints=0 then exit; + if NumberOfPoints=2 then + begin + P1:=Point[1]; + P2:=Point[2]; + if P1.X>P2.X then + begin + Output:=P1; + P1:=P2; + P2:=Output; + end; + if (P1.X<=XValue) and (P2.X>=XValue) then + begin + if abs(P1.X-P2.X)<1e6 then Parameter:=0.5 + else Parameter:=(XValue-P1.X)/(P2.X-P1.X); + Results.NumberOfHits:=Results.NumberOfHits+1; + Results.Parameter[Results.NumberOfHits]:=Parameter; + Results.Point[Results.NumberOfHits]:=Value(Parameter); + Results.Point[Results.NumberOfHits].X:=XValue; + end; + end else + begin + UpperLimit:=1; + P1:=Point[1]; + repeat + Finished:=false; + repeat + P2:=Value(UpperLimit/MaxCalcSteps); + if ((P1.X<=XValue) and (P2.X>=XValue)) or + ((P1.X>=XValue) and (P2.X<=XValue)) then Finished:=true; + if not Finished then + begin + if UpperLimit=MaxCalcSteps then + begin + Result:=Results.NumberOfHits>0; + exit; + end else + begin + inc(UpperLimit); + P1:=P2; + end; + end; + until Finished; + mx:=UpperLimit/MaxCalcSteps; + mn:=(UpperLimit-1)/MaxCalcSteps; + Counter:=0; + repeat + if abs(P1.X-P2.X)<1e-6 then Parameter:=0.5*(mn+mx) else + if (P1.X<=XValue) and (P2.X>=XValue) then Parameter:=mn+(mx-mn)*((XValue-P1.X)/(P2.X-P1.X)) + else Parameter:=mn+((P1.X-XValue)*(mx-mn)/(P1.X-P2.X)); + if Parameter<mn then Parameter:=mn; + if Parameter>mx then Parameter:=mx; + Output:=Value(parameter); + if XValue=0 then Error:=abs(Output.X-XValue) else + Error:=abs((XValue-Output.X)/XValue); + if Output.X>XValue then + begin + if (P1.X<=XValue) and (P2.X>=XValue) then + begin + mx:=parameter; + P2:=Output; + end else + begin + mn:=parameter; + P1:=Output; + end; + end else + begin + if (P1.X<=XValue) and (P2.X>=XValue) then + begin + mn:=parameter; + P1:=Output; + end else + begin + mx:=parameter; + P2:=Output; + end; + end; + inc(Counter); + until (Error<MaxError) or (Counter>MaxIterations); + if Results.NumberOfHits>=MaxResults then Raise Exception.Create('Max. number of results exceeded in TBSpline.KnownX'); + Results.NumberOfHits:=Results.NumberOfHits+1; + Results.Parameter[Results.NumberOfHits]:=Parameter; + Results.Point[Results.NumberOfHits]:=Value(Parameter); + Results.Point[Results.NumberOfHits].X:=XValue; + mx:=UpperLimit/MaxCalcSteps; + P1:=Value(mx); + Inc(UpperLimit); + until UpperLimit>MaxCalcSteps; + end; + Result:=Results.NumberOfHits>0; +end;{TBSpline.KnownX} + +function TBSpline.KnownY(YValue:TDataType;var Results:T2DResults):Boolean; +var UpperLimit : integer; + Counter : integer; + mn, mx : extended; + Parameter : extended; + Error : extended; + Finished : boolean; + P1,P2 : TVertex; + Output : TVertex; +begin + Result:=false; + if not FBuild then + begin + Rebuild; + if not FBuild then exit; + end; + Results.NumberOfHits:=0; + if NumberOfPoints=0 then exit; + if NumberOfPoints=2 then + begin + P1:=Point[1]; + P2:=Point[2]; + if P1.Y>P2.Y then + begin + Output:=P1; + P1:=P2; + P2:=Output; + end; + if (P1.Y<=YValue) and (P2.Y>=YValue) then + begin + if abs(P1.Y-P2.Y)<1e6 then Parameter:=0.5 + else Parameter:=(YValue-P1.Y)/(P2.Y-P1.Y); + Results.NumberOfHits:=Results.NumberOfHits+1; + Results.Parameter[Results.NumberOfHits]:=Parameter; + Results.Point[Results.NumberOfHits]:=Value(Parameter); + Results.Point[Results.NumberOfHits].Y:=YValue; + end; + end else + begin + UpperLimit:=1; + P1:=Point[1]; + repeat + Finished:=false; + repeat + P2:=Value(UpperLimit/MaxCalcSteps); + if ((P1.Y<=YValue) and (P2.Y>=YValue)) or + ((P1.Y>=YValue) and (P2.Y<=YValue)) then Finished:=true; + if not Finished then + begin + if UpperLimit=MaxCalcSteps then + begin + Result:=Results.NumberOfHits>0; + exit; + end else + begin + inc(UpperLimit); + P1:=P2; + end; + end; + until Finished; + mx:=UpperLimit/MaxCalcSteps; + mn:=(UpperLimit-1)/MaxCalcSteps; + Counter:=0; + repeat + if abs(P1.Y-P2.Y)<1e-6 then Parameter:=0.5*(mn+mx) else + if (P1.Y<=YValue) and (P2.Y>=YValue) then Parameter:=mn+(mx-mn)*((YValue-P1.Y)/(P2.Y-P1.Y)) + else Parameter:=mn+((P1.Y-YValue)*(mx-mn)/(P1.Y-P2.Y)); + if Parameter<mn then Parameter:=mn; + if Parameter>mx then Parameter:=mx; + Output:=Value(parameter); + if YValue=0 then Error:=abs(Output.Y-YValue) else + Error:=abs((YValue-Output.Y)/YValue); + if Output.Y>YValue then + begin + if (P1.Y<=YValue) and (P2.Y>=YValue) then + begin + mx:=parameter; + P2:=Output; + end else + begin + mn:=parameter; + P1:=Output; + end; + end else + begin + if (P1.Y<=YValue) and (P2.Y>=YValue) then + begin + mn:=parameter; + P1:=Output; + end else + begin + mx:=parameter; + P2:=Output; + end; + end; + inc(Counter); + until (Error<MaxError) or (Counter>MaxIterations); + if Results.NumberOfHits>=MaxResults then Raise Exception.Create('Max. number of results exceeded in TBSpline.KnownY'); + Results.NumberOfHits:=Results.NumberOfHits+1; + Results.Parameter[Results.NumberOfHits]:=Parameter; + Results.Point[Results.NumberOfHits]:=Value(Parameter); + Results.Point[Results.NumberOfHits].Y:=YValue; + mx:=UpperLimit/MaxCalcSteps; + P1:=Value(mx); + Inc(UpperLimit); + until UpperLimit>MaxCalcSteps; + end; + Result:=Results.NumberOfHits>0; +end;{TBSpline.KnownY} + +procedure TBSpline.AddPoint(Vertex:TVertex); +begin + if NumberOfPoints=Capacity then Capacity:=Capacity+VerticesIncrement; + inc(FNoPoints); + Point[NumberOfPoints]:=Vertex; + Build:=false; +end;{TBSpline.AddPoint} + +constructor TBSpline.Create; +begin + inherited Create; + FPointList:=nil; + FVertexList:=nil; + FKnuckleList:=nil; + FCapacity:=0; + Clear; +end;{TBSpline.Create} + +procedure TBSpline.DeletePoint(Index:Integer); +var I : integer; +begin + if NumberOfPoints>0 then + begin + dec(FNoPoints); + for I:=Index to NumberOfPoints do + begin + FPointList^[I]:=FPointList^[I+1]; + FKnuckleList^[I]:=FKnuckleList^[I+1]; + end; + Build:=false; + end; + if NumberOfPoints=0 then Clear; +end;{TBSpline.DeletePoint} + +destructor TBSpline.Destroy; +begin + Clear; + inherited Destroy; +end;{TBSpline.Destroy} + +procedure TBSpline.Draw(Canvas:TCanvas); +var J : Integer; + ParameterValue : single; + V : TVertex; +begin + //Canvas.Pen.Color:=Color; + For J:=0 to Fragments do {Draw the spline in 200 steps} + begin + ParameterValue:=(J/Fragments); // parameter value must be in the range 0.0-1.0 + V:=Value(ParameterValue); + // Use used moveto/lineto method for demo-drawing. + // using the Canvas.polyline method is SIGNIFICANTLY FASTER though!! + if J=0 then Canvas.MoveTo(Round(V.X),Round(V.Y)) + else Canvas.LineTo(Round(V.X),Round(V.Y)); + end; + if ShowVertices then For J:=1 to NumberOfPoints do {Draw the vertices} + begin + V:=Point[J]; + Canvas.Pen.Color:=clRed; + Canvas.Ellipse(Round(V.X)-2,Round(V.Y)-2,Round(V.X)+2,Round(V.Y)+2); + end; +end;{TBSpline.Draw} + +procedure TBSpline.Extents(Var Min,Max : TVertex); +var I : Integer; + P : TVertex; +begin + for I:=1 to NumberOfPoints do + begin + P:=Point[I]; + if P.X<Min.X then Min.X:=P.X; + if P.X>Max.X then Max.X:=P.X; + if P.Y<Min.Y then Min.Y:=P.Y; + if P.Y>Max.Y then Max.Y:=P.Y; + end; +end;{TBSpline.Extents} + +function TBSpline.FirstDerive(Parameter:extended):TVertex; +var c,S,E : integer; + Dist : extended; + Mix : extended; + Mid : Extended; +begin + Result.X:=0; + Result.Y:=0; + if FNoPoints<2 then exit; + if not FBuild then Rebuild; + Mid:=(NumberOfVertices-1)*Parameter+1; + S:=Trunc(Mid-1); + if S<0 then S:=0; + E:=S+3; + if S>FNovertices+1 then S:=FNovertices+1; + for c:=S to E do + begin + dist:=C-Mid; + if (dist>-2) and (dist<=-1) then Mix:=(2+dist)*(2+dist)*0.5 else + if (dist>=-1) and (dist<=0) then Mix:=(-2*dist-1.5*dist*dist) else + if (dist>=0) and (dist<=1) then Mix:=(-2*dist+1.5*dist*dist) else + if (dist>=1) and (dist<2) then Mix:=-(2-dist)*(2-dist)*0.5 else + mix:=0; + Result.x:=Result.x+FVertexList^[c].x*mix; + Result.y:=Result.y+FVertexList^[c].y*mix; + end; +end;{TBSpline.FirstDerive} + +procedure TBSpline.InsertPoint(Index:Integer;Vertex:TVertex); +var I : integer; +begin + if (Index>=0) and (Index<=NumberOfPoints) then + begin + if NumberOfPoints=Capacity then Capacity:=Capacity+VerticesIncrement; + inc(FNoPoints); + for I:=NumberOfPoints downto Index+1 do + begin + FPointList^[I]:=FPointList^[I-1]; + FKnuckleList^[I]:=FKnuckleList^[I-1]; + end; + FPointList^[Index]:=Vertex; + FKnuckleList^[Index]:=False; + Build:=false; + end else raise Exception.Create('Index out of range'); +end;{TBSpline.InsertPoint} + +procedure TBSpline.Invert; +var OldPoints : P2DPointList; + OldVertices : P2DVertexList; + OldKnuckle : PKnuckleList; + I : Integer; +begin +exit; // Backup current data + OldPoints:=FPointList; + FPointList:=nil; + OldKnuckle:=FKnuckleList; + FKnuckleList:=Nil; + OldVertices:=FVertexList; + FVertexList:=nil; + // Prepare new arrays + GetMem(FPointList,Capacity*SizeOf(TVertex)); + GetMem(FKnuckleList,Capacity); + GetMem(FVertexList,(Capacity+2)*SizeOf(TVertex)); + // Initialize knuckle list + FillChar(FKnuckleList^,Capacity,0); + // Copy controlpoints + for I:=1 to NumberOfPoints do + begin + FPointList^[I]:=OldPoints^[NumberOfPoints-I+1]; + FKnuckleList^[I]:=OldKnuckle^[NumberOfPoints-I+1]; + end; + // Copy vertices + if (OldVertices<>nil) and (FNoVertices<>0) and (Build) then for I:=0 to NumberOfVertices+1 do FVertexList^[I]:=OldVertices^[FNoVertices-I+1]; + // Destroy old arrays + FreeMem(OldPoints,Capacity*SizeOf(TVertex)); + if (Oldvertices<>nil) and (FNoVertices<>0) and (build) then FreeMem(OldVertices,(Capacity+2)*SizeOf(TVertex)); + FreeMem(OldKnuckle,Capacity); +end;{TBSpline.Invert} + +procedure TBSpline.Clear; +begin + FColor:=clBlack; + if (FVertexList<>nil) and (NumberOfVertices>0) then + begin + Freemem(FVertexList,(FNoVertices+2)*SizeOf(TVertex)); + FVertexList:=nil; + end; + FShowvertices:=False; + FNoPoints:=0; + FNoVertices:=0; + Build:=False; + Capacity:=0; + FInterpolated:=false; + FFragments:=100; +end;{TBSpline.Clear} + +procedure TBSpline.FPhantomPoints; +var I : integer; +begin + if NumberOfVertices>1 then + begin + I:=0; + FVertexList^[I].X:=2*FVertexList^[I+1].X-FVertexList^[I+2].X; + FVertexList^[I].Y:=2*FVertexList^[I+1].Y-FVertexList^[I+2].Y; + FVertexList^[NumberOfVertices+1].X:=2*FVertexList^[NumberOfVertices].X-FVertexList^[NumberOfVertices-1].X; + FVertexList^[NumberOfVertices+1].Y:=2*FVertexList^[NumberOfVertices].Y-FVertexList^[NumberOfVertices-1].Y; + end; +end;{TBSpline.FPhantomPoints} + +procedure TBSpline.FFillMatrix; +var I,J : integer; +begin + if (FNoVertices>2) and (FNoVertices<=MaxInterpolatedVertices) then + begin + for I:=2 to FNoVertices-1 do + begin + Matrix[I]^[I-1]:=1/6; + Matrix[I]^[I]:=2/3; + Matrix[I]^[I+1]:=1/6; + end; + Matrix[1]^[1]:=1; + Matrix[FNoVertices]^[FNoVertices]:=1; + I:=3; + while I<FNoVertices-1 do + begin + if (abs(FVertexList^[I].X-FVertexList^[I-1].X)<1e-5) and (abs(FVertexList^[I+1].X-FVertexList^[I].X)<1e-5) and + (abs(FVertexList^[I].Y-FVertexList^[I-1].Y)<1e-5) and (abs(FVertexList^[I+1].Y-FVertexList^[I].Y)<1e-5) then + begin + for J:=I-1 to I+1 do + begin + Matrix[J]^[J-1]:=0; + Matrix[J]^[J]:=1; + Matrix[J]^[J+1]:=0; + end; + inc(I,2); + end else inc(I); + end; + end; +end;{TBSpline.FFillMatrix} + +function TBSpline.Value(Parameter:extended):TVertex; +var c,S,E : integer; + Dist : extended; + Mix : extended; + Mid : TDataType; +begin + Result.X:=0; + Result.Y:=0; + if FNoPoints<2 then exit; + if not FBuild then Rebuild; + Mid:=(NumberOfVertices-1)*Parameter+1; + S:=Trunc(Mid-1); + if S<0 then S:=0; + E:=S+3; + if S>FNovertices+1 then S:=FNovertices+1; + for c:=S to E do + begin + dist:=abs(C-Mid); + if dist<2 then + begin + if dist<1 then mix:=4/6-dist*dist+0.5*dist*dist*dist else + mix:=(2-dist)*(2-dist)*(2-dist)/6; + Result.x:=Result.x+FVertexList^[c].x*mix; + Result.y:=Result.y+FVertexList^[c].y*mix; + end; + end; +end;{TBSpline.Value} + +function TBSpline.secondDerive(Parameter:extended):TVertex; +var c,S,E : integer; + Dist : extended; + Mix : extended; + Mid : Extended; +begin + Result.X:=0; + Result.Y:=0; + if FNoPoints<2 then exit; + if not FBuild then Rebuild; + Mid:=(NumberOfVertices-1)*Parameter+1; + S:=Trunc(Mid-1); + if S<0 then S:=0; + E:=S+3; + if S>FNovertices+1 then S:=FNovertices+1; + for c:=S to E do + begin + dist:=C-Mid; + if (dist>=-2) and (dist<=-1) then Mix:=2+dist else + if (dist>=-1) and (dist<=0) then Mix:=-2-3*dist else + if (dist>=0) and (dist<=1) then Mix:=-2+3*dist else + if (dist>=1) and (dist<=2) then Mix:=2-dist else Mix:=0; + Result.x:=Result.x+FVertexList^[c].x*mix; + Result.y:=Result.y+FVertexList^[c].y*mix; + end; +end;{TBSpline.secondDerive} + +end. diff --git a/components/nicechart/source/NiceChart.dcr b/components/nicechart/source/NiceChart.dcr new file mode 100644 index 0000000000000000000000000000000000000000..f2dfcf794ef719ac98acecaff4b58af1b9a39021 GIT binary patch literal 476 zcmZ{gu}Z{16h-ff&4Q3EEw@w<w($o<1Z^zD4@zk%c55>*-3|eNAy|gMe!>1j+6jT{ zeKVVZ1^1En?%}?hVG;mXtI6ELlloWy_j1S!yyF!wc*K+X84q}qGuLXhyqx()aDD6r zvc1+h|5pv@L0xCj6rycgsV(ecCd{Il?@Aobl+vZD(KBpDKXsd7=6zGRVd!W7SHbqG zv;5>^P-g1Iop;-m@4LHk$KX=F*^gfgx5F}>AMK^j>RUn^%FAN3C6(WjPE2F(A`3@X Y_($ubFA|$EREg6#;qrlkGr!^R2RT3Ke*gdg literal 0 HcmV?d00001 diff --git a/components/nicechart/source/NiceChart.pas b/components/nicechart/source/NiceChart.pas new file mode 100644 index 000000000..0eba8fefc --- /dev/null +++ b/components/nicechart/source/NiceChart.pas @@ -0,0 +1,1536 @@ +{------------------------------------------------------------------------------- + +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + + The Original Code is NiceChart.pas released at May 26th, 2007. + The Initial Developer of the Original Code is Priyatna. + (Website: http://www.priyatna.org Email: me@priyatna.org) + All Rights Reserved. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +-------------------------------------------------------------------------------} + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +unit NiceChart; + +interface + +uses + Windows, Messages, Classes, Graphics, Forms, Controls, ExtCtrls, SysUtils, + BSplines, Math; + +const + UndefinedValueChart: Double = MaxDouble; + +type + TNiceChart = class; + + TSeriesKind = (skLine, skSmooth, skBar); + + TNiceSeries = class(TObject) + private + Top: Integer; + Values: TList; + Chart: TNiceChart; + FCaption: string; + Spline: TBSpline; + FKind: TSeriesKind; + procedure SetCaption(const Value: string); + function GetMaxXValue: Double; + function GetMinXValue: Double; + function GetMinYValue: Double; + function GetMaxYValue: Double; + procedure SetKind(const Value: TSeriesKind); + protected + procedure InternalClear; + public + constructor Create(AChart: TNiceChart; AKind: TSeriesKind); + destructor Destroy; override; + function AddXY(AX, AY: Double; AHint: string = ''): Integer; + procedure Remove(Index: Integer); + procedure Clear; + property Caption: string read FCaption write SetCaption; + property Kind: TSeriesKind read FKind write SetKind; + end; + + TValueTranslator = record + MinValue: Double; + Scale: Double; + Base: Integer; + end; + + TMarkerProc = procedure (ACanvas: TCanvas; X, Y, Size: Integer); + + TNiceChart = class(TCustomPanel) + private + Brushes: array [0..15] of TBitmap; + Temp: TStringList; + MarkSize: Integer; + Marker: TMarkerProc; + BarCount: Integer; + BarWidth: Integer; + DestWidth, DestHeight: Integer; + YZero: Integer; + ChartEmpty: Boolean; + List: TList; + XAxis: TList; + YAxis: TList; + FShowLegend: Boolean; + FShowTitle: Boolean; + FTitle: string; + FTitleFont: TFont; + FNormalFont: TFont; + FUpdating: Boolean; + RcChart, RcLegend, RcTitle: TRect; + FXTranslate: TValueTranslator; + FYTranslate: TValueTranslator; + FAxisXOnePerValue: Boolean; + FAxisYTitle: string; + FAxisXTitle: string; + FAxisLineWidth: Integer; + FShowYGrid: Boolean; + FShowXGrid: Boolean; + FAxisYScale: Single; + FAxisXScale: Single; + FMonochrome: Boolean; + FSoftColors: Boolean; + procedure InternalClear; + procedure InternalPaint(ACanvas: TCanvas); + procedure Calculate(AWidth, AHeight: Integer); + procedure DoPaint; + procedure SetShowLegend(const Value: Boolean); + procedure SetShowTitle(const Value: Boolean); + procedure SetTitle(const Value: string); + procedure SetTitleFont(const Value: TFont); + procedure TitleFontChanged(Sender: TObject); + procedure WMSize(var Msg: TWMSize); message WM_SIZE; + procedure WMEraseBkgnd(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND; + function GetSeries(Index: Integer): TNiceSeries; + function GetSeriesCount: Integer; + procedure DrawLegend(ACanvas: TCanvas); + procedure DrawTitle(ACanvas: TCanvas); + procedure SetAxisXTitle(const Value: string); + procedure SetAxisYTitle(const Value: string); + procedure BuildYAxis; + procedure DrawYAxis(ACanvas: TCanvas); + procedure DrawXAxis(ACanvas: TCanvas); + procedure DrawChart(ACanvas: TCanvas); + procedure BuildXAxis; + procedure ClearAxis; + procedure AdjustYAxis; + procedure SetAxisXOnePerValue(const Value: Boolean); + procedure SetShowXGrid(const Value: Boolean); + procedure SetShowYGrid(const Value: Boolean); + procedure CalculateSeries; + procedure DrawSeries(ACanvas: TCanvas; Index: Integer); + procedure AutoColors(ACanvas: TCanvas; Index: Integer; IsBar: Boolean); + procedure SetAxisXScale(const Value: Single); + procedure SetAxisYScale(const Value: Single); + procedure SetMonochrome(const Value: Boolean); + function GetLabel(Value: Double): string; + procedure SetSoftColors(const Value: Boolean); + function IsAxisXScaleStored: Boolean; + function IsAxisXTitleStored: Boolean; + function IsAxisYScaleStored: Boolean; + function IsAxisYTitleStored: Boolean; + function IsTitleStored: Boolean; + procedure SetAxisLineWidth(const Value: Integer); + protected + procedure Paint; override; + procedure Changed; + procedure ChartToClient(const AX, AY: Double; var X, Y: Integer); + procedure CreateHandle; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure BeginUpdate; + procedure EndUpdate; + function AddSeries(AKind: TSeriesKind): TNiceSeries; + function ClientToChart(const X, Y: Integer; var AX, AY: Double): Boolean; + procedure RemoveSeries(ASeries: TNiceSeries); + procedure Clear; + property Series[Index: Integer]: TNiceSeries read GetSeries; + property SeriesCount: Integer read GetSeriesCount; + {$IFNDEF FPC} // Lazarus has not metafile... + function CreateMetafile: TMetafile; + procedure CopyToClipboard; + {$ENDIF} + published + property AxisLineWidth: Integer read FAxisLineWidth write SetAxisLineWidth default 3; + property ShowLegend: Boolean read FShowLegend write SetShowLegend; + property ShowTitle: Boolean read FShowTitle write SetShowTitle; + property ShowXGrid: Boolean read FShowXGrid write SetShowXGrid; + property ShowYGrid: Boolean read FShowYGrid write SetShowYGrid; + property Title: string read FTitle write SetTitle stored IsTitleStored; + property TitleFont: TFont read FTitleFont write SetTitleFont; + property AxisXTitle: string read FAxisXTitle write SetAxisXTitle stored IsAxisXTitleStored; + property AxisYTitle: string read FAxisYTitle write SetAxisYTitle stored IsAxisYTitleStored; + property AxisXOnePerValue: Boolean read FAxisXOnePerValue write SetAxisXOnePerValue default false; + property AxisXScale: Single read FAxisXScale write SetAxisXScale stored IsAxisXScaleStored; + property AxisYScale: Single read FAxisYScale write SetAxisYScale stored IsAxisYScaleStored; + property Monochrome: Boolean read FMonochrome write SetMonochrome default false; + property SoftColors: Boolean read FSoftColors write SetSoftColors default false; + property Align; + property Anchors; + property BevelInner default bvNone; + property BevelOuter default bvNone; + property BorderStyle default bsSingle; + {$IFDEF FPC} + property BorderSpacing; + {$ELSE} + property BevelKind; + {$ENDIF} + property OnMouseMove; + property OnMouseDown; + property OnMouseUp; + property PopupMenu; + end; + + procedure CalculateAxis(AMin, AMax: Double; Count: Integer; + out Delta, Lowest: Double); + + procedure Register; + +implementation + +{$R NiceChart.res} +{$IFDEF FPC} + {$R nicechart_images.res} +{$ENDIF} + +uses + ClipBrd; + +procedure Register; +begin + RegisterComponents('priyatna.org', [TNiceChart]); +end; + +const + OUTER_MARGIN = 20; + INNER_MARGIN = 10; + SMALL_MARGIN = 2; + LEGEND_ITEM = 20; + AXIS_DEFSIZE = 50; + + Formatter = '0.##'; + +type + PXYInfo = ^TXYInfo; + TXYInfo = record + X, Y: Double; + Px, Py: Integer; + Rc: TRect; + Hint: string; + end; + + PAxisInfo = ^TAxisInfo; + TAxisInfo = record + Value: Double; + Px, Py: Integer; + Caption: string; + end; + + +function GetMan10(Value: Double): Double; +var + Str: string; +begin + Str := UpperCase(Format('%E', [Value])); + Result := StrToFloat('1E' + Copy(Str, Pos('E', Str) + 1, Length(Str))); +end; + +procedure CalculateAxis(AMin, AMax: Double; Count: Integer; + out Delta, Lowest: Double); +label + Retry; +var + c, n, m10: Double; +begin + c := Max(2, Count-1); + n := (Abs(AMax - AMin) / c); + m10 := GetMan10(n); + Delta := 0; + while (Delta < n) + do Delta := Delta + (0.5 * m10); + if (Delta = 0) then + begin + Delta := 1; + Lowest := AMin - (Count div 2); + Exit; + end; + Retry: + Lowest := Trunc(AMin / Delta) * Delta; + if (Lowest > AMin) + then Lowest := Lowest - Delta; + if ((Lowest + (Delta * c)) < AMax) then + begin + Delta := Delta + (0.5 * m10); + goto Retry; + end; +end; + + +{ TNiceSeries } + +constructor TNiceSeries.Create(AChart: TNiceChart; AKind: TSeriesKind); +begin + inherited Create; + Chart := AChart; + Values := TList.Create; + FCaption := 'Series'; + Spline := TBSpline.Create; + FKind := AKind; +end; + +destructor TNiceSeries.Destroy; +begin + Spline.Free; + InternalClear; + Values.Free; + inherited Destroy; +end; + +procedure TNiceSeries.InternalClear; +var + x: Integer; +begin + for x := 0 to Values.Count-1 + do Dispose(PXYInfo(Values[x])); + Values.Clear; +end; + +procedure TNiceSeries.Clear; +begin + InternalClear; + Chart.Changed; +end; + +function TNiceSeries.AddXY(AX, AY: Double; AHint: string): Integer; +var + Info: PXYInfo; +begin + Info := New(PXYInfo); + Info^.X := AX; + Info^.Y := AY; + Info^.Px := 0; + Info^.Py := 0; + Info^.Rc := Rect(0, 0, 0, 0); + Info^.Hint := AHint; + Result := Values.Add(Info); + Chart.Changed; +end; + +procedure TNiceSeries.Remove(Index: Integer); +var + P: PXYInfo; +begin + if (Index >= 0) and (Index < Values.Count) then + begin + P := Values[Index]; + Values.Remove(P); + Dispose(P); + Chart.Changed; + end; +end; + +function TNiceSeries.GetMaxXValue: Double; +var + x: Integer; +begin + Result := -MaxDouble; + for x := 0 to Values.Count-1 + do Result := Max(Result, PXYInfo(Values[x])^.X); +end; + +function TNiceSeries.GetMinXValue: Double; +var + x: Integer; +begin + Result := MaxDouble; + for x := 0 to Values.Count-1 + do Result := Min(Result, PXYInfo(Values[x])^.X); +end; + +function TNiceSeries.GetMaxYValue: Double; +var + x: Integer; +begin + Result := -MaxDouble; + for x := 0 to Values.Count-1 + do Result := Max(Result, PXYInfo(Values[x])^.Y); +end; + +function TNiceSeries.GetMinYValue: Double; +var + x: Integer; +begin + Result := MaxDouble; + for x := 0 to Values.Count-1 + do Result := Min(Result, PXYInfo(Values[x])^.Y); +end; + +procedure TNiceSeries.SetCaption(const Value: string); +begin + if (FCaption <> Value) then + begin + FCaption := Value; + Chart.Changed; + end; +end; + +procedure TNiceSeries.SetKind(const Value: TSeriesKind); +begin + if (FKind <> Value) then + begin + FKind := Value; + Chart.Changed; + end; +end; + +{ TNiceChart } + +constructor TNiceChart.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + ParentColor := False; + ParentBackground := False; + ParentFont := False; + Temp := TStringList.Create; + Width := 300; + Height := 200; + Color := clWhite; + BevelOuter := bvNone; + BevelInner := bvNone; + BorderStyle := bsSingle; + ControlStyle := ControlStyle + [csNeedsBorderPaint]; + List := TList.Create; + FShowLegend := True; + FShowTitle := True; + FShowXGrid := True; + FShowYGrid := True; + FMonochrome := False; + FTitle := 'Chart Title'; + FTitleFont := TFont.Create; + FTitleFont.Name := 'Arial'; + FTitleFont.Size := 14; + FTitleFont.Style := []; + FTitleFont.OnChange := TitleFontChanged; + FNormalFont := TFont.Create; + FNormalFont.Name := 'Arial'; + FAxisLineWidth := 3; + FAxisXTitle := 'X Axis'; + FAxisYTitle := 'Y Axis'; + FAxisXScale := 1; + FAxisYScale := 1; + XAxis := TList.Create; + YAxis := TList.Create; + FUpdating := False; +end; + +destructor TNiceChart.Destroy; +var + x: Integer; +begin + for x := 0 to 15 do + begin + if Assigned(Brushes[x]) + then Brushes[x].Free; + end; + InternalClear; + List.Free; + FTitleFont.Free; + FNormalFont.Free; + XAxis.Free; + YAxis.Free; + Temp.Free; + inherited Destroy; +end; + +procedure TNiceChart.InternalClear; +var + x: Integer; +begin + for x := 0 to List.Count-1 + do TNiceSeries(List[x]).Free; + ClearAxis; + List.Clear; +end; + +procedure TNiceChart.Paint; +begin + if HandleAllocated + then DoPaint; +end; + +procedure TNiceChart.DoPaint; +begin + InternalPaint(Canvas); +end; + +procedure TNiceChart.SetMonochrome(const Value: Boolean); +begin + if (FMonochrome <> Value) then + begin + FMonochrome := Value; + Changed; + end; +end; + +procedure TNiceChart.SetSoftColors(const Value: Boolean); +begin + if (FSoftColors <> Value) then + begin + FSoftColors := Value; + Changed; + end; +end; + +procedure TNiceChart.SetShowLegend(const Value: Boolean); +begin + if (FShowLegend <> Value) then + begin + FShowLegend := Value; + Changed; + end; +end; + +procedure TNiceChart.SetAxisXOnePerValue(const Value: Boolean); +begin + if (FAxisXOnePerValue <> Value) then + begin + FAxisXOnePerValue := Value; + Changed; + end; +end; + +procedure TNiceChart.SetShowTitle(const Value: Boolean); +begin + if (FShowTitle <> Value) then + begin + FShowTitle := Value; + Changed; + end; +end; + +procedure TNiceChart.SetTitle(const Value: string); +begin + if (FTitle <> Value) then + begin + FTitle := Value; + Changed; + end; +end; + +procedure TNiceChart.SetTitleFont(const Value: TFont); +begin + FTitleFont.Assign(Value); +end; + +procedure TNiceChart.TitleFontChanged(Sender: TObject); +begin + Changed; +end; + +procedure TNiceChart.SetAxisXTitle(const Value: string); +begin + if (FAxisXTitle <> Value) then + begin + FAxisXTitle := Value; + Changed; + end; +end; + +procedure TNiceChart.SetAxisYTitle(const Value: string); +begin + if (FAxisYTitle <> Value) then + begin + FAxisYTitle := Value; + Changed; + end; +end; + +function TNiceChart.IsAxisXScaleStored: Boolean; +begin + Result := FAxisXScale <> 1.0; +end; + +function TNiceChart.IsAxisXTitleStored: Boolean; +begin + Result := FaxisXTitle <> ''; +end; + +function TNiceChart.IsAxisYScaleStored: Boolean; +begin + Result := FAxisYScale <> 1.0; +end; + +function TNiceChart.IsAxisYTitleStored: Boolean; +begin + Result := FAxisYTitle <> ''; +end; + +function TNiceChart.IsTitleStored: Boolean; +begin + Result := FTitle <> ''; +end; + +procedure TNiceChart.SetAxisXScale(const Value: Single); +begin + if (FAxisXScale <> Value) then + begin + FAxisXScale := Value; + if (FAxisXScale = 0) + then FAxisXScale := 1; + Changed; + end; +end; + +procedure TNiceChart.SetAxisLineWidth(const Value: Integer); +begin + if (FAxisLineWidth <> Value) then + begin + FAxisLineWidth := Value; + if FAxisLineWidth < 1 then + FAxisLineWidth := 1; + Changed; + end; +end; + +procedure TNiceChart.SetAxisYScale(const Value: Single); +begin + if (FAxisYScale <> Value) then + begin + FAxisYScale := Value; + if (FAxisYScale = 0) + then FAxisYScale := 1; + Changed; + end; +end; + +procedure TNiceChart.SetShowXGrid(const Value: Boolean); +begin + if (FShowXGrid <> Value) then + begin + FShowXGrid := Value; + DoPaint; + end; +end; + +procedure TNiceChart.SetShowYGrid(const Value: Boolean); +begin + if (FShowYGrid <> Value) then + begin + FShowYGrid := Value; + DoPaint; + end; +end; + +procedure TNiceChart.BeginUpdate; +begin + FUpdating := True; +end; + +procedure TNiceChart.EndUpdate; +begin + FUpdating := False; + Calculate(ClientWidth, ClientHeight); + DoPaint; +end; + +procedure TNiceChart.Changed; +begin + if not FUpdating then + begin + Calculate(ClientWidth, ClientHeight); + DoPaint; + end; +end; + +procedure TNiceChart.WMSize(var Msg: TWMSize); +begin + inherited; + Changed; +end; + +procedure TNiceChart.WMEraseBkgnd(var Msg: TWMEraseBkgnd); +begin + Msg.Result := 1; +end; + +function TNiceChart.GetSeries(Index: Integer): TNiceSeries; +begin + Result := TNiceSeries(List[Index]); +end; + +function TNiceChart.AddSeries(AKind: TSeriesKind): TNiceSeries; +begin + Result := TNiceSeries.Create(Self, AKind); + List.Add(Result); +end; + +procedure TNiceChart.Clear; +begin + InternalClear; + Changed; +end; + +procedure TNiceChart.RemoveSeries(ASeries: TNiceSeries); +begin + if Assigned(ASeries) then + begin + List.Remove(ASeries); + ASeries.Free; + Changed; + end; +end; + +function TNiceChart.GetSeriesCount: Integer; +begin + Result := List.Count; +end; + +procedure TNiceChart.DrawLegend(ACanvas: TCanvas); +var + x, y, l, t: Integer; + th, g: Integer; +begin + with ACanvas do + begin + Pen.Width := 1; + Pen.Style := psSolid; + Font.Assign(FNormalFont); + g := TextHeight('Ag'); + th := (LEGEND_ITEM - g) div 2; + Brush.Style := bsSolid; + Brush.Color := clBlack; + FillRect(Rect(RcLegend.Right, RcLegend.Top + 3, RcLegend.Right + 3, RcLegend.Bottom + 3)); + FillRect(Rect(RcLegend.Left + 3, RcLegend.Bottom, RcLegend.Right + 3, RcLegend.Bottom + 3)); + Brush.Style := bsClear; + Rectangle(RcLegend); + Brush.Style := bsClear; + l := RcLegend.Left + INNER_MARGIN + LEGEND_ITEM + SMALL_MARGIN; + for x := 0 to List.Count-1 do + begin + Temp.Text := Trim(TNiceSeries(List[x]).FCaption); + t := RcLegend.Top + TNiceSeries(List[x]).Top; + for y := 0 to Temp.Count-1 do + begin + TextOut(l, t + th, Trim(Temp[y])); + Inc(t, g); + end; + end; + end; +end; + +procedure TNiceChart.DrawTitle(ACanvas: TCanvas); +begin + with ACanvas do + begin + Brush.Style := bsClear; + Font.Assign(FTitleFont); + DrawText(Handle, PChar(FTitle), Length(FTitle), RcTitle, + DT_CENTER or DT_VCENTER or DT_WORDBREAK); + end; +end; + +procedure RotTextOut(ACanvas: TCanvas; x, y, Angle: Integer; Txt: String); +var + RotFont, OldFont: Integer; + FBold, FItalic, FUnderline, FStrikeOut: integer; +begin + if (Txt = '') + then Exit; + SetBkMode(ACanvas.Handle, TRANSPARENT); + if (fsItalic in ACanvas.Font.Style) + then FItalic := 1 + else FItalic := 0; + if (fsUnderline in ACanvas.Font.Style) + then FUnderline := 1 + else FUnderline := 0; + if (fsStrikeOut in ACanvas.Font.Style) + then FStrikeOut := 1 + else FStrikeOut := 0; + if (fsBold in ACanvas.Font.Style) + then FBold := FW_BOLD + else FBold := FW_NORMAL; + RotFont := CreateFont(ACanvas.Font.Height, 0, Angle*10, 0, + FBold, FItalic, FUnderline, FStrikeOut, 1, 4, $10, + ANTIALIASED_QUALITY, 4, PChar(ACanvas.Font.Name)); + OldFont := SelectObject(ACanvas.Handle, RotFont); + TextOut(ACanvas.Handle, x, y, PChar(Txt), Length(Txt)); + SelectObject(ACanvas.Handle, OldFont); + DeleteObject(RotFont); +end; + +procedure TNiceChart.InternalPaint(ACanvas: TCanvas); +begin + with ACanvas do + begin + Pen.Color := clBlack; + Pen.Width := 1; + Brush.Style := bsSolid; + Brush.Color := Color; + FillRect(Rect(0, 0, DestWidth, DestHeight)); + end; + if FShowLegend and (List.Count > 0) + then DrawLegend(ACanvas); + if FShowTitle and (FTitle <> '') + then DrawTitle(ACanvas); + DrawXAxis(ACanvas); + DrawYAxis(ACanvas); + DrawChart(ACanvas); +end; + +procedure TNiceChart.Calculate(AWidth, AHeight: Integer); +var + x, w, h, y, g: Integer; + Titled: Boolean; + +begin + + ClearAxis; + + DestWidth := AWidth; + DestHeight := AHeight; + RcChart := Rect(0, 0, DestWidth, DestHeight); + MarkSize := Max(1, Round(DestWidth * 0.004)); + + InflateRect(RcChart, -OUTER_MARGIN, -OUTER_MARGIN); + + Titled := False; + if FShowTitle and (FTitle <> '') then + begin + Canvas.Font.Assign(TitleFont); + w := Canvas.TextHeight(FTitle); + RcTitle := Rect(RcChart.Left, RcChart.Top, RcChart.Right, RcChart.Left + w); + DrawText(Canvas.Handle, PChar(FTitle), Length(FTitle), RcTitle, + DT_CENTER or DT_VCENTER or DT_WORDBREAK or DT_CALCRECT); + RcChart.Top := RcTitle.Bottom + INNER_MARGIN; + Titled := True; + end else + SetRectEmpty(RcTitle); + + Canvas.Font.Assign(FNormalFont); + h := Canvas.TextHeight('Ag'); + RcChart.Bottom := RcChart.Bottom - (2 * h) - INNER_MARGIN - (2 * SMALL_MARGIN); + + BuildYAxis; + w := 0; + for x := 0 to YAxis.Count-1 + do w := Max(w, Canvas.TextWidth(PAxisInfo(YAxis[x])^.Caption)); + RcChart.Left := RcChart.Left + h + INNER_MARGIN + w + (2 * SMALL_MARGIN); + RcTitle.Left := RcChart.Left; + RcTitle.Right := RcChart.Right; + AdjustYAxis; + + if FShowLegend and (List.Count > 0) then + begin + Canvas.Font.Assign(FNormalFont); + w := 0; + h := INNER_MARGIN; + g := Canvas.TextHeight('Ag'); + for x := 0 to List.Count-1 do + begin + TNiceSeries(List[x]).Top := h; + Temp.Text := Trim(TNiceSeries(List[x]).FCaption); + for y := 0 to Temp.Count-1 + do w := Max(w, Canvas.TextWidth(Trim(Temp[y]))); + h := h + Max(LEGEND_ITEM, Temp.Count * g); + if (x <> List.Count-1) + then h := h + SMALL_MARGIN; + end; + w := w + (2 * INNER_MARGIN) + LEGEND_ITEM + SMALL_MARGIN; + h := h + INNER_MARGIN; + RcLegend := Rect(RcChart.Right - w, RcChart.Top, RcChart.Right, RcChart.Top + h); + RcChart.Right := RcLegend.Left - (2 * INNER_MARGIN); + if Titled + then RcTitle.Right := RcChart.Right; + end else + SetRectEmpty(RcLegend); + + BuildXAxis; + + CalculateSeries; + +end; + +procedure TNiceChart.ClearAxis; +var + x: Integer; +begin + for x := 0 to XAxis.Count-1 + do Dispose(PAxisInfo(XAxis[x])); + XAxis.Clear; + for x := 0 to YAxis.Count-1 + do Dispose(PAxisInfo(YAxis[x])); + YAxis.Clear; +end; + +type + PDoubleList = ^TDoubleList; + TDoubleList = array [0..0] of Double; + +procedure QuickSortDouble(SortList: PDoubleList; L, R: Integer); +var + I, J: Integer; + P, T: Double; +begin + repeat + I := L; + J := R; + P := SortList^[(L + R) shr 1]; + repeat + while (SortList^[I] < P) + do Inc(I); + while (SortList^[J] > P) + do Dec(J); + if I <= J then + begin + T := SortList^[I]; + SortList^[I] := SortList^[J]; + SortList^[J] := T; + Inc(I); + Dec(J); + end; + until I > J; + if L < J + then QuickSortDouble(SortList, L, J); + L := I; + until I >= R; +end; + +function TNiceChart.GetLabel(Value: Double): string; +begin + if (Value = UndefinedValueChart) + then Result := '~' + else Result := FormatFloat(Formatter, Value); +end; + +procedure TNiceChart.BuildXAxis; +var + x, y, w: Integer; + mi, ma: Double; + Cnt, i, n: Integer; + Delta, Lowest, l: Double; + P: PAxisInfo; + tmp: PDoubleList; + Vals: TList; + Last: Double; + Scale: Double; + dx: Integer; + +begin + + if (List.Count = 0) or ChartEmpty + then Exit; + + BarCount := 0; + for x := 0 to List.Count-1 do + begin + if (TNiceSeries(List[x]).FKind = skBar) + then Inc(BarCount); + end; + if (BarCount > 0) + then FAxisXOnePerValue := True; + + if FAxisXOnePerValue then + begin + w := RcChart.Right - RcChart.Left; + Cnt := 0; + for x := 0 to List.Count-1 + do Cnt := Cnt + Series[x].Values.Count; + GetMem(tmp, Cnt * SizeOf(Double)); + i := 0; + for x := 0 to List.Count-1 do + begin + Vals := TNiceSeries(List[x]).Values; + for y := 0 to Vals.Count-1 do + begin + tmp^[i] := PXYInfo(Vals[y])^.X; + Inc(i); + end; + end; + QuickSortDouble(tmp, 0, Cnt-1); + n := 0; + Last := MaxDouble; + for x := 0 to Cnt-1 do + begin + l := tmp^[x]; + if (l = Last) + then Continue; + Inc(n); + Last := l; + end; + if (BarCount > 0) then + begin + Scale := w / n; + dx := Round(Scale / 2); + BarWidth := Round(Scale); + end else + begin + Scale := w / (n-1); + dx := 0; + end; + Last := MaxDouble; + i := 0; + for x := 0 to Cnt-1 do + begin + l := tmp^[x]; + if (l = Last) + then Continue; + P := New(PAxisInfo); + P^.Value := l; + P^.Py := RcChart.Bottom; + P^.Px := RcChart.Left + dx + Round(i * Scale); + P^.Caption := GetLabel(l / FAxisXScale); + XAxis.Add(P); + Last := l; + Inc(i); + end; + FreeMem(tmp); + end else + begin + w := RcChart.Right - RcChart.Left; + Cnt := (w div AXIS_DEFSIZE) + 1; + mi := MaxDouble; + ma := -MaxDouble; + for x := 0 to List.Count-1 do + begin + mi := Min(mi, Series[x].GetMinXValue); + ma := Max(ma, Series[x].GetMaxXValue); + end; + CalculateAxis(mi, ma, Cnt, Delta, Lowest); + Scale := w / (Delta * Max(1, Cnt-1)); + for x := 0 to Cnt-1 do + begin + l := x * Delta; + P := New(PAxisInfo); + P^.Py := RcChart.Bottom; + P^.Px := RcChart.Left + Round(l * Scale); + P^.Caption := GetLabel((Lowest + l) / FAxisXScale); + XAxis.Add(P); + end; + FXTranslate.MinValue := Lowest; + FXTranslate.Scale := Scale; + FXTranslate.Base := RcChart.Left; + end; + +end; + +procedure TNiceChart.BuildYAxis; +var + x, w: Integer; + mi, ma: Double; + Cnt: Integer; + Delta, Lowest, t: Double; + P: PAxisInfo; + Scale: Double; +begin + if (List.Count = 0) + then Exit; + w := RcChart.Bottom - RcChart.Top; + Cnt := (w div AXIS_DEFSIZE) + 1; + ChartEmpty := True; + mi := MaxDouble; + ma := -MaxDouble; + for x := 0 to List.Count-1 do + begin + if (Series[x].Values.Count > 0) then + begin + mi := Min(mi, Series[x].GetMinYValue); + ma := Max(ma, Series[x].GetMaxYValue); + ChartEmpty := False; + end; + end; + if ChartEmpty + then Exit; + CalculateAxis(mi, ma, Cnt, Delta, Lowest); + Scale := w / (Delta * Max(1, Cnt-1)); + for x := 0 to Cnt-1 do + begin + t := x * Delta; + P := New(PAxisInfo); + P^.Value := Lowest + t; + P^.Py := Round(t * Scale); + P^.Caption := GetLabel((Lowest + t) / FAxisYScale); + YAxis.Add(P); + end; + FYTranslate.MinValue := Lowest; + FYTranslate.Scale := Scale; +end; + +procedure TNiceChart.AdjustYAxis; +var + x: Integer; + P: PAxisInfo; + l: Integer; +begin + l := RcChart.Left; + YZero := -1; + for x := 0 to YAxis.Count-1 do + begin + P := PAxisInfo(YAxis[x]); + P^.Px := l; + P^.Py := RcChart.Bottom - P^.Py; + if (P^.Value = 0) + then YZero := P^.Py; + end; + if (YZero = -1) + then YZero := RcChart.Bottom; + FYTranslate.Base := RcChart.Bottom; +end; + +procedure TNiceChart.DrawXAxis(ACanvas: TCanvas); +var + l, t, w, x: Integer; + P: PAxisInfo; + Str: string; + Last: Integer; +begin + with ACanvas do + begin + Pen.Style := psSolid; + Pen.Width := FAxisLineWidth; + MoveTo(RcChart.Left, RcChart.Bottom); + LineTo(RcChart.Right, RcChart.Bottom); + Font.Assign(FNormalFont); + Font.Style := [fsBold]; + w := RcChart.Right - RcChart.Left; + t := RcChart.Bottom + INNER_MARGIN + (2 * SMALL_MARGIN) + TextHeight('Ag'); + l := RcChart.Left + ((w - TextWidth(FAxisXTitle)) div 2); + TextOut(l, t, FAxisXTitle); + Font.Assign(FNormalFont); + Pen.Color := clBlack; + Pen.Width := 1; + Pen.Style := psSolid; + t := RcChart.Bottom + (2 * SMALL_MARGIN); + Last := 0; + for x := 0 to XAxis.Count-1 do + begin + P := PAxisInfo(XAxis[x]); + Str := P^.Caption; + w := TextWidth(Str); + l := P^.Px - (w div 2); + if (Last < l) then + begin + TextOut(l, t, Str); + Last := l + w; + end; + MoveTo(P^.Px, P^.Py); + LineTo(P^.Px, P^.Py + SMALL_MARGIN); + end; + if FShowXGrid then + begin + Pen.Style := psDot; + Pen.Color := clGray; + t := RcChart.Top; + for x := 1 to XAxis.Count-2 do + begin + P := PAxisInfo(XAxis[x]); + MoveTo(P^.Px, P^.Py); + LineTo(P^.px, t); + end; + Pen.Color := clBlack; + end; + end; +end; + +procedure TNiceChart.DrawYAxis(ACanvas: TCanvas); +var + l, t, h, w: Integer; + x: Integer; + Str: string; + P: PAxisInfo; +begin + with ACanvas do + begin + Pen.Style := psSolid; + Pen.Width := FAxisLineWidth; + MoveTo(RcChart.Left, RcChart.Top); + LineTo(RcChart.Left, RcChart.Bottom); + h := RcChart.Bottom - RcChart.Top; + l := OUTER_MARGIN; + Font.Assign(FNormalFont); + Font.Style := [fsBold]; + t := RcChart.Bottom - ((h - TextWidth(FAxisYTitle)) div 2); + RotTextOut(ACanvas, l, t, 90, FAxisYTitle); + Font.Assign(FNormalFont); + Pen.Color := clBlack; + Pen.Width := 1; + Pen.Style := psSolid; + l := RcChart.Left - (2 * SMALL_MARGIN); + for x := 0 to YAxis.Count-1 do + begin + P := PAxisInfo(YAxis[x]); + Str := P^.Caption; + w := TextWidth(Str); + h := TextHeight(Str); + t := P^.Py - (h div 2); + TextOut(l - w, t, Str); + MoveTo(P^.Px - SMALL_MARGIN, P^.Py); + LineTo(P^.Px, P^.Py); + end; + if FShowYGrid then + begin + l := RcChart.Right; + for x := 1 to YAxis.Count-2 do + begin + P := PAxisInfo(YAxis[x]); + if (P^.Value = 0) then + begin + Pen.Style := psSolid; + Pen.Color := clBlack; + end else + begin + Pen.Style := psDot; + Pen.Color := clGray; + end; + MoveTo(P^.Px, P^.Py); + LineTo(l, P^.Py); + end; + Pen.Color := clBlack; + end; + end; +end; + +procedure TNiceChart.DrawChart(ACanvas: TCanvas); +var + x: Integer; +begin + with ACanvas do + begin + Brush.Style := bsClear; + Pen.Style := psSolid; + Pen.Width := 1; + MoveTo(RcChart.Left, RcChart.Top); + LineTo(RcChart.Right, RcChart.Top); + LineTo(RcChart.Right, RcChart.Bottom); + end; + for x := 0 to List.Count-1 do + begin + if (TNiceSeries(List[x]).FKind = skBar) + then DrawSeries(ACanvas, x); + end; + for x := 0 to List.Count-1 do + begin + if (TNiceSeries(List[x]).FKind <> skBar) + then DrawSeries(ACanvas, x); + end; +end; + + +//-----------------------------------------------------------------------------// + +procedure MarkerRectangle(ACanvas: TCanvas; X, Y, Size: Integer); +begin + ACanvas.Rectangle(X-Size, Y-Size, X+Size, Y+Size); +end; + +procedure MarkerCircle(ACanvas: TCanvas; X, Y, Size: Integer); +begin + ACanvas.Ellipse(X-Size, Y-Size, X+Size, Y+Size); +end; + +procedure MarkerTriangle1(ACanvas: TCanvas; X, Y, Size: Integer); +begin + ACanvas.Polygon([Point(x, y-Size), Point(x+Size, y+Size), Point(x-Size, y+Size)]); +end; + +procedure MarkerTriangle2(ACanvas: TCanvas; X, Y, Size: Integer); +begin + ACanvas.Polygon([Point(x+Size, y-Size), Point(x-Size, y-Size), Point(x, y+Size)]); +end; + +procedure MarkerDiamond(ACanvas: TCanvas; X, Y, Size: Integer); +begin + ACanvas.Polygon([Point(x, y-Size), Point(x+Size, y), Point(x, y+Size), Point(x-Size, y)]); +end; + +const + Colors1: array [0..13] of TColor = ( + clRed, clBlue, clGreen, clFuchsia, clNavy, clMaroon, clBlack, clOlive, + clPurple, clTeal, clGray, clLime, clYellow, clAqua + ); + Colors2: array [0..13] of TColor = ( + $0066C2FF, $005AFADA, $00F4C84D, $00B54DF4, $00669FFF, $00F44D5A, + $0066E0FF, $0066FFFF, $00F44DAE, $006863FE, $004DF474, $00F4934D, + clSilver, clGray + ); + + Markers: array [0..4] of TMarkerProc = ( + MarkerRectangle, MarkerCircle, MarkerTriangle1, MarkerTriangle2, + MarkerDiamond); + + +procedure TNiceChart.AutoColors(ACanvas: TCanvas; Index: Integer; Isbar: Boolean); +var + cl: TColor; + Idx: Integer; + Bmp: TBitmap; +begin + if FMonochrome + then cl := clBlack else + if FSoftColors + then cl := Colors2[Index mod 14] + else cl := Colors1[Index mod 14]; + Marker := Markers[Index mod 5]; + with ACanvas do + begin + Pen.Color := cl; + Brush.Bitmap := nil; + Brush.Style := bsSolid; + if IsBar + then Brush.Color := cl + else Brush.Color := clWhite; + if IsBar and FMonochrome then + begin + Idx := Index mod 16; + if not Assigned(Brushes[Idx]) then + begin + Bmp := TBitmap.Create; + Bmp.LoadFromResourceName(hInstance, Format('brush%.2d', [Idx+1])); + Brushes[Idx] := Bmp; + end; + Brush.Bitmap := Brushes[Idx]; + end; + end; +end; + + +//-----------------------------------------------------------------------------// + + +procedure TNiceChart.DrawSeries(ACanvas: TCanvas; Index: Integer); +var + x: Integer; + P: PXYInfo; + l, t, t2: Integer; + Sr: TNiceSeries; + Rc: TRect; +begin + Sr := TNiceSeries(List[Index]); + AutoColors(ACanvas, Index, sr.FKind = skBar); + with ACanvas do + begin + if (sr.FKind = skBar) then + begin + for x := 0 to Sr.Values.Count-1 do + begin + P := PXYInfo(Sr.Values[x]); + Rectangle(P^.Rc); + end; + end else + begin + if (sr.FKind = skLine) then + begin + for x := 0 to Sr.Values.Count-1 do + begin + P := PXYInfo(Sr.Values[x]); + if (x = 0) + then MoveTo(P^.Px, P^.Py) + else LineTo(P^.Px, P^.Py); + end; + end else + if (sr.FKind = skSmooth) + then sr.Spline.Draw(ACanvas); + for x := 0 to Sr.Values.Count-1 do + begin + P := PXYInfo(Sr.Values[x]); + Marker(ACanvas, P^.Px, P^.Py, MarkSize); + end; + end; + if FShowLegend then + begin + l := RcLegend.Left + INNER_MARGIN; + t := RcLegend.Top + Sr.Top; + if (sr.FKind = skBar) then + begin + Rc := Rect(l, t, l + LEGEND_ITEM, t + LEGEND_ITEM); + InflateRect(Rc, -2, -2); + Rectangle(Rc); + end else + begin + t2 := t + (LEGEND_ITEM div 2); + MoveTo(l, t2); + LineTo(l + LEGEND_ITEM, t2); + Marker(ACanvas, l + (LEGEND_ITEM div 2), t2, MarkSize); + end; + end; + end; +end; + +procedure TNiceChart.CalculateSeries; +var + x, y: Integer; + Values: TList; + P: PXYInfo; + S: TBSpline; + Vertex: TVertex; + sr: TNiceSeries; + bw, rw, bi, dx, l: Integer; +begin + if (List.Count = 0) or ChartEmpty + then Exit; + bi := 0; + bw := 0; + if (BarCount > 0) + then bw := Round(BarWidth / (BarCount + 1)); + for x := 0 to List.Count-1 do + begin + sr := TNiceSeries(List[x]); + s := sr.Spline; + s.Clear; + Values := sr.Values; + case sr.FKind of + skBar: + begin + dx := Round(-(BarWidth / 2) + (bw / 2) + (bi * bw) + (bw * 0.1)); + rw := Round(bw * 0.8); + for y := 0 to Values.Count-1 do + begin + P := PXYInfo(Values[y]); + ChartToClient(P^.X, P^.Y, P^.Px, P^.Py); + l := P^.Px + dx; + if (P^.Y < 0) + then P^.Rc := Rect(l, YZero, l + rw, P^.Py) + else P^.Rc := Rect(l, P^.Py, l + rw, YZero); + end; + Inc(bi); + end; + skLine: + begin + for y := 0 to Values.Count-1 do + begin + P := PXYInfo(Values[y]); + ChartToClient(P^.X, P^.Y, P^.Px, P^.Py); + P^.Rc := Rect(P^.Px-MarkSize, P^.Py-MarkSize, P^.Px+MarkSize, P^.Py+MarkSize); + end; + end; + skSmooth: + begin + for y := 0 to Values.Count-1 do + begin + P := PXYInfo(Values[y]); + ChartToClient(P^.X, P^.Y, P^.Px, P^.Py); + P^.Rc := Rect(P^.Px-MarkSize, P^.Py-MarkSize, P^.Px+MarkSize, P^.Py+MarkSize); + Vertex.X := P^.Px; + Vertex.Y := P^.Py; + s.AddPoint(Vertex); + end; + s.Interpolated := True; + s.Fragments := s.NumberOfPoints * 20; + end; + end; + end; +end; + +procedure TNiceChart.ChartToClient(const AX, AY: Double; var X, Y: Integer); +var + i: Integer; +begin + if FAxisXOnePerValue then + begin + for i := 0 to XAxis.Count-1 do + begin + if (AX = PAxisInfo(XAxis[i])^.Value) then + begin + X := PAxisInfo(XAxis[i])^.Px; + Break; + end; + end; + end else + X := FXTranslate.Base + Round((AX - FXTranslate.MinValue) * FXTranslate.Scale); + Y := FYTranslate.Base - Round((AY - FYTranslate.MinValue) * FYTranslate.Scale); +end; + +function TNiceChart.ClientToChart(const X, Y: Integer; var AX, AY: Double): Boolean; +var + i: Integer; + n, d: Integer; +begin + Result := PtInRect(RcChart, Point(X, Y)); + if Result then + begin + if FAxisXOnePerValue then + begin + n := MaxInt; + for i := 0 to XAxis.Count-1 do + begin + d := Abs(X - PAxisInfo(XAxis[i])^.Px); + if (d < n) then + begin + AX := PAxisInfo(XAxis[i])^.Value; + n := d; + end; + end; + end else + AX := FXTranslate.MinValue + ((X - FXTranslate.Base) / FXTranslate.Scale); + AY := FYTranslate.MinValue + ((FYTranslate.Base - Y) / FYTranslate.Scale); + end; +end; + +procedure TNiceChart.CreateHandle; +begin + inherited; + Changed; +end; + +{$IFNDEF FPC} +function TNiceChart.CreateMetafile: TMetafile; +const + InitWidth = 800; + InitHeight = 600; +var + mc: TMetafileCanvas; + AWidth, AHeight: Integer; +begin + AWidth := InitWidth; + AHeight := InitHeight; + Calculate(AWidth, AHeight); + if (RcLegend.Bottom > (AHeight - OUTER_MARGIN)) + then AHeight := RcLegend.Bottom + OUTER_MARGIN; + if ((RcChart.Right - RcChart.Left) < (RcChart.Bottom - RcChart.Top)) + then AWidth := AWidth + ((RcChart.Bottom - RcChart.Top) - (RCChart.Right - RcChart.Left)); + if (AWidth <> InitWidth) or (AHeight <> InitHeight) + then Calculate(AWidth, AHeight); + Result := TMetafile.Create; + Result.Width := AWidth; + Result.Height := AHeight; + mc := TMetafileCanvas.Create(Result, 0); + InternalPaint(mc); + mc.Free; + Calculate(ClientWidth, ClientHeight); +end; + +procedure TNiceChart.CopyToClipboard; +var + Wmf: TMetafile; +begin + Wmf := CreateMetafile; + Clipboard.Assign(Wmf); + Wmf.Free; +end; +{$ENDIF} + +end. + diff --git a/components/nicechart/source/NiceChart.res b/components/nicechart/source/NiceChart.res new file mode 100644 index 0000000000000000000000000000000000000000..d6f55f9639f2520a68514832b56ffa546d4dd8c2 GIT binary patch literal 2008 zcmb`HJ#GRq5QPVX5Hxg1DN!m43YLTbZ7NEB#4Tu1u8^Z3id-OVu8|8+a0JYI_F7st zc{KJ&Z)axL-j89{V`eshoC`vDXDehQ$hoGy+s1abwWW=%C|8ZG+lm{82s))2*6_Cn zxc>Bl{EhPB0Nf$|hUhP)ujYz9!CG1hyN~@Rh-~_GEm!OptfQr{Kd}E7QeLrN35KPx zW4+2N_B5cA+138?H^lskSh3$Su%GdcPe^&io@HROP8=`abNWLqSL`{~(Ng-&{j8bB z`e`vgB3A5$Uzx_{_s#zDTj%+%=l`<{)Eg|NZvN--e19RX=4a$f=<i%B<XmfGJr(EL z6Jj;j_IO6os<Em!$2?=LkEGZ+<{5j-9<$f%aXnY;9P<n~f3}oY>?t?EQogb927OiR K9P^BG<dJTB_2Kpa literal 0 HcmV?d00001 diff --git a/components/nicechart/source/nicechart_images.res b/components/nicechart/source/nicechart_images.res new file mode 100644 index 0000000000000000000000000000000000000000..4164de7838171c19a0be9667ff978c804afc672e GIT binary patch literal 476 zcmZ{gv1-FG6h&`JmqNiAJ7#R5kflFRN}ydjlzx!Mj-^|=2((og`U@tbG2{#K4_;*q zxA)1BXofuby?40pN=OEPm6DuOcoH8A;6Vy`fp@&(1y9&0pYez{DLIzQOu()1=9mjy zrol?*<oIWmRHqMhZKTu^v~8<yie1ba=cYQ}l{lOUxl2@|XIPJZ>efT%eN(t$=(E0) zvAyohKlvEsnR;>O-8T9A?tc7XaLM27$1jGv;VPXUZPRD<twt;IOJcMk<=>J{Ok?jN b3rAP@SL35D5}PnoiBmb@@<73v-*ET?J6Y+1 literal 0 HcmV?d00001