From 9884ea62f3315fb423f915cb319e6d0fed1f263e Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sat, 5 Dec 2020 10:46:43 +0800 Subject: [PATCH] feat: add image/plotters --- README.md | 3 +- __image/plotters/Cargo.lock | 945 ++++++++++++++++++++++++ __image/plotters/Cargo.toml | 15 + __image/plotters/examples/area-chart.rs | 51 ++ __image/plotters/examples/slc-temp.rs | 169 +++++ __image/plotters/examples/stock.rs | 73 ++ __image/plotters/justfile | 12 + __image/plotters/sample.png | Bin 0 -> 27145 bytes __image/plotters/src/main.rs | 30 + 9 files changed, 1297 insertions(+), 1 deletion(-) create mode 100644 __image/plotters/Cargo.lock create mode 100644 __image/plotters/Cargo.toml create mode 100644 __image/plotters/examples/area-chart.rs create mode 100644 __image/plotters/examples/slc-temp.rs create mode 100644 __image/plotters/examples/stock.rs create mode 100644 __image/plotters/justfile create mode 100644 __image/plotters/sample.png create mode 100644 __image/plotters/src/main.rs diff --git a/README.md b/README.md index abd8571..4efc0ca 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Project or files: ├── __fs │   └── fuse ├── __image +│   ├── plotters │   └── svg ├── __lang │   ├── peg @@ -147,7 +148,7 @@ Project or files: ├── vec.rs └── while.rs -119 directories, 26 files +120 directories, 26 files ``` diff --git a/__image/plotters/Cargo.lock b/__image/plotters/Cargo.lock new file mode 100644 index 0000000..285ec86 --- /dev/null +++ b/__image/plotters/Cargo.lock @@ -0,0 +1,945 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "approx" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "bumpalo" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" + +[[package]] +name = "bytemuck" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41aa2ec95ca3b5c54cf73c91acf06d24f4495d5f1b1c12506ae3483d646177ac" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "cc" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time", + "winapi", +] + +[[package]] +name = "cmake" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb6210b637171dfba4cda12e579ac6dc73f5165ad56133e5d72ef3131f320855" +dependencies = [ + "cc", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "core-foundation" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" + +[[package]] +name = "core-graphics" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "libc", +] + +[[package]] +name = "core-text" +version = "15.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "131b3fd1f8bd5db9f2b398fa4fdb6008c64afc04d447c306ac2c7e98fba2a61d" +dependencies = [ + "core-foundation", + "core-graphics", + "foreign-types", + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "deflate" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "dirs" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +dependencies = [ + "cfg-if 0.1.10", + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dwrote" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" +dependencies = [ + "lazy_static", + "libc", + "winapi", + "wio", +] + +[[package]] +name = "expat-sys" +version = "2.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa" +dependencies = [ + "cmake", + "pkg-config", +] + +[[package]] +name = "float-ord" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bad48618fdb549078c333a7a8528acb57af271d0433bdecd523eb620628364e" + +[[package]] +name = "font-kit" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ab2cdc792b545c49acb23aafa1cdc9381ea96140741f10bac596fd1bd1aa4f" +dependencies = [ + "bitflags", + "byteorder", + "core-foundation", + "core-graphics", + "core-text", + "dirs", + "dwrote", + "float-ord", + "freetype", + "lazy_static", + "libc", + "log", + "pathfinder_geometry", + "pathfinder_simd", + "servo-fontconfig", + "walkdir", + "winapi", +] + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "freetype" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11926b2b410b469d0e9399eca4cbbe237a9ef02176c485803b29216307e8e028" +dependencies = [ + "libc", + "servo-freetype-sys", +] + +[[package]] +name = "getrandom" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gif" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af" +dependencies = [ + "color_quant", + "lzw", +] + +[[package]] +name = "image" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ed2ada878397b045454ac7cfb011d73132c59f31a955d230bd1f1c2e68eb4a" +dependencies = [ + "byteorder", + "jpeg-decoder", + "num-iter", + "num-rational 0.2.4", + "num-traits", + "png 0.15.3", +] + +[[package]] +name = "image" +version = "0.23.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce04077ead78e39ae8610ad26216aed811996b043d47beed5090db674f9e9b5" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "jpeg-decoder", + "num-iter", + "num-rational 0.3.2", + "num-traits", + "png 0.16.7", +] + +[[package]] +name = "inflate" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" +dependencies = [ + "adler32", +] + +[[package]] +name = "jpeg-decoder" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc797adac5f083b8ff0ca6f6294a999393d76e197c36488e2ef732c4715f6fa3" +dependencies = [ + "byteorder", +] + +[[package]] +name = "js-sys" +version = "0.3.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d7383929f7c9c7c2d0fa596f325832df98c3704f2c60553080f7127a58175" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" + +[[package]] +name = "libm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +dependencies = [ + "cfg-if 0.1.10", +] + +[[package]] +name = "lzw" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "ordered-float" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3741934be594d77de1c8461ebcbbe866f585ea616a9753aa78f2bdc69f0e4579" +dependencies = [ + "num-traits", +] + +[[package]] +name = "pathfinder_geometry" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b7e7b4ea703700ce73ebf128e1450eb69c3a8329199ffbfb9b2a0418e5ad3" +dependencies = [ + "log", + "pathfinder_simd", +] + +[[package]] +name = "pathfinder_simd" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b451513912d6b3440e443aa75a73ab22203afedc4a90df8526d008c0f86f7cb3" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "plotters" +version = "0.1.0" +dependencies = [ + "chrono", + "plotters 0.3.0", + "rand", + "rand_distr", + "rand_xorshift", +] + +[[package]] +name = "plotters" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" +dependencies = [ + "chrono", + "font-kit", + "image 0.23.12", + "lazy_static", + "num-traits", + "plotters-backend", + "plotters-bitmap", + "plotters-svg", + "rusttype", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" + +[[package]] +name = "plotters-bitmap" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b0bdaf5194ad865c6225f5e82f5fdde700ce999d227471809551d6e0b1c557" +dependencies = [ + "gif", + "image 0.22.5", + "plotters-backend", +] + +[[package]] +name = "plotters-svg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "png" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef859a23054bbfee7811284275ae522f0434a3c8e7f4b74bd4a35ae7e1c4a283" +dependencies = [ + "bitflags", + "crc32fast", + "deflate 0.7.20", + "inflate", +] + +[[package]] +name = "png" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfe7f9f1c730833200b134370e1d5098964231af8450bce9b78ee3ab5278b970" +dependencies = [ + "bitflags", + "crc32fast", + "deflate 0.8.6", + "miniz_oxide", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_distr" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_xorshift" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_users" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +dependencies = [ + "getrandom", + "redox_syscall", + "rust-argon2", +] + +[[package]] +name = "rust-argon2" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +dependencies = [ + "base64", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "rusttype" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f61411055101f7b60ecf1041d87fb74205fb20b0c7a723f07ef39174cf6b4c0" +dependencies = [ + "approx", + "ordered-float", + "stb_truetype", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "servo-fontconfig" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a088f8d775a5c5314aae09bd77340bc9c67d72b9a45258be34c83548b4814cd9" +dependencies = [ + "libc", + "servo-fontconfig-sys", +] + +[[package]] +name = "servo-fontconfig-sys" +version = "4.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b3e166450f523f4db06c14f02a2d39e76d49b5d8cbd224338d93e3595c156c" +dependencies = [ + "expat-sys", + "pkg-config", + "servo-freetype-sys", +] + +[[package]] +name = "servo-freetype-sys" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ccb6d0d32d277d3ef7dea86203d8210945eb7a45fba89dd445b3595dd0dfc" +dependencies = [ + "cmake", + "pkg-config", +] + +[[package]] +name = "stb_truetype" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51" +dependencies = [ + "byteorder", +] + +[[package]] +name = "syn" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8833e20724c24de12bbaba5ad230ea61c3eafb05b881c7c9d3cfe8638b187e68" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "time" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasm-bindgen" +version = "0.2.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd364751395ca0f68cafb17666eee36b63077fb5ecd972bbcd74c90c4bf736e" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1114f89ab1f4106e5b55e688b828c0ab0ea593a1ea7c094b141b14cbaaec2d62" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6ac8995ead1f084a8dea1e65f194d0973800c7f571f6edd70adf06ecf77084" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a48c72f299d80557c7c62e37e7225369ecc0c963964059509fbafe917c7549" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158" + +[[package]] +name = "web-sys" +version = "0.3.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222b1ef9334f92a21d3fb53dc3fd80f30836959a90f9274a626d7e06315ba3c3" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi", +] diff --git a/__image/plotters/Cargo.toml b/__image/plotters/Cargo.toml new file mode 100644 index 0000000..6079059 --- /dev/null +++ b/__image/plotters/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "plotters" +version = "0.1.0" +authors = ["Hatter Jiang "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.7.3" +rand_distr = "0.3.0" +rand_xorshift = "0.2.0" +chrono = "0.4.19" +plotters = "0.3.0" + diff --git a/__image/plotters/examples/area-chart.rs b/__image/plotters/examples/area-chart.rs new file mode 100644 index 0000000..29f9b38 --- /dev/null +++ b/__image/plotters/examples/area-chart.rs @@ -0,0 +1,51 @@ +use plotters::prelude::*; + +use rand::SeedableRng; +use rand_distr::{Distribution, Normal}; +use rand_xorshift::XorShiftRng; + +fn main() -> Result<(), Box> { + let data: Vec<_> = { + let norm_dist = Normal::new(500.0, 100.0).unwrap(); + let mut x_rand = XorShiftRng::from_seed(*b"MyFragileSeed123"); + let x_iter = norm_dist.sample_iter(&mut x_rand); + x_iter + .filter(|x| *x < 1500.0) + .take(100) + .zip(0..) + .map(|(x, b)| x + (b as f64).powf(1.2)) + .collect() + }; + + let root = + BitMapBackend::new("area-chart.png", (1024, 768)).into_drawing_area(); + + root.fill(&WHITE)?; + + let mut chart = ChartBuilder::on(&root) + .set_label_area_size(LabelAreaPosition::Left, 60) + .set_label_area_size(LabelAreaPosition::Bottom, 60) + .caption("Area Chart Demo", ("sans-serif", 40)) + .build_cartesian_2d(0..(data.len() - 1), 0.0..1500.0)?; + + chart + .configure_mesh() + .disable_x_mesh() + .disable_y_mesh() + .draw()?; + + chart.draw_series( + AreaSeries::new( + (0..).zip(data.iter()).map(|(x, y)| (x, *y)), + 0.0, + &RED.mix(0.2), + ) + .border_style(&RED), + )?; + + Ok(()) +} +#[test] +fn entry_point() { + main().unwrap() +} diff --git a/__image/plotters/examples/slc-temp.rs b/__image/plotters/examples/slc-temp.rs new file mode 100644 index 0000000..3143569 --- /dev/null +++ b/__image/plotters/examples/slc-temp.rs @@ -0,0 +1,169 @@ +use plotters::prelude::*; + +use chrono::{TimeZone, Utc}; + +use std::error::Error; + +fn main() -> Result<(), Box> { + let root = + BitMapBackend::new("slc-temp.png", (1024, 768)).into_drawing_area(); + + root.fill(&WHITE)?; + + let mut chart = ChartBuilder::on(&root) + .margin(10) + .caption( + "Monthly Average Temperate in Salt Lake City, UT", + ("sans-serif", 40), + ) + .set_label_area_size(LabelAreaPosition::Left, 60) + .set_label_area_size(LabelAreaPosition::Right, 60) + .set_label_area_size(LabelAreaPosition::Bottom, 40) + .build_cartesian_2d( + (Utc.ymd(2010, 1, 1)..Utc.ymd(2018, 12, 1)).monthly(), + 14.0..104.0, + )? + .set_secondary_coord( + (Utc.ymd(2010, 1, 1)..Utc.ymd(2018, 12, 1)).monthly(), + -10.0..40.0, + ); + + chart + .configure_mesh() + .disable_x_mesh() + .disable_y_mesh() + .x_labels(30) + .y_desc("Average Temp (F)") + .draw()?; + chart + .configure_secondary_axes() + .y_desc("Average Temp (C)") + .draw()?; + + chart.draw_series(LineSeries::new( + DATA.iter().map(|(y, m, t)| (Utc.ymd(*y, *m, 1), *t)), + &BLUE, + ))?; + + chart.draw_series( + DATA.iter() + .map(|(y, m, t)| Circle::new((Utc.ymd(*y, *m, 1), *t), 3, BLUE.filled())), + )?; + + Ok(()) +} + +const DATA: [(i32, u32, f64); 12 * 9] = [ + (2010, 1, 32.4), + (2010, 2, 37.5), + (2010, 3, 44.5), + (2010, 4, 50.3), + (2010, 5, 55.0), + (2010, 6, 70.0), + (2010, 7, 78.7), + (2010, 8, 76.5), + (2010, 9, 68.9), + (2010, 10, 56.3), + (2010, 11, 40.3), + (2010, 12, 36.5), + (2011, 1, 28.8), + (2011, 2, 35.1), + (2011, 3, 45.5), + (2011, 4, 48.9), + (2011, 5, 55.1), + (2011, 6, 68.8), + (2011, 7, 77.9), + (2011, 8, 78.4), + (2011, 9, 68.2), + (2011, 10, 55.0), + (2011, 11, 41.5), + (2011, 12, 31.0), + (2012, 1, 35.6), + (2012, 2, 38.1), + (2012, 3, 49.1), + (2012, 4, 56.1), + (2012, 5, 63.4), + (2012, 6, 73.0), + (2012, 7, 79.0), + (2012, 8, 79.0), + (2012, 9, 68.8), + (2012, 10, 54.9), + (2012, 11, 45.2), + (2012, 12, 34.9), + (2013, 1, 19.7), + (2013, 2, 31.1), + (2013, 3, 46.2), + (2013, 4, 49.8), + (2013, 5, 61.3), + (2013, 6, 73.3), + (2013, 7, 80.3), + (2013, 8, 77.2), + (2013, 9, 68.3), + (2013, 10, 52.0), + (2013, 11, 43.2), + (2013, 12, 25.7), + (2014, 1, 31.5), + (2014, 2, 39.3), + (2014, 3, 46.4), + (2014, 4, 52.5), + (2014, 5, 63.0), + (2014, 6, 71.3), + (2014, 7, 81.0), + (2014, 8, 75.3), + (2014, 9, 70.0), + (2014, 10, 58.6), + (2014, 11, 42.1), + (2014, 12, 38.0), + (2015, 1, 35.3), + (2015, 2, 45.2), + (2015, 3, 50.9), + (2015, 4, 54.3), + (2015, 5, 60.5), + (2015, 6, 77.1), + (2015, 7, 76.2), + (2015, 8, 77.3), + (2015, 9, 70.4), + (2015, 10, 60.6), + (2015, 11, 40.9), + (2015, 12, 32.4), + (2016, 1, 31.5), + (2016, 2, 35.1), + (2016, 3, 49.1), + (2016, 4, 55.1), + (2016, 5, 60.9), + (2016, 6, 76.9), + (2016, 7, 80.0), + (2016, 8, 77.0), + (2016, 9, 67.1), + (2016, 10, 59.1), + (2016, 11, 47.4), + (2016, 12, 31.8), + (2017, 1, 29.4), + (2017, 2, 42.4), + (2017, 3, 51.7), + (2017, 4, 51.7), + (2017, 5, 62.5), + (2017, 6, 74.8), + (2017, 7, 81.3), + (2017, 8, 78.1), + (2017, 9, 65.7), + (2017, 10, 52.5), + (2017, 11, 49.0), + (2017, 12, 34.4), + (2018, 1, 38.1), + (2018, 2, 37.5), + (2018, 3, 45.4), + (2018, 4, 54.6), + (2018, 5, 64.0), + (2018, 6, 74.9), + (2018, 7, 82.5), + (2018, 8, 78.1), + (2018, 9, 71.9), + (2018, 10, 53.2), + (2018, 11, 39.7), + (2018, 12, 33.6), +]; +#[test] +fn entry_point() { + main().unwrap() +} diff --git a/__image/plotters/examples/stock.rs b/__image/plotters/examples/stock.rs new file mode 100644 index 0000000..de6426a --- /dev/null +++ b/__image/plotters/examples/stock.rs @@ -0,0 +1,73 @@ +use chrono::offset::{Local, TimeZone}; +use chrono::{Date, Duration}; +use plotters::prelude::*; +fn parse_time(t: &str) -> Date { + Local + .datetime_from_str(&format!("{} 0:0", t), "%Y-%m-%d %H:%M") + .unwrap() + .date() +} +fn main() -> Result<(), Box> { + let data = get_data(); + let root = BitMapBackend::new("stock.png", (1024, 768)).into_drawing_area(); + root.fill(&WHITE)?; + + let (to_date, from_date) = ( + parse_time(&data[0].0) + Duration::days(1), + parse_time(&data[29].0) - Duration::days(1), + ); + + let mut chart = ChartBuilder::on(&root) + .x_label_area_size(40) + .y_label_area_size(40) + .caption("MSFT Stock Price", ("sans-serif", 50.0).into_font()) + .build_cartesian_2d(from_date..to_date, 110f32..135f32)?; + + chart.configure_mesh().light_line_style(&WHITE).draw()?; + + chart.draw_series( + data.iter() + .map(|x| CandleStick::new(parse_time(x.0), x.1, x.2, x.3, x.4, &GREEN, &RED, 15)), + )?; + + Ok(()) +} + +fn get_data() -> Vec<(&'static str, f32, f32, f32, f32)> { + return vec![ + ("2019-04-25", 130.0600, 131.3700, 128.8300, 129.1500), + ("2019-04-24", 125.7900, 125.8500, 124.5200, 125.0100), + ("2019-04-23", 124.1000, 125.5800, 123.8300, 125.4400), + ("2019-04-22", 122.6200, 124.0000, 122.5700, 123.7600), + ("2019-04-18", 122.1900, 123.5200, 121.3018, 123.3700), + ("2019-04-17", 121.2400, 121.8500, 120.5400, 121.7700), + ("2019-04-16", 121.6400, 121.6500, 120.1000, 120.7700), + ("2019-04-15", 120.9400, 121.5800, 120.5700, 121.0500), + ("2019-04-12", 120.6400, 120.9800, 120.3700, 120.9500), + ("2019-04-11", 120.5400, 120.8500, 119.9200, 120.3300), + ("2019-04-10", 119.7600, 120.3500, 119.5400, 120.1900), + ("2019-04-09", 118.6300, 119.5400, 118.5800, 119.2800), + ("2019-04-08", 119.8100, 120.0200, 118.6400, 119.9300), + ("2019-04-05", 119.3900, 120.2300, 119.3700, 119.8900), + ("2019-04-04", 120.1000, 120.2300, 118.3800, 119.3600), + ("2019-04-03", 119.8600, 120.4300, 119.1500, 119.9700), + ("2019-04-02", 119.0600, 119.4800, 118.5200, 119.1900), + ("2019-04-01", 118.9500, 119.1085, 118.1000, 119.0200), + ("2019-03-29", 118.0700, 118.3200, 116.9600, 117.9400), + ("2019-03-28", 117.4400, 117.5800, 116.1300, 116.9300), + ("2019-03-27", 117.8750, 118.2100, 115.5215, 116.7700), + ("2019-03-26", 118.6200, 118.7050, 116.8500, 117.9100), + ("2019-03-25", 116.5600, 118.0100, 116.3224, 117.6600), + ("2019-03-22", 119.5000, 119.5900, 117.0400, 117.0500), + ("2019-03-21", 117.1350, 120.8200, 117.0900, 120.2200), + ("2019-03-20", 117.3900, 118.7500, 116.7100, 117.5200), + ("2019-03-19", 118.0900, 118.4400, 116.9900, 117.6500), + ("2019-03-18", 116.1700, 117.6100, 116.0500, 117.5700), + ("2019-03-15", 115.3400, 117.2500, 114.5900, 115.9100), + ("2019-03-14", 114.5400, 115.2000, 114.3300, 114.5900), + ]; +} +#[test] +fn entry_point() { + main().unwrap() +} diff --git a/__image/plotters/justfile b/__image/plotters/justfile new file mode 100644 index 0000000..a9b389f --- /dev/null +++ b/__image/plotters/justfile @@ -0,0 +1,12 @@ +main: + cargo r + +stock: + cargo r --example stock + +slc: + cargo r --example slc-temp + +area-chart: + cargo r --example area-chart + diff --git a/__image/plotters/sample.png b/__image/plotters/sample.png new file mode 100644 index 0000000000000000000000000000000000000000..1afe6ff0e1ee4b319684f5880920ef9f5c8c0405 GIT binary patch literal 27145 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 c04VD0OoAk<58n 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 wY>qwz9?|3}@Q Result<(), Box> { + let root = BitMapBackend::new("sample.png", (640, 480)).into_drawing_area(); + root.fill(&WHITE)?; + let mut chart = ChartBuilder::on(&root) + .caption("y=x^2", ("sans-serif", 50).into_font()) + .margin(5) + .x_label_area_size(30) + .y_label_area_size(30) + .build_cartesian_2d(-1f32..1f32, -0.1f32..1f32)?; + + chart.configure_mesh().draw()?; + + chart + .draw_series(LineSeries::new( + (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)), + &RED, + ))? + .label("y = x^2") + .legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &RED)); + + chart + .configure_series_labels() + .background_style(&WHITE.mix(0.8)) + .border_style(&BLACK) + .draw()?; + + Ok(()) +}