From d59b1b9df2d50444598f3c9f2d884a33d423b244 Mon Sep 17 00:00:00 2001 From: Elliott Clarke Date: Fri, 5 Feb 2021 12:19:54 -0500 Subject: [PATCH 01/27] Add angle transform --- plotters-backend/src/text.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plotters-backend/src/text.rs b/plotters-backend/src/text.rs index 16e2c665..c0363b62 100644 --- a/plotters-backend/src/text.rs +++ b/plotters-backend/src/text.rs @@ -135,6 +135,8 @@ pub enum FontTransform { Rotate180, /// Rotating the text 270 degree clockwise Rotate270, + /// Rotating the text to an arbitrary degree clockwise + RotateAngle(f32), } impl FontTransform { @@ -149,6 +151,10 @@ impl FontTransform { FontTransform::Rotate90 => (-y, x), FontTransform::Rotate180 => (-x, -y), FontTransform::Rotate270 => (y, -x), + FontTransform::RotateAngle(angle) => ( + ((x as f32) * angle.cos()).round() as i32, + ((y as f32) * angle.sin()).round() as i32, + ), } } } From f674554a4ad6316602e898cd8a01c792c8133f07 Mon Sep 17 00:00:00 2001 From: Elliott Clarke Date: Fri, 5 Feb 2021 13:39:54 -0500 Subject: [PATCH 02/27] Botched the math last time... Fix that and add tests to make sure it works. --- plotters-backend/src/text.rs | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/plotters-backend/src/text.rs b/plotters-backend/src/text.rs index c0363b62..ff901876 100644 --- a/plotters-backend/src/text.rs +++ b/plotters-backend/src/text.rs @@ -151,10 +151,12 @@ impl FontTransform { FontTransform::Rotate90 => (-y, x), FontTransform::Rotate180 => (-x, -y), FontTransform::Rotate270 => (y, -x), - FontTransform::RotateAngle(angle) => ( - ((x as f32) * angle.cos()).round() as i32, - ((y as f32) * angle.sin()).round() as i32, - ), + FontTransform::RotateAngle(angle) => { + let (x, y) = (x as f32, y as f32); + let (sin, cos) = angle.to_radians().sin_cos(); + let (x, y) = (x * cos - y * sin, x * sin + y * cos); + (x.round() as i32, y.round() as i32) + } } } } @@ -249,3 +251,19 @@ pub trait BackendTextStyle { draw: DrawFunc, ) -> Result, Self::FontError>; } + +#[cfg(test)] +mod tests { + use crate::FontTransform; + + #[test] + fn text_rotation_works() { + assert_eq!(FontTransform::None.transform(1, 0), (1, 0)); + assert_eq!(FontTransform::Rotate90.transform(1, 0), (0, 1)); + assert_eq!(FontTransform::Rotate180.transform(1, 0), (-1, 0)); + assert_eq!(FontTransform::Rotate270.transform(1, 0), (0, -1)); + + assert_eq!(FontTransform::RotateAngle(45f32).transform(10, 0), (7, 7)); + assert_eq!(FontTransform::RotateAngle(45f32).transform(0, 10), (-7, 7)); + } +} From c8364744a9d6bfc4e9c2128189a98ea1a292b494 Mon Sep 17 00:00:00 2001 From: shinmili Date: Sat, 9 Jul 2022 22:06:07 +0900 Subject: [PATCH 03/27] Rename `Cubiod` to `Cuboid` --- plotters/src/element/basic_shapes_3d.rs | 18 +++++++++++------- plotters/src/element/mod.rs | 2 +- plotters/src/lib.rs | 4 +++- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/plotters/src/element/basic_shapes_3d.rs b/plotters/src/element/basic_shapes_3d.rs index 97b15e62..fb248996 100644 --- a/plotters/src/element/basic_shapes_3d.rs +++ b/plotters/src/element/basic_shapes_3d.rs @@ -14,25 +14,25 @@ drawing_area.fill(&WHITE).unwrap(); let mut chart_builder = ChartBuilder::on(&drawing_area); let mut chart_context = chart_builder.margin(20).build_cartesian_3d(0.0..3.5, 0.0..2.5, 0.0..1.5).unwrap(); chart_context.configure_axes().x_labels(4).y_labels(3).z_labels(2).draw().unwrap(); -let cubiod = Cubiod::new([(0.,0.,0.), (3.,2.,1.)], BLUE.mix(0.2), BLUE); -chart_context.draw_series(std::iter::once(cubiod)).unwrap(); +let cuboid = Cuboid::new([(0.,0.,0.), (3.,2.,1.)], BLUE.mix(0.2), BLUE); +chart_context.draw_series(std::iter::once(cuboid)).unwrap(); ``` The result is a semi-transparent cuboid with blue edges: ![](https://cdn.jsdelivr.net/gh/facorread/plotters-doc-data@b6703f7/apidoc/cuboid.svg) */ -pub struct Cubiod { +pub struct Cuboid { face_style: ShapeStyle, edge_style: ShapeStyle, vert: [(X, Y, Z); 8], } -impl Cubiod { +impl Cuboid { /** Creates a cuboid. - See [`Cubiod`] for more information and examples. + See [`Cuboid`] for more information and examples. */ #[allow(clippy::redundant_clone)] pub fn new, ES: Into>( @@ -58,7 +58,7 @@ impl Cubiod { } impl<'a, X: 'a, Y: 'a, Z: 'a> PointCollection<'a, (X, Y, Z), BackendCoordAndZ> - for &'a Cubiod + for &'a Cuboid { type Point = &'a (X, Y, Z); type IntoIter = &'a [(X, Y, Z)]; @@ -67,7 +67,7 @@ impl<'a, X: 'a, Y: 'a, Z: 'a> PointCollection<'a, (X, Y, Z), BackendCoordAndZ> } } -impl Drawable for Cubiod { +impl Drawable for Cuboid { fn draw>( &self, points: I, @@ -106,3 +106,7 @@ impl Drawable for Cubiod = Cuboid; diff --git a/plotters/src/element/mod.rs b/plotters/src/element/mod.rs index e2790051..b8296182 100644 --- a/plotters/src/element/mod.rs +++ b/plotters/src/element/mod.rs @@ -272,7 +272,7 @@ impl CoordMapper for BackendCoordOnly { /** Used for 3d coordinate transformations. -See [`Cubiod`] for more information and an example. +See [`Cuboid`] for more information and an example. */ pub struct BackendCoordAndZ; diff --git a/plotters/src/lib.rs b/plotters/src/lib.rs index 677aafb9..c8be522d 100644 --- a/plotters/src/lib.rs +++ b/plotters/src/lib.rs @@ -832,8 +832,10 @@ pub mod prelude { }; // Elements + #[allow(deprecated)] + pub use crate::element::Cubiod; pub use crate::element::{ - Circle, Cross, Cubiod, DynElement, EmptyElement, IntoDynElement, MultiLineText, + Circle, Cross, Cuboid, DynElement, EmptyElement, IntoDynElement, MultiLineText, PathElement, Pie, Pixel, Polygon, Rectangle, Text, TriangleMarker, }; From 5c755400e53852f9243546f16ce614d3dcbfb264 Mon Sep 17 00:00:00 2001 From: Hao Hou Date: Sat, 9 Jul 2022 09:40:00 -0700 Subject: [PATCH 04/27] Bump the version number in the next release branch to 0.4.0 --- plotters-backend/Cargo.toml | 2 +- plotters-bitmap/Cargo.toml | 2 +- plotters-svg/Cargo.toml | 2 +- plotters/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plotters-backend/Cargo.toml b/plotters-backend/Cargo.toml index 9a2ba856..9ae8fe17 100644 --- a/plotters-backend/Cargo.toml +++ b/plotters-backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plotters-backend" -version = "0.3.4" +version = "0.4.0" authors = ["Hao Hou "] edition = "2018" license = "MIT" diff --git a/plotters-bitmap/Cargo.toml b/plotters-bitmap/Cargo.toml index d5d0650d..443a883f 100644 --- a/plotters-bitmap/Cargo.toml +++ b/plotters-bitmap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plotters-bitmap" -version = "0.3.3" +version = "0.4.0" authors = ["Hao Hou "] edition = "2018" license = "MIT" diff --git a/plotters-svg/Cargo.toml b/plotters-svg/Cargo.toml index 58e8900f..e96364c0 100644 --- a/plotters-svg/Cargo.toml +++ b/plotters-svg/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plotters-svg" -version = "0.3.3" +version = "0.4.0" authors = ["Hao Hou "] edition = "2018" license = "MIT" diff --git a/plotters/Cargo.toml b/plotters/Cargo.toml index a14d9a70..da02e27b 100644 --- a/plotters/Cargo.toml +++ b/plotters/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plotters" -version = "0.3.3" +version = "0.4.0" authors = ["Hao Hou "] edition = "2021" license = "MIT" From 9d7b8a541710e0fe173c16908498224164d10ffc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Jul 2022 13:44:25 +0000 Subject: [PATCH 05/27] Bump criterion from 0.3.5 to 0.3.6 Bumps [criterion](https://github.com/bheisler/criterion.rs) from 0.3.5 to 0.3.6. - [Release notes](https://github.com/bheisler/criterion.rs/releases) - [Changelog](https://github.com/bheisler/criterion.rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/bheisler/criterion.rs/compare/0.3.5...0.3.6) --- updated-dependencies: - dependency-name: criterion dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 18 ++++++++++++------ plotters-bitmap/Cargo.toml | 2 +- plotters/Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f478384c..96a83d04 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,6 +76,12 @@ dependencies = [ "rustc_version 0.4.0", ] +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.0.73" @@ -207,12 +213,12 @@ dependencies = [ [[package]] name = "criterion" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" +checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" dependencies = [ "atty", - "cast", + "cast 0.3.0", "clap", "criterion-plot", "csv", @@ -237,7 +243,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" dependencies = [ - "cast", + "cast 0.2.7", "itertools", ] @@ -1007,9 +1013,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" dependencies = [ "itoa 1.0.2", "ryu", diff --git a/plotters-bitmap/Cargo.toml b/plotters-bitmap/Cargo.toml index 443a883f..0a904526 100644 --- a/plotters-bitmap/Cargo.toml +++ b/plotters-bitmap/Cargo.toml @@ -34,7 +34,7 @@ features = ["ttf", "line_series", "bitmap_backend"] path = "../plotters" [dev-dependencies] -criterion = "0.3.4" +criterion = "0.3.6" rayon = "1.5.1" [[bench]] diff --git a/plotters/Cargo.toml b/plotters/Cargo.toml index f4f9b885..8326baa3 100644 --- a/plotters/Cargo.toml +++ b/plotters/Cargo.toml @@ -104,7 +104,7 @@ deprecated_items = [] # Keep some of the deprecated items for backward compatibi [dev-dependencies] itertools = "0.10.0" -criterion = "0.3.4" +criterion = "0.3.6" rayon = "1.5.1" serde_json = "1.0.82" serde = "1.0.138" From e2a9920304a66ecb5ce3e8a66226d499e215dcb1 Mon Sep 17 00:00:00 2001 From: Hao Hou Date: Thu, 7 Jul 2022 10:12:55 -0700 Subject: [PATCH 06/27] Update Cargo.toml --- plotters-svg/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plotters-svg/Cargo.toml b/plotters-svg/Cargo.toml index e96364c0..be179057 100644 --- a/plotters-svg/Cargo.toml +++ b/plotters-svg/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "MIT" description = "Plotters SVG backend" homepage = "https://plotters-rs.github.io/" -repository = "https://github.com/plotters-rs/plotters-svg.git" +repository = "https://github.com/plotters-rs/plotters.git" readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 0e6f7a1e87c0c4c97e2ea6c4a5a4fc8d8b901643 Mon Sep 17 00:00:00 2001 From: Hao Hou Date: Sun, 10 Jul 2022 08:52:23 -0700 Subject: [PATCH 07/27] Remove cargo.lock from repository according to the cargo team guideline --- Cargo.lock | 1283 ---------------------------------------------------- 1 file changed, 1283 deletions(-) delete mode 100644 Cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index f478384c..00000000 --- a/Cargo.lock +++ /dev/null @@ -1,1283 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bstr" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata", - "serde", -] - -[[package]] -name = "bumpalo" -version = "3.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" - -[[package]] -name = "bytemuck" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "cast" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" -dependencies = [ - "rustc_version 0.4.0", -] - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" - -[[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 = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "bitflags", - "textwrap", - "unicode-width", -] - -[[package]] -name = "cmake" -version = "0.1.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" -dependencies = [ - "cc", -] - -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - -[[package]] -name = "const-cstr" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3d0b5ff30645a68f35ece8cea4556ca14ef8a1651455f789a099a0513532a6" - -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "core-graphics" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" -dependencies = [ - "bitflags", - "core-foundation", - "core-graphics-types", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" -dependencies = [ - "bitflags", - "core-foundation", - "foreign-types", - "libc", -] - -[[package]] -name = "core-text" -version = "19.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" -dependencies = [ - "core-foundation", - "core-graphics", - "foreign-types", - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "criterion" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" -dependencies = [ - "atty", - "cast", - "clap", - "criterion-plot", - "csv", - "itertools", - "lazy_static", - "num-traits", - "oorandom", - "plotters 0.3.1", - "rayon", - "regex", - "serde", - "serde_cbor", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" -dependencies = [ - "cast", - "itertools", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "once_cell", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "csv" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" -dependencies = [ - "bstr", - "csv-core", - "itoa 0.4.8", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - -[[package]] -name = "deflate" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" -dependencies = [ - "adler32", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dlib" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" -dependencies = [ - "libloading", -] - -[[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 = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[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.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21fe28504d371085fae9ac7a3450f0b289ab71e07c8e57baa3fb68b9e57d6ce5" -dependencies = [ - "bitflags", - "byteorder", - "core-foundation", - "core-graphics", - "core-text", - "dirs-next", - "dwrote", - "float-ord", - "freetype", - "lazy_static", - "libc", - "log", - "pathfinder_geometry", - "pathfinder_simd", - "walkdir", - "winapi", - "yeslogic-fontconfig-sys", -] - -[[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.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee38378a9e3db1cc693b4f88d166ae375338a0ff75cb8263e1c601d51f35dc6" -dependencies = [ - "freetype-sys", - "libc", -] - -[[package]] -name = "freetype-sys" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" -dependencies = [ - "cmake", - "libc", - "pkg-config", -] - -[[package]] -name = "getrandom" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "gif" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b" -dependencies = [ - "color_quant", - "weezl", -] - -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "image" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28edd9d7bc256be2502e325ac0628bde30b7001b9b52e0abe31a1a9dc2701212" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "jpeg-decoder", - "num-iter", - "num-rational", - "num-traits", - "png", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "itoa" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" - -[[package]] -name = "jpeg-decoder" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9478aa10f73e7528198d75109c8be5cd7d15fb530238040148d5f9a22d4c5b3b" - -[[package]] -name = "js-sys" -version = "0.3.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" -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.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" - -[[package]] -name = "libloading" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "libm" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - -[[package]] -name = "miniz_oxide" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" -dependencies = [ - "adler", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - -[[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.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39fe46acc5503595e5949c17b818714d26fdf9b4920eacf3b2947f0199f4a6ff" -dependencies = [ - "rustc_version 0.3.3", -] - -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - -[[package]] -name = "pkg-config" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" - -[[package]] -name = "plotters" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" -dependencies = [ - "num-traits", - "plotters-backend 0.3.2", - "plotters-svg 0.3.1", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters" -version = "0.3.3" -dependencies = [ - "chrono", - "criterion", - "font-kit", - "image", - "itertools", - "lazy_static", - "num-traits", - "pathfinder_geometry", - "plotters-backend 0.3.4", - "plotters-bitmap", - "plotters-svg 0.3.3", - "rand", - "rand_distr", - "rand_xorshift", - "rayon", - "serde", - "serde_derive", - "serde_json", - "ttf-parser", - "wasm-bindgen", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" - -[[package]] -name = "plotters-backend" -version = "0.3.4" - -[[package]] -name = "plotters-bitmap" -version = "0.3.3" -dependencies = [ - "criterion", - "gif", - "image", - "plotters 0.3.3", - "plotters-backend 0.3.4", - "rayon", -] - -[[package]] -name = "plotters-svg" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" -dependencies = [ - "plotters-backend 0.3.2", -] - -[[package]] -name = "plotters-svg" -version = "0.3.3" -dependencies = [ - "plotters 0.3.3", - "plotters-backend 0.3.4", -] - -[[package]] -name = "png" -version = "0.17.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba" -dependencies = [ - "bitflags", - "crc32fast", - "deflate", - "miniz_oxide", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" - -[[package]] -name = "proc-macro2" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_distr" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" -dependencies = [ - "num-traits", - "rand", -] - -[[package]] -name = "rand_xorshift" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rayon" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom", - "redox_syscall", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" - -[[package]] -name = "regex-syntax" -version = "0.6.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" - -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver 1.0.10", -] - -[[package]] -name = "ryu" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" - -[[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 = "scoped-tls" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c" - -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - -[[package]] -name = "serde" -version = "1.0.138" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47" - -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half", - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.138" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" -dependencies = [ - "itoa 1.0.2", - "ryu", - "serde", -] - -[[package]] -name = "syn" -version = "1.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "thiserror" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[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 = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "ttf-parser" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd" - -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - -[[package]] -name = "unicode-ident" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" - -[[package]] -name = "wasm-bindgen-test" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b30cf2cba841a812f035c40c50f53eb9c56181192a9dd2c71b65e6a87a05ba" -dependencies = [ - "console_error_panic_hook", - "js-sys", - "scoped-tls", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test-macro", -] - -[[package]] -name = "wasm-bindgen-test-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad594bf33e73cafcac2ae9062fc119d4f75f9c77e25022f91c9a64bd5b6463" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "web-sys" -version = "0.3.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "weezl" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c97e489d8f836838d497091de568cf16b117486d529ec5579233521065bd5e4" - -[[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", -] - -[[package]] -name = "yeslogic-fontconfig-sys" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb008343871c7e56f01bfbd13f022064c8cbd12f622ab64f3997abe125e3302b" -dependencies = [ - "const-cstr", - "dlib", - "once_cell", - "pkg-config", -] From a884f127652ac830c420046e528b298f16576eb8 Mon Sep 17 00:00:00 2001 From: Hao Hou Date: Sun, 10 Jul 2022 08:52:30 -0700 Subject: [PATCH 08/27] Remove Cargo.lock According to the cargo team guidelines, we should remove the lock file for library --- .gitignore | 11 +- CHANGELOG.md | 331 +++++++++++++++++++++++++-------------------------- 2 files changed, 172 insertions(+), 170 deletions(-) diff --git a/.gitignore b/.gitignore index e1eddfd7..4f2e1070 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,9 @@ -/target -.*.sw* +# According to the new guideline from the cargo team, we should ignore the lock file for libraries. +**/Cargo.lock + +# Build diectories **/target -.vscode/* + +# Editor/IDE temporary files +.*.sw* +.vscode/* \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index cf52bd8c..051bd409 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,287 +1,284 @@ # Changelog -## Plotters 0.3.3 (?) +## Plotters latest ## Plotters 0.3.2 (2022-07-05) -### Added +- Added + - Pie element (by @hhamana) -- Pie element (by @hhamana) +- Improved -### Improved + - Improved documentaiton for predefined colors. (Thanks to @siefkenj) + - Introduce the full Material Design 2014 Color Palette. (Thanks to @siefkenj) + - Massive documentation improvements (Thanks to @facorread and many others) -- Improved documentaiton for predefined colors. (Thanks to @siefkenj) -- Introduce the full Material Design 2014 Color Palette. (Thanks to @siefkenj) -- Massive documentation improvements (Thanks to @facorread and many others) +- Fixed -### Fixed - -- More float point axis key point algorithm fixes (@38) -- Default rasterizer fixes (@shinmili and @38) + - More float point axis key point algorithm fixes (@38) + - Default rasterizer fixes (@shinmili and @38) ## Plotters 0.3.1 (2021-05-21) -### Improved - -- Surface series now supports more customizations -- Z-orde support for 3D plots -- Allow passing colors by value and reference (thanks to chrisduerr) +- Improved + - Surface series now supports more customizations + - Z-orde support for 3D plots + - Allow passing colors by value and reference (thanks to chrisduerr) -### Fixed +- Fixed -- Infinte loop / panic when the axis range is zero -- UB in minifb example (thanks to TheEdward162) -- Examples that uses old APIs (thanks to chrisduerr) + - Infinte loop / panic when the axis range is zero + - UB in minifb example (thanks to TheEdward162) + - Examples that uses old APIs (thanks to chrisduerr) ## Plotters 0.3.0 (2020-09-03) This is the next major release of Plotters, see [release notes](./RELEASE-NOTES.md) for more detials. -### Added +- Added -- The plotters backend API crate is introduced which allows third-party backend. -- Allow slice used as a coordinate if the item type implements `PartialOrd`. -- Linspace coordinate type, which allows define a discrete coordinate on continous value types (such as f32, DateTime, etc) with a step specification -- Nested coordinate type, now we support define pair of category and nested values as nested coordinate. -- Introduce backend crates: plotters-bitmap, plotters-svg, plotters-cairo, plotters-canvas, plotters-console -- 3D Plotting features + - The plotters backend API crate is introduced which allows third-party backend. + - Allow slice used as a coordinate if the item type implements `PartialOrd`. + - Linspace coordinate type, which allows define a discrete coordinate on continous value types (such as f32, DateTime, etc) with a step specification + - Nested coordinate type, now we support define pair of category and nested values as nested coordinate. + - Introduce backend crates: plotters-bitmap, plotters-svg, plotters-cairo, plotters-canvas, plotters-console + - 3D Plotting features -### Fixed +- Fixed -- Adjust Canvas backend size with DPR (Thanks to Marius-Mueller) + - Adjust Canvas backend size with DPR (Thanks to Marius-Mueller) -### Improvement +- Improvement -- Enhanced key point algorithms: New key point hint trait are used for key point algorithms && many improvment on key point algorithms for different types -- Renamed `MeshStyle::line\_style\_1` and `MeshStyle::line\_style\_2` to `bold\_line\_style` and `light\_line\_style` -- Reorganize the "plotters::coord" namespace -- Improved discrete coordinate trait -- Split backend code into isolated crates and can be maintained indepdendenly -- Category coordinate is now replaced by slice coordinate -- Removing the requirement for `Debug` trait for chart coordinate, allows ranged coordinate define its own formatting function. + - Enhanced key point algorithms: New key point hint trait are used for key point algorithms && many improvment on key point algorithms for different types + - Renamed `MeshStyle::line\_style\_1` and `MeshStyle::line\_style\_2` to `bold\_line\_style` and `light\_line\_style` + - Reorganize the "plotters::coord" namespace + - Improved discrete coordinate trait + - Split backend code into isolated crates and can be maintained indepdendenly + - Category coordinate is now replaced by slice coordinate + - Removing the requirement for `Debug` trait for chart coordinate, allows ranged coordinate define its own formatting function. -### Removed +- Removed -- The `Path` name alias for `PathElement` -- Most code `plotters::drawing::backend\_impl::\*` (expect `MockedBackend` for testing purpose) is removed due to crate split. -- Piston backend due to the Piston project seems not actively developing + - The `Path` name alias for `PathElement` + - Most code `plotters::drawing::backend\_impl::\*` (expect `MockedBackend` for testing purpose) is removed due to crate split. + - Piston backend due to the Piston project seems not actively developing ## Plotters 0.2.15 (2020-05-26) -### Fixed +- Fixed -- Division by zero with logarithmic coord (issue #143) -- Update dependencies + - Division by zero with logarithmic coord (issue #143) + - Update dependencies ## Plotters 0.2.14 (2020-05-05) -### Fixed +- Fixed -- Compile error with older rustc which causing breaks + - Compile error with older rustc which causing breaks ## Plotters 0.2.13 (2020-05-04) -### Added - -- Line width is supported for SVG -### Fixed +- Added + - Line width is supported for SVG -- Updated dependencies -- Default rasterizer causing bitmap backend draw out-of-range pixels -- Depdendicy fix +- Fixed + - Updated dependencies + - Default rasterizer causing bitmap backend draw out-of-range pixels + - Depdendicy fix ## Plotters 0.2.12 (2019-12-06) -### Added -- BitMapBackend now is able to support different pixel format natively. Check our new minifb demo for details. -- Incremental Rendering by saving the previous chart context into a state and restore it on a different drawing area. -- BoxPlot support (See boxplot example for more details) (Thanks to @nuald) -- Category coordinate spec which allows use a list of given values as coordinate (Thanks to @nuald) -- New text positioning model which allows develvoper sepecify the anchor point. This is critical for layouting SVG correctly. See `plotters::style::text::text_anchor` for details. (Thanks to @nuald) +- Added + - BitMapBackend now is able to support different pixel format natively. Check our new minifb demo for details. + - Incremental Rendering by saving the previous chart context into a state and restore it on a different drawing area. + - BoxPlot support (See boxplot example for more details) (Thanks to @nuald) + - Category coordinate spec which allows use a list of given values as coordinate (Thanks to @nuald) + - New text positioning model which allows develvoper sepecify the anchor point. This is critical for layouting SVG correctly. See `plotters::style::text::text_anchor` for details. (Thanks to @nuald) -### Improved +- Improved -- Faster bitmap blending algorithm, which is 5x faster than the original one. -- Text alignment improvement, now we can suggest the invariant point by giving `TextAlignment` to the text style (Thanks to @nauld) -- More controls on features, allows opt in and out series types -- Remove dependency to svg crate, since it doesn't provide more feature than a plain string. + - Faster bitmap blending algorithm, which is 5x faster than the original one. + - Text alignment improvement, now we can suggest the invariant point by giving `TextAlignment` to the text style (Thanks to @nauld) + - More controls on features, allows opt in and out series types + - Remove dependency to svg crate, since it doesn't provide more feature than a plain string. ## Plotters 0.2.11 (2019-10-27) -### Added +- Added -- Add font style support, now we are able to set font variations: normal, oblique, italic or bold. + - Add font style support, now we are able to set font variations: normal, oblique, italic or bold. -### Improved +- Improved -- Font description is greatly improved, general font family is supported: `serif`, `serif-sans`, `monospace` (Thanks to @Tatrix) -- Tested the font loading on Linux, OSX and Windowns. Make font loading more reliable. -- `BitMapBackend` isn't depdends on `image` crate now. Only the image encoding part relies on the `image` crate -- Refactored WASM demo use ES6 and `wasm-pack` (Thanks to @Tatrix) -- Label style for X axis and Y axis can be set seperately now using `x\_label\_style` and `y\_label\_style`. (Thanks to @zhiburt) + - Font description is greatly improved, general font family is supported: `serif`, `serif-sans`, `monospace` (Thanks to @Tatrix) + - Tested the font loading on Linux, OSX and Windowns. Make font loading more reliable. + - `BitMapBackend` isn't depdends on `image` crate now. Only the image encoding part relies on the `image` crate + - Refactored WASM demo use ES6 and `wasm-pack` (Thanks to @Tatrix) + - Label style for X axis and Y axis can be set seperately now using `x\_label\_style` and `y\_label\_style`. (Thanks to @zhiburt) ## Plotters 0.2.10 (2019-10-23) -### Improved +- Improved -- Refactored and simplified TTF font cache, use RwLock instead of mutex which may benefit for parallel rendering. (Thanks to @Tatrix) + - Refactored and simplified TTF font cache, use RwLock instead of mutex which may benefit for parallel rendering. (Thanks to @Tatrix) -### Bug Fix +- Bug Fix -- The fast bitmap filling algorithm may overflow the framebuffer and cause segfault + - The fast bitmap filling algorithm may overflow the framebuffer and cause segfault ## Plotters 0.2.9 (2019-10-21) -### Improvement +- Improvement -- Avoid copying image buffer when manipulate the image. (Thanks to @ralfbiedert) -- Bitmap element which allows blit the image to another drawing area. -- Performance improvement: now the bitmap backend is 8 times faster -- Added benchmarks to monitor the performance change + - Avoid copying image buffer when manipulate the image. (Thanks to @ralfbiedert) + - Bitmap element which allows blit the image to another drawing area. + - Performance improvement: now the bitmap backend is 8 times faster + - Added benchmarks to monitor the performance change -### Bug Fix +- Bug Fix -- Performance fix: '?' operator is very slow -- Dynamic Element lifetime bound: Fix a bug that prevents area series draws on non-static lifetime backend + - Performance fix: '?' operator is very slow + - Dynamic Element lifetime bound: Fix a bug that prevents area series draws on non-static lifetime backend ## Plotters 0.2.8 (2019-10-12) -### Added +- Added -- Cairo backend, which supports using Plotters draw a GTK surface. -- Allow secondary axis to be configured with different label style. -- Relative Sizing, now font and size can use relative scale: `(10).percent\_height()` means we want the size is 10% of parent's height. -- Allow the axis overlapping with the plotting area with `ChartBuilder::set\_\label\_area\_overlap`. -- Allow label area is on the top of the drawing area by setting the label area size to negative (Thanks to @serzhiio). -- Allow configure the tick mark size, when the tick mark size is negative the axis becomes inward (Thanks to @serzhiio). + - Cairo backend, which supports using Plotters draw a GTK surface. + - Allow secondary axis to be configured with different label style. + - Relative Sizing, now font and size can use relative scale: `(10).percent\_height()` means we want the size is 10% of parent's height. + - Allow the axis overlapping with the plotting area with `ChartBuilder::set\_\label\_area\_overlap`. + - Allow label area is on the top of the drawing area by setting the label area size to negative (Thanks to @serzhiio). + - Allow configure the tick mark size, when the tick mark size is negative the axis becomes inward (Thanks to @serzhiio). -### Bug Fix +- Bug Fix -- `FontError` from rusttype isn't `Sync` and `Send`. We don't have trait bound to ensure this. (Thanks to @dalance) + - `FontError` from rusttype isn't `Sync` and `Send`. We don't have trait bound to ensure this. (Thanks to @dalance) -### Improvement +- Improvement -- New convenient functions: `disable_mesh` and `disable_axes` + - New convenient functions: `disable_mesh` and `disable_axes` ## Plotters 0.2.7 (2019-10-1) -### Added +- Added -- GIF Support, now bitmap backend is able to render gif animation + - GIF Support, now bitmap backend is able to render gif animation -### Bug Fix +- Bug Fix -- Fixed several polygon filling bugs. -- Completely DateTime coordinate system support + - Fixed several polygon filling bugs. + - Completely DateTime coordinate system support ## Plotters 0.2.6 (2019-09-19) -### Added +- Added -- Allowing axis be placed on top or right by setting `right_y_label_area` and `top_x_label_area` -- Dual-coord system chart support: Now we are able to attach a secondary coord system to the chart using `ChartContext::set_secondary_coord`. And `draw_secondary_axes` to configure the style of secondary axes. Use `draw_secondary axis` to draw series under the secondary coordinate system. -- Add support for `y_label_offset`. Previously only X axis label supports offset attribute. -- New label area size API `set_label_area_size` can be used for all 4 label area -- Added new error bar element -- New axis specification type `PartialAxis` which allows the partially rendered axis. For example, we can define the chart's axis range as `0..1`, but only `0.3..0.7` is rendered on axis. This can be done by `(0.0..1.0).partial_axis(0.3..0.7)` -- Drawing backend now support fill polygon and introduce polygon element -- Area Chart Support + - Allowing axis be placed on top or right by setting `right_y_label_area` and `top_x_label_area` + - Dual-coord system chart support: Now we are able to attach a secondary coord system to the chart using `ChartContext::set_secondary_coord`. And `draw_secondary_axes` to configure the style of secondary axes. Use `draw_secondary axis` to draw series under the secondary coordinate system. + - Add support for `y_label_offset`. Previously only X axis label supports offset attribute. + - New label area size API `set_label_area_size` can be used for all 4 label area + - Added new error bar element + - New axis specification type `PartialAxis` which allows the partially rendered axis. For example, we can define the chart's axis range as `0..1`, but only `0.3..0.7` is rendered on axis. This can be done by `(0.0..1.0).partial_axis(0.3..0.7)` + - Drawing backend now support fill polygon and introduce polygon element + - Area Chart Support -### Improvement +- Improvement -- More examples are included -- Date coordinate now support using monthly or yearly axis. This is useful when plotting some data in monthly or yearly basis. -- Make margin on different side of a chart can be configured separately. -- Better test coverage + - More examples are included + - Date coordinate now support using monthly or yearly axis. This is useful when plotting some data in monthly or yearly basis. + - Make margin on different side of a chart can be configured separately. + - Better test coverage ## Plotters 0.2.5 (2019-09-07) -### Bug Fix +- Bug Fix -- Key points algorithm for numeric coordinate might not respect the constraint + - Key points algorithm for numeric coordinate might not respect the constraint ## Plotters 0.2.4 (2019-09-05) -### Improvement +- Improvement -- Add `i128` and `u128` as coordinate type (Credit to @Geemili) + - Add `i128` and `u128` as coordinate type (Credit to @Geemili) -### Bug Fix +- Bug Fix -- Date coordinate is working for a long time span now + - Date coordinate is working for a long time span now ## Plotters 0.2.3 (2019-08-19) -### Improvement +- Improvement -- Color system now is based on `palette` crate (Credit to @Veykril) + - Color system now is based on `palette` crate (Credit to @Veykril) ## Plotters 0.2.2 (2019-06-25) -### Added +- Added -- More documentation: a Jupyter interactive notebook of Plotters tutorial -- Add more quadrants to the `SeriesLabelPosition` (Credit to @wolfjagger). + - More documentation: a Jupyter interactive notebook of Plotters tutorial + - Add more quadrants to the `SeriesLabelPosition` (Credit to @wolfjagger). -### Improvement +- Improvement -- Histogram improvements, horizontal bar is supported, new creation API which compiler can infer the type -- Supporting split the drawing area with a list of breakpoints using `DrawingArea::split_by_breakpoints` -- Enable SVG support for WASM -- Make the `BitMapBackend` takes an in memory mutable buffer + - Histogram improvements, horizontal bar is supported, new creation API which compiler can infer the type + - Supporting split the drawing area with a list of breakpoints using `DrawingArea::split_by_breakpoints` + - Enable SVG support for WASM + - Make the `BitMapBackend` takes an in memory mutable buffer -### Fix +- Fix -- Rectangle drawing bug when the axis is reversed + - Rectangle drawing bug when the axis is reversed ## Plotters 0.2.1 (2019-06-10) -### Improvement +- Improvement -- Move the sample images and other documentation data out of this repository. + - Move the sample images and other documentation data out of this repository. -### Fix -- Make drawing errors shareable across threads. Otherwise, it causes compile error in some cases. (Thanks to @rkarp) +- Fix + - Make drawing errors shareable across threads. Otherwise, it causes compile error in some cases. (Thanks to @rkarp) ## Plotters 0.2.0 (2019-06-08) -### Added -- Add relative sizing by added function `DrawingArea::relative_to_height` and `DrawingArea::relative_to_width`. -- Added piston backend, now we can render plot on a window and dynamically render the plot +- Added + - Add relative sizing by added function `DrawingArea::relative_to_height` and `DrawingArea::relative_to_width`. + - Added piston backend, now we can render plot on a window and dynamically render the plot -### Improved -- Creating drawing area with `&Rc>`. Previously, the drawing area creation requires take over the drawing backend ownership. But sometimes the drawing backend may have additional options. With new API, this can be done by putting the backend drawing area into smart pointers, thus, the drawing backend is accessible after creates the root drawing area. +- Improved + - Creating drawing area with `&Rc>`. Previously, the drawing area creation requires take over the drawing backend ownership. But sometimes the drawing backend may have additional options. With new API, this can be done by putting the backend drawing area into smart pointers, thus, the drawing backend is accessible after creates the root drawing area. ## Plotters 0.1.14 (2019-06-06) -### Added -- Font is now support rotation transformation. Use `FontDesc::transform` to apply an rotation to transformation. For example, `font.transform(FontTransform::Rotate90)`. -- ChartContext now support drawing axis description. Use `MeshStyle::x_desc` and `MeshStyle::y_desc` to specify the axis description text. -- Add series label support. `ChartContext::draw_series` now returns a struct `SeriesAnno` that collects the additional information for series labeling. `ChartContext::draw_series_labels` are used to actually draw the series label. (See `examples/chart.rs` for detailed examples) -- Mocking drawing backend. -- evcxr Support +- Added + - Font is now support rotation transformation. Use `FontDesc::transform` to apply an rotation to transformation. For example, `font.transform(FontTransform::Rotate90)`. + - ChartContext now support drawing axis description. Use `MeshStyle::x_desc` and `MeshStyle::y_desc` to specify the axis description text. + - Add series label support. `ChartContext::draw_series` now returns a struct `SeriesAnno` that collects the additional information for series labeling. `ChartContext::draw_series_labels` are used to actually draw the series label. (See `examples/chart.rs` for detailed examples) + - Mocking drawing backend. + - evcxr Support -### Improvement -- Unify `OwnedText` and `Text` into `Text`. Previously, `OwnedText` and `Text` are two separate types, one holds a `String` another holds a `&str`. Now `OwnedText` is removed. +- Improvement + - Unify `OwnedText` and `Text` into `Text`. Previously, `OwnedText` and `Text` are two separate types, one holds a `String` another holds a `&str`. Now `OwnedText` is removed. use `Text::new("text".to_string(),...)` for owned text element and `Text::new("text", ...)` for borrowed text. -- Refactor the color representation code, since previously it's heavily relies on the trait object and hard to use -- More test cases + - Refactor the color representation code, since previously it's heavily relies on the trait object and hard to use + - More test cases ## Plotters 0.1.13 (2019-05-31) -### Added -- New abstraction of backend style with `BackendStyle` trait which should be able to extend easier in the future -- Backend support features, now feature options can be used to control which backend should be supported -- Add new trait `IntoDrawingArea`, now we can use `backend.into_drawing_area()` to convert the backend into a raw drawing area -- Now elements support dynamic dispatch, use `element.into_dyn()` to convert the element into a runtime dispatching element - -### Improvement -- Improved the overall code quality -- Documentation polish -- Stabilized APIs -- New conversion traits implementations -- Now transparent color is ignored by SVG, bitmap and HTML Canvas backend - -### Fix -- Changed the open-close pattern to a `present` function which indicates the end of drawing one frame -- Fix the but that `ChartBuilder::title` and `ChartBuilder::margin` cannot be called at the same time && `build_ranged` now returning a result. +- Added + - New abstraction of backend style with `BackendStyle` trait which should be able to extend easier in the future + - Backend support features, now feature options can be used to control which backend should be supported + - Add new trait `IntoDrawingArea`, now we can use `backend.into_drawing_area()` to convert the backend into a raw drawing area + - Now elements support dynamic dispatch, use `element.into_dyn()` to convert the element into a runtime dispatching element + +- Improvement + - Improved the overall code quality + - Documentation polish + - Stabilized APIs + - New conversion traits implementations + - Now transparent color is ignored by SVG, bitmap and HTML Canvas backend + +- Fix + - Changed the open-close pattern to a `present` function which indicates the end of drawing one frame + - Fix the but that `ChartBuilder::title` and `ChartBuilder::margin` cannot be called at the same time && `build_ranged` now returning a result. From 07966261951912830c49771b3311b9a71599ca44 Mon Sep 17 00:00:00 2001 From: "Fabio A. Correa" Date: Sat, 10 Sep 2022 21:47:34 -0400 Subject: [PATCH 09/27] Revert the effects of extraneous commit a92035c --- .gitignore | 3 +-- CHANGELOG.md | 12 --------- Cargo.toml | 1 + README.md | 2 +- doc-template/latest_version | 2 +- plotters-bitmap/Cargo.toml | 2 +- plotters-svg/Cargo.toml | 7 ------ plotters-svg/src/svg.rs | 9 +++---- plotters/Cargo.toml | 11 ++++----- plotters/src/drawing/backend_impl/mocked.rs | 7 ------ plotters/src/evcxr.rs | 27 --------------------- plotters/src/lib.rs | 2 +- plotters/src/style/color.rs | 6 ----- plotters/src/test.rs | 8 ------ 14 files changed, 15 insertions(+), 84 deletions(-) diff --git a/.gitignore b/.gitignore index 1a2e13d6..4f2e1070 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,4 @@ # Editor/IDE temporary files .*.sw* -.vscode/* -Cargo.lock +.vscode/* \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a679bc67..051bd409 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,18 +2,6 @@ ## Plotters latest -## Plotters 0.3.4 (?) - -## Plotters 0.3.3 (2022-08-19) - -### Improved - -- The EvcxR integration now supports bitmap output. (Thanks to @lisanhu) - -### Fixed - -- Fix the plotters crate's edition requirement - ## Plotters 0.3.2 (2022-07-05) - Added diff --git a/Cargo.toml b/Cargo.toml index cd387118..1c1f359c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,4 @@ [workspace] members = ["plotters", "plotters-backend", "plotters-bitmap", "plotters-svg"] default-members = ["plotters"] + diff --git a/README.md b/README.md index fa451ddd..b2748cdc 100644 --- a/README.md +++ b/README.md @@ -226,7 +226,7 @@ extern crate plotters; use plotters::prelude::*; let figure = evcxr_figure((640, 480), |root| { - root.fill(&WHITE)?; + root.fill(&WHITE); let mut chart = ChartBuilder::on(&root) .caption("y=x^2", ("Arial", 50).into_font()) .margin(5) diff --git a/doc-template/latest_version b/doc-template/latest_version index 1c09c74e..d15723fb 100644 --- a/doc-template/latest_version +++ b/doc-template/latest_version @@ -1 +1 @@ -0.3.3 +0.3.2 diff --git a/plotters-bitmap/Cargo.toml b/plotters-bitmap/Cargo.toml index 20d50089..0a904526 100644 --- a/plotters-bitmap/Cargo.toml +++ b/plotters-bitmap/Cargo.toml @@ -18,7 +18,7 @@ gif = { version = "0.11.2", optional = true } path = "../plotters-backend" [target.'cfg(not(target_arch = "wasm32"))'.dependencies.image] -version = "0.24.3" +version = "0.24.2" optional = true default-features = false features = ["jpeg", "png", "bmp"] diff --git a/plotters-svg/Cargo.toml b/plotters-svg/Cargo.toml index d33b6cca..be179057 100644 --- a/plotters-svg/Cargo.toml +++ b/plotters-svg/Cargo.toml @@ -14,15 +14,8 @@ readme = "README.md" [dependencies.plotters-backend] path = "../plotters-backend" -[dependencies.image] -version = "0.24.2" -optional = true -default-features = false -features = ["jpeg", "png", "bmp"] - [features] debug = [] -bitmap_encoder = ["image"] [dev-dependencies.plotters] default_features = false diff --git a/plotters-svg/src/svg.rs b/plotters-svg/src/svg.rs index 43bf36a2..1c047b68 100644 --- a/plotters-svg/src/svg.rs +++ b/plotters-svg/src/svg.rs @@ -487,19 +487,18 @@ impl<'a> DrawingBackend for SVGBackend<'a> { (w, h): (u32, u32), src: &'b [u8], ) -> Result<(), DrawingErrorKind> { - use image::codecs::png::PngEncoder; - use image::ImageEncoder; + use image::png::PNGEncoder; let mut data = vec![0; 0]; { let cursor = Cursor::new(&mut data); - let encoder = PngEncoder::new(cursor); + let encoder = PNGEncoder::new(cursor); - let color = image::ColorType::Rgb8; + let color = image::ColorType::RGB(8); - encoder.write_image(src, w, h, color).map_err(|e| { + encoder.encode(src, w, h, color).map_err(|e| { DrawingErrorKind::DrawingError(Error::new( std::io::ErrorKind::Other, format!("Image error: {}", e), diff --git a/plotters/Cargo.toml b/plotters/Cargo.toml index 475f5104..8326baa3 100644 --- a/plotters/Cargo.toml +++ b/plotters/Cargo.toml @@ -2,7 +2,7 @@ name = "plotters" version = "0.4.0" authors = ["Hao Hou "] -edition = "2018" +edition = "2021" license = "MIT" description = "A Rust drawing library focus on data plotting for both WASM and native applications" repository = "https://github.com/plotters-rs/plotters" @@ -14,7 +14,7 @@ exclude = ["doc-template", "plotters-doc-data"] [dependencies] num-traits = "0.2.14" -chrono = { version = "0.4.20", optional = true } +chrono = { version = "0.4.19", optional = true } [dependencies.plotters-backend] path = "../plotters-backend" @@ -36,7 +36,7 @@ pathfinder_geometry = { version = "0.5.1", optional = true } font-kit = { version = "0.11.0", optional = true } [target.'cfg(not(all(target_arch = "wasm32", not(target_os = "wasi"))))'.dependencies.image] -version = "0.24.3" +version = "0.24.2" optional = true default-features = false features = ["jpeg", "png", "bmp"] @@ -100,7 +100,6 @@ fontconfig-dlopen = ["font-kit/source-fontconfig-dlopen"] # Misc datetime = ["chrono"] evcxr = ["svg_backend"] -evcxr_bitmap = ["evcxr", "bitmap_backend", "plotters-svg/bitmap_encoder"] deprecated_items = [] # Keep some of the deprecated items for backward compatibility [dev-dependencies] @@ -108,8 +107,8 @@ itertools = "0.10.0" criterion = "0.3.6" rayon = "1.5.1" serde_json = "1.0.82" -serde = "1.0.139" -serde_derive = "1.0.140" +serde = "1.0.138" +serde_derive = "1.0.138" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] rand = "0.8.3" diff --git a/plotters/src/drawing/backend_impl/mocked.rs b/plotters/src/drawing/backend_impl/mocked.rs index 7569e732..da6bfecc 100644 --- a/plotters/src/drawing/backend_impl/mocked.rs +++ b/plotters/src/drawing/backend_impl/mocked.rs @@ -269,13 +269,6 @@ impl DrawingBackend for MockedBackend { impl Drop for MockedBackend { fn drop(&mut self) { - // `self.drop_check` is typically a testing function; it can panic. - // The current `drop` call may be a part of stack unwinding caused - // by another panic. If so, we should never call it. - if std::thread::panicking() { - return; - } - let mut temp = None; std::mem::swap(&mut temp, &mut self.drop_check); diff --git a/plotters/src/evcxr.rs b/plotters/src/evcxr.rs index 8117d35f..e91418ea 100644 --- a/plotters/src/evcxr.rs +++ b/plotters/src/evcxr.rs @@ -1,11 +1,7 @@ use crate::coord::Shift; use crate::drawing::{DrawingArea, IntoDrawingArea}; -use plotters_backend::DrawingBackend; use plotters_svg::SVGBackend; -#[cfg(feature = "evcxr_bitmap")] -use plotters_bitmap::BitMapBackend; - /// The wrapper for the generated SVG pub struct SVGWrapper(String, String); @@ -44,26 +40,3 @@ pub fn evcxr_figure< draw(root).expect("Drawing failure"); SVGWrapper(buffer, "".to_string()) } - -/// Start drawing an evcxr figure -#[cfg(feature = "evcxr_bitmap")] -pub fn evcxr_bitmap_figure< - Draw: FnOnce(DrawingArea) -> Result<(), Box>, ->( - size: (u32, u32), - draw: Draw, -) -> SVGWrapper { - const PIXEL_SIZE : usize = 3; - let mut buf = Vec::new(); - buf.resize((size.0 as usize) * (size.1 as usize) * PIXEL_SIZE, 0); - let root = BitMapBackend::with_buffer(&mut buf, size).into_drawing_area(); - draw(root).expect("Drawing failure"); - let mut buffer = "".to_string(); - { - let mut svg_root = SVGBackend::with_string(&mut buffer, size); - svg_root - .blit_bitmap((0, 0), size, &buf) - .expect("Failure converting to SVG"); - } - SVGWrapper(buffer, "".to_string()) -} diff --git a/plotters/src/lib.rs b/plotters/src/lib.rs index aa2988de..c8be522d 100644 --- a/plotters/src/lib.rs +++ b/plotters/src/lib.rs @@ -102,7 +102,7 @@ including bitmap, vector graph, piston window, GTK/Cairo and WebAssembly.
Real-time Rendering - [code] + [code]
diff --git a/plotters/src/style/color.rs b/plotters/src/style/color.rs index 7e372cd1..2c01d4a1 100644 --- a/plotters/src/style/color.rs +++ b/plotters/src/style/color.rs @@ -76,12 +76,6 @@ impl Color for RGBAColor { } } -impl From for RGBAColor { - fn from(rgb: RGBColor) -> Self { - Self(rgb.0, rgb.1, rgb.2, 1.0) - } -} - /// A color in the given palette #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default)] pub struct PaletteColor(usize, PhantomData

); diff --git a/plotters/src/test.rs b/plotters/src/test.rs index 2c94f082..59ba2e60 100644 --- a/plotters/src/test.rs +++ b/plotters/src/test.rs @@ -12,11 +12,3 @@ fn regression_test_issue_267() { .draw_line(p1, p2, &RGBColor(0, 0, 0).stroke_width(0)) .unwrap(); } - -#[test] -fn from_trait_impl_rgba_color() { - let rgb = RGBColor(1, 2, 3); - let c = RGBAColor::from(rgb); - - assert_eq!(c.rgb(), rgb.rgb()); -} From 8a3467c5bbec7b1f8089146c0fc29a6b0c096ec3 Mon Sep 17 00:00:00 2001 From: "Fabio A. Correa" Date: Sat, 10 Sep 2022 22:10:02 -0400 Subject: [PATCH 10/27] Removed plotters-svg version requirement to avoid CI failure --- plotters/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/plotters/Cargo.toml b/plotters/Cargo.toml index 8326baa3..4d874f32 100644 --- a/plotters/Cargo.toml +++ b/plotters/Cargo.toml @@ -25,7 +25,6 @@ optional = true path = "../plotters-bitmap" [dependencies.plotters-svg] -version = "^0.3" optional = true path = "../plotters-svg" From 25a2f867b7e06d397b74451a3fb78ccf267358b3 Mon Sep 17 00:00:00 2001 From: Mark Beinker Date: Thu, 13 Oct 2022 23:23:53 +0200 Subject: [PATCH 11/27] Unit tests for TimeValue unmap added --- plotters/src/coord/ranged1d/types/datetime.rs | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/plotters/src/coord/ranged1d/types/datetime.rs b/plotters/src/coord/ranged1d/types/datetime.rs index 9b12358c..6c96e8f7 100644 --- a/plotters/src/coord/ranged1d/types/datetime.rs +++ b/plotters/src/coord/ranged1d/types/datetime.rs @@ -1168,4 +1168,52 @@ mod test { assert_eq!(coord1.index_of(&coord1.from_index(i).unwrap()).unwrap(), i); } } + + #[test] + fn test_datetime_with_unmap() { + let start_time = Utc.ymd(2021, 1, 1).and_hms(8, 0, 0); + let end_time = Utc.ymd(2023, 1,1,).and_hms(8, 0, 0); + let mid = Utc.ymd(2022, 1, 1).and_hms(8, 0, 0); + let coord: RangedDate> = (start_time..end_time).into(); + let pos = coord.map(&mid, (1000, 2000)); + assert_eq!(pos, 1500); + let value = coord.unmap(pos, (1000, 2000)); + assert_eq!(value, Some(mid)); + } + + #[test] + fn test_naivedatetime_with_unmap() { + let start_time = chrono::NaiveDate::from_ymd(2021, 1, 1).and_hms_milli(8, 0, 0, 0); + let end_time = chrono::NaiveDate::from_ymd(2023, 1,1,).and_hms_milli(8, 0, 0, 0); + let mid = chrono::NaiveDate::from_ymd(2022, 1, 1).and_hms_milli(8, 0, 0, 0); + let coord: RangedDate = (start_time..end_time).into(); + let pos = coord.map(&mid, (1000, 2000)); + assert_eq!(pos, 1500); + let value = coord.unmap(pos, (1000, 2000)); + assert_eq!(value, Some(mid)); + } + + #[test] + fn test_date_with_unmap() { + let start_date = Utc.ymd(2021, 1, 1); + let end_date= Utc.ymd(2023, 1,1,); + let mid = Utc.ymd(2022, 1, 1); + let coord: RangedDate> = (start_date..end_date).into(); + let pos = coord.map(&mid, (1000, 2000)); + assert_eq!(pos, 1500); + let value = coord.unmap(pos, (1000, 2000)); + assert_eq!(value, Some(mid)); + } + + #[test] + fn test_naivedate_with_unmap() { + let start_date = chrono::NaiveDate::from_ymd(2021, 1, 1); + let end_date= chrono::NaiveDate::from_ymd(2023, 1,1,); + let mid = chrono::NaiveDate::from_ymd(2022, 1, 1); + let coord: RangedDate = (start_date..end_date).into(); + let pos = coord.map(&mid, (1000, 2000)); + assert_eq!(pos, 1500); + let value = coord.unmap(pos, (1000, 2000)); + assert_eq!(value, Some(mid)); + } } From 463c2b8a63a97a88154f50f7167dc1bec65f6103 Mon Sep 17 00:00:00 2001 From: Mark Beinker Date: Fri, 14 Oct 2022 17:53:13 +0200 Subject: [PATCH 12/27] implement ReversibleRanged for TimeValue --- plotters/src/coord/ranged1d/types/datetime.rs | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/plotters/src/coord/ranged1d/types/datetime.rs b/plotters/src/coord/ranged1d/types/datetime.rs index 6c96e8f7..b5eb90ce 100644 --- a/plotters/src/coord/ranged1d/types/datetime.rs +++ b/plotters/src/coord/ranged1d/types/datetime.rs @@ -4,12 +4,12 @@ use std::ops::{Add, Range, Sub}; use crate::coord::ranged1d::{ AsRangedCoord, DefaultFormatting, DiscreteRanged, KeyPointHint, NoDefaultFormatting, Ranged, - ValueFormatter, + ReversibleRanged, ValueFormatter, }; /// The trait that describe some time value. This is the uniformed abstraction that works /// for both Date, DateTime and Duration, etc. -pub trait TimeValue: Eq { +pub trait TimeValue: Eq + Sized { type DateType: Datelike + PartialOrd; /// Returns the date that is no later than the time @@ -20,6 +20,8 @@ pub trait TimeValue: Eq { fn earliest_after_date(date: Self::DateType) -> Self; /// Returns the duration between two time value fn subtract(&self, other: &Self) -> Duration; + /// Add duration to time value + fn add(&self, duration: &Duration) -> Self; /// Instantiate a date type for current time value; fn ymd(&self, year: i32, month: u32, date: u32) -> Self::DateType; /// Cast current date type into this type @@ -46,6 +48,25 @@ pub trait TimeValue: Eq { (f64::from(limit.1 - limit.0) * value_days / total_days) as i32 + limit.0 } + + /// Map pixel to coord spec + fn unmap_coord(point: i32, begin: &Self, end: &Self, limit: (i32, i32)) -> Self { + let total_span = end.subtract(begin); + let offset = (point - limit.0) as i64; + + // Check if nanoseconds fit in i64 + if let Some(total_ns) = total_span.num_nanoseconds() { + if i64::MAX/total_ns < offset.abs() { + let nano_seconds = offset*total_ns/((limit.1-limit.0) as i64); + return begin.add(&Duration::nanoseconds(nano_seconds)); + } + } + + // Otherwise, use days + let total_days = total_span.num_days() as f64; + let days = (((offset as f64)*total_days)/((limit.1-limit.0) as f64)) as i64; + begin.add(&Duration::days(days)) + } } impl TimeValue for NaiveDate { @@ -62,6 +83,9 @@ impl TimeValue for NaiveDate { fn subtract(&self, other: &NaiveDate) -> Duration { *self - *other } + fn add(&self, other: &Duration) -> NaiveDate { + self.clone() + *other + } fn ymd(&self, year: i32, month: u32, date: u32) -> Self::DateType { NaiveDate::from_ymd(year, month, date) @@ -86,6 +110,9 @@ impl TimeValue for Date { fn subtract(&self, other: &Date) -> Duration { self.clone() - other.clone() } + fn add(&self, other: &Duration) -> Date { + self.clone() + other.clone() + } fn ymd(&self, year: i32, month: u32, date: u32) -> Self::DateType { self.timezone().ymd(year, month, date) @@ -115,6 +142,9 @@ impl TimeValue for DateTime { fn subtract(&self, other: &DateTime) -> Duration { self.clone() - other.clone() } + fn add(&self, other: &Duration) -> DateTime { + self.clone() + *other + } fn ymd(&self, year: i32, month: u32, date: u32) -> Self::DateType { self.timezone().ymd(year, month, date) @@ -144,6 +174,9 @@ impl TimeValue for NaiveDateTime { fn subtract(&self, other: &NaiveDateTime) -> Duration { *self - *other } + fn add(&self, other: &Duration) -> NaiveDateTime { + *self + *other + } fn ymd(&self, year: i32, month: u32, date: u32) -> Self::DateType { NaiveDate::from_ymd(year, month, date) @@ -663,6 +696,19 @@ where } } +impl

ReversibleRanged for RangedDateTime
+where + DT: Datelike + Timelike + TimeValue + Clone + PartialOrd, + DT: Add, + DT: Sub, + RangedDate: Ranged, +{ + /// Perform the reverse mapping + fn unmap(&self, input: i32, limit: (i32, i32)) -> Option { + Some(TimeValue::unmap_coord(input, &self.0, &self.1, limit)) + } +} + /// The coordinate that for duration of time #[derive(Clone)] pub struct RangedDuration(Duration, Duration); From e64880c175aec7d39e3bc30a4148e41608837c48 Mon Sep 17 00:00:00 2001 From: Mark Beinker Date: Sat, 15 Oct 2022 23:37:11 +0200 Subject: [PATCH 13/27] Fixed rounding issue --- plotters/src/coord/ranged1d/types/datetime.rs | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/plotters/src/coord/ranged1d/types/datetime.rs b/plotters/src/coord/ranged1d/types/datetime.rs index b5eb90ce..d4adb0cc 100644 --- a/plotters/src/coord/ranged1d/types/datetime.rs +++ b/plotters/src/coord/ranged1d/types/datetime.rs @@ -48,23 +48,24 @@ pub trait TimeValue: Eq + Sized { (f64::from(limit.1 - limit.0) * value_days / total_days) as i32 + limit.0 } - + /// Map pixel to coord spec fn unmap_coord(point: i32, begin: &Self, end: &Self, limit: (i32, i32)) -> Self { let total_span = end.subtract(begin); let offset = (point - limit.0) as i64; - + // Check if nanoseconds fit in i64 if let Some(total_ns) = total_span.num_nanoseconds() { - if i64::MAX/total_ns < offset.abs() { - let nano_seconds = offset*total_ns/((limit.1-limit.0) as i64); + let factor = total_ns / ((limit.1 - limit.0) as i64); + if i64::MAX / factor > offset.abs() { + let nano_seconds = offset * factor; return begin.add(&Duration::nanoseconds(nano_seconds)); } } - + // Otherwise, use days let total_days = total_span.num_days() as f64; - let days = (((offset as f64)*total_days)/((limit.1-limit.0) as f64)) as i64; + let days = (((offset as f64) * total_days) / ((limit.1 - limit.0) as f64)) as i64; begin.add(&Duration::days(days)) } } @@ -1214,11 +1215,11 @@ mod test { assert_eq!(coord1.index_of(&coord1.from_index(i).unwrap()).unwrap(), i); } } - + #[test] fn test_datetime_with_unmap() { let start_time = Utc.ymd(2021, 1, 1).and_hms(8, 0, 0); - let end_time = Utc.ymd(2023, 1,1,).and_hms(8, 0, 0); + let end_time = Utc.ymd(2023, 1, 1).and_hms(8, 0, 0); let mid = Utc.ymd(2022, 1, 1).and_hms(8, 0, 0); let coord: RangedDate> = (start_time..end_time).into(); let pos = coord.map(&mid, (1000, 2000)); @@ -1226,11 +1227,11 @@ mod test { let value = coord.unmap(pos, (1000, 2000)); assert_eq!(value, Some(mid)); } - + #[test] fn test_naivedatetime_with_unmap() { let start_time = chrono::NaiveDate::from_ymd(2021, 1, 1).and_hms_milli(8, 0, 0, 0); - let end_time = chrono::NaiveDate::from_ymd(2023, 1,1,).and_hms_milli(8, 0, 0, 0); + let end_time = chrono::NaiveDate::from_ymd(2023, 1, 1).and_hms_milli(8, 0, 0, 0); let mid = chrono::NaiveDate::from_ymd(2022, 1, 1).and_hms_milli(8, 0, 0, 0); let coord: RangedDate = (start_time..end_time).into(); let pos = coord.map(&mid, (1000, 2000)); @@ -1238,11 +1239,11 @@ mod test { let value = coord.unmap(pos, (1000, 2000)); assert_eq!(value, Some(mid)); } - + #[test] fn test_date_with_unmap() { let start_date = Utc.ymd(2021, 1, 1); - let end_date= Utc.ymd(2023, 1,1,); + let end_date = Utc.ymd(2023, 1, 1); let mid = Utc.ymd(2022, 1, 1); let coord: RangedDate> = (start_date..end_date).into(); let pos = coord.map(&mid, (1000, 2000)); @@ -1250,11 +1251,11 @@ mod test { let value = coord.unmap(pos, (1000, 2000)); assert_eq!(value, Some(mid)); } - + #[test] fn test_naivedate_with_unmap() { let start_date = chrono::NaiveDate::from_ymd(2021, 1, 1); - let end_date= chrono::NaiveDate::from_ymd(2023, 1,1,); + let end_date = chrono::NaiveDate::from_ymd(2023, 1, 1); let mid = chrono::NaiveDate::from_ymd(2022, 1, 1); let coord: RangedDate = (start_date..end_date).into(); let pos = coord.map(&mid, (1000, 2000)); From 6bb34ffa62fb865dfe783e63d0da08514d90c68c Mon Sep 17 00:00:00 2001 From: Mark Beinker Date: Sun, 16 Oct 2022 13:01:09 +0200 Subject: [PATCH 14/27] Fix unmap for small TimeValue periods --- plotters/src/coord/ranged1d/types/datetime.rs | 59 ++++++++++++++----- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/plotters/src/coord/ranged1d/types/datetime.rs b/plotters/src/coord/ranged1d/types/datetime.rs index d4adb0cc..0a532f8a 100644 --- a/plotters/src/coord/ranged1d/types/datetime.rs +++ b/plotters/src/coord/ranged1d/types/datetime.rs @@ -56,9 +56,14 @@ pub trait TimeValue: Eq + Sized { // Check if nanoseconds fit in i64 if let Some(total_ns) = total_span.num_nanoseconds() { - let factor = total_ns / ((limit.1 - limit.0) as i64); - if i64::MAX / factor > offset.abs() { - let nano_seconds = offset * factor; + let pixel_span = (limit.1 - limit.0) as i64; + let factor = total_ns / pixel_span; + let remainder = total_ns % pixel_span; + if factor == 0 + || i64::MAX / factor > offset.abs() + || (remainder == 0 && i64::MAX / factor >= offset.abs()) + { + let nano_seconds = offset * factor + (remainder * offset) / pixel_span; return begin.add(&Duration::nanoseconds(nano_seconds)); } } @@ -85,7 +90,7 @@ impl TimeValue for NaiveDate { *self - *other } fn add(&self, other: &Duration) -> NaiveDate { - self.clone() + *other + *self + *other } fn ymd(&self, year: i32, month: u32, date: u32) -> Self::DateType { @@ -112,7 +117,7 @@ impl TimeValue for Date { self.clone() - other.clone() } fn add(&self, other: &Duration) -> Date { - self.clone() + other.clone() + self.clone() + *other } fn ymd(&self, year: i32, month: u32, date: u32) -> Self::DateType { @@ -1221,7 +1226,7 @@ mod test { let start_time = Utc.ymd(2021, 1, 1).and_hms(8, 0, 0); let end_time = Utc.ymd(2023, 1, 1).and_hms(8, 0, 0); let mid = Utc.ymd(2022, 1, 1).and_hms(8, 0, 0); - let coord: RangedDate> = (start_time..end_time).into(); + let coord: RangedDateTime<_> = (start_time..end_time).into(); let pos = coord.map(&mid, (1000, 2000)); assert_eq!(pos, 1500); let value = coord.unmap(pos, (1000, 2000)); @@ -1230,10 +1235,10 @@ mod test { #[test] fn test_naivedatetime_with_unmap() { - let start_time = chrono::NaiveDate::from_ymd(2021, 1, 1).and_hms_milli(8, 0, 0, 0); - let end_time = chrono::NaiveDate::from_ymd(2023, 1, 1).and_hms_milli(8, 0, 0, 0); - let mid = chrono::NaiveDate::from_ymd(2022, 1, 1).and_hms_milli(8, 0, 0, 0); - let coord: RangedDate = (start_time..end_time).into(); + let start_time = NaiveDate::from_ymd(2021, 1, 1).and_hms_milli(8, 0, 0, 0); + let end_time = NaiveDate::from_ymd(2023, 1, 1).and_hms_milli(8, 0, 0, 0); + let mid = NaiveDate::from_ymd(2022, 1, 1).and_hms_milli(8, 0, 0, 0); + let coord: RangedDateTime<_> = (start_time..end_time).into(); let pos = coord.map(&mid, (1000, 2000)); assert_eq!(pos, 1500); let value = coord.unmap(pos, (1000, 2000)); @@ -1245,7 +1250,7 @@ mod test { let start_date = Utc.ymd(2021, 1, 1); let end_date = Utc.ymd(2023, 1, 1); let mid = Utc.ymd(2022, 1, 1); - let coord: RangedDate> = (start_date..end_date).into(); + let coord: RangedDate> = (start_date..end_date).into(); let pos = coord.map(&mid, (1000, 2000)); assert_eq!(pos, 1500); let value = coord.unmap(pos, (1000, 2000)); @@ -1254,13 +1259,37 @@ mod test { #[test] fn test_naivedate_with_unmap() { - let start_date = chrono::NaiveDate::from_ymd(2021, 1, 1); - let end_date = chrono::NaiveDate::from_ymd(2023, 1, 1); - let mid = chrono::NaiveDate::from_ymd(2022, 1, 1); - let coord: RangedDate = (start_date..end_date).into(); + let start_date = NaiveDate::from_ymd(2021, 1, 1); + let end_date = NaiveDate::from_ymd(2023, 1, 1); + let mid = NaiveDate::from_ymd(2022, 1, 1); + let coord: RangedDate = (start_date..end_date).into(); let pos = coord.map(&mid, (1000, 2000)); assert_eq!(pos, 1500); let value = coord.unmap(pos, (1000, 2000)); assert_eq!(value, Some(mid)); } + + #[test] + fn test_datetime_unmap_for_nanoseconds() { + let start_time = Utc.ymd(2021, 1, 1).and_hms(8, 0, 0); + let end_time = start_time + Duration::nanoseconds(1900); + let mid = start_time + Duration::nanoseconds(950); + let coord: RangedDateTime<_> = (start_time..end_time).into(); + let pos = coord.map(&mid, (1000, 2000)); + assert_eq!(pos, 1500); + let value = coord.unmap(pos, (1000, 2000)); + assert_eq!(value, Some(mid)); + } + + #[test] + fn test_datetime_unmap_for_nanoseconds_small_period() { + let start_time = Utc.ymd(2021, 1, 1).and_hms(8, 0, 0); + let end_time = start_time + Duration::nanoseconds(400); + let coord: RangedDateTime<_> = (start_time..end_time).into(); + let value = coord.unmap(2000, (1000, 2000)); + assert_eq!(value, Some(end_time)); + let mid = start_time + Duration::nanoseconds(200); + let value = coord.unmap(500, (0, 1000)); + assert_eq!(value, Some(mid)); + } } From d014ebf5f1238c87d644ac34891296faa5c4a5fd Mon Sep 17 00:00:00 2001 From: raldone01 Date: Sun, 8 Jan 2023 13:39:14 +0100 Subject: [PATCH 15/27] Make error type `'static`. --- plotters-backend/src/lib.rs | 2 +- plotters/examples/console.rs | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/plotters-backend/src/lib.rs b/plotters-backend/src/lib.rs index d4fd904c..823d1863 100644 --- a/plotters-backend/src/lib.rs +++ b/plotters-backend/src/lib.rs @@ -105,7 +105,7 @@ impl Error for DrawingErrorKind {} /// will use the pixel-based approach to draw other types of low-level shapes. pub trait DrawingBackend: Sized { /// The error type reported by the backend - type ErrorType: Error + Send + Sync; + type ErrorType: Error + Send + Sync + 'static; /// Get the dimension of the drawing backend in pixels fn get_size(&self) -> (u32, u32); diff --git a/plotters/examples/console.rs b/plotters/examples/console.rs index feba0956..441fd57d 100644 --- a/plotters/examples/console.rs +++ b/plotters/examples/console.rs @@ -151,10 +151,7 @@ impl DrawingBackend for TextDrawingBackend { fn draw_chart( b: DrawingArea, -) -> Result<(), Box> -where - DB::ErrorType: 'static, -{ +) -> Result<(), Box> { let mut chart = ChartBuilder::on(&b) .margin(1) .caption("Sine and Cosine", ("sans-serif", (10).percent_height())) From 4eec72e0ae62ad15ce288c88aef9c07223f25143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iver=20Sm=C3=A5ge=20men=20b=C3=A6rbar?= Date: Thu, 23 Feb 2023 18:18:45 +0100 Subject: [PATCH 16/27] add transformation queue --- plotters/src/coord/ranged3d/projection.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/plotters/src/coord/ranged3d/projection.rs b/plotters/src/coord/ranged3d/projection.rs index a9c57c1b..8ad0acc1 100644 --- a/plotters/src/coord/ranged3d/projection.rs +++ b/plotters/src/coord/ranged3d/projection.rs @@ -140,7 +140,7 @@ impl ProjectionMatrix { } /// The helper struct to build a projection matrix -#[derive(Copy, Clone)] +#[derive(Clone)] pub struct ProjectionMatrixBuilder { /// Specifies the yaw of the 3D coordinate system pub yaw: f64, @@ -150,6 +150,7 @@ pub struct ProjectionMatrixBuilder { pub scale: f64, pivot_before: (i32, i32, i32), pivot_after: (i32, i32), + transformation_queue: Vec, } impl Default for ProjectionMatrixBuilder { @@ -160,6 +161,7 @@ impl Default for ProjectionMatrixBuilder { scale: 1.0, pivot_after: (0, 0), pivot_before: (0, 0, 0), + transformation_queue: [].to_vec(), } } } @@ -178,6 +180,12 @@ impl ProjectionMatrixBuilder { self } + /// Adds matrix to list of transformations to apply + pub fn add_transform(&mut self, projection: ProjectionMatrix) -> &mut Self { + self.transformation_queue.push(projection); + self + } + /// Build the matrix based on the configuration pub fn into_matrix(self) -> ProjectionMatrix { let mut ret = if self.pivot_before == (0, 0, 0) { @@ -187,6 +195,10 @@ impl ProjectionMatrixBuilder { ProjectionMatrix::shift(-x as f64, -y as f64, -z as f64) * ProjectionMatrix::default() }; + for transform in self.transformation_queue { + ret = ret * transform; + } + if self.yaw.abs() > 1e-20 { ret = ret * ProjectionMatrix::rotate(0.0, self.yaw, 0.0); } From 789e4a1655ec75d29d76401971225ec45119bbda Mon Sep 17 00:00:00 2001 From: Vincent Foulon Date: Fri, 7 Apr 2023 09:09:37 +0200 Subject: [PATCH 17/27] Allow custom rotation in degrees, for backends that supports it (e.g. SVG) Add comments --- plotters-svg/src/svg.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plotters-svg/src/svg.rs b/plotters-svg/src/svg.rs index 1c047b68..75b69076 100644 --- a/plotters-svg/src/svg.rs +++ b/plotters-svg/src/svg.rs @@ -8,12 +8,12 @@ use plotters_backend::{ FontStyle, FontTransform, }; +use std::fmt::Write as _; use std::fs::File; #[allow(unused_imports)] use std::io::Cursor; use std::io::{BufWriter, Error, Write}; use std::path::Path; -use std::fmt::Write as _; fn make_svg_color(color: BackendColor) -> String { let (r, g, b) = color.rgb; @@ -459,6 +459,9 @@ impl<'a> DrawingBackend for SVGBackend<'a> { FontTransform::Rotate270 => { attrs.push(("transform", format!("rotate(270, {}, {})", x0, y0))); } + FontTransform::RotateAngle(deg) => { + attrs.push(("transform", format!("rotate({deg}, {x0}, {y0})"))) + } _ => {} } From fa604ae4176b0fc3f19720527408026a01bcf9a7 Mon Sep 17 00:00:00 2001 From: Vincent Foulon Date: Fri, 7 Apr 2023 00:53:47 +0200 Subject: [PATCH 18/27] Add HPos and VPos::Default to allow the user to override axes label anchors --- plotters-backend/src/lib.rs | 4 ++-- plotters-backend/src/text.rs | 10 ++++++++-- plotters-svg/src/svg.rs | 4 ++-- plotters/examples/console.rs | 4 ++-- plotters/src/chart/context/cartesian2d/draw_impl.rs | 10 ++++++++++ 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/plotters-backend/src/lib.rs b/plotters-backend/src/lib.rs index 823d1863..410bf136 100644 --- a/plotters-backend/src/lib.rs +++ b/plotters-backend/src/lib.rs @@ -236,12 +236,12 @@ pub trait DrawingBackend: Sized { let width = (max_x - min_x) as i32; let height = (max_y - min_y) as i32; let dx = match style.anchor().h_pos { - HPos::Left => 0, + HPos::Left | HPos::Default => 0, HPos::Right => -width, HPos::Center => -width / 2, }; let dy = match style.anchor().v_pos { - VPos::Top => 0, + VPos::Top | VPos::Default => 0, VPos::Center => -height / 2, VPos::Bottom => -height, }; diff --git a/plotters-backend/src/text.rs b/plotters-backend/src/text.rs index ff901876..bcf3a7a8 100644 --- a/plotters-backend/src/text.rs +++ b/plotters-backend/src/text.rs @@ -62,6 +62,9 @@ pub mod text_anchor { /// The horizontal position of the anchor point relative to the text. #[derive(Clone, Copy)] pub enum HPos { + /// Default value (Left), except chart axes that might provide a different pos. + /// Use another variant to override the default positionning + Default, /// Anchor point is on the left side of the text Left, /// Anchor point is on the right side of the text @@ -73,6 +76,9 @@ pub mod text_anchor { /// The vertical position of the anchor point relative to the text. #[derive(Clone, Copy)] pub enum VPos { + /// Default value (Top), except chart axes that might provide a different pos + /// Use another variant to override the default positionning + Default, /// Anchor point is on the top of the text Top, /// Anchor point is in the vertical center of the text @@ -117,8 +123,8 @@ pub mod text_anchor { /// ``` pub fn default() -> Self { Pos { - h_pos: HPos::Left, - v_pos: VPos::Top, + h_pos: HPos::Default, + v_pos: VPos::Default, } } } diff --git a/plotters-svg/src/svg.rs b/plotters-svg/src/svg.rs index 1c047b68..36f3a00d 100644 --- a/plotters-svg/src/svg.rs +++ b/plotters-svg/src/svg.rs @@ -395,13 +395,13 @@ impl<'a> DrawingBackend for SVGBackend<'a> { let (x0, y0) = pos; let text_anchor = match style.anchor().h_pos { - HPos::Left => "start", + HPos::Left | HPos::Default => "start", HPos::Right => "end", HPos::Center => "middle", }; let dy = match style.anchor().v_pos { - VPos::Top => "0.76em", + VPos::Top | VPos::Default => "0.76em", VPos::Center => "0.5ex", VPos::Bottom => "-0.5ex", }; diff --git a/plotters/examples/console.rs b/plotters/examples/console.rs index 441fd57d..49fc393b 100644 --- a/plotters/examples/console.rs +++ b/plotters/examples/console.rs @@ -132,12 +132,12 @@ impl DrawingBackend for TextDrawingBackend { let (width, height) = self.estimate_text_size(text, style)?; let (width, height) = (width as i32, height as i32); let dx = match style.anchor().h_pos { - HPos::Left => 0, + HPos::Left | HPos::Default => 0, HPos::Right => -width, HPos::Center => -width / 2, }; let dy = match style.anchor().v_pos { - VPos::Top => 0, + VPos::Top | VPos::Default => 0, VPos::Center => -height / 2, VPos::Bottom => -height, }; diff --git a/plotters/src/chart/context/cartesian2d/draw_impl.rs b/plotters/src/chart/context/cartesian2d/draw_impl.rs index 6dafa087..e52f976a 100644 --- a/plotters/src/chart/context/cartesian2d/draw_impl.rs +++ b/plotters/src/chart/context/cartesian2d/draw_impl.rs @@ -250,6 +250,16 @@ impl<'a, DB: DrawingBackend, X: Ranged, Y: Ranged> ChartContext<'a, DB, Cartesia (cx, cy + label_offset) }; + let h_pos = if matches!(label_style.pos.h_pos, HPos::Default) { + h_pos + } else { + label_style.pos.h_pos + }; + let v_pos = if matches!(label_style.pos.v_pos, VPos::Default) { + v_pos + } else { + label_style.pos.v_pos + }; let label_style = &label_style.pos(Pos::new(h_pos, v_pos)); area.draw_text(t, label_style, (text_x, text_y))?; From c4bead218cc8fda74a1e777701060545929e192a Mon Sep 17 00:00:00 2001 From: Vincent Foulon Date: Fri, 7 Apr 2023 16:45:11 +0200 Subject: [PATCH 19/27] Derive Default trait for HPos, VPos and Pos --- plotters-backend/src/text.rs | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/plotters-backend/src/text.rs b/plotters-backend/src/text.rs index bcf3a7a8..4acd931b 100644 --- a/plotters-backend/src/text.rs +++ b/plotters-backend/src/text.rs @@ -60,10 +60,11 @@ impl<'a> From<&'a str> for FontFamily<'a> { /// ``` pub mod text_anchor { /// The horizontal position of the anchor point relative to the text. - #[derive(Clone, Copy)] + #[derive(Default, Clone, Copy)] pub enum HPos { /// Default value (Left), except chart axes that might provide a different pos. /// Use another variant to override the default positionning + #[default] Default, /// Anchor point is on the left side of the text Left, @@ -74,10 +75,11 @@ pub mod text_anchor { } /// The vertical position of the anchor point relative to the text. - #[derive(Clone, Copy)] + #[derive(Default, Clone, Copy)] pub enum VPos { /// Default value (Top), except chart axes that might provide a different pos /// Use another variant to override the default positionning + #[default] Default, /// Anchor point is on the top of the text Top, @@ -88,7 +90,7 @@ pub mod text_anchor { } /// The text anchor position. - #[derive(Clone, Copy)] + #[derive(Default, Clone, Copy)] pub struct Pos { /// The horizontal position of the anchor point pub h_pos: HPos, @@ -111,22 +113,6 @@ pub mod text_anchor { pub fn new(h_pos: HPos, v_pos: VPos) -> Self { Pos { h_pos, v_pos } } - - /// Create a default text anchor position (top left). - /// - /// - **returns** The default text anchor position - /// - /// ```rust - /// use plotters_backend::text_anchor::{Pos, HPos, VPos}; - /// - /// let pos = Pos::default(); - /// ``` - pub fn default() -> Self { - Pos { - h_pos: HPos::Default, - v_pos: VPos::Default, - } - } } } From 7dd77a43275bd19317ff5e1448e67190f3eb21d8 Mon Sep 17 00:00:00 2001 From: Yuyi Wang Date: Thu, 20 Apr 2023 16:46:33 +0800 Subject: [PATCH 20/27] Fix unaligned write in bitmap backend. --- plotters-bitmap/src/bitmap_pixel/rgb.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plotters-bitmap/src/bitmap_pixel/rgb.rs b/plotters-bitmap/src/bitmap_pixel/rgb.rs index e8b88216..b7eae78f 100644 --- a/plotters-bitmap/src/bitmap_pixel/rgb.rs +++ b/plotters-bitmap/src/bitmap_pixel/rgb.rs @@ -212,9 +212,9 @@ impl PixelFormat for RGBPixel { b, r, g, b, r, g, b, r, // QW2 g, b, r, g, b, r, g, b, // QW3 ]); - *ptr = d1; - *ptr.offset(1) = d2; - *ptr.offset(2) = d3; + ptr.write_unaligned(d1); + ptr.offset(1).write_unaligned(d2); + ptr.offset(2).write_unaligned(d3); } } From 92d91d2e5c14d8fce86461dfa054ba3a46dc5db4 Mon Sep 17 00:00:00 2001 From: Yuyi Wang Date: Thu, 20 Apr 2023 16:51:08 +0800 Subject: [PATCH 21/27] Fix unaligned read. --- plotters-bitmap/src/bitmap_pixel/rgb.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plotters-bitmap/src/bitmap_pixel/rgb.rs b/plotters-bitmap/src/bitmap_pixel/rgb.rs index b7eae78f..8d4ed07d 100644 --- a/plotters-bitmap/src/bitmap_pixel/rgb.rs +++ b/plotters-bitmap/src/bitmap_pixel/rgb.rs @@ -95,7 +95,7 @@ impl PixelFormat for RGBPixel { let slice = unsafe { std::slice::from_raw_parts_mut(start_ptr, (count - 1) / 8) }; for p in slice.iter_mut() { let ptr = p as *mut [u8; 24] as *mut (u64, u64, u64); - let (d1, d2, d3) = unsafe { *ptr }; + let (d1, d2, d3) = unsafe { ptr.read_unaligned() }; let (mut h1, mut h2, mut h3) = ((d1 >> 8) & M, (d2 >> 8) & M, (d3 >> 8) & M); let (mut l1, mut l2, mut l3) = (d1 & M, d2 & M, d3 & M); From 548561216152b4e4d455f416cda51d4dd9def88d Mon Sep 17 00:00:00 2001 From: Yuyi Wang Date: Thu, 20 Apr 2023 16:53:13 +0800 Subject: [PATCH 22/27] Fix another unaligned write. --- plotters-bitmap/src/bitmap_pixel/rgb.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plotters-bitmap/src/bitmap_pixel/rgb.rs b/plotters-bitmap/src/bitmap_pixel/rgb.rs index 8d4ed07d..2024fddf 100644 --- a/plotters-bitmap/src/bitmap_pixel/rgb.rs +++ b/plotters-bitmap/src/bitmap_pixel/rgb.rs @@ -120,7 +120,7 @@ impl PixelFormat for RGBPixel { } unsafe { - *ptr = (h1 | l1, h2 | l2, h3 | l3); + ptr.write_unaligned((h1 | l1, h2 | l2, h3 | l3)); } } From 1355455c21590973143bb6d9f34294531aeb5385 Mon Sep 17 00:00:00 2001 From: Yuyi Wang Date: Thu, 20 Apr 2023 19:45:39 +0800 Subject: [PATCH 23/27] Use array instead of tuple. --- plotters-bitmap/src/bitmap_pixel/rgb.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plotters-bitmap/src/bitmap_pixel/rgb.rs b/plotters-bitmap/src/bitmap_pixel/rgb.rs index 2024fddf..39b3f502 100644 --- a/plotters-bitmap/src/bitmap_pixel/rgb.rs +++ b/plotters-bitmap/src/bitmap_pixel/rgb.rs @@ -67,7 +67,7 @@ impl PixelFormat for RGBPixel { // Since we should always make sure the RGB payload occupies the logic lower bits // thus, this type purning should work for both LE and BE CPUs #[rustfmt::skip] - let (p1, p2, p3): (u64, u64, u64) = unsafe { + let [p1, p2, p3]: [u64; 3] = unsafe { std::mem::transmute([ u16::from(r), u16::from(b), u16::from(g), u16::from(r), // QW1 u16::from(b), u16::from(g), u16::from(r), u16::from(b), // QW2 @@ -76,7 +76,7 @@ impl PixelFormat for RGBPixel { }; #[rustfmt::skip] - let (q1, q2, q3): (u64, u64, u64) = unsafe { + let [q1, q2, q3]: [u64; 3] = unsafe { std::mem::transmute([ u16::from(g), u16::from(r), u16::from(b), u16::from(g), // QW1 u16::from(r), u16::from(b), u16::from(g), u16::from(r), // QW2 @@ -94,8 +94,8 @@ impl PixelFormat for RGBPixel { let start_ptr = &mut dst[start * Self::PIXEL_SIZE] as *mut u8 as *mut [u8; 24]; let slice = unsafe { std::slice::from_raw_parts_mut(start_ptr, (count - 1) / 8) }; for p in slice.iter_mut() { - let ptr = p as *mut [u8; 24] as *mut (u64, u64, u64); - let (d1, d2, d3) = unsafe { ptr.read_unaligned() }; + let ptr = p as *mut [u8; 24] as *mut [u64; 3]; + let [d1, d2, d3] = unsafe { ptr.read_unaligned() }; let (mut h1, mut h2, mut h3) = ((d1 >> 8) & M, (d2 >> 8) & M, (d3 >> 8) & M); let (mut l1, mut l2, mut l3) = (d1 & M, d2 & M, d3 & M); @@ -120,7 +120,7 @@ impl PixelFormat for RGBPixel { } unsafe { - ptr.write_unaligned((h1 | l1, h2 | l2, h3 | l3)); + ptr.write_unaligned([h1 | l1, h2 | l2, h3 | l3]); } } @@ -207,7 +207,7 @@ impl PixelFormat for RGBPixel { // TODO: Consider using AVX instructions when possible let ptr = p as *mut [u8; 24] as *mut u64; unsafe { - let (d1, d2, d3): (u64, u64, u64) = std::mem::transmute([ + let [d1, d2, d3]: [u64; 3] = std::mem::transmute([ r, g, b, r, g, b, r, g, // QW1 b, r, g, b, r, g, b, r, // QW2 g, b, r, g, b, r, g, b, // QW3 From da3b24111ce395fa8e0772d20b1eeba5a9dd62b2 Mon Sep 17 00:00:00 2001 From: Berrysoft Date: Thu, 20 Apr 2023 19:49:56 +0800 Subject: [PATCH 24/27] Also fix for bgrx. --- plotters-bitmap/src/bitmap_pixel/bgrx.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plotters-bitmap/src/bitmap_pixel/bgrx.rs b/plotters-bitmap/src/bitmap_pixel/bgrx.rs index 16bcd25e..2f90d9d5 100644 --- a/plotters-bitmap/src/bitmap_pixel/bgrx.rs +++ b/plotters-bitmap/src/bitmap_pixel/bgrx.rs @@ -87,7 +87,7 @@ impl PixelFormat for BGRXPixel { let slice = unsafe { std::slice::from_raw_parts_mut(start_ptr, (count - 1) / 2) }; for rp in slice.iter_mut() { let ptr = rp as *mut [u8; 8] as *mut u64; - let d1 = unsafe { *ptr }; + let d1 = unsafe { ptr.read_unaligned() }; let mut h = (d1 >> 8) & M; let mut l = d1 & M; @@ -104,7 +104,7 @@ impl PixelFormat for BGRXPixel { } unsafe { - *ptr = h | l; + ptr.write_unaligned(h | l); } } @@ -196,7 +196,7 @@ impl PixelFormat for BGRXPixel { let d: u64 = std::mem::transmute([ b, g, r, 0, b, g, r, 0, // QW1 ]); - *ptr = d; + ptr.write_unaligned(d); } } From 2209ca924a4bc5a65b5497f231ca9e0bef9ccbf8 Mon Sep 17 00:00:00 2001 From: Adrian Ratiu Date: Thu, 28 Dec 2023 22:28:28 +0200 Subject: [PATCH 25/27] types/datetime: replace deprecated chrono::Date* with NaiveDate The chrono crate deprecated the Date and DateTime APIs in favor of NaiveDate* and also added interfaces like from_ymd_opt() which return Options. Many APIs inside Utc::* have also been deprecated. Eventually the deprecated APIs will be removed so this migrates to the new APIs (NaiveDate is already implemented, so we just do the minimal required migration). Deprecation started since 0.4.23: https://docs.rs/chrono/0.4.31/chrono/struct.Date.html While at it, also bump the chrono dep 0.4.20 -> 0.4.31 and fix all test cases. Closes: #530 --- plotters/Cargo.toml | 2 +- plotters/examples/slc-temp.rs | 17 +- plotters/examples/stock.rs | 10 +- plotters/src/coord/ranged1d/types/datetime.rs | 223 +++++++----------- 4 files changed, 101 insertions(+), 151 deletions(-) diff --git a/plotters/Cargo.toml b/plotters/Cargo.toml index 4d874f32..053af3dd 100644 --- a/plotters/Cargo.toml +++ b/plotters/Cargo.toml @@ -14,7 +14,7 @@ exclude = ["doc-template", "plotters-doc-data"] [dependencies] num-traits = "0.2.14" -chrono = { version = "0.4.19", optional = true } +chrono = { version = "0.4.31", optional = true } [dependencies.plotters-backend] path = "../plotters-backend" diff --git a/plotters/examples/slc-temp.rs b/plotters/examples/slc-temp.rs index 9d6e4731..5318cb28 100644 --- a/plotters/examples/slc-temp.rs +++ b/plotters/examples/slc-temp.rs @@ -1,9 +1,16 @@ use plotters::prelude::*; -use chrono::{TimeZone, Utc}; +use chrono::NaiveDate; use std::error::Error; +// it's safe to use unwrap because we use known good values in test cases +macro_rules! create_date { + ($year:expr, $month:expr, $day:expr) => { + NaiveDate::from_ymd_opt($year, $month, $day).unwrap() + }; +} + const OUT_FILE_NAME: &'static str = "plotters-doc-data/slc-temp.png"; fn main() -> Result<(), Box> { let root = BitMapBackend::new(OUT_FILE_NAME, (1024, 768)).into_drawing_area(); @@ -20,11 +27,11 @@ fn main() -> Result<(), Box> { .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(), + (create_date!(2010, 1, 1)..create_date!(2018, 12, 1)).monthly(), 14.0..104.0, )? .set_secondary_coord( - (Utc.ymd(2010, 1, 1)..Utc.ymd(2018, 12, 1)).monthly(), + (create_date!(2010, 1, 1)..create_date!(2018, 12, 1)).monthly(), -10.0..40.0, ); @@ -42,13 +49,13 @@ fn main() -> Result<(), Box> { .draw()?; chart.draw_series(LineSeries::new( - DATA.iter().map(|(y, m, t)| (Utc.ymd(*y, *m, 1), *t)), + DATA.iter().map(|(y, m, t)| (create_date!(*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())), + .map(|(y, m, t)| Circle::new((create_date!(*y, *m, 1), *t), 3, BLUE.filled())), )?; // To avoid the IO failure being ignored silently, we manually call the present function diff --git a/plotters/examples/stock.rs b/plotters/examples/stock.rs index 8e9416f6..29939a69 100644 --- a/plotters/examples/stock.rs +++ b/plotters/examples/stock.rs @@ -1,11 +1,9 @@ -use chrono::offset::{Local, TimeZone}; -use chrono::{Date, Duration}; +use chrono::{DateTime, Duration, NaiveDate}; use plotters::prelude::*; -fn parse_time(t: &str) -> Date { - Local - .datetime_from_str(&format!("{} 0:0", t), "%Y-%m-%d %H:%M") +fn parse_time(t: &str) -> NaiveDate { + DateTime::parse_from_str(&format!("{} 0:0", t), "%Y-%m-%d %H:%M") .unwrap() - .date() + .date_naive() } const OUT_FILE_NAME: &'static str = "plotters-doc-data/stock.png"; fn main() -> Result<(), Box> { diff --git a/plotters/src/coord/ranged1d/types/datetime.rs b/plotters/src/coord/ranged1d/types/datetime.rs index 0a532f8a..5476bf33 100644 --- a/plotters/src/coord/ranged1d/types/datetime.rs +++ b/plotters/src/coord/ranged1d/types/datetime.rs @@ -1,5 +1,5 @@ /// The datetime coordinates -use chrono::{Date, DateTime, Datelike, Duration, NaiveDate, NaiveDateTime, TimeZone, Timelike}; +use chrono::{Datelike, Duration, NaiveDate, NaiveDateTime, Timelike}; use std::ops::{Add, Range, Sub}; use crate::coord::ranged1d::{ @@ -23,7 +23,7 @@ pub trait TimeValue: Eq + Sized { /// Add duration to time value fn add(&self, duration: &Duration) -> Self; /// Instantiate a date type for current time value; - fn ymd(&self, year: i32, month: u32, date: u32) -> Self::DateType; + fn ymd_opt(&self, year: i32, month: u32, date: u32) -> Option; /// Cast current date type into this type fn from_date(date: Self::DateType) -> Self; @@ -93,8 +93,8 @@ impl TimeValue for NaiveDate { *self + *other } - fn ymd(&self, year: i32, month: u32, date: u32) -> Self::DateType { - NaiveDate::from_ymd(year, month, date) + fn ymd_opt(&self, year: i32, month: u32, date: u32) -> Option { + NaiveDate::from_ymd_opt(year, month, date) } fn from_date(date: Self::DateType) -> Self { @@ -102,65 +102,6 @@ impl TimeValue for NaiveDate { } } -impl TimeValue for Date { - type DateType = Date; - fn date_floor(&self) -> Date { - self.clone() - } - fn date_ceil(&self) -> Date { - self.clone() - } - fn earliest_after_date(date: Date) -> Self { - date - } - fn subtract(&self, other: &Date) -> Duration { - self.clone() - other.clone() - } - fn add(&self, other: &Duration) -> Date { - self.clone() + *other - } - - fn ymd(&self, year: i32, month: u32, date: u32) -> Self::DateType { - self.timezone().ymd(year, month, date) - } - - fn from_date(date: Self::DateType) -> Self { - date - } -} - -impl TimeValue for DateTime { - type DateType = Date; - fn date_floor(&self) -> Date { - self.date() - } - fn date_ceil(&self) -> Date { - if self.time().num_seconds_from_midnight() > 0 { - self.date() + Duration::days(1) - } else { - self.date() - } - } - fn earliest_after_date(date: Date) -> DateTime { - date.and_hms(0, 0, 0) - } - - fn subtract(&self, other: &DateTime) -> Duration { - self.clone() - other.clone() - } - fn add(&self, other: &Duration) -> DateTime { - self.clone() + *other - } - - fn ymd(&self, year: i32, month: u32, date: u32) -> Self::DateType { - self.timezone().ymd(year, month, date) - } - - fn from_date(date: Self::DateType) -> Self { - date.and_hms(0, 0, 0) - } -} - impl TimeValue for NaiveDateTime { type DateType = NaiveDate; fn date_floor(&self) -> NaiveDate { @@ -174,7 +115,8 @@ impl TimeValue for NaiveDateTime { } } fn earliest_after_date(date: NaiveDate) -> NaiveDateTime { - date.and_hms(0, 0, 0) + // directly unwrap to avoid nested Options because the op is constant + date.and_hms_opt(0, 0, 0).unwrap() } fn subtract(&self, other: &NaiveDateTime) -> Duration { @@ -184,12 +126,13 @@ impl TimeValue for NaiveDateTime { *self + *other } - fn ymd(&self, year: i32, month: u32, date: u32) -> Self::DateType { - NaiveDate::from_ymd(year, month, date) + fn ymd_opt(&self, year: i32, month: u32, date: u32) -> Option { + NaiveDate::from_ymd_opt(year, month, date) } fn from_date(date: Self::DateType) -> Self { - date.and_hms(0, 0, 0) + // directly unwrap to avoid nested Options because the op is constant + date.and_hms_opt(0, 0, 0).unwrap() } } @@ -276,11 +219,6 @@ where } } -impl AsRangedCoord for Range> { - type CoordDescType = RangedDate>; - type Value = Date; -} - impl AsRangedCoord for Range { type CoordDescType = RangedDate; type Value = NaiveDate; @@ -333,11 +271,9 @@ impl Monthly { ) -> Vec { let mut ret = vec![]; while end_year > start_year || (end_year == start_year && end_month >= start_month) { - ret.push(T::earliest_after_date(builder.ymd( - start_year, - start_month as u32, - 1, - ))); + if let Some(date) = builder.ymd_opt(start_year, start_month as u32, 1) { + ret.push(T::earliest_after_date(date)); + } start_month += step as i32; if start_month >= 13 { @@ -461,11 +397,12 @@ where let index_from_start_year = index + (self.0.start.date_ceil().month() - 1) as usize; let year = self.0.start.date_ceil().year() + index_from_start_year as i32 / 12; let month = index_from_start_year % 12; - Some(T::earliest_after_date(self.0.start.ymd( - year, - month as u32 + 1, - 1, - ))) + + if let Some(start_ymd) = self.0.start.ymd_opt(year, month as u32 + 1, 1) { + return Some(T::earliest_after_date(start_ymd)); + } + + None } } @@ -503,11 +440,9 @@ fn generate_yearly_keypoints( let mut ret = vec![]; while start_year <= end_year { - ret.push(T::earliest_after_date(builder.ymd( - start_year, - start_month, - 1, - ))); + if let Some(date) = builder.ymd_opt(start_year, start_month, 1) { + ret.push(T::earliest_after_date(date)); + } start_year += freq as i32; } @@ -591,11 +526,14 @@ where fn from_index(&self, index: usize) -> Option { let year = self.0.start.date_ceil().year() + index as i32; - let ret = T::earliest_after_date(self.0.start.ymd(year, 1, 1)); - if ret.date_ceil() <= self.0.start.date_floor() { - return Some(self.0.start.clone()); + if let Some(date) = self.0.start.ymd_opt(year, 1, 1) { + let ret = T::earliest_after_date(date); + if ret.date_ceil() <= self.0.start.date_floor() { + return Some(self.0.start.clone()); + } + return Some(ret); } - Some(ret) + None } } @@ -627,17 +565,6 @@ impl IntoYearly for Range { #[derive(Clone)] pub struct RangedDateTime(DT, DT); -impl AsRangedCoord for Range> { - type CoordDescType = RangedDateTime>; - type Value = DateTime; -} - -impl From>> for RangedDateTime> { - fn from(range: Range>) -> Self { - Self(range.start, range.end) - } -} - impl From> for RangedDateTime { fn from(range: Range) -> Self { Self(range.start, range.end) @@ -898,16 +825,30 @@ fn compute_period_per_point(total_ns: u64, max_points: usize, sub_daily: bool) - #[cfg(test)] mod test { use super::*; - use chrono::{TimeZone, Utc}; + + // it's safe to use unwrap in these macros because testcases use good known values + macro_rules! create_date { + ($year:expr, $month:expr, $day:expr) => { + NaiveDate::from_ymd_opt($year, $month, $day).unwrap() + }; + } + macro_rules! create_datetime { + ($year:expr, $month:expr, $day:expr, $hour:expr, $min:expr, $sec:expr) => { + NaiveDate::from_ymd_opt($year, $month, $day) + .unwrap() + .and_hms_opt($hour, $min, $sec) + .unwrap() + }; + } #[test] fn test_date_range_long() { - let range = Utc.ymd(1000, 1, 1)..Utc.ymd(2999, 1, 1); + let range = create_date!(1000, 1, 1)..create_date!(2999, 1, 1); let ranged_coord = Into::>::into(range); - assert_eq!(ranged_coord.map(&Utc.ymd(1000, 8, 10), (0, 100)), 0); - assert_eq!(ranged_coord.map(&Utc.ymd(2999, 8, 10), (0, 100)), 100); + assert_eq!(ranged_coord.map(&create_date!(1000, 8, 10), (0, 100)), 0); + assert_eq!(ranged_coord.map(&create_date!(2999, 8, 10), (0, 100)), 100); let kps = ranged_coord.key_points(23); @@ -930,7 +871,7 @@ mod test { #[test] fn test_date_range_short() { - let range = Utc.ymd(2019, 1, 1)..Utc.ymd(2019, 1, 21); + let range = create_date!(2019, 1, 1)..create_date!(2019, 1, 21); let ranged_coord = Into::>::into(range); let kps = ranged_coord.key_points(4); @@ -973,11 +914,11 @@ mod test { #[test] fn test_yearly_date_range() { use crate::coord::ranged1d::BoldPoints; - let range = Utc.ymd(1000, 8, 5)..Utc.ymd(2999, 1, 1); + let range = create_date!(1000, 8, 5)..create_date!(2999, 1, 1); let ranged_coord = range.yearly(); - assert_eq!(ranged_coord.map(&Utc.ymd(1000, 8, 10), (0, 100)), 0); - assert_eq!(ranged_coord.map(&Utc.ymd(2999, 8, 10), (0, 100)), 100); + assert_eq!(ranged_coord.map(&create_date!(1000, 8, 10), (0, 100)), 0); + assert_eq!(ranged_coord.map(&create_date!(2999, 8, 10), (0, 100)), 100); let kps = ranged_coord.key_points(23); @@ -998,7 +939,7 @@ mod test { assert!(kps.into_iter().all(|x| x.month() == 9 && x.day() == 1)); - let range = Utc.ymd(2019, 8, 5)..Utc.ymd(2020, 1, 1); + let range = create_date!(2019, 8, 5)..create_date!(2020, 1, 1); let ranged_coord = range.yearly(); let kps = ranged_coord.key_points(BoldPoints(23)); assert!(kps.len() == 1); @@ -1006,7 +947,7 @@ mod test { #[test] fn test_monthly_date_range() { - let range = Utc.ymd(2019, 8, 5)..Utc.ymd(2020, 9, 1); + let range = create_date!(2019, 8, 5)..create_date!(2020, 9, 1); let ranged_coord = range.monthly(); use crate::coord::ranged1d::BoldPoints; @@ -1034,14 +975,14 @@ mod test { #[test] fn test_datetime_long_range() { let coord: RangedDateTime<_> = - (Utc.ymd(1000, 1, 1).and_hms(0, 0, 0)..Utc.ymd(3000, 1, 1).and_hms(0, 0, 0)).into(); + (create_datetime!(1000, 1, 1, 0, 0, 0)..create_datetime!(3000, 1, 1, 0, 0, 0)).into(); assert_eq!( - coord.map(&Utc.ymd(1000, 1, 1).and_hms(0, 0, 0), (0, 100)), + coord.map(&create_datetime!(1000, 1, 1, 0, 0, 0), (0, 100)), 0 ); assert_eq!( - coord.map(&Utc.ymd(3000, 1, 1).and_hms(0, 0, 0), (0, 100)), + coord.map(&create_datetime!(3000, 1, 1, 0, 0, 0), (0, 100)), 100 ); @@ -1067,7 +1008,7 @@ mod test { #[test] fn test_datetime_medium_range() { let coord: RangedDateTime<_> = - (Utc.ymd(2019, 1, 1).and_hms(0, 0, 0)..Utc.ymd(2019, 1, 11).and_hms(0, 0, 0)).into(); + (create_datetime!(2019, 1, 1, 0, 0, 0)..create_datetime!(2019, 1, 11, 0, 0, 0)).into(); let kps = coord.key_points(23); @@ -1091,7 +1032,7 @@ mod test { #[test] fn test_datetime_short_range() { let coord: RangedDateTime<_> = - (Utc.ymd(2019, 1, 1).and_hms(0, 0, 0)..Utc.ymd(2019, 1, 2).and_hms(0, 0, 0)).into(); + (create_datetime!(2019, 1, 1, 0, 0, 0)..create_datetime!(2019, 1, 2, 0, 0, 0)).into(); let kps = coord.key_points(50); @@ -1114,7 +1055,7 @@ mod test { #[test] fn test_datetime_nano_range() { - let start = Utc.ymd(2019, 1, 1).and_hms(0, 0, 0); + let start = create_datetime!(2019, 1, 1, 0, 0, 0); let end = start.clone() + Duration::nanoseconds(100); let coord: RangedDateTime<_> = (start..end).into(); @@ -1188,16 +1129,20 @@ mod test { #[test] fn test_date_discrete() { - let coord: RangedDate> = (Utc.ymd(2019, 1, 1)..Utc.ymd(2019, 12, 31)).into(); + let coord: RangedDate = + (create_date!(2019, 1, 1)..create_date!(2019, 12, 31)).into(); assert_eq!(coord.size(), 365); - assert_eq!(coord.index_of(&Utc.ymd(2019, 2, 28)), Some(31 + 28 - 1)); - assert_eq!(coord.from_index(364), Some(Utc.ymd(2019, 12, 31))); + assert_eq!( + coord.index_of(&create_date!(2019, 2, 28)), + Some(31 + 28 - 1) + ); + assert_eq!(coord.from_index(364), Some(create_date!(2019, 12, 31))); } #[test] fn test_monthly_discrete() { - let coord1 = (Utc.ymd(2019, 1, 10)..Utc.ymd(2019, 12, 31)).monthly(); - let coord2 = (Utc.ymd(2019, 1, 10)..Utc.ymd(2020, 1, 1)).monthly(); + let coord1 = (create_date!(2019, 1, 10)..create_date!(2019, 12, 31)).monthly(); + let coord2 = (create_date!(2019, 1, 10)..create_date!(2020, 1, 1)).monthly(); assert_eq!(coord1.size(), 12); assert_eq!(coord2.size(), 13); @@ -1212,7 +1157,7 @@ mod test { #[test] fn test_yearly_discrete() { - let coord1 = (Utc.ymd(2000, 1, 10)..Utc.ymd(2019, 12, 31)).yearly(); + let coord1 = (create_date!(2000, 1, 10)..create_date!(2019, 12, 31)).yearly(); assert_eq!(coord1.size(), 20); for i in 0..20 { @@ -1223,9 +1168,9 @@ mod test { #[test] fn test_datetime_with_unmap() { - let start_time = Utc.ymd(2021, 1, 1).and_hms(8, 0, 0); - let end_time = Utc.ymd(2023, 1, 1).and_hms(8, 0, 0); - let mid = Utc.ymd(2022, 1, 1).and_hms(8, 0, 0); + let start_time = create_datetime!(2021, 1, 1, 8, 0, 0); + let end_time = create_datetime!(2023, 1, 1, 8, 0, 0); + let mid = create_datetime!(2022, 1, 1, 8, 0, 0); let coord: RangedDateTime<_> = (start_time..end_time).into(); let pos = coord.map(&mid, (1000, 2000)); assert_eq!(pos, 1500); @@ -1235,9 +1180,9 @@ mod test { #[test] fn test_naivedatetime_with_unmap() { - let start_time = NaiveDate::from_ymd(2021, 1, 1).and_hms_milli(8, 0, 0, 0); - let end_time = NaiveDate::from_ymd(2023, 1, 1).and_hms_milli(8, 0, 0, 0); - let mid = NaiveDate::from_ymd(2022, 1, 1).and_hms_milli(8, 0, 0, 0); + let start_time = create_datetime!(2021, 1, 1, 8, 0, 0); + let end_time = create_datetime!(2023, 1, 1, 8, 0, 0); + let mid = create_datetime!(2022, 1, 1, 8, 0, 0); let coord: RangedDateTime<_> = (start_time..end_time).into(); let pos = coord.map(&mid, (1000, 2000)); assert_eq!(pos, 1500); @@ -1247,10 +1192,10 @@ mod test { #[test] fn test_date_with_unmap() { - let start_date = Utc.ymd(2021, 1, 1); - let end_date = Utc.ymd(2023, 1, 1); - let mid = Utc.ymd(2022, 1, 1); - let coord: RangedDate> = (start_date..end_date).into(); + let start_date = create_date!(2021, 1, 1); + let end_date = create_date!(2023, 1, 1); + let mid = create_date!(2022, 1, 1); + let coord: RangedDate = (start_date..end_date).into(); let pos = coord.map(&mid, (1000, 2000)); assert_eq!(pos, 1500); let value = coord.unmap(pos, (1000, 2000)); @@ -1259,9 +1204,9 @@ mod test { #[test] fn test_naivedate_with_unmap() { - let start_date = NaiveDate::from_ymd(2021, 1, 1); - let end_date = NaiveDate::from_ymd(2023, 1, 1); - let mid = NaiveDate::from_ymd(2022, 1, 1); + let start_date = create_date!(2021, 1, 1); + let end_date = create_date!(2023, 1, 1); + let mid = create_date!(2022, 1, 1); let coord: RangedDate = (start_date..end_date).into(); let pos = coord.map(&mid, (1000, 2000)); assert_eq!(pos, 1500); @@ -1271,7 +1216,7 @@ mod test { #[test] fn test_datetime_unmap_for_nanoseconds() { - let start_time = Utc.ymd(2021, 1, 1).and_hms(8, 0, 0); + let start_time = create_datetime!(2021, 1, 1, 8, 0, 0); let end_time = start_time + Duration::nanoseconds(1900); let mid = start_time + Duration::nanoseconds(950); let coord: RangedDateTime<_> = (start_time..end_time).into(); @@ -1283,7 +1228,7 @@ mod test { #[test] fn test_datetime_unmap_for_nanoseconds_small_period() { - let start_time = Utc.ymd(2021, 1, 1).and_hms(8, 0, 0); + let start_time = create_datetime!(2021, 1, 1, 8, 0, 0); let end_time = start_time + Duration::nanoseconds(400); let coord: RangedDateTime<_> = (start_time..end_time).into(); let value = coord.unmap(2000, (1000, 2000)); From 0dace111507c1b9237078beae4204975ce58eea0 Mon Sep 17 00:00:00 2001 From: wangjiawen2013 Date: Mon, 24 Jun 2024 13:55:32 +0800 Subject: [PATCH 26/27] rgb to rgba piechart --- plotters/src/element/pie.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plotters/src/element/pie.rs b/plotters/src/element/pie.rs index 95298345..33dbf4c0 100644 --- a/plotters/src/element/pie.rs +++ b/plotters/src/element/pie.rs @@ -1,6 +1,6 @@ use crate::{ element::{Drawable, PointCollection}, - style::{IntoFont, RGBColor, TextStyle, BLACK}, + style::{IntoFont, RGBAColor, TextStyle, BLACK}, }; use plotters_backend::{BackendCoord, DrawingBackend, DrawingErrorKind}; use std::{error::Error, f64::consts::PI, fmt::Display}; @@ -24,7 +24,7 @@ pub struct Pie<'a, Coord, Label: Display> { center: &'a Coord, // cartesian coord radius: &'a f64, sizes: &'a [f64], - colors: &'a [RGBColor], + colors: &'a [RGBAColor], labels: &'a [Label], total: f64, start_radian: f64, @@ -40,7 +40,7 @@ impl<'a, Label: Display> Pie<'a, (i32, i32), Label> { center: &'a (i32, i32), radius: &'a f64, sizes: &'a [f64], - colors: &'a [RGBColor], + colors: &'a [RGBAColor], labels: &'a [Label], ) -> Self { // fold iterator to pre-calculate total from given slice sizes @@ -69,7 +69,7 @@ impl<'a, Label: Display> Pie<'a, (i32, i32), Label> { /// Default is set to start at 0, which is aligned on the x axis. /// ``` /// use plotters::prelude::*; - /// let mut pie = Pie::new(&(50,50), &10.0, &[50.0, 25.25, 20.0, 5.5], &[RED, BLUE, GREEN, WHITE], &["Red", "Blue", "Green", "White"]); + /// let mut pie = Pie::new(&(50,50), &10.0, &[50.0, 25.25, 20.0, 5.5], &[RED.to_rgba(), BLUE.to_rgba(), GREEN.to_rgba(), WHITE.to_rgba()], &["Red", "Blue", "Green", "White"]); /// pie.start_angle(-90.0); // retract to a right angle, so it starts aligned to a vertical Y axis. /// ``` pub fn start_angle(&mut self, start_angle: f64) { From 7024adc3ef28cf14b6a63d335ad668996cbadddf Mon Sep 17 00:00:00 2001 From: Aaron Erhardt Date: Mon, 24 Jun 2024 16:50:21 +0200 Subject: [PATCH 27/27] Fix example and format code --- plotters-backend/src/rasterizer/mod.rs | 2 +- plotters/examples/pie.rs | 2 +- .../src/chart/context/cartesian2d/draw_impl.rs | 5 +---- plotters/src/chart/series.rs | 4 +--- plotters/src/drawing/area.rs | 16 +++++++--------- plotters/src/element/pie.rs | 14 +++++--------- plotters/src/series/line_series.rs | 3 +-- 7 files changed, 17 insertions(+), 29 deletions(-) diff --git a/plotters-backend/src/rasterizer/mod.rs b/plotters-backend/src/rasterizer/mod.rs index d322391e..b475acd2 100644 --- a/plotters-backend/src/rasterizer/mod.rs +++ b/plotters-backend/src/rasterizer/mod.rs @@ -10,7 +10,7 @@ // the question mark operator has a huge performance impact due to LLVM unable to handle it. // So the question is if this trick is still useful, or LLVM is smart enough to handle it since // then. -// +// // -- // Original comment: // diff --git a/plotters/examples/pie.rs b/plotters/examples/pie.rs index a950c021..7bd6c3ab 100644 --- a/plotters/examples/pie.rs +++ b/plotters/examples/pie.rs @@ -12,7 +12,7 @@ fn main() -> Result<(), Box> { let radius = 300.0; let sizes = vec![66.0, 33.0]; let _rgba = RGBAColor(0, 50, 255, 1.0); - let colors = vec![RGBColor(0, 50, 255), CYAN]; + let colors = vec![RGBColor(0, 50, 255).to_rgba(), CYAN.to_rgba()]; let labels = vec!["Pizza", "Pacman"]; let mut pie = Pie::new(¢er, &radius, &sizes, &colors, &labels); diff --git a/plotters/src/chart/context/cartesian2d/draw_impl.rs b/plotters/src/chart/context/cartesian2d/draw_impl.rs index e52f976a..24245a7a 100644 --- a/plotters/src/chart/context/cartesian2d/draw_impl.rs +++ b/plotters/src/chart/context/cartesian2d/draw_impl.rs @@ -119,10 +119,7 @@ impl<'a, DB: DrawingBackend, X: Ranged, Y: Ranged> ChartContext<'a, DB, Cartesia y1 = axis_range.end; } - area.draw(&PathElement::new( - vec![(x0, y0), (x1, y1)], - *axis_style, - ))?; + area.draw(&PathElement::new(vec![(x0, y0), (x1, y1)], *axis_style))?; } Ok(axis_range) diff --git a/plotters/src/chart/series.rs b/plotters/src/chart/series.rs index 8c430cbe..4aecf6a1 100644 --- a/plotters/src/chart/series.rs +++ b/plotters/src/chart/series.rs @@ -250,9 +250,7 @@ impl<'a, 'b, DB: DrawingBackend + 'a, CT: CoordTranslate> SeriesLabelStyle<'a, ' continue; } - funcs.push( - draw_func.unwrap_or(&|p: BackendCoord| EmptyElement::at(p).into_dyn()), - ); + funcs.push(draw_func.unwrap_or(&|p: BackendCoord| EmptyElement::at(p).into_dyn())); label_element.push_line(label_text); } diff --git a/plotters/src/drawing/area.rs b/plotters/src/drawing/area.rs index 2e5c3fe3..9519f378 100644 --- a/plotters/src/drawing/area.rs +++ b/plotters/src/drawing/area.rs @@ -87,7 +87,7 @@ impl Rect { .map(|(a, b)| (*a, *b)) .collect(); - // Justify: this is actually needed. Because we need to return a iterator that have + // Justify: this is actually needed. Because we need to return a iterator that have // static life time, thus we need to copy the value to a buffer and then turn the buffer // into a iterator. #[allow(clippy::needless_collect)] @@ -97,14 +97,12 @@ impl Rect { .map(|(a, b)| (*a, *b)) .collect(); - ysegs - .into_iter() - .flat_map(move |(y0, y1)| { - xsegs - .clone() - .into_iter() - .map(move |(x0, x1)| Self { x0, y0, x1, y1 }) - }) + ysegs.into_iter().flat_map(move |(y0, y1)| { + xsegs + .clone() + .into_iter() + .map(move |(x0, x1)| Self { x0, y0, x1, y1 }) + }) } /// Make the coordinate in the range of the rectangle diff --git a/plotters/src/element/pie.rs b/plotters/src/element/pie.rs index 33dbf4c0..7994d2f5 100644 --- a/plotters/src/element/pie.rs +++ b/plotters/src/element/pie.rs @@ -109,18 +109,14 @@ impl<'a, DB: DrawingBackend, Label: Display> Drawable for Pie<'a, (i32, i32) let radian_increment = PI / 180.0 / self.radius.sqrt() * 2.0; let mut perc_labels = Vec::new(); for (index, slice) in self.sizes.iter().enumerate() { - let slice_style = - self.colors - .get(index) - .ok_or_else(|| DrawingErrorKind::FontError(Box::new( - PieError::LengthMismatch, - )))?; + let slice_style = self + .colors + .get(index) + .ok_or_else(|| DrawingErrorKind::FontError(Box::new(PieError::LengthMismatch)))?; let label = self .labels .get(index) - .ok_or_else(|| DrawingErrorKind::FontError(Box::new( - PieError::LengthMismatch, - )))?; + .ok_or_else(|| DrawingErrorKind::FontError(Box::new(PieError::LengthMismatch)))?; // start building wedge line against the previous edge let mut points = vec![*self.center]; let ratio = slice / self.total; diff --git a/plotters/src/series/line_series.rs b/plotters/src/series/line_series.rs index 2d0cf986..448d029e 100644 --- a/plotters/src/series/line_series.rs +++ b/plotters/src/series/line_series.rs @@ -45,8 +45,7 @@ impl Iterator for LineSeries