├── .github
└── workflows
│ └── continuous-integration.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── Readme.md
├── cargo_util.py
├── doc
├── Cargo.toml
├── dark.css
├── dummy.rs
├── fg.readme_example.png
├── fg1.1.png
├── gh_pages_upload.sh
├── light.css
└── rustdoc.css
├── gnuplot
├── Cargo.toml
├── examples
│ ├── animation_example.rs
│ ├── box_and_whisker.rs
│ ├── box_xy_error.rs
│ ├── color.rs
│ ├── color_cycling.rs
│ ├── common.rs
│ ├── dash_type.rs
│ ├── example1.rs
│ ├── example2.rs
│ ├── example3.rs
│ ├── example4.rs
│ ├── gif.rs
│ ├── inverse_api.rs
│ ├── lines_3d.rs
│ ├── lines_points_3d.rs
│ ├── multiple_axes.rs
│ ├── multiplot_options.rs
│ ├── patterns.rs
│ ├── points_3d.rs
│ ├── polygons.rs
│ ├── readme_example.rs
│ ├── text.rs
│ ├── time.rs
│ └── variable_color.rs
└── src
│ ├── axes2d.rs
│ ├── axes3d.rs
│ ├── axes_common.rs
│ ├── color.rs
│ ├── coordinates.rs
│ ├── datatype.rs
│ ├── error_types.rs
│ ├── figure.rs
│ ├── lib.rs
│ ├── options.rs
│ ├── palettes
│ ├── cm_listed.rs
│ └── mod.rs
│ ├── util.rs
│ └── writer.rs
├── rustfmt.toml
└── setup_venv.sh
/.github/workflows/continuous-integration.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 | on:
3 | push:
4 | pull_request:
5 | types: [opened, synchronize, reopened, edited]
6 | jobs:
7 | ubuntu_test:
8 | name: Ubuntu tests
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v3
13 | with:
14 | fetch-depth: 1
15 | - name: Install Rust
16 | run: |
17 | rustup toolchain install nightly
18 | rustup default nightly
19 | rustup component add rustfmt --toolchain nightly-x86_64-unknown-linux-gnu
20 | - name: Setup
21 | run: |
22 | curl -LsSf https://astral.sh/uv/install.sh | sh
23 | . setup_venv.sh
24 | sudo apt-get install gnuplot
25 | - name: Tests
26 | run: |
27 | . venv/bin/activate
28 | ./cargo_util.py --test
29 | ./gnuplot/target/debug/examples/example1 --no-show
30 | ./gnuplot/target/debug/examples/example2 --no-show
31 | ./gnuplot/target/debug/examples/example3 --no-show
32 | ./gnuplot/target/debug/examples/example4 --no-show
33 |
34 | if [ -n "${{ github.base_ref }}" ]; then
35 | CHANGED_OUTPUTS=$(echo "${{ github.event.pull_request.body }}" | sed -n 's/.*CHANGED_OUTPUTS=\([^ ]*\).*/\1/p')
36 | BASE_REF="${{ github.base_ref }}"
37 | HEAD_REF=$(git rev-parse HEAD)
38 | echo "CHANGED_OUTPUTS: $CHANGED_OUTPUTS"
39 |
40 | git fetch origin $BASE_REF
41 | git checkout $BASE_REF
42 | ./cargo_util.py --make_golden_outputs
43 | git checkout $HEAD_REF
44 | ./cargo_util.py --test_outputs --ignore_new_outputs --changed_outputs=$CHANGED_OUTPUTS
45 | fi
46 | - name: Upload golden outputs
47 | if: ${{ always() }}
48 | uses: actions/upload-artifact@v4
49 | with:
50 | name: golden_outputs
51 | path: golden_outputs
52 | - name: Upload test outputs
53 | if: ${{ always() }}
54 | uses: actions/upload-artifact@v4
55 | with:
56 | name: test_outputs
57 | path: test_outputs
58 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | target
3 | Cargo.lock
4 | gnuplot/*.png
5 | gnuplot/*.gif
6 | gnuplot/*.pdf
7 | gnuplot/*.gnuplot
8 | /*.png
9 | /*.gif
10 | /*.pdf
11 | /*.gnuplot
12 | .idea
13 | venv
14 | golden_outputs
15 | test_outputs
16 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Style
2 |
3 | Please run `cargo fmt` before sending pull requests.
4 |
5 | # Output tests
6 |
7 | The CI verifies that the PNG outputs do not unexpectedly change for existing
8 | examples. This is done by checking out the repository before your PR and after
9 | the PR and comparing the outputs. If you changed some examples deliberately,
10 | you can indicate this in the PR description by adding a line like:
11 |
12 | ```
13 | CHANGED_OUTPUTS=image1.png,image2.png
14 | ```
15 |
16 | where `image1` etc is derived from the string you pass to the `c.show(&mut fg,
17 | "image1");` line in the example. To run the tests manually you run these two
18 | commands (requires [uv](https://github.com/astral-sh/uv) to be installed):
19 |
20 | ```bash
21 | source setup_venv.sh # Do this once
22 | . venv/bin/activate # Do this if you already set up venv
23 | ./cargo_util.py --make_golden_outputs # On the base commit (typically master)
24 | ./cargo_util.py --test_outputs --ignore_new_outputs --changed_outputs=image1.png,image2.png # With your changes applied
25 | ```
26 |
27 | We don't check in the golden outputs because gnuplot does not guarantee
28 | cross-platform pixel-perfect outputs, so the outputs end up being specific to
29 | the platform they're generated on. Thus, we only compare two commits instead on
30 | the same platform (i.e. your local machine, or the CI runner).
31 |
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # RustGnuplot
2 |
3 | A Gnuplot controller written in Rust.
4 |
5 | 
6 | [](https://crates.io/crates/gnuplot)
7 |
8 | ## Documentation
9 |
10 | On [docs.rs](https://docs.rs/gnuplot/latest/gnuplot/)
11 |
12 | ## Examples
13 |
14 | A simple example:
15 |
16 | ```rust
17 | let mut fg = Figure::new();
18 | fg.axes2d()
19 | .set_title("A plot", &[])
20 | .set_legend(Graph(0.5), Graph(0.9), &[], &[])
21 | .set_x_label("x", &[])
22 | .set_y_label("y^2", &[])
23 | .lines(
24 | &[-3., -2., -1., 0., 1., 2., 3.],
25 | &[9., 4., 1., 0., 1., 4., 9.],
26 | &[Caption("Parabola")],
27 | );
28 | fg.show().unwrap();
29 | ```
30 |
31 | 
32 |
33 | A somewhat involved 2D example (see `example1.rs` in the `examples` directory):
34 |
35 | 
36 |
37 | ## Features
38 |
39 | * Simple 2D plots
40 | * lines
41 | * points
42 | * points + lines
43 | * error bars
44 | * ...and more!
45 | * Simple 3D plots
46 | * surface plots
47 | * heatmaps
48 | * contours
49 |
50 | ## Building
51 |
52 | ### Via Cargo
53 |
54 | ```
55 | cargo build
56 | ```
57 |
--------------------------------------------------------------------------------
/cargo_util.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import argparse
4 | import fileinput
5 | import re
6 | import os
7 | import glob
8 | import time
9 | import toml
10 | import json
11 | import pathlib
12 | from shutil import copy, rmtree
13 | from subprocess import check_call, check_output, CalledProcessError
14 |
15 | def split(s):
16 | ret = s.split('\n')
17 | return filter(lambda v: v, ret)
18 |
19 | crate_list=split("""
20 | gnuplot
21 | """)
22 |
23 | parser = argparse.ArgumentParser(description='Perform an operation on all crates.')
24 | parser.add_argument('--version', metavar='VERSION', default='', help='set the version to VERSION')
25 | parser.add_argument('--publish', action='store_true', help='publish the crates')
26 | parser.add_argument('--build', action='store_true', help='build the crates')
27 | parser.add_argument('--test', action='store_true', help='test the crates')
28 | parser.add_argument('--make_golden_outputs', action='store_true', help='make the golden outputs')
29 | parser.add_argument('--test_outputs', action='store_true', help='run the output tests')
30 | parser.add_argument('--ignore_new_outputs', action='store_true', help='whether to ignore new outputs')
31 | parser.add_argument('--changed_outputs', type=str, default='', help='comma separated list of outputs to ignore failures in, e.g. "foo.png,bar.png"')
32 | parser.add_argument('--clean', action='store_true', help='clean the crates')
33 | parser.add_argument('--doc', action='store_true', help='build the documentation')
34 | parser.add_argument('--format', action='store_true', help='format all the non-sys crates')
35 | parser.add_argument('--verbose', action='store_true', help='pass --verbose to cargo')
36 | parser.add_argument('--num_retries', type=float, default=5, help='number of retries when publishing')
37 |
38 | args = parser.parse_args()
39 |
40 | def cargo_cmd(*command):
41 | return ['cargo'] + list(command) + (['--verbose'] if args.verbose else [])
42 |
43 | if len(args.version) > 0:
44 | crates_and_doc = ['doc']
45 | crates_and_doc.extend(crate_list)
46 |
47 | for crate in crates_and_doc:
48 | cargo_toml = crate + '/Cargo.toml'
49 | print('Processing', cargo_toml)
50 |
51 | for line in fileinput.input(cargo_toml, inplace=1):
52 | line = re.sub('version = "(=?).*" #auto', r'version = "\g<1>' + args.version + '" #auto', line)
53 | print(line, end='')
54 |
55 | if args.publish:
56 | for crate in crate_list:
57 | print('Publishing crate inside', crate)
58 | metadata = json.loads(
59 | check_output(
60 | 'cargo metadata --format-version=1 --no-deps'.split(' '),
61 | cwd=crate,
62 | )
63 | )
64 |
65 | package_metadata = metadata['packages'][0]
66 | new_version = package_metadata['version']
67 | crate_name = package_metadata['name']
68 |
69 | search_output = check_output(
70 | f'cargo search {crate_name} --limit 9999'.split(' ')
71 | ).decode('utf8')
72 |
73 | search_result = toml.loads(search_output)
74 | old_version = search_result[crate_name]
75 | if old_version == new_version:
76 | print(f'Version {new_version} already published, skipping.')
77 | continue
78 |
79 | for i in range(args.num_retries):
80 | try:
81 | check_call(cargo_cmd('publish'), cwd=crate)
82 | break
83 | except CalledProcessError:
84 | print(f'Try {i} failed')
85 | time.sleep(1. + i)
86 |
87 | if args.build:
88 | for crate in crate_list:
89 | check_call(cargo_cmd('build'), cwd=crate)
90 |
91 | if args.format:
92 | for crate in crate_list:
93 | check_call(cargo_cmd('fmt'), cwd=crate)
94 |
95 | if args.test:
96 | crates_no_examples = filter(lambda crate: crate != 'examples', crate_list)
97 | for crate in crates_no_examples:
98 | check_call(cargo_cmd('test'), cwd=crate)
99 | check_call(cargo_cmd('fmt', '--check'), cwd=crate)
100 |
101 | if args.test_outputs or args.make_golden_outputs:
102 | import numpy as np
103 | from PIL import Image
104 |
105 | if args.test_outputs:
106 | output_dir = 'test_outputs'
107 | else:
108 | output_dir = 'golden_outputs'
109 | os.makedirs(output_dir, exist_ok=True)
110 | output_dir = os.path.abspath(output_dir)
111 | metadata = json.loads(check_output(cargo_cmd('metadata', '--format-version=1', '--no-deps'), cwd='gnuplot').decode('utf8'))
112 | for target in metadata['packages'][0]['targets']:
113 | if target['kind'] != ['example']:
114 | continue
115 |
116 | if target['name'] in [
117 | 'animation_example', # Special.
118 | 'inverse_api', # Special.
119 | 'example3', # Broken.
120 | ]:
121 | continue
122 |
123 | check_call(cargo_cmd('run', '--example', target['name'], '--', '--no-show', '--output-dir', output_dir, '--save-png'), cwd='gnuplot')
124 |
125 | if args.make_golden_outputs:
126 | exit(0)
127 |
128 | golden_images = [pathlib.Path(f) for f in glob.glob('golden_outputs/*.png')]
129 | test_images = [pathlib.Path(f) for f in glob.glob(f'{output_dir}/*.png')]
130 |
131 | golden_filenames = set(f.name for f in golden_images)
132 | test_filenames = set(f.name for f in test_images)
133 | if golden_filenames != test_filenames:
134 | missing = set(golden_filenames) - set(test_filenames)
135 | extra = set(test_filenames) - set(golden_filenames)
136 | if not args.ignore_new_outputs or missing:
137 | assert False, f"Test images don't match golden images.\nExtra: {extra}\nMissing: {missing}"
138 |
139 | changed_outputs = args.changed_outputs.split(',')
140 | failed = False
141 | for image_name in golden_images:
142 | golden_image_path = pathlib.Path(image_name)
143 | test_image_path = pathlib.Path(output_dir) / golden_image_path.name
144 | assert test_image_path.exists(), f"{test_image_path} not found"
145 | if golden_image_path.name in changed_outputs:
146 | continue
147 | golden_image = np.array(Image.open(golden_image_path)).astype(np.float32)
148 | test_image = np.array(Image.open(test_image_path)).astype(np.float32)
149 | try:
150 | np.testing.assert_allclose(golden_image, test_image, atol=5, err_msg=f"{golden_image_path.resolve()}\n{test_image_path.resolve()}")
151 | except AssertionError as e:
152 | failed = True
153 | print(e)
154 | if failed:
155 | exit(1)
156 |
157 |
158 | if args.clean:
159 | crates_and_doc = ['doc']
160 | crates_and_doc.extend(crate_list)
161 | for crate in crates_and_doc:
162 | print('Cleaning', crate)
163 | lock = crate + '/Cargo.lock'
164 | if os.path.exists(lock):
165 | os.remove(lock)
166 | check_call(cargo_cmd('clean'), cwd=crate)
167 |
168 | if args.doc:
169 | rmtree('doc/target/doc', ignore_errors=True)
170 | print('Building docs')
171 | check_call(['cargo', 'doc'], cwd='doc')
172 | print('Fixing up the search index')
173 | found = False
174 | for line in fileinput.input('doc/target/doc/search-index.js', inplace=1):
175 | new_line = re.sub(r'"delete_me".*', r'\\', line)
176 | if new_line != line:
177 | found = True
178 | else:
179 | print(new_line, end='')
180 | if not found:
181 | raise Exception("Couldn't find the line in search-index.js!")
182 | found = False
183 | for line in fileinput.input('doc/target/doc/source-files.js', inplace=1):
184 | new_line = re.sub(r'sourcesIndex\["delete_me"\].*', r'', line)
185 | if new_line != line:
186 | found = True
187 | else:
188 | print(new_line, end='')
189 | if not found:
190 | raise Exception("Couldn't find the line in source-files.js!")
191 | print('Copying new CSS')
192 | copy('doc/rustdoc.css', 'doc/target/doc/rustdoc.css')
193 | copy('doc/light.css', 'doc/target/doc/light.css')
194 | copy('doc/dark.css', 'doc/target/doc/dark.css')
195 |
--------------------------------------------------------------------------------
/doc/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 |
3 | name = "doc"
4 | version = "0.0.46" #auto
5 | authors = [ "SiegeLord " ]
6 |
7 | [lib]
8 | name = "delete_me"
9 | path = "dummy.rs"
10 |
11 | [dependencies.gnuplot]
12 |
13 | path = "../gnuplot"
14 | version = "=0.0.46" #auto
15 |
--------------------------------------------------------------------------------
/doc/dark.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2015 The Rust Project Developers. See the COPYRIGHT
3 | * file at the top-level directory of this distribution and at
4 | * http://rust-lang.org/COPYRIGHT.
5 | *
6 | * Licensed under the Apache License, Version 2.0 or the MIT license
8 | * , at your
9 | * option. This file may not be copied, modified, or distributed
10 | * except according to those terms.
11 | */
12 |
13 | /* General structure and fonts */
14 |
15 | body {
16 | background-color: #000030;
17 | color: black;
18 | }
19 |
20 | h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {
21 | color: black;
22 | }
23 | h1.fqn {
24 | border-bottom-color: #D5D5D5;
25 | }
26 | h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {
27 | border-bottom-color: #DDDDDD;
28 | }
29 | h1.fqn {
30 | font-size: 20pt;
31 | font-weight: normal;
32 | }
33 |
34 | /*
35 | .in-band {
36 | background-color: white;
37 | }
38 | */
39 |
40 | .invisible {
41 | background: rgba(0, 0, 0, 0);
42 | }
43 |
44 | pre {
45 | background-color: #F5F5F5;
46 | }
47 |
48 | .sidebar {
49 | background-color: #F1F1F1;
50 | }
51 |
52 | .sidebar .current {
53 | background-color: #FDFFD3;
54 | }
55 |
56 | .source .sidebar {
57 | background-color: #fff;
58 | }
59 |
60 | .sidebar .version {
61 | border-bottom-color: #DDD;
62 | }
63 |
64 | #sidebar-toggle {
65 | background-color: #F1F1F1;
66 | }
67 | #sidebar-toggle:hover {
68 | background-color: #E0E0E0;
69 | }
70 | #source-sidebar {
71 | background-color: #F1F1F1;
72 | }
73 | #source-sidebar>.title {
74 | border-bottom-color: #ccc;
75 | }
76 |
77 | a[href].sidebar-title {
78 | background-color: #000030;
79 | background-image: linear-gradient( #000030, #000090 );
80 | border: 0px;
81 | margin: 0px;
82 | color: white;
83 | font-weight: bold;
84 | }
85 |
86 | a:hover[href].sidebar-title {
87 | background-color: #000030;
88 | background-image: linear-gradient( #000030, #000090 );
89 | text-shadow: 0 0 0.25em #EEEEEC;
90 | border: 0px;
91 | margin: 0px;
92 | color: white;
93 | font-weight: bold;
94 | }
95 |
96 | .block a:hover {
97 | background: #F5F5F5;
98 | }
99 |
100 | .line-numbers span { color: #c67e2d; }
101 | .line-numbers .line-highlighted {
102 | background-color: #f6fdb0 !important;
103 | }
104 |
105 | .docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 {
106 | border-bottom-color: #DDD;
107 | }
108 |
109 | .docblock table {
110 | border-color: #ddd;
111 | }
112 |
113 | .docblock table td {
114 | border-top-color: #ddd;
115 | border-bottom-color: #ddd;
116 | }
117 |
118 | .docblock table th {
119 | border-top-color: #ddd;
120 | border-bottom-color: #ddd;
121 | }
122 |
123 | :target { background: #FDFFD3; }
124 |
125 | :target > .in-band {
126 | background: #FDFFD3;
127 | }
128 |
129 | .content {
130 | background: #E1E1E1;
131 | }
132 |
133 | .content .method .where,
134 | .content .fn .where,
135 | .content .where.fmt-newline {
136 | color: #4E4C4C;
137 | }
138 |
139 | .content h1.fqn, .content > h2, .content > h3 {
140 | background-color: #000030;
141 | background-image: linear-gradient( #000030, #000090 );
142 | color: #FFFFFF;
143 | padding: 6pt;
144 | }
145 |
146 | .content h1.fqn a:hover[href], .content > h2 a:hover[href] {
147 | text-shadow: 0 0 0.25em #EEEEEC;
148 | border: 0px;
149 | margin: 0px;
150 | }
151 |
152 | .content h1.fqn a, .content > h2 a {
153 | color: #FCFCFC
154 | }
155 |
156 | .content h1 {
157 | padding-left: 10px;
158 | margin-top: 0;
159 | font-weight: bold;
160 | }
161 |
162 | .content .highlighted {
163 | color: #000 !important;
164 | background-color: #ccc;
165 | }
166 | .content .highlighted a, .content .highlighted span { color: #000 !important; }
167 | .content .highlighted.trait { background-color: #c7b6ff; }
168 | .content .highlighted.mod,
169 | .content .highlighted.externcrate { background-color: #afc6e4; }
170 | .content .highlighted.enum { background-color: #b4d1b9; }
171 | .content .highlighted.struct { background-color: #e7b1a0; }
172 | .content .highlighted.union { background-color: #b7bd49; }
173 | .content .highlighted.fn,
174 | .content .highlighted.method,
175 | .content .highlighted.tymethod { background-color: #c6afb3; }
176 | .content .highlighted.type { background-color: #ffc891; }
177 | .content .highlighted.foreigntype { background-color: #f5c4ff; }
178 | .content .highlighted.macro { background-color: #8ce488; }
179 | .content .highlighted.constant,
180 | .content .highlighted.static { background-color: #c3e0ff; }
181 | .content .highlighted.primitive { background-color: #9aecff; }
182 |
183 | .content span.enum, .content a.enum, .block a.current.enum { color: #508157; }
184 | .content span.struct, .content a.struct, .block a.current.struct { color: #ad448e; !important }
185 | .content span.type, .content a.type, .block a.current.type { color: #ba5d00; }
186 | .content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #cd00e2; }
187 | .content span.macro, .content a.macro, .block a.current.macro { color: #068000; }
188 | .content span.union, .content a.union, .block a.current.union { color: #767b27; }
189 | .content span.constant, .content a.constant, .block a.current.constant,
190 | .content span.static, .content a.static, .block a.current.static { color: #546e8a; }
191 | .content span.primitive, .content a.primitive, .block a.current.primitive { color: #2c8093; }
192 | .content span.externcrate,
193 | .content span.mod, .content a.mod, .block a.current.mod { color: #4d76ae; }
194 | .content span.trait, .content a.trait, .block a.current.trait { color: #7c5af3; }
195 | .content span.fn, .content a.fn, .block a.current.fn,
196 | .content span.method, .content a.method, .block a.current.method,
197 | .content span.tymethod, .content a.tymethod, .block a.current.tymethod,
198 | .content .fnname { color: #9a6e31; }
199 |
200 | pre.rust .comment { color: #8E908C; }
201 | pre.rust .doccomment { color: #4D4D4C; }
202 |
203 | nav {
204 | border-bottom-color: #e0e0e0;
205 | }
206 | nav.main .current {
207 | border-top-color: #000;
208 | border-bottom-color: #000;
209 | }
210 | nav.main .separator {
211 | border: 1px solid #000;
212 | }
213 | a {
214 | color: #000;
215 | }
216 |
217 | .docblock a, .docblock-short a, .stability a {
218 | color: #3873AD;
219 | }
220 |
221 | a[href] {
222 | text-decoration: none;
223 | color: #1D23A5;
224 | }
225 |
226 | a:hover[href] {
227 | border: 1px dotted #000000;
228 | margin: -1px -1px -1px -1px;
229 | }
230 |
231 | nav.sidebar > a:hover[href] {
232 | border: 0;
233 | margin: 0 0 0 0;
234 | }
235 |
236 | a.test-arrow {
237 | color: #f5f5f5;
238 | }
239 |
240 | .collapse-toggle {
241 | color: #999;
242 | }
243 |
244 | .search-input {
245 | color: #555;
246 | box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent;
247 | background-color: white;
248 | }
249 |
250 | .search-input:focus {
251 | border-color: #66afe9;
252 | }
253 |
254 | .stab.unstable { background: #FFF5D6; border-color: #FFC600; }
255 | .stab.deprecated { background: #F3DFFF; border-color: #7F0087; }
256 | .stab.portability { background: #C4ECFF; border-color: #7BA5DB; }
257 |
258 | .module-item .stab {
259 | color: #000;
260 | }
261 |
262 | #help > div {
263 | background: #e9e9e9;
264 | border-color: #bfbfbf;
265 | }
266 |
267 | .since {
268 | color: grey;
269 | }
270 |
271 | tr.result span.primitive::after {
272 | color: black;
273 | }
274 |
275 | .line-numbers :target { background-color: transparent; }
276 |
277 | /* Code highlighting */
278 | pre.rust .kw { color: #8959A8; }
279 | pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; }
280 | pre.rust .number, pre.rust .string { color: #718C00; }
281 | pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val,
282 | pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; }
283 | pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
284 | pre.rust .lifetime { color: #B76514; }
285 | pre.rust .question-mark {
286 | color: #ff9011;
287 | }
288 |
289 | a.test-arrow {
290 | background-color: rgba(78, 139, 202, 0.2);
291 | }
292 |
293 | a.test-arrow:hover{
294 | background-color: #4e8bca;
295 | }
296 |
297 | .toggle-label {
298 | color: #999;
299 | }
300 |
301 | :target > code {
302 | background: #FDFFD3;
303 | }
304 |
305 | pre.compile_fail {
306 | border-left: 2px solid rgba(255,0,0,.4);
307 | }
308 |
309 | pre.compile_fail:hover, .information:hover + pre.compile_fail {
310 | border-left: 2px solid #f00;
311 | }
312 |
313 | pre.ignore {
314 | border-left: 2px solid rgba(255,142,0,.4);
315 | }
316 |
317 | pre.ignore:hover, .information:hover + pre.ignore {
318 | border-left: 2px solid #ff9200;
319 | }
320 |
321 | .tooltip.compile_fail {
322 | color: rgba(255,0,0,.3);
323 | }
324 |
325 | .information > .compile_fail:hover {
326 | color: #f00;
327 | }
328 |
329 | .tooltip.ignore {
330 | color: rgba(255,142,0,.3);
331 | }
332 |
333 | .information > .ignore:hover {
334 | color: rgba(255,142,0,1);
335 | }
336 |
337 | .search-failed > a {
338 | color: #0089ff;
339 | }
340 |
341 | .tooltip .tooltiptext {
342 | background-color: black;
343 | color: #fff;
344 | }
345 |
346 | .tooltip .tooltiptext::after {
347 | border-color: transparent black transparent transparent;
348 | }
349 |
350 | .important-traits .tooltip .tooltiptext {
351 | background-color: white;
352 | color: black;
353 | border-color: black;
354 | }
355 |
356 | #titles > div {
357 | border-bottom-color: #ccc;
358 | }
359 |
360 | #titles > div.selected {
361 | border-bottom-color: #0078ee;
362 | }
363 |
364 | #titles > div:hover {
365 | border-bottom-color: #0089ff;
366 | }
367 |
368 | #titles > div > div.count {
369 | color: #888;
370 | }
371 |
372 | .modal {
373 | background-color: rgba(0,0,0,0.3);
374 | }
375 |
376 | .modal-content {
377 | background-color: #eee;
378 | border-color: #999;
379 | }
380 |
381 | .modal-content > .close {
382 | background-color: #eee;
383 | border-color: #999;
384 | }
385 |
386 | .modal-content > .close:hover {
387 | background-color: #ff1f1f;
388 | color: white;
389 | }
390 |
391 | .modal-content > .whiter {
392 | background-color: #eee;
393 | }
394 |
395 | .modal-content > .close:hover + .whiter {
396 | background-color: #ff1f1f;
397 | }
398 |
399 | @media (max-width: 700px) {
400 | .sidebar-menu {
401 | background-color: #F1F1F1;
402 | border-bottom-color: #e0e0e0;
403 | border-right-color: #e0e0e0;
404 | }
405 |
406 | .sidebar-elems {
407 | background-color: #F1F1F1;
408 | border-right-color: #000;
409 | }
410 |
411 | #sidebar-filler {
412 | background-color: #F1F1F1;
413 | border-bottom-color: #e0e0e0;
414 | }
415 | }
416 |
417 | kbd {
418 | color: #000;
419 | background-color: #fafbfc;
420 | border-color: #d1d5da;
421 | border-bottom-color: #c6cbd1;
422 | box-shadow-color: #c6cbd1;
423 | }
424 |
425 | #theme-picker, #settings-menu {
426 | border-color: #e0e0e0;
427 | background-color: #fff;
428 | }
429 |
430 | #theme-picker:hover, #theme-picker:focus,
431 | #settings-menu:hover, #settings-menu:focus {
432 | border-color: #717171;
433 | }
434 |
435 | #theme-choices {
436 | border-color: #ccc;
437 | background-color: #fff;
438 | }
439 |
440 | #theme-choices > button:not(:first-child) {
441 | border-top-color: #e0e0e0;
442 | }
443 |
444 | #theme-choices > button:hover, #theme-choices > button:focus {
445 | background-color: #eee;
446 | }
447 |
448 | @media (max-width: 700px) {
449 | #theme-picker {
450 | background: #fff;
451 | }
452 | }
453 |
454 | #all-types {
455 | background-color: #fff;
456 | }
457 | #all-types:hover {
458 | background-color: #f9f9f9;
459 | }
460 |
--------------------------------------------------------------------------------
/doc/dummy.rs:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/doc/fg.readme_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SiegeLord/RustGnuplot/8a1dde97369dbfeea66698d8f2dd20f2a47ac7d1/doc/fg.readme_example.png
--------------------------------------------------------------------------------
/doc/fg1.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SiegeLord/RustGnuplot/8a1dde97369dbfeea66698d8f2dd20f2a47ac7d1/doc/fg1.1.png
--------------------------------------------------------------------------------
/doc/gh_pages_upload.sh:
--------------------------------------------------------------------------------
1 | if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
2 | echo Starting gh-pages upload...
3 |
4 | cp -r doc $HOME/doc
5 |
6 | # Go to home and setup git
7 | cd $HOME
8 | git config --global user.email "travis@travis-ci.org"
9 | git config --global user.name "Travis"
10 |
11 | # Clone gh-pages branch
12 | git clone --quiet --branch=gh-pages https://${GH_TOKEN}@github.com/SiegeLord/RustGnuplot.git gh-pages > /dev/null
13 |
14 | # Copy over the documentation
15 | cd gh-pages
16 | rm -rf doc
17 | cp -r $HOME/doc .
18 |
19 | # Add, commit and push files
20 | git add -f --all .
21 | git commit -m "Update docs from Travis build $TRAVIS_BUILD_NUMBER"
22 | git push -fq origin gh-pages > /dev/null
23 |
24 | echo Done uploading documentation to gh-pages!
25 | fi
26 |
--------------------------------------------------------------------------------
/doc/light.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2015 The Rust Project Developers. See the COPYRIGHT
3 | * file at the top-level directory of this distribution and at
4 | * http://rust-lang.org/COPYRIGHT.
5 | *
6 | * Licensed under the Apache License, Version 2.0 or the MIT license
8 | * , at your
9 | * option. This file may not be copied, modified, or distributed
10 | * except according to those terms.
11 | */
12 |
13 | /* General structure and fonts */
14 |
15 | body {
16 | background-color: #000030;
17 | color: black;
18 | }
19 |
20 | h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {
21 | color: black;
22 | }
23 | h1.fqn {
24 | border-bottom-color: #D5D5D5;
25 | }
26 | h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {
27 | border-bottom-color: #DDDDDD;
28 | }
29 | h1.fqn {
30 | font-size: 20pt;
31 | font-weight: normal;
32 | }
33 |
34 | /*
35 | .in-band {
36 | background-color: white;
37 | }
38 | */
39 |
40 | .invisible {
41 | background: rgba(0, 0, 0, 0);
42 | }
43 |
44 | pre {
45 | background-color: #F5F5F5;
46 | }
47 |
48 | .sidebar {
49 | background-color: #F1F1F1;
50 | }
51 |
52 | .sidebar .current {
53 | background-color: #FDFFD3;
54 | }
55 |
56 | .source .sidebar {
57 | background-color: #fff;
58 | }
59 |
60 | .sidebar .version {
61 | border-bottom-color: #DDD;
62 | }
63 |
64 | #sidebar-toggle {
65 | background-color: #F1F1F1;
66 | }
67 | #sidebar-toggle:hover {
68 | background-color: #E0E0E0;
69 | }
70 | #source-sidebar {
71 | background-color: #F1F1F1;
72 | }
73 | #source-sidebar>.title {
74 | border-bottom-color: #ccc;
75 | }
76 |
77 | a[href].sidebar-title {
78 | background-color: #000030;
79 | background-image: linear-gradient( #000030, #000090 );
80 | border: 0px;
81 | margin: 0px;
82 | color: white;
83 | font-weight: bold;
84 | }
85 |
86 | a:hover[href].sidebar-title {
87 | background-color: #000030;
88 | background-image: linear-gradient( #000030, #000090 );
89 | text-shadow: 0 0 0.25em #EEEEEC;
90 | border: 0px;
91 | margin: 0px;
92 | color: white;
93 | font-weight: bold;
94 | }
95 |
96 | .block a:hover {
97 | background: #F5F5F5;
98 | }
99 |
100 | .line-numbers span { color: #c67e2d; }
101 | .line-numbers .line-highlighted {
102 | background-color: #f6fdb0 !important;
103 | }
104 |
105 | .docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 {
106 | border-bottom-color: #DDD;
107 | }
108 |
109 | .docblock table {
110 | border-color: #ddd;
111 | }
112 |
113 | .docblock table td {
114 | border-top-color: #ddd;
115 | border-bottom-color: #ddd;
116 | }
117 |
118 | .docblock table th {
119 | border-top-color: #ddd;
120 | border-bottom-color: #ddd;
121 | }
122 |
123 | :target { background: #FDFFD3; }
124 |
125 | :target > .in-band {
126 | background: #FDFFD3;
127 | }
128 |
129 | .content {
130 | background: #E1E1E1;
131 | }
132 |
133 | .content .method .where,
134 | .content .fn .where,
135 | .content .where.fmt-newline {
136 | color: #4E4C4C;
137 | }
138 |
139 | .content h1.fqn, .content > h2, .content > h3 {
140 | background-color: #000030;
141 | background-image: linear-gradient( #000030, #000090 );
142 | color: #FFFFFF;
143 | padding: 6pt;
144 | }
145 |
146 | .content h1.fqn a:hover[href], .content > h2 a:hover[href] {
147 | text-shadow: 0 0 0.25em #EEEEEC;
148 | border: 0px;
149 | margin: 0px;
150 | }
151 |
152 | .content h1.fqn a, .content > h2 a {
153 | color: #FCFCFC
154 | }
155 |
156 | .content h1 {
157 | padding-left: 10px;
158 | margin-top: 0;
159 | font-weight: bold;
160 | }
161 |
162 | .content .highlighted {
163 | color: #000 !important;
164 | background-color: #ccc;
165 | }
166 | .content .highlighted a, .content .highlighted span { color: #000 !important; }
167 | .content .highlighted.trait { background-color: #c7b6ff; }
168 | .content .highlighted.mod,
169 | .content .highlighted.externcrate { background-color: #afc6e4; }
170 | .content .highlighted.enum { background-color: #b4d1b9; }
171 | .content .highlighted.struct { background-color: #e7b1a0; }
172 | .content .highlighted.union { background-color: #b7bd49; }
173 | .content .highlighted.fn,
174 | .content .highlighted.method,
175 | .content .highlighted.tymethod { background-color: #c6afb3; }
176 | .content .highlighted.type { background-color: #ffc891; }
177 | .content .highlighted.foreigntype { background-color: #f5c4ff; }
178 | .content .highlighted.macro { background-color: #8ce488; }
179 | .content .highlighted.constant,
180 | .content .highlighted.static { background-color: #c3e0ff; }
181 | .content .highlighted.primitive { background-color: #9aecff; }
182 |
183 | .content span.enum, .content a.enum, .block a.current.enum { color: #508157; }
184 | .content span.struct, .content a.struct, .block a.current.struct { color: #ad448e; !important }
185 | .content span.type, .content a.type, .block a.current.type { color: #ba5d00; }
186 | .content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #cd00e2; }
187 | .content span.macro, .content a.macro, .block a.current.macro { color: #068000; }
188 | .content span.union, .content a.union, .block a.current.union { color: #767b27; }
189 | .content span.constant, .content a.constant, .block a.current.constant,
190 | .content span.static, .content a.static, .block a.current.static { color: #546e8a; }
191 | .content span.primitive, .content a.primitive, .block a.current.primitive { color: #2c8093; }
192 | .content span.externcrate,
193 | .content span.mod, .content a.mod, .block a.current.mod { color: #4d76ae; }
194 | .content span.trait, .content a.trait, .block a.current.trait { color: #7c5af3; }
195 | .content span.fn, .content a.fn, .block a.current.fn,
196 | .content span.method, .content a.method, .block a.current.method,
197 | .content span.tymethod, .content a.tymethod, .block a.current.tymethod,
198 | .content .fnname { color: #9a6e31; }
199 |
200 | pre.rust .comment { color: #8E908C; }
201 | pre.rust .doccomment { color: #4D4D4C; }
202 |
203 | nav {
204 | border-bottom-color: #e0e0e0;
205 | }
206 | nav.main .current {
207 | border-top-color: #000;
208 | border-bottom-color: #000;
209 | }
210 | nav.main .separator {
211 | border: 1px solid #000;
212 | }
213 | a {
214 | color: #000;
215 | }
216 |
217 | .docblock a, .docblock-short a, .stability a {
218 | color: #3873AD;
219 | }
220 |
221 | a[href] {
222 | text-decoration: none;
223 | color: #1D23A5;
224 | }
225 |
226 | a:hover[href] {
227 | border: 1px dotted #000000;
228 | margin: -1px -1px -1px -1px;
229 | }
230 |
231 | nav.sidebar > a:hover[href] {
232 | border: 0;
233 | margin: 0 0 0 0;
234 | }
235 |
236 | a.test-arrow {
237 | color: #f5f5f5;
238 | }
239 |
240 | .collapse-toggle {
241 | color: #999;
242 | }
243 |
244 | .search-input {
245 | color: #555;
246 | box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent;
247 | background-color: white;
248 | }
249 |
250 | .search-input:focus {
251 | border-color: #66afe9;
252 | }
253 |
254 | .stab.unstable { background: #FFF5D6; border-color: #FFC600; }
255 | .stab.deprecated { background: #F3DFFF; border-color: #7F0087; }
256 | .stab.portability { background: #C4ECFF; border-color: #7BA5DB; }
257 |
258 | .module-item .stab {
259 | color: #000;
260 | }
261 |
262 | #help > div {
263 | background: #e9e9e9;
264 | border-color: #bfbfbf;
265 | }
266 |
267 | .since {
268 | color: grey;
269 | }
270 |
271 | tr.result span.primitive::after {
272 | color: black;
273 | }
274 |
275 | .line-numbers :target { background-color: transparent; }
276 |
277 | /* Code highlighting */
278 | pre.rust .kw { color: #8959A8; }
279 | pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; }
280 | pre.rust .number, pre.rust .string { color: #718C00; }
281 | pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val,
282 | pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; }
283 | pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
284 | pre.rust .lifetime { color: #B76514; }
285 | pre.rust .question-mark {
286 | color: #ff9011;
287 | }
288 |
289 | a.test-arrow {
290 | background-color: rgba(78, 139, 202, 0.2);
291 | }
292 |
293 | a.test-arrow:hover{
294 | background-color: #4e8bca;
295 | }
296 |
297 | .toggle-label {
298 | color: #999;
299 | }
300 |
301 | :target > code {
302 | background: #FDFFD3;
303 | }
304 |
305 | pre.compile_fail {
306 | border-left: 2px solid rgba(255,0,0,.4);
307 | }
308 |
309 | pre.compile_fail:hover, .information:hover + pre.compile_fail {
310 | border-left: 2px solid #f00;
311 | }
312 |
313 | pre.ignore {
314 | border-left: 2px solid rgba(255,142,0,.4);
315 | }
316 |
317 | pre.ignore:hover, .information:hover + pre.ignore {
318 | border-left: 2px solid #ff9200;
319 | }
320 |
321 | .tooltip.compile_fail {
322 | color: rgba(255,0,0,.3);
323 | }
324 |
325 | .information > .compile_fail:hover {
326 | color: #f00;
327 | }
328 |
329 | .tooltip.ignore {
330 | color: rgba(255,142,0,.3);
331 | }
332 |
333 | .information > .ignore:hover {
334 | color: rgba(255,142,0,1);
335 | }
336 |
337 | .search-failed > a {
338 | color: #0089ff;
339 | }
340 |
341 | .tooltip .tooltiptext {
342 | background-color: black;
343 | color: #fff;
344 | }
345 |
346 | .tooltip .tooltiptext::after {
347 | border-color: transparent black transparent transparent;
348 | }
349 |
350 | .important-traits .tooltip .tooltiptext {
351 | background-color: white;
352 | color: black;
353 | border-color: black;
354 | }
355 |
356 | #titles > div {
357 | border-bottom-color: #ccc;
358 | }
359 |
360 | #titles > div.selected {
361 | border-bottom-color: #0078ee;
362 | }
363 |
364 | #titles > div:hover {
365 | border-bottom-color: #0089ff;
366 | }
367 |
368 | #titles > div > div.count {
369 | color: #888;
370 | }
371 |
372 | .modal {
373 | background-color: rgba(0,0,0,0.3);
374 | }
375 |
376 | .modal-content {
377 | background-color: #eee;
378 | border-color: #999;
379 | }
380 |
381 | .modal-content > .close {
382 | background-color: #eee;
383 | border-color: #999;
384 | }
385 |
386 | .modal-content > .close:hover {
387 | background-color: #ff1f1f;
388 | color: white;
389 | }
390 |
391 | .modal-content > .whiter {
392 | background-color: #eee;
393 | }
394 |
395 | .modal-content > .close:hover + .whiter {
396 | background-color: #ff1f1f;
397 | }
398 |
399 | @media (max-width: 700px) {
400 | .sidebar-menu {
401 | background-color: #F1F1F1;
402 | border-bottom-color: #e0e0e0;
403 | border-right-color: #e0e0e0;
404 | }
405 |
406 | .sidebar-elems {
407 | background-color: #F1F1F1;
408 | border-right-color: #000;
409 | }
410 |
411 | #sidebar-filler {
412 | background-color: #F1F1F1;
413 | border-bottom-color: #e0e0e0;
414 | }
415 | }
416 |
417 | kbd {
418 | color: #000;
419 | background-color: #fafbfc;
420 | border-color: #d1d5da;
421 | border-bottom-color: #c6cbd1;
422 | box-shadow-color: #c6cbd1;
423 | }
424 |
425 | #theme-picker, #settings-menu {
426 | border-color: #e0e0e0;
427 | background-color: #fff;
428 | }
429 |
430 | #theme-picker:hover, #theme-picker:focus,
431 | #settings-menu:hover, #settings-menu:focus {
432 | border-color: #717171;
433 | }
434 |
435 | #theme-choices {
436 | border-color: #ccc;
437 | background-color: #fff;
438 | }
439 |
440 | #theme-choices > button:not(:first-child) {
441 | border-top-color: #e0e0e0;
442 | }
443 |
444 | #theme-choices > button:hover, #theme-choices > button:focus {
445 | background-color: #eee;
446 | }
447 |
448 | @media (max-width: 700px) {
449 | #theme-picker {
450 | background: #fff;
451 | }
452 | }
453 |
454 | #all-types {
455 | background-color: #fff;
456 | }
457 | #all-types:hover {
458 | background-color: #f9f9f9;
459 | }
460 |
--------------------------------------------------------------------------------
/doc/rustdoc.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 The Rust Project Developers. See the COPYRIGHT
3 | * file at the top-level directory of this distribution and at
4 | * http://rust-lang.org/COPYRIGHT.
5 | *
6 | * Licensed under the Apache License, Version 2.0 or the MIT license
8 | * , at your
9 | * option. This file may not be copied, modified, or distributed
10 | * except according to those terms.
11 | */
12 |
13 | * {
14 | -webkit-box-sizing: border-box;
15 | -moz-box-sizing: border-box;
16 | box-sizing: border-box;
17 | }
18 |
19 | /* General structure and fonts */
20 |
21 | body {
22 | font: 11pt sans-serif;
23 | line-height: 150%;
24 | margin: 0;
25 | position: relative;
26 | padding: 10px 15px 20px 15px;
27 |
28 | -webkit-font-feature-settings: "kern", "liga";
29 | -moz-font-feature-settings: "kern", "liga";
30 | font-feature-settings: "kern", "liga";
31 | }
32 |
33 | body.source {
34 | padding: 10px 15px 20px 25px;
35 | }
36 |
37 | h1 {
38 | font-size: 1.5em;
39 | }
40 | h2 {
41 | font-size: 1.4em;
42 | }
43 | h3 {
44 | font-size: 1.3em;
45 | }
46 | h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod):not(.important), h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) {
47 | font-weight: 500;
48 | margin: 20px 0 15px 0;
49 | }
50 | h1.fqn {
51 | margin-top: 0;
52 | position: relative;
53 | }
54 | h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) {
55 | border-bottom: 1px solid;
56 | }
57 | h3.impl, h3.method, h4.method, h3.type, h4.type, h4.associatedconstant {
58 | font-weight: 600;
59 | margin-top: 10px;
60 | margin-bottom: 10px;
61 | position: relative;
62 | }
63 | h3.impl, h3.method, h3.type {
64 | padding-left: 15px;
65 | }
66 |
67 | ol, ul {
68 | padding-left: 25px;
69 | }
70 | ul ul, ol ul, ul ol, ol ol {
71 | margin-bottom: 0;
72 | }
73 |
74 | p {
75 | margin: 0 0 .6em 0;
76 | }
77 |
78 | summary {
79 | outline: none;
80 | }
81 |
82 | code, pre {
83 | white-space: pre-wrap;
84 | }
85 | .docblock code, .docblock-short code {
86 | border-radius: 3px;
87 | padding: 0 0.2em;
88 | }
89 | .docblock pre code, .docblock-short pre code, .docblock code.spotlight {
90 | padding: 0;
91 | }
92 | .docblock code.spotlight :last-child {
93 | padding-bottom: 0.6em;
94 | }
95 | pre {
96 | padding: 14px;
97 | margin-right: 20px;
98 | border-radius: 1.0em;
99 | background: #F3F3F3;
100 | box-shadow: inset 1pt 1pt 2pt #000000;
101 | }
102 |
103 | .source .content pre {
104 | padding: 20px;
105 | }
106 |
107 | img {
108 | max-width: 100%;
109 | }
110 |
111 | .source .content {
112 | max-width: none;
113 | overflow: visible;
114 | margin-left: 0px;
115 | min-width: 70em;
116 | }
117 |
118 | nav.sub {
119 | font-size: 16px;
120 | text-transform: uppercase;
121 | }
122 |
123 | .sidebar {
124 | width: 200px;
125 | position: fixed;
126 | left: 0;
127 | top: 0;
128 | height: 100vh;
129 | overflow: auto;
130 | }
131 |
132 | .sidebar .block > ul > li {
133 | margin-right: -10px;
134 | }
135 |
136 | /* Everything else */
137 |
138 | .js-only, .hidden {
139 | display: none !important;
140 | }
141 |
142 | .sidebar img {
143 | margin: 20px auto;
144 | display: block;
145 | margin-top: 10px;
146 | }
147 |
148 | .sidebar .location {
149 | font-size: 17px;
150 | margin: 30px 10px 20px 10px;
151 | word-wrap: break-word;
152 | }
153 |
154 | .sidebar .version {
155 | font-size: 15px;
156 | text-align: center;
157 | border-bottom: 1px solid;
158 | overflow-wrap: break-word;
159 | word-wrap: break-word; /* deprecated */
160 | word-break: break-word; /* Chrome, non-standard */
161 | }
162 |
163 | .location:empty {
164 | border: none;
165 | }
166 |
167 | .location a:first-child {
168 | font-weight: 500;
169 | }
170 |
171 | .block {
172 | padding: 0;
173 | margin-bottom: 14px;
174 | }
175 | .block h2, .block h3 {
176 | margin-top: 0;
177 | margin-bottom: 8px;
178 | text-align: center;
179 | }
180 | .block ul, .block li {
181 | padding: 0;
182 | list-style: none;
183 | }
184 |
185 | .block a {
186 | padding-left: 10px;
187 | display: block;
188 | text-overflow: ellipsis;
189 | overflow: hidden;
190 | line-height: 24px;
191 | }
192 |
193 | .sidebar-title {
194 | border-top: 1px solid;
195 | border-bottom: 1px solid;
196 | text-align: center;
197 | font-size: 17px;
198 | margin-bottom: 5px;
199 | }
200 |
201 | .sidebar-links {
202 | margin-bottom: 15px;
203 | }
204 |
205 | .sidebar-links > a {
206 | padding-left: 10px;
207 | width: 100%;
208 | }
209 |
210 | .sidebar-menu {
211 | display: none;
212 | }
213 |
214 | .content {
215 | padding: 15px 0;
216 | border-radius: 13px;
217 | }
218 |
219 | .source .content pre.rust {
220 | white-space: pre;
221 | overflow: auto;
222 | }
223 |
224 | .source .sidebar {
225 | width: 0;
226 | }
227 |
228 | #search {
229 | position: relative;
230 | }
231 |
232 | #results {
233 | right: 0;
234 | left: 0;
235 | overflow: auto;
236 | }
237 |
238 | #results > table {
239 | width: 100%;
240 | table-layout: fixed;
241 | }
242 |
243 | div.files>a {
244 | display: block;
245 | padding: 0 3px;
246 | }
247 |
248 | #sidebar-toggle {
249 | position: fixed;
250 | top: 21px;
251 | left: 300px;
252 | z-index: 10;
253 | padding: 3px;
254 | border-top-right-radius: 3px;
255 | border-bottom-right-radius: 3px;
256 | cursor: pointer;
257 | font-weight: bold;
258 | transition: left .5s;
259 | font-size: 1.2em;
260 | border: 1px solid;
261 | border-left: 0;
262 | }
263 | #source-sidebar {
264 | position: fixed;
265 | top: 0;
266 | bottom: 0;
267 | left: 0;
268 | width: 300px;
269 | z-index: 1;
270 | overflow: auto;
271 | transition: left .5s;
272 | border-right: 1px solid;
273 | }
274 | #source-sidebar>.title {
275 | font-size: 1.5em;
276 | text-align: center;
277 | border-bottom: 1px solid;
278 | margin-bottom: 6px;
279 | }
280 | #source-sidebar {
281 | z-index: 11;
282 | }
283 |
284 | .content pre.line-numbers {
285 | float: left;
286 | border: none;
287 | position: relative;
288 | margin-left: 20px;
289 |
290 | -webkit-user-select: none;
291 | -moz-user-select: none;
292 | -ms-user-select: none;
293 | user-select: none;
294 | }
295 | .line-numbers span {
296 | cursor: pointer;
297 | }
298 |
299 | .docblock-short p {
300 | display: inline;
301 | }
302 |
303 | .docblock-short.nowrap {
304 | display: block;
305 | overflow: hidden;
306 | white-space: nowrap;
307 | text-overflow: ellipsis;
308 | }
309 |
310 | .docblock-short p {
311 | overflow: hidden;
312 | text-overflow: ellipsis;
313 | margin: 0;
314 | }
315 | .docblock-short code {
316 | white-space: nowrap;
317 | }
318 |
319 | .docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 {
320 | border-bottom: 1px solid;
321 | }
322 |
323 | #main > .docblock h1 { font-size: 1.3em; }
324 | #main > .docblock h2 { font-size: 1.15em; }
325 | #main > .docblock h3, #main > .docblock h4, #main > .docblock h5 { font-size: 1em; }
326 |
327 | .docblock h1 { font-size: 1.2em; }
328 | .docblock h2 { font-size: 0.95em; }
329 | .docblock h3, .docblock h4, .docblock h5 { font-size: 0.9em; }
330 |
331 | .docblock {
332 | margin-left: 24px;
333 | position: relative;
334 | }
335 |
336 | .content .out-of-band {
337 | font-size: 23px;
338 | margin: 0px;
339 | margin-right: 5px;
340 | padding: 0px;
341 | text-align: right;
342 | display: inline-block;
343 | font-weight: normal;
344 | position: absolute;
345 | right: 0;
346 | }
347 |
348 | .content > h3.impl, h3.impl {
349 | margin-top: 10pt;
350 | margin-bottom: 10pt;
351 | background-color: #D1D1D1;
352 | background-image: none;
353 | color: black;
354 | padding: 5pt;
355 | padding-left: 25px;
356 | box-shadow: 1px 1px 2px #000000;
357 | }
358 |
359 | .methods h3, h4 {
360 | margin-top: 10pt;
361 | margin-bottom: 10pt;
362 | box-shadow: 1px 1px 2px #000000;
363 | border-top-left-radius: 1em;
364 | border-bottom-left-radius: 1em;
365 | padding: 5pt 5pt 5pt 20pt;
366 | background: #D1D1D1;
367 | }
368 |
369 | h3.impl > .out-of-band {
370 | font-size: 21px;
371 | }
372 |
373 | h4.method > .out-of-band {
374 | font-size: 19px;
375 | }
376 |
377 | ul.item-list > li > .out-of-band {
378 | font-size: 19px;
379 | }
380 |
381 | h4 > code, h3 > code, .invisible > code {
382 | max-width: calc(100% - 41px);
383 | display: block;
384 | }
385 |
386 | .in-band, code {
387 | z-index: 5;
388 | }
389 |
390 | .invisible {
391 | width: 100%;
392 | }
393 |
394 | .content .in-band {
395 | margin: 0px;
396 | padding: 0px;
397 | }
398 |
399 | .in-band > code {
400 | display: inline-block;
401 | }
402 |
403 | #main {
404 | position: relative;
405 | }
406 | #main > .since {
407 | top: inherit;
408 | font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
409 | }
410 |
411 | .content table:not(.table-display) {
412 | border-spacing: 0 5px;
413 | border-collapse: separate;
414 | margin-left: 24px;
415 | }
416 | .content td { vertical-align: top; }
417 | .content td:first-child { padding-right: 20px; }
418 | .content td p:first-child { margin-top: 0; }
419 | .content td h1, .content td h2 { margin-left: 0; font-size: 1.1em; }
420 |
421 | .docblock table {
422 | margin: .5em 0;
423 | border-collapse: collapse;
424 | width: 100%;
425 | }
426 |
427 | .docblock table td {
428 | padding: .5em;
429 | }
430 |
431 | .docblock table th {
432 | padding: .5em;
433 | text-align: left;
434 | }
435 |
436 | .fields + table {
437 | margin-bottom: 1em;
438 | }
439 |
440 | .content .item-list {
441 | list-style-type: none;
442 | padding: 0;
443 | }
444 |
445 | .content .item-list li {
446 | margin-bottom: 1em;
447 | }
448 |
449 | .content .multi-column {
450 | -moz-column-count: 5;
451 | -moz-column-gap: 2.5em;
452 | -webkit-column-count: 5;
453 | -webkit-column-gap: 2.5em;
454 | column-count: 5;
455 | column-gap: 2.5em;
456 | }
457 | .content .multi-column li { width: 100%; display: inline-block; }
458 |
459 | .content .method {
460 | font-size: 1em;
461 | position: relative;
462 | margin-left: 20px;
463 | }
464 | /* Shift "where ..." part of method or fn definition down a line */
465 | .content .method .where,
466 | .content .fn .where,
467 | .content .where.fmt-newline {
468 | display: block;
469 | font-size: 0.8em;
470 | }
471 |
472 | .content .methods > div:not(.important-traits) {
473 | margin-left: 40px;
474 | margin-bottom: 15px;
475 | }
476 |
477 | .content .impl-items .docblock, .content .impl-items .stability {
478 | margin-bottom: .6em;
479 | }
480 | .content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant {
481 | margin-left: 20px;
482 | }
483 |
484 | .content .stability code {
485 | font-size: 90%;
486 | }
487 |
488 | nav {
489 | padding-bottom: 10px;
490 | margin-bottom: 10px;
491 | }
492 | nav.main {
493 | padding: 20px 0;
494 | text-align: center;
495 | }
496 | nav.main .current {
497 | border-top: 1px solid;
498 | border-bottom: 1px solid;
499 | }
500 | nav.main .separator {
501 | border: 1px solid;
502 | display: inline-block;
503 | height: 23px;
504 | margin: 0 20px;
505 | }
506 | nav.sum { text-align: right; }
507 | nav.sub form { display: inline; }
508 |
509 | nav.sub, .content {
510 | margin-left: 210px;
511 | margin-right: 10pt;
512 | }
513 |
514 | .source nav.sub, .source .content {
515 | margin-left: 0px;
516 | }
517 |
518 | a {
519 | text-decoration: none;
520 | background: transparent;
521 | }
522 |
523 | .small-section-header:hover > .anchor {
524 | display: initial;
525 | }
526 |
527 | .in-band:hover > .anchor {
528 | display: inline-block;
529 | position: absolute;
530 | }
531 | .anchor {
532 | display: none;
533 | position: absolute;
534 | left: -7px;
535 | }
536 | .anchor.field {
537 | left: -5px;
538 | }
539 | .small-section-header > .anchor {
540 | left: -20px;
541 | }
542 | .small-section-header > .anchor:not(.field) {
543 | left: -28px;
544 | }
545 | .anchor:before {
546 | content: '\2002\00a7\2002';
547 | }
548 |
549 | .docblock a:hover, .docblock-short a:hover, .stability a {
550 | text-decoration: underline;
551 | }
552 |
553 | .block a.current.crate { font-weight: 500; }
554 |
555 | .search-container {
556 | position: relative;
557 | }
558 | .search-container>div {
559 | display: inline-flex;
560 | width: calc(100% - 34px);
561 | }
562 | #crate-search {
563 | margin-top: 6px;
564 | padding: 6px;
565 | padding-right: 19px;
566 | flex: none;
567 | border: 0;
568 | border-right: 0;
569 | border-radius: 4px 0 0 4px;
570 | outline: none;
571 | cursor: pointer;
572 | border-right: 1px solid;
573 | -moz-appearance: none;
574 | -webkit-appearance: none;
575 | text-indent: 0.01px;
576 | text-overflow: "";
577 | background-repeat: no-repeat;
578 | background-size: 20px;
579 | background-position: calc(100% - 1px) 56%;
580 | }
581 | .search-container>.top-button {
582 | position: absolute;
583 | right: 0;
584 | top: 10px;
585 | }
586 | .search-input {
587 | -moz-box-sizing: border-box !important;
588 | box-sizing: border-box !important;
589 | outline: none;
590 | border: 0;
591 | margin-top: 7px;
592 | margin-bottom: 1px;
593 | padding: 10px 16px;
594 | font-size: 17px;
595 | transition: border-color 300ms ease;
596 | transition: border-radius 300ms ease-in-out;
597 | transition: box-shadow 300ms ease-in-out;
598 | width: 100%;
599 | }
600 | #crate-search+.search-input {
601 | border-radius: 0 4px 4px 0;
602 | width: calc(100% - 32px);
603 | }
604 | .search-input:focus {
605 | border-radius: 2px;
606 | border: 0;
607 | outline: 0;
608 | }
609 |
610 | .search-results .desc {
611 | white-space: nowrap;
612 | text-overflow: ellipsis;
613 | overflow: hidden;
614 | display: block;
615 | }
616 |
617 | .search-results a {
618 | display: block;
619 | }
620 |
621 | .search-results a:hover[href] {
622 | border: 0;
623 | margin: 0;
624 | }
625 |
626 | .content .search-results td:first-child {
627 | padding-right: 0;
628 | width: 75%;
629 | }
630 | .content .search-results td:first-child a {
631 | padding-right: 10px;
632 | }
633 | .content .search-results td:first-child a span {
634 | float: left;
635 | }
636 |
637 | tr.result span.primitive::after {
638 | content: ' (primitive type)';
639 | font-style: italic;
640 | }
641 |
642 | body.blur > :not(#help) {
643 | filter: blur(8px);
644 | -webkit-filter: blur(8px);
645 | opacity: .7;
646 | }
647 |
648 | #help {
649 | width: 100%;
650 | height: 100vh;
651 | position: fixed;
652 | top: 0;
653 | left: 0;
654 | display: flex;
655 | justify-content: center;
656 | align-items: center;
657 | }
658 | #help > div {
659 | flex: 0 0 auto;
660 | box-shadow: 0 0 6px rgba(0,0,0,.2);
661 | width: 550px;
662 | height: auto;
663 | border: 1px solid;
664 | }
665 | #help dt {
666 | float: left;
667 | clear: left;
668 | display: block;
669 | }
670 | #help dd { margin: 5px 35px; }
671 | #help .infos { padding-left: 0; }
672 | #help h1, #help h2 { margin-top: 0; }
673 | #help > div div {
674 | width: 50%;
675 | float: left;
676 | padding: 20px;
677 | padding-left: 17px;
678 | }
679 |
680 | .stab {
681 | display: table;
682 | border-width: 1px;
683 | border-style: solid;
684 | padding: 3px;
685 | margin-bottom: 5px;
686 | font-size: 90%;
687 | }
688 | .stab p {
689 | display: inline;
690 | }
691 |
692 | .stab summary {
693 | display: list-item;
694 | }
695 |
696 | .stab .microscope {
697 | font-size: 1.5em;
698 | }
699 |
700 | .module-item .stab {
701 | display: inline;
702 | border-width: 0;
703 | padding: 0;
704 | margin: 0;
705 | background: inherit !important;
706 | }
707 |
708 | .module-item.unstable {
709 | opacity: 0.65;
710 | }
711 |
712 | .since {
713 | font-weight: normal;
714 | font-size: initial;
715 | position: absolute;
716 | right: 0;
717 | top: 0;
718 | }
719 |
720 | .variants_table {
721 | width: 100%;
722 | }
723 |
724 | .variants_table tbody tr td:first-child {
725 | width: 1%; /* make the variant name as small as possible */
726 | }
727 |
728 | td.summary-column {
729 | width: 100%;
730 | }
731 |
732 | .summary {
733 | padding-right: 0px;
734 | }
735 |
736 | pre.rust .question-mark {
737 | font-weight: bold;
738 | }
739 |
740 | a.test-arrow {
741 | display: inline-block;
742 | position: absolute;
743 | padding: 5px 10px 5px 10px;
744 | border-radius: 5px;
745 | font-size: 130%;
746 | top: 5px;
747 | right: 5px;
748 | }
749 | a.test-arrow:hover{
750 | text-decoration: none;
751 | }
752 |
753 | .section-header:hover a:before {
754 | position: absolute;
755 | left: -25px;
756 | content: '\2002\00a7\2002';
757 | }
758 |
759 | .section-header:hover a {
760 | text-decoration: none;
761 | }
762 |
763 | .section-header a {
764 | color: inherit;
765 | }
766 |
767 | .collapse-toggle {
768 | font-weight: 300;
769 | position: absolute;
770 | left: 1px;
771 | top: 1px;
772 | }
773 |
774 | h3 > .collapse-toggle {
775 | font-size: 0.8em;
776 | top: 5pt;
777 | }
778 |
779 | h4 > .collapse-toggle {
780 | font-size: 0.8em;
781 | top: 7px;
782 | }
783 |
784 | .toggle-wrapper > .collapse-toggle {
785 | left: -24px;
786 | margin-top: 0px;
787 | }
788 |
789 | .toggle-wrapper {
790 | position: relative;
791 | margin-top: 5px;
792 | }
793 |
794 | .toggle-wrapper.collapsed {
795 | height: 25px;
796 | transition: height .2s;
797 | margin-bottom: .6em;
798 | }
799 |
800 | .collapse-toggle > .inner {
801 | display: inline-block;
802 | width: 1.2ch;
803 | text-align: center;
804 | }
805 |
806 | .ghost {
807 | display: none;
808 | }
809 |
810 | .ghost + .since {
811 | position: initial;
812 | display: table-cell;
813 | }
814 |
815 | .since + .srclink {
816 | display: table-cell;
817 | padding-left: 10px;
818 | }
819 |
820 | .item-spacer {
821 | width: 100%;
822 | height: 12px;
823 | }
824 |
825 | span.since {
826 | position: initial;
827 | font-size: 20px;
828 | margin-right: 5px;
829 | }
830 |
831 | .toggle-wrapper > .collapse-toggle {
832 | left: 0;
833 | }
834 |
835 | .variant + .toggle-wrapper + .docblock > p {
836 | margin-top: 5px;
837 | }
838 |
839 | .sub-variant, .sub-variant > h3 {
840 | margin-top: 0 !important;
841 | }
842 |
843 | .toggle-label {
844 | display: inline-block;
845 | margin-left: 4px;
846 | margin-top: 3px;
847 | }
848 |
849 | .enum > .toggle-wrapper + .docblock, .struct > .toggle-wrapper + .docblock {
850 | margin-left: 30px;
851 | margin-bottom: 20px;
852 | margin-top: 5px;
853 | }
854 |
855 | .docblock > .section-header:first-child {
856 | margin-left: 15px;
857 | margin-top: 0;
858 | }
859 |
860 | .docblock > .section-header:first-child:hover > a:before {
861 | left: -10px;
862 | }
863 |
864 | .enum > .collapsed, .struct > .collapsed {
865 | margin-bottom: 25px;
866 | }
867 |
868 | #main > .variant, #main > .structfield {
869 | margin-left: 24px;
870 | display: block;
871 | }
872 |
873 | .attributes {
874 | display: block;
875 | margin: 0px 0px 0px 30px !important;
876 | }
877 | .toggle-attributes.collapsed {
878 | margin-bottom: 5px;
879 | }
880 |
881 | :target > code {
882 | opacity: 1;
883 | }
884 |
885 | /* Media Queries */
886 |
887 | @media (max-width: 700px) {
888 | body {
889 | padding-top: 0px;
890 | }
891 |
892 | .sidebar {
893 | height: 45px;
894 | min-height: 40px;
895 | width: calc(100% + 30px);
896 | margin: 0;
897 | margin-left: -15px;
898 | padding: 0 15px;
899 | position: static;
900 | z-index: 1;
901 | }
902 |
903 | .sidebar > .location {
904 | float: right;
905 | margin: 0px;
906 | margin-top: 2px;
907 | padding: 3px 10px 1px 10px;
908 | min-height: 39px;
909 | background: inherit;
910 | text-align: left;
911 | font-size: 24px;
912 | }
913 |
914 | .sidebar .location:empty {
915 | padding: 0;
916 | }
917 |
918 | .sidebar img {
919 | width: 35px;
920 | margin-top: 5px;
921 | margin-bottom: 5px;
922 | float: left;
923 | margin-left: 50px;
924 | }
925 |
926 | .sidebar-menu {
927 | position: fixed;
928 | z-index: 10;
929 | font-size: 2rem;
930 | cursor: pointer;
931 | width: 45px;
932 | left: 0;
933 | text-align: center;
934 | display: block;
935 | border-bottom: 1px solid;
936 | border-right: 1px solid;
937 | height: 45px;
938 | }
939 |
940 | .sidebar-elems {
941 | position: fixed;
942 | z-index: 1;
943 | left: 0;
944 | top: 45px;
945 | bottom: 0;
946 | overflow-y: auto;
947 | border-right: 1px solid;
948 | display: none;
949 | }
950 |
951 | .sidebar > .block.version {
952 | border-bottom: none;
953 | margin-top: 12px;
954 | }
955 |
956 | nav.sub {
957 | width: calc(100% - 32px);
958 | float: right;
959 | }
960 |
961 | .content {
962 | margin-left: 0px;
963 | }
964 |
965 | #main {
966 | margin-top: 45px;
967 | padding: 0;
968 | }
969 |
970 | .content .in-band {
971 | width: 100%;
972 | }
973 |
974 | .content h4 > .out-of-band {
975 | position: inherit;
976 | }
977 |
978 | .toggle-wrapper > .collapse-toggle {
979 | left: 0px;
980 | }
981 |
982 | .toggle-wrapper {
983 | height: 1.5em;
984 | }
985 |
986 | #search {
987 | margin-left: 0;
988 | }
989 |
990 | .content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant {
991 | display: flex;
992 | }
993 |
994 | .anchor {
995 | display: none !important;
996 | }
997 | }
998 |
999 | @media print {
1000 | nav.sub, .content .out-of-band, .collapse-toggle {
1001 | display: none;
1002 | }
1003 | }
1004 |
1005 | .information {
1006 | position: absolute;
1007 | left: -20px;
1008 | margin-top: 7px;
1009 | z-index: 1;
1010 | }
1011 |
1012 | .tooltip {
1013 | position: relative;
1014 | display: inline-block;
1015 | cursor: pointer;
1016 | }
1017 |
1018 | .tooltip .tooltiptext {
1019 | width: 120px;
1020 | display: none;
1021 | text-align: center;
1022 | padding: 5px 3px;
1023 | border-radius: 6px;
1024 | margin-left: 5px;
1025 | top: -5px;
1026 | left: 105%;
1027 | z-index: 1;
1028 | }
1029 |
1030 | .tooltip:hover .tooltiptext {
1031 | display: inline;
1032 | }
1033 |
1034 | .tooltip .tooltiptext::after {
1035 | content: " ";
1036 | position: absolute;
1037 | top: 50%;
1038 | left: 11px;
1039 | margin-top: -5px;
1040 | border-width: 5px;
1041 | border-style: solid;
1042 | }
1043 |
1044 | .important-traits .tooltip .tooltiptext {
1045 | border: 1px solid;
1046 | }
1047 |
1048 | pre.rust {
1049 | position: relative;
1050 | }
1051 |
1052 | .search-failed {
1053 | text-align: center;
1054 | margin-top: 20px;
1055 | }
1056 |
1057 | #titles {
1058 | height: 35px;
1059 | }
1060 |
1061 | #titles > div {
1062 | float: left;
1063 | width: 33.3%;
1064 | text-align: center;
1065 | border-bottom: 1px solid;
1066 | font-size: 18px;
1067 | cursor: pointer;
1068 | }
1069 |
1070 | #titles > div.selected {
1071 | border-bottom: 3px solid;
1072 | }
1073 |
1074 | #titles > div:hover {
1075 | border-bottom: 3px solid;
1076 | }
1077 |
1078 | #titles > div > div.count {
1079 | display: inline-block;
1080 | font-size: 16px;
1081 | }
1082 |
1083 | .important-traits {
1084 | cursor: pointer;
1085 | z-index: 2;
1086 | }
1087 |
1088 | h4 > .important-traits {
1089 | position: absolute;
1090 | left: -44px;
1091 | top: 2px;
1092 | }
1093 |
1094 | @media (max-width: 700px) {
1095 | h4 > .important-traits {
1096 | position: absolute;
1097 | left: -22px;
1098 | top: 24px;
1099 | }
1100 |
1101 | #titles > div > div.count {
1102 | float: left;
1103 | width: 100%;
1104 | }
1105 |
1106 | #titles {
1107 | height: 50px;
1108 | }
1109 |
1110 | .sidebar.mobile {
1111 | position: fixed;
1112 | width: 100%;
1113 | margin-left: 0;
1114 | background-color: rgba(0,0,0,0);
1115 | height: 100%;
1116 | }
1117 |
1118 | .show-it {
1119 | display: block;
1120 | width: 246px;
1121 | }
1122 |
1123 | .show-it > .block.items {
1124 | margin: 8px 0;
1125 | }
1126 |
1127 | .show-it > .block.items > ul {
1128 | margin: 0;
1129 | }
1130 |
1131 | .show-it > .block.items > ul > li {
1132 | text-align: center;
1133 | margin: 2px 0;
1134 | }
1135 |
1136 | .show-it > .block.items > ul > li > a {
1137 | font-size: 21px;
1138 | }
1139 |
1140 | /* Because of ios, we need to actually have a full height sidebar title so the
1141 | * actual sidebar can show up. But then we need to make it transparent so we don't
1142 | * hide content. The filler just allows to create the background for the sidebar
1143 | * title. But because of the absolute position, I had to lower the z-index.
1144 | */
1145 | #sidebar-filler {
1146 | position: fixed;
1147 | left: 45px;
1148 | width: calc(100% - 45px);
1149 | top: 0;
1150 | height: 45px;
1151 | z-index: -1;
1152 | border-bottom: 1px solid;
1153 | }
1154 |
1155 | .collapse-toggle {
1156 | left: -20px;
1157 | }
1158 |
1159 | .impl > .collapse-toggle {
1160 | left: -10px;
1161 | }
1162 | }
1163 |
1164 |
1165 | @media (max-width: 416px) {
1166 | #titles {
1167 | height: 73px;
1168 | }
1169 |
1170 | #titles > div {
1171 | height: 73px;
1172 | }
1173 | }
1174 |
1175 | .modal {
1176 | position: fixed;
1177 | width: 100vw;
1178 | height: 100vh;
1179 | z-index: 10000;
1180 | top: 0;
1181 | left: 0;
1182 | }
1183 |
1184 | .modal-content {
1185 | display: block;
1186 | max-width: 60%;
1187 | min-width: 200px;
1188 | padding: 8px;
1189 | top: 40%;
1190 | position: absolute;
1191 | left: 50%;
1192 | transform: translate(-50%, -40%);
1193 | border: 1px solid;
1194 | border-radius: 4px;
1195 | border-top-right-radius: 0;
1196 | }
1197 |
1198 | .modal-content > .docblock {
1199 | margin: 0;
1200 | }
1201 |
1202 | h3.important {
1203 | margin: 0;
1204 | margin-bottom: 13px;
1205 | font-size: 19px;
1206 | }
1207 |
1208 | .modal-content > .docblock > code.content {
1209 | margin: 0;
1210 | padding: 0;
1211 | font-size: 20px;
1212 | }
1213 |
1214 | .modal-content > .close {
1215 | position: absolute;
1216 | font-weight: 900;
1217 | right: -25px;
1218 | top: -1px;
1219 | font-size: 18px;
1220 | width: 25px;
1221 | padding-right: 2px;
1222 | border-top-right-radius: 5px;
1223 | border-bottom-right-radius: 5px;
1224 | text-align: center;
1225 | border: 1px solid;
1226 | border-right: 0;
1227 | cursor: pointer;
1228 | }
1229 |
1230 | .modal-content > .whiter {
1231 | height: 25px;
1232 | position: absolute;
1233 | width: 3px;
1234 | right: -2px;
1235 | top: 0px;
1236 | }
1237 |
1238 | #main > div.important-traits {
1239 | position: absolute;
1240 | left: -24px;
1241 | margin-top: 16px;
1242 | }
1243 |
1244 | .content > .methods > div.important-traits {
1245 | position: absolute;
1246 | left: -42px;
1247 | margin-top: 2px;
1248 | }
1249 |
1250 | kbd {
1251 | display: inline-block;
1252 | padding: 3px 5px;
1253 | font: 15px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
1254 | line-height: 10px;
1255 | vertical-align: middle;
1256 | border: solid 1px;
1257 | border-radius: 3px;
1258 | box-shadow: inset 0 -1px 0;
1259 | cursor: default;
1260 | }
1261 |
1262 | .theme-picker {
1263 | display: none;
1264 | }
1265 |
1266 | .theme-picker button {
1267 | outline: none;
1268 | }
1269 |
1270 | #settings-menu {
1271 | position: absolute;
1272 | right: 0;
1273 | top: 13px;
1274 | outline: none;
1275 | }
1276 |
1277 | #theme-picker, #settings-menu {
1278 | padding: 4px;
1279 | width: 27px;
1280 | height: 29px;
1281 | border: 1px solid;
1282 | border-radius: 3px;
1283 | cursor: pointer;
1284 | }
1285 |
1286 | #theme-choices {
1287 | display: none;
1288 | position: absolute;
1289 | left: 0;
1290 | top: 28px;
1291 | border: 1px solid;
1292 | border-radius: 3px;
1293 | z-index: 1;
1294 | cursor: pointer;
1295 | }
1296 |
1297 | #theme-choices > button {
1298 | border: none;
1299 | width: 100%;
1300 | padding: 4px;
1301 | text-align: center;
1302 | background: rgba(0,0,0,0);
1303 | }
1304 |
1305 | #theme-choices > button:not(:first-child) {
1306 | border-top: 1px solid;
1307 | }
1308 |
1309 | @media (max-width: 700px) {
1310 | .theme-picker {
1311 | left: 10px;
1312 | top: 54px;
1313 | z-index: 1;
1314 | }
1315 | }
1316 |
1317 | .hidden-by-impl-hider,
1318 | .hidden-by-usual-hider {
1319 | /* important because of conflicting rule for small screens */
1320 | display: none !important;
1321 | }
1322 |
1323 | #implementations-list > h3 > span.in-band {
1324 | width: 100%;
1325 | }
1326 |
1327 | .table-display {
1328 | width: 100%;
1329 | border: 0;
1330 | border-collapse: collapse;
1331 | border-spacing: 0;
1332 | font-size: 16px;
1333 | }
1334 |
1335 | .table-display tr td:first-child {
1336 | padding-right: 0;
1337 | }
1338 |
1339 | .table-display tr td:last-child {
1340 | float: right;
1341 | }
1342 | .table-display .out-of-band {
1343 | position: relative;
1344 | font-size: 19px;
1345 | display: block;
1346 | }
1347 |
1348 | #main > ul {
1349 | padding-left: 10px;
1350 | }
1351 | #main > ul > li {
1352 | list-style: none;
1353 | }
1354 | #all-types {
1355 | text-align: center;
1356 | border: 1px solid;
1357 | margin: 0 10px;
1358 | margin-bottom: 10px;
1359 | display: block;
1360 | border-radius: 7px;
1361 | }
1362 | #all-types > p {
1363 | margin: 5px 0;
1364 | }
1365 |
1366 | div.children {
1367 | padding-left: 27px;
1368 | display: none;
1369 | }
1370 | div.name {
1371 | cursor: pointer;
1372 | position: relative;
1373 | margin-left: 16px;
1374 | }
1375 | div.name:hover {
1376 | border: 1px dotted #000000;
1377 | margin: -1px -1px -1px 15px;
1378 | }
1379 | div.files>a {
1380 | display: block;
1381 | padding: 0 3px;
1382 | }
1383 | div.files>a:hover {
1384 | border: 1px dotted #000000;
1385 | margin: -1px -1px -1px -1px;
1386 | }
1387 | div.name.expand+.children {
1388 | display: block;
1389 | }
1390 | div.name::before {
1391 | content: "\25B6";
1392 | padding-left: 4px;
1393 | font-size: 0.7em;
1394 | position: absolute;
1395 | left: -16px;
1396 | top: 4px;
1397 | }
1398 | div.name.expand::before {
1399 | transform: rotate(90deg);
1400 | left: -15px;
1401 | top: 2px;
1402 | }
1403 |
--------------------------------------------------------------------------------
/gnuplot/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 |
3 | name = "gnuplot"
4 | version = "0.0.46" #auto
5 | license = "LGPL-3.0"
6 | repository = "https://github.com/SiegeLord/RustGnuplot"
7 | documentation = "http://siegelord.github.io/RustGnuplot/doc/gnuplot/index.html"
8 | keywords = ["plots", "graphics", "plotting", "gnuplot", "visualization"]
9 | authors = [ "SiegeLord " ]
10 | description = "Rust gnuplot controller"
11 | autobins = false
12 | autoexamples = false
13 | autotests = false
14 | autobenches = false
15 | categories = ["visualization"]
16 | edition = "2021"
17 |
18 | [lib]
19 |
20 | name = "gnuplot"
21 | path = "src/lib.rs"
22 |
23 | [dev-dependencies]
24 |
25 | argparse-rs = "=0.1.0"
26 | tempfile = "3.3.0"
27 |
28 | [[example]]
29 |
30 | name = "example1"
31 | path = "examples/example1.rs"
32 |
33 | [[example]]
34 |
35 | name = "example2"
36 | path = "examples/example2.rs"
37 |
38 | [[example]]
39 |
40 | name = "example3"
41 | path = "examples/example3.rs"
42 |
43 | [[example]]
44 |
45 | name = "example4"
46 | path = "examples/example4.rs"
47 |
48 | [[example]]
49 |
50 | name = "animation_example"
51 | path = "examples/animation_example.rs"
52 |
53 | [[example]]
54 |
55 | name = "box_and_whisker"
56 | path = "examples/box_and_whisker.rs"
57 |
58 | [[example]]
59 |
60 | name = "box_xy_error"
61 | path = "examples/box_xy_error.rs"
62 |
63 | [[example]]
64 |
65 | name = "color"
66 | path = "examples/color.rs"
67 |
68 | [[example]]
69 |
70 | name = "variable_color"
71 | path = "examples/variable_color.rs"
72 |
73 | [[example]]
74 |
75 | name = "lines_3d"
76 | path = "examples/lines_3d.rs"
77 |
78 | [[example]]
79 |
80 | name = "points_3d"
81 | path = "examples/points_3d.rs"
82 |
83 | [[example]]
84 |
85 | name = "lines_points_3d"
86 | path = "examples/lines_points_3d.rs"
87 |
88 | [[example]]
89 |
90 | name = "readme_example"
91 | path = "examples/readme_example.rs"
92 |
93 | [[example]]
94 |
95 | name = "time"
96 | path = "examples/time.rs"
97 |
98 | [[example]]
99 |
100 | name = "gif"
101 | path = "examples/gif.rs"
102 |
103 | [[example]]
104 |
105 | name = "color_cycling"
106 | path = "examples/color_cycling.rs"
107 |
108 | [[example]]
109 |
110 | name = "dash_type"
111 | path = "examples/dash_type.rs"
112 |
113 | [[example]]
114 |
115 | name = "patterns"
116 | path = "examples/patterns.rs"
117 |
118 | [[example]]
119 |
120 | name = "inverse_api"
121 | path = "examples/inverse_api.rs"
122 |
123 | [[example]]
124 |
125 | name = "multiplot_options"
126 | path = "examples/multiplot_options.rs"
127 |
128 | [[example]]
129 |
130 | name = "multiple_axes"
131 | path = "examples/multiple_axes.rs"
132 |
133 | [[example]]
134 |
135 | name = "text"
136 | path = "examples/text.rs"
137 |
138 | [[example]]
139 |
140 | name = "polygons"
141 | path = "examples/polygons.rs"
142 |
143 | [dependencies]
144 | byteorder = "1.4.3"
145 | tempfile = "3.9"
146 |
--------------------------------------------------------------------------------
/gnuplot/examples/animation_example.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use gnuplot::*;
3 | use std::thread::sleep;
4 | use std::time::Duration;
5 |
6 | fn main()
7 | {
8 | println!("This is a silly example of doing an animation... Ctrl-C to quit.");
9 | let mut fg = Figure::new();
10 | let mut x = vec![];
11 | for i in 0..100i32
12 | {
13 | x.push(i as f32 * 0.1 - 5.0);
14 | }
15 |
16 | let mut t = 0.0;
17 | loop
18 | {
19 | fg.clear_axes();
20 | fg.axes2d().set_y_range(Fix(-1.0), Fix(1.0)).lines(
21 | x.iter(),
22 | x.iter().map(|&x| (x + t).sin()),
23 | &[],
24 | );
25 | t += 0.1;
26 | fg.show_and_keep_running().unwrap();
27 | sleep(Duration::from_millis(500));
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/gnuplot/examples/box_and_whisker.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 |
5 | mod common;
6 |
7 | fn example(c: Common)
8 | {
9 | let mut fg = Figure::new();
10 |
11 | fg.axes2d()
12 | .set_title("Box and whisker", &[])
13 | .box_and_whisker(
14 | [-0.6f32, 1.5, 2.5].iter(),
15 | [-1.0f32, 0.0, 1.0].iter(),
16 | [-2.0f32, -1.0, 0.0].iter(),
17 | [2.0f32, 3.0, 4.0].iter(),
18 | [1.0f32, 2.0, 3.0].iter(),
19 | &[
20 | BoxWidth([0.5f64, 0.25, 0.125].into()),
21 | WhiskerBars(0.5),
22 | Color("blue".into()),
23 | LineWidth(2.0),
24 | LineStyle(SmallDot),
25 | FillAlpha(0.5),
26 | ],
27 | )
28 | .box_and_whisker(
29 | [0.0f32, 1.0, 2.0].iter(),
30 | [-1.0f32, 0.0, 1.0].iter(),
31 | [-2.0f32, -1.0, 0.0].iter(),
32 | [2.0f32, 3.0, 4.0].iter(),
33 | [1.0f32, 2.0, 3.0].iter(),
34 | &[],
35 | )
36 | .set_x_range(Fix(-1.0), Fix(3.0))
37 | .set_y_range(Fix(-3.0), Fix(5.0));
38 |
39 | c.show(&mut fg, "box_and_whisker");
40 | }
41 |
42 | fn main()
43 | {
44 | Common::new().map(|c| example(c));
45 | }
46 |
--------------------------------------------------------------------------------
/gnuplot/examples/box_xy_error.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 |
5 | mod common;
6 |
7 | fn example(c: Common)
8 | {
9 | let mut fg = Figure::new();
10 |
11 | fg.axes2d()
12 | .set_title("Box XY Error", &[])
13 | .box_xy_error_delta(
14 | [0.0f32, 1.0, 2.0].iter(),
15 | [-1.0f32, 0.0, 1.0].iter(),
16 | [0.25f32, 0.375, 0.15].iter(),
17 | [2.0f32, 3.0, 4.0].iter(),
18 | &[],
19 | )
20 | .box_xy_error_low_high(
21 | [-0.6f32, 1.5, 2.5].iter(),
22 | [-1.0f32, 0.0, 1.0].iter(),
23 | [-0.9f32, -1.0, 2.2].iter(),
24 | [-0.45f32, 3.0, 2.95].iter(),
25 | [-1.5f32, 4.5, 3.0].iter(),
26 | [0.5f32, 4.75, 0.125].iter(),
27 | &[
28 | Color("blue".into()),
29 | LineWidth(2.0),
30 | LineStyle(SmallDot),
31 | FillAlpha(0.5),
32 | ],
33 | )
34 | .set_x_range(Fix(-1.0), Fix(3.0))
35 | .set_y_range(Fix(-3.0), Fix(5.0));
36 |
37 | c.show(&mut fg, "box_xy_error");
38 | }
39 |
40 | fn main()
41 | {
42 | Common::new().map(|c| example(c));
43 | }
44 |
--------------------------------------------------------------------------------
/gnuplot/examples/color.rs:
--------------------------------------------------------------------------------
1 | use std::{fmt::Debug, iter};
2 |
3 | // This file is released into Public Domain.
4 | use crate::common::*;
5 | use gnuplot::*;
6 |
7 | mod common;
8 |
9 | fn color_name(color: &PlotOption) -> String
10 | {
11 | match color
12 | {
13 | Color(color_type) => format!("{:?}", color_type),
14 | _ => panic!(),
15 | }
16 | }
17 |
18 | fn example(c: Common)
19 | {
20 | let x = 0..5;
21 |
22 | let colors = [
23 | Color("black".into()), // Conversion to RGBString is implicit
24 | Color(ColorType::RGBString("black")), // Explicit use of RGBString
25 | Color("red".into()), // Conversion to RGBString is implicit
26 | Color(RGBString("#ff0000")), // Red using Hex coded RRGGBB
27 | Color(RGBString("#ffff0000")), // Red using Hex coded AARRGGBB
28 | Color("#ff8888".into()), // Pink using Hex coded RRGGBB. Conversion to RGBString is implict
29 | Color("#77ff0000".into()), // Pink using Hex coded AARRGGBB. Conversion to RGBString is implict
30 | Color(ColorType::RGBString("#ffff0000")), // Transparent using Hex coded AARRGGBB
31 | Color((128, 0, 255).into()), // Purple using implict RGBInteger
32 | Color(RGBInteger(128, 0, 255)), // Purple using explict RGBInteger
33 | Color((0.5, 0.0, 1.0).try_into().unwrap()), // Purple using implict float to int conversion
34 | Color((64, 128, 0, 255).into()), // Pale purple using implict ARGBInteger
35 | Color(ARGBInteger(64, 128, 0, 255)), // Pale purple using explict ARGBInteger
36 | Color((0.25, 0.5, 0.0, 1.0).try_into().unwrap()), // Pale purple using implict float to int conversion
37 | ];
38 |
39 | let mut fg = Figure::new();
40 | let ax = fg.axes2d();
41 | ax.set_title(
42 | "Demo of RGBString in various forms\nSee code comments for how to construct the colors",
43 | &[],
44 | )
45 | .set_x_range(Fix(-9.0), Auto)
46 | .set_legend(Graph(0.5), Graph(0.9), &[], &[Font("", 12.0)]);
47 |
48 | let n_colors = colors.len();
49 | for (i, color) in colors.into_iter().enumerate()
50 | {
51 | ax.box_xy_error_delta(
52 | x.clone(),
53 | iter::repeat((n_colors - 1) - i),
54 | iter::repeat(0.4),
55 | iter::repeat(0.2),
56 | &[
57 | Caption(&color_name(&color)),
58 | LineWidth(1.0),
59 | BorderColor("black".into()),
60 | color,
61 | ],
62 | );
63 | }
64 |
65 | // Draw line across the boxes in fixed black and background colors
66 | ax.lines(
67 | [0, 0],
68 | [0, n_colors - 1],
69 | &[
70 | LineWidth(7.0),
71 | Color(Black),
72 | Caption(&color_name::(&Color(Black))),
73 | ],
74 | );
75 |
76 | ax.lines(
77 | [4, 4],
78 | [0, n_colors - 1],
79 | &[
80 | LineWidth(7.0),
81 | Color(Background),
82 | Caption(&color_name::(&Color(Background))),
83 | ],
84 | );
85 |
86 | // any of the forms used for Color can also be used with TextColor and BorderColor
87 | ax.set_x_label(
88 | "Labels can be colored using TextColor",
89 | &[TextColor((128, 0, 255).into())],
90 | );
91 |
92 | c.show(&mut fg, "rgb_color");
93 |
94 | // ########################################################################
95 |
96 | let mut fg = Figure::new();
97 | let ax = fg.axes2d();
98 | let max_cb = 10.0;
99 | ax.set_cb_range(Fix(0.0), Fix(max_cb));
100 | for color_value in (0..=10).into_iter().step_by(2)
101 | {
102 | let color_float = color_value as f64;
103 | let frac_color = Color(PaletteFracColor(color_float / max_cb));
104 | let cb_range_color = Color(PaletteCBColor(color_float));
105 |
106 | ax.box_xy_error_delta(
107 | [color_value],
108 | [0],
109 | [0.4],
110 | [0.4],
111 | &[
112 | Caption(&color_name(&frac_color)),
113 | LineWidth(1.0),
114 | BorderColor("black".into()),
115 | frac_color,
116 | ],
117 | )
118 | .box_xy_error_delta(
119 | [color_value],
120 | [1],
121 | [0.4],
122 | [0.4],
123 | &[
124 | Caption(&color_name(&cb_range_color)),
125 | LineWidth(1.0),
126 | BorderColor("black".into()),
127 | cb_range_color,
128 | ],
129 | );
130 | }
131 | ax.set_x_range(Fix(-10.0), Fix(11.0))
132 | .set_y_range(Fix(-0.5), Fix(1.5))
133 | .set_legend(Graph(0.45), Graph(0.9), &[], &[Font("", 12.0)]);
134 | c.show(&mut fg, "palette_colors");
135 | }
136 |
137 | fn main()
138 | {
139 | Common::new().map(|c| example(c));
140 | }
141 |
--------------------------------------------------------------------------------
/gnuplot/examples/color_cycling.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 |
5 | mod common;
6 |
7 | fn example(c: Common)
8 | {
9 | let x = 0..10;
10 |
11 | let mut fg = Figure::new();
12 |
13 | let ax = fg.axes2d();
14 | ax.set_title("Color cycling", &[]);
15 | ax.set_legend(Graph(0.2), Graph(0.9), &[], &[]);
16 | for i in 0..10
17 | {
18 | ax.lines_points(
19 | x.clone(),
20 | x.clone().map(|v| v * 2 + i),
21 | &[Caption(&format!("{}", i))],
22 | );
23 | }
24 |
25 | c.show(&mut fg, "color_cycling");
26 | }
27 |
28 | fn main()
29 | {
30 | Common::new().map(|c| example(c));
31 | }
32 |
--------------------------------------------------------------------------------
/gnuplot/examples/common.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | #![allow(dead_code)]
3 | use argparse_rs::*;
4 | use gnuplot::*;
5 | use std::env;
6 | use std::path::Path;
7 |
8 | #[derive(Copy, Clone)]
9 | pub struct BetterIterator<'l, T: 'l>
10 | {
11 | idx: usize,
12 | slice: &'l [T],
13 | }
14 |
15 | impl<'l, T: 'l> Iterator for BetterIterator<'l, T>
16 | {
17 | type Item = &'l T;
18 | fn next(&mut self) -> Option<&'l T>
19 | {
20 | let ret = self.slice.get(self.idx);
21 | self.idx += 1;
22 | ret
23 | }
24 | }
25 |
26 | pub trait BetterIteratorExt<'l, T>
27 | {
28 | fn iter2(self) -> BetterIterator<'l, T>;
29 | }
30 |
31 | impl<'l, T: 'l> BetterIteratorExt<'l, T> for &'l [T]
32 | {
33 | fn iter2(self) -> BetterIterator<'l, T>
34 | {
35 | BetterIterator {
36 | idx: 0,
37 | slice: self,
38 | }
39 | }
40 | }
41 |
42 | pub struct Common
43 | {
44 | pub no_show: bool,
45 | pub save_png: bool,
46 | pub term: Option,
47 | pub extension: String,
48 | pub output_dir: String,
49 | pub echo: bool,
50 | }
51 |
52 | impl Common
53 | {
54 | pub fn new() -> Option
55 | {
56 | let arg_vec: Vec<_> = env::args().collect();
57 |
58 | let mut args = ArgParser::new(arg_vec[0].clone());
59 |
60 | args.add_opt(
61 | "no-show",
62 | Some("false"),
63 | 'n',
64 | false,
65 | "do not run the gnuplot process.",
66 | ArgType::Flag,
67 | );
68 | args.add_opt(
69 | "terminal",
70 | None,
71 | 't',
72 | false,
73 | "specify what terminal to use for gnuplot.",
74 | ArgType::Option,
75 | );
76 | args.add_opt(
77 | "output-dir",
78 | None,
79 | 'o',
80 | false,
81 | "output directory.",
82 | ArgType::Option,
83 | );
84 | args.add_opt(
85 | "extension",
86 | Some("out"),
87 | 'e',
88 | false,
89 | "specify what extension the output file should have. Default: 'out'",
90 | ArgType::Option,
91 | );
92 | args.add_opt(
93 | "save-png",
94 | Some("false"),
95 | 's',
96 | false,
97 | "render the plots to images.",
98 | ArgType::Flag,
99 | );
100 | args.add_opt(
101 | "echo",
102 | Some("false"),
103 | 'g',
104 | false,
105 | "echo gnuplot commands.",
106 | ArgType::Flag,
107 | );
108 |
109 | let res = args.parse(arg_vec.iter()).unwrap();
110 |
111 | if res.get("help").unwrap_or(false)
112 | {
113 | args.help();
114 | return None;
115 | }
116 |
117 | Some(Common {
118 | output_dir: res.get("output-dir").unwrap_or("".into()),
119 | no_show: res.get("no-show").unwrap(),
120 | save_png: res.get("save-png").unwrap(),
121 | echo: res.get("echo").unwrap_or(false),
122 | term: res.get::("terminal").map(|s| s.to_string()),
123 | extension: res.get::("extension").unwrap(),
124 | })
125 | }
126 |
127 | pub fn show(&self, fg: &mut Figure, filename: &str)
128 | {
129 | let out_path = Path::new(&self.output_dir).join(filename);
130 | self.term.as_ref().map(|t| {
131 | fg.set_terminal(
132 | &t,
133 | out_path.with_extension(&self.extension).to_str().unwrap(),
134 | );
135 | });
136 | if !self.no_show
137 | {
138 | fg.show().unwrap();
139 | }
140 | if self.save_png
141 | {
142 | fg.save_to_png(out_path.with_extension("png").to_str().unwrap(), 800, 600)
143 | .unwrap();
144 | }
145 | if self.echo
146 | {
147 | fg.echo_to_file(out_path.with_extension("gnuplot").to_str().unwrap());
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/gnuplot/examples/dash_type.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 |
5 | mod common;
6 |
7 | fn example(c: Common)
8 | {
9 | let x = 0..10;
10 |
11 | let mut fg = Figure::new();
12 |
13 | let ax = fg.axes2d();
14 | ax.set_title("Dash type", &[]);
15 | ax.set_legend(Graph(0.3), Graph(0.9), &[], &[]);
16 | for (i, &dt) in [Solid, SmallDot, Dot, Dash, DotDash, DotDotDash]
17 | .iter()
18 | .enumerate()
19 | {
20 | ax.lines(
21 | x.clone(),
22 | x.clone().map(|v| v * 2 + 2 * i),
23 | &[
24 | LineWidth(2.),
25 | Color("black".into()),
26 | LineStyle(dt),
27 | Caption(&format!("{:?}", dt)),
28 | ],
29 | );
30 | }
31 |
32 | c.show(&mut fg, "dash_type");
33 | }
34 |
35 | fn main()
36 | {
37 | Common::new().map(|c| example(c));
38 | }
39 |
--------------------------------------------------------------------------------
/gnuplot/examples/example1.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 |
4 | use gnuplot::*;
5 | use std::iter::repeat;
6 |
7 | mod common;
8 |
9 | fn example(c: Common)
10 | {
11 | let x = &[1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0];
12 | let x = x.iter2();
13 | let y1: Vec = x
14 | .map(|&v| {
15 | let z = v - 4.0;
16 | z * z - 5.0
17 | })
18 | .collect();
19 | let y1 = y1.iter2();
20 | let y2: Vec = x
21 | .map(|&v| {
22 | let z = v - 4.0;
23 | -z * z + 5.0
24 | })
25 | .collect();
26 | let y2 = y2.iter2();
27 | let y3: Vec = x.map(|&v| v - 4.0).collect();
28 | let y3 = y3.iter2();
29 | let y4: Vec = x.map(|&v| 0.9 * v - 4.0).collect();
30 | let y4 = y4.iter2();
31 | let x_err = repeat(0.1f32);
32 | let y_err = repeat(0.2f32);
33 |
34 | let mut fg = Figure::new();
35 |
36 | fg.axes2d()
37 | .set_size(0.75, 1.0)
38 | .set_title("Example Plot fg1.1", &[])
39 | .set_x_ticks(Some((Fix(1.0), 1)), &[Mirror(false)], &[])
40 | .set_y_ticks(Some((Fix(1.0), 1)), &[Mirror(false)], &[])
41 | .set_legend(
42 | Graph(1.0),
43 | Graph(0.5),
44 | &[Placement(AlignLeft, AlignCenter)],
45 | &[TextAlign(AlignRight)],
46 | )
47 | .set_border(true, &[Left, Bottom], &[LineWidth(2.0)])
48 | .set_x_label("Abscissa", &[])
49 | .set_y_label("Ordinate", &[])
50 | .arrow(
51 | Axis(5.7912),
52 | Axis(2.7912),
53 | Axis(5.7912),
54 | Axis(1.7912),
55 | &[
56 | ArrowType(Closed),
57 | ArrowSize(0.1),
58 | LineWidth(2.0),
59 | Color("black".into()),
60 | ],
61 | )
62 | .label("Here", Axis(5.7912), Axis(3.1), &[TextAlign(AlignCenter)])
63 | .fill_between(
64 | x,
65 | y1.map(|&y| y * 0.85 - 1.0),
66 | y1.map(|&y| y * 1.15 + 1.0),
67 | &[Color("#aaaaff".into())],
68 | )
69 | .lines(
70 | x,
71 | y1,
72 | &[
73 | Caption("(x - 4)^2 - 5"),
74 | LineWidth(1.5),
75 | Color("black".into()),
76 | ],
77 | )
78 | .y_error_lines(
79 | x,
80 | y2,
81 | repeat(1.0f32),
82 | &[
83 | Caption("-(x - 4)^2 + 5"),
84 | LineWidth(1.5),
85 | Color("red".into()),
86 | ],
87 | )
88 | .lines_points(
89 | x,
90 | y3,
91 | &[
92 | Caption("x - 4"),
93 | PointSymbol('t'),
94 | LineWidth(1.5),
95 | LineStyle(Dash),
96 | Color("#11ff11".into()),
97 | ],
98 | );
99 |
100 | c.show(&mut fg, "example1_1");
101 |
102 | let mut fg = Figure::new();
103 |
104 | fg.axes2d()
105 | .set_pos_grid(2, 2, 0)
106 | .lines(
107 | x,
108 | y1,
109 | &[Caption("Lines"), LineWidth(3.0), Color("violet".into())],
110 | )
111 | .set_title("Plot1 fg1.2", &[]);
112 |
113 | fg.axes2d()
114 | .set_pos_grid(2, 1, 1)
115 | .points(
116 | x,
117 | y2,
118 | &[
119 | Caption("Points"),
120 | PointSymbol('D'),
121 | Color("#ffaa77".into()),
122 | PointSize(2.0),
123 | ],
124 | )
125 | .set_title("Plot2", &[]);
126 |
127 | c.show(&mut fg, "example1_2");
128 |
129 | let mut fg = Figure::new();
130 |
131 | fg.axes2d().lines(
132 | x,
133 | y1,
134 | &[Caption("Lines"), LineWidth(3.0), Color("violet".into())],
135 | );
136 |
137 | fg.axes2d()
138 | .set_pos(0.2, 0.4)
139 | .set_size(0.3, 0.6)
140 | .set_aspect_ratio(Fix(1.0))
141 | .points(
142 | x,
143 | y2,
144 | &[Caption("Points"), PointSymbol('T'), Color("#ffaa77".into())],
145 | )
146 | .set_title("Inset fg1.3", &[]);
147 |
148 | c.show(&mut fg, "example1_3");
149 |
150 | let mut fg = Figure::new();
151 |
152 | fg.axes2d()
153 | .lines(
154 | x,
155 | y1,
156 | &[Caption("Lines"), LineWidth(3.0), Color("violet".into())],
157 | )
158 | .set_y_range(Fix(-30.0), Auto)
159 | .set_y_label("This axis is manually scaled on the low end", &[])
160 | .set_title("Range fg1.4", &[]);
161 |
162 | c.show(&mut fg, "example1_4");
163 |
164 | let mut fg = Figure::new();
165 |
166 | fg.axes2d()
167 | .x_error_lines(
168 | x,
169 | y1,
170 | x_err.clone(),
171 | &[
172 | Caption(r"x\_error\_lines"),
173 | LineWidth(2.0),
174 | PointSymbol('O'),
175 | Color("red".into()),
176 | ],
177 | )
178 | .y_error_lines(
179 | x,
180 | y2,
181 | y_err.clone(),
182 | &[
183 | Caption(r"y\_error\_lines"),
184 | LineWidth(2.0),
185 | PointSymbol('S'),
186 | Color("blue".into()),
187 | ],
188 | )
189 | .x_error_bars(
190 | x,
191 | y3,
192 | x_err,
193 | &[
194 | Caption(r"x\_error\_bars"),
195 | PointSymbol('T'),
196 | Color("cyan".into()),
197 | ],
198 | )
199 | .y_error_bars(
200 | x,
201 | y4,
202 | y_err,
203 | &[
204 | Caption(r"y\_error\_bars"),
205 | PointSymbol('R'),
206 | Color("green".into()),
207 | ],
208 | )
209 | .set_title("Error fg1.5", &[]);
210 |
211 | c.show(&mut fg, "example1_5");
212 |
213 | let mut fg = Figure::new();
214 |
215 | fg.axes2d()
216 | .set_size(1.0, 0.8)
217 | .set_pos(0.0, 0.2)
218 | .fill_between(
219 | x,
220 | y1,
221 | y3,
222 | &[
223 | Color("red".into()),
224 | FillAlpha(0.5),
225 | FillRegion(Above),
226 | Caption("A > B"),
227 | ],
228 | )
229 | .fill_between(
230 | x,
231 | y1,
232 | y3,
233 | &[
234 | Color("green".into()),
235 | FillAlpha(0.5),
236 | FillRegion(Below),
237 | Caption("A < B"),
238 | ],
239 | )
240 | .fill_between(
241 | x,
242 | y2,
243 | y3,
244 | &[
245 | Color("blue".into()),
246 | FillAlpha(0.5),
247 | FillRegion(Between),
248 | Caption("Between C and B"),
249 | ],
250 | )
251 | .lines(
252 | x,
253 | y1,
254 | &[
255 | Color("black".into()),
256 | LineWidth(2.0),
257 | LineStyle(Dash),
258 | Caption("A"),
259 | ],
260 | )
261 | .lines(
262 | x,
263 | y2,
264 | &[Color("black".into()), LineWidth(2.0), Caption("C")],
265 | )
266 | .lines(
267 | x,
268 | y3,
269 | &[
270 | Color("black".into()),
271 | LineWidth(2.0),
272 | LineStyle(DotDotDash),
273 | Caption("B"),
274 | ],
275 | )
276 | .set_title("Fill and legend fg1.6", &[])
277 | .set_legend(
278 | Graph(0.5),
279 | Graph(-0.2),
280 | &[
281 | Horizontal,
282 | Placement(AlignCenter, AlignTop),
283 | Title("Legend Title"),
284 | ],
285 | &[TextAlign(AlignRight)],
286 | );
287 |
288 | c.show(&mut fg, "example1_6");
289 |
290 | let mut fg = Figure::new();
291 |
292 | fg.axes2d()
293 | .set_pos(0.1, 0.1)
294 | .set_size(0.8, 0.8)
295 | .lines(
296 | x,
297 | y1,
298 | &[
299 | Caption("(x - 4)^2 - 5"),
300 | LineWidth(3.0),
301 | Color("violet".into()),
302 | LineStyle(DotDash),
303 | ],
304 | )
305 | .points(
306 | x,
307 | y2,
308 | &[
309 | Caption("-(x - 4)^2 + 5"),
310 | PointSymbol('S'),
311 | Color("#ffaa77".into()),
312 | ],
313 | )
314 | .lines_points(
315 | x,
316 | y3,
317 | &[
318 | Caption("x - 4"),
319 | PointSymbol('O'),
320 | Color("black".into()),
321 | LineStyle(SmallDot),
322 | ],
323 | )
324 | .set_x_label(
325 | "X Label",
326 | &[Font("Arial", 24.0), TextColor("red".into()), Rotate(45.0)],
327 | )
328 | .set_y_label("Y Label", &[Rotate(0.0)])
329 | .set_title(
330 | "Goings nuts with the formatting fg1.7",
331 | &[Font("Times", 24.0), TextOffset(-10.0, 0.5)],
332 | )
333 | .label(
334 | "Intersection",
335 | Axis(2.208),
336 | Axis(-1.791),
337 | &[
338 | MarkerSymbol('*'),
339 | TextAlign(AlignCenter),
340 | TextOffset(0.0, -1.0),
341 | MarkerColor(RGBString("red")),
342 | MarkerSize(2.0),
343 | ],
344 | );
345 |
346 | c.show(&mut fg, "example1_7");
347 | }
348 |
349 | fn main()
350 | {
351 | Common::new().map(|c| example(c));
352 | }
353 |
--------------------------------------------------------------------------------
/gnuplot/examples/example2.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 |
4 | use gnuplot::*;
5 |
6 | mod common;
7 |
8 | fn example(c: Common)
9 | {
10 | let x = &[1i32, 2, 3, 4, 5];
11 | let x = x.iter2();
12 | let y1: Vec = x.map(|&v| v * v).collect();
13 | let y1 = y1.iter2();
14 |
15 | let x2 = &[1i32, 4, 5];
16 | let x2 = x2.iter2();
17 | let y2: Vec = x2.map(|&v| v * v).collect();
18 | let y2 = y2.iter2();
19 |
20 | let x3 = &[1i32, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
21 | let x3 = x3.iter2();
22 | let y3: Vec = x3.map(|&v| v * v * v).collect();
23 | let y3 = y3.iter2();
24 |
25 | let zw = 16;
26 | let zh = 16;
27 | let mut z1 = Vec::with_capacity((zw * zh) as usize);
28 | for i in 0..zh
29 | {
30 | for j in 0..zw
31 | {
32 | let y = 8.0 * (i as f64) / zh as f64 - 4.0;
33 | let x = 8.0 * (j as f64) / zw as f64 - 4.0;
34 | z1.push(x + y);
35 | }
36 | }
37 |
38 | let mut fg = Figure::new();
39 |
40 | fg.axes2d()
41 | .set_title("Arrows fg2.1", &[])
42 | .lines(
43 | x,
44 | y1,
45 | &[LineWidth(3.0), Color("brown".into()), LineStyle(DotDash)],
46 | )
47 | .arrow(
48 | Graph(0.5),
49 | Graph(1.0),
50 | Axis(1.0),
51 | Axis(1.0),
52 | &[
53 | ArrowType(Filled),
54 | ArrowSize(0.1),
55 | LineStyle(DotDotDash),
56 | LineWidth(2.0),
57 | Color("red".into()),
58 | ],
59 | )
60 | .arrow(
61 | Graph(0.5),
62 | Graph(1.0),
63 | Axis(3.0),
64 | Axis(9.0),
65 | &[ArrowType(Open), Color("green".into())],
66 | );
67 |
68 | c.show(&mut fg, "example2_1");
69 |
70 | let mut fg = Figure::new();
71 |
72 | fg.axes2d()
73 | .set_title("Boxes fg2.2", &[])
74 | .boxes(
75 | x2,
76 | y2,
77 | &[
78 | LineWidth(2.0),
79 | Color("cyan".into()),
80 | BorderColor("blue".into()),
81 | LineStyle(DotDash),
82 | ],
83 | )
84 | .boxes(
85 | x,
86 | y1,
87 | &[
88 | LineWidth(2.0),
89 | Color("gray".into()),
90 | BorderColor("black".into()),
91 | BoxWidth([0.5, 0.4, 0.55, 0.7, 0.2].into()),
92 | ],
93 | );
94 |
95 | c.show(&mut fg, "example2_2");
96 |
97 | let mut fg = Figure::new();
98 |
99 | fg.axes2d()
100 | .set_title("Axis Ticks fg2.3", &[])
101 | .lines(x3, y3, &[LineWidth(2.0), Color("blue".into())])
102 | .set_x_ticks_custom(
103 | x3.map(|&x| Major(x as f32, Fix("%.2f ms".to_string())))
104 | .chain(x3.map(|&i| i as f32 + 0.5).map(|x| Minor(x))),
105 | &[MajorScale(2.0), MinorScale(0.5), OnAxis(true)],
106 | &[TextColor("blue".into()), TextAlign(AlignCenter)],
107 | )
108 | .set_x_log(Some(10.0))
109 | .set_y_ticks(
110 | Some((Fix(100.0), 1)),
111 | &[Mirror(false), Format("%.1f s")],
112 | &[],
113 | );
114 |
115 | c.show(&mut fg, "example2_3");
116 |
117 | let mut fg = Figure::new();
118 |
119 | fg.axes2d()
120 | .set_title("Border, Axes fg2.4", &[])
121 | .set_border(true, &[Left, Bottom], &[LineWidth(2.0)])
122 | .set_x_ticks(Some((Fix(1.0), 1)), &[Mirror(false)], &[])
123 | .set_y_ticks(Some((Fix(50.0), 0)), &[Mirror(false)], &[])
124 | .lines(x3, y3, &[LineWidth(2.0), Color("blue".into())])
125 | .set_x_axis(true, &[LineWidth(2.0), LineStyle(DotDotDash)])
126 | .set_y_axis(true, &[LineWidth(2.0), Color("red".into())]);
127 |
128 | c.show(&mut fg, "example2_4");
129 |
130 | let mut fg = Figure::new();
131 |
132 | fg.axes2d().set_title("Image fg2.5", &[]).image(
133 | z1.iter(),
134 | zw,
135 | zh,
136 | Some((-4.0, -4.0, 4.0, 4.0)),
137 | &[],
138 | );
139 |
140 | c.show(&mut fg, "example2_5");
141 |
142 | let mut fg = Figure::new();
143 |
144 | fg.axes2d()
145 | .set_title("Image without borders fg2.6", &[])
146 | .set_border(false, &[], &[])
147 | .set_x_ticks(None, &[], &[])
148 | .set_y_ticks(None, &[], &[])
149 | .image(z1.iter(), zw, zh, Some((-4.0, -4.0, 4.0, 4.0)), &[]);
150 |
151 | c.show(&mut fg, "example2_6");
152 |
153 | let x4 = &[1f32, 10.0, 100.0];
154 | let y4 = &[1f32, 3f32, 9f32];
155 |
156 | let mut fg = Figure::new();
157 |
158 | fg.axes2d()
159 | .set_title("Logarithmic fg2.7", &[])
160 | .lines(x4.iter(), y4.iter(), &[])
161 | .set_x_ticks(Some((Auto, 1)), &[], &[])
162 | .set_y_ticks(Some((Auto, 1)), &[], &[])
163 | .set_x_log(Some(10.0))
164 | .set_y_log(Some(3.0));
165 |
166 | c.show(&mut fg, "example2_7");
167 |
168 | let mut fg = Figure::new();
169 |
170 | fg.axes2d()
171 | .set_title("Axis Grid fg2.8", &[])
172 | .lines(x3, y3, &[LineWidth(2.0), Color("blue".into())])
173 | .set_y_ticks(Some((Auto, 2)), &[], &[])
174 | .set_grid_options(true, &[LineStyle(DotDotDash), Color("black".into())])
175 | .set_minor_grid_options(&[LineStyle(SmallDot), Color("red".into())])
176 | .set_x_grid(true)
177 | .set_y_grid(true)
178 | .set_y_minor_grid(true);
179 |
180 | c.show(&mut fg, "example2_8");
181 | }
182 |
183 | fn main()
184 | {
185 | Common::new().map(|c| example(c));
186 | }
187 |
--------------------------------------------------------------------------------
/gnuplot/examples/example3.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 |
4 | use gnuplot::*;
5 | use std::vec::Vec;
6 |
7 | mod common;
8 |
9 | fn example(c: Common)
10 | {
11 | let w = 61;
12 | let h = 61;
13 | let mut z1 = Vec::with_capacity((w * h) as usize);
14 | for i in 0..h
15 | {
16 | for j in 0..w
17 | {
18 | let y = 8.0 * (i as f64) / h as f64 - 4.0;
19 | let x = 8.0 * (j as f64) / w as f64 - 4.0;
20 | z1.push(x.cos() * y.cos() / ((x * x + y * y).sqrt() + 1.0));
21 | }
22 | }
23 |
24 | let mut fg = Figure::new();
25 |
26 | fg.axes3d()
27 | .set_title("Surface fg3.1", &[])
28 | .surface(z1.iter(), w, h, Some((-4.0, -4.0, 4.0, 4.0)), &[])
29 | .set_x_label("X", &[])
30 | .set_y_label("Y", &[])
31 | .set_z_label("Z", &[])
32 | .set_z_range(Fix(-1.0), Fix(1.0))
33 | .set_z_ticks(Some((Fix(1.0), 1)), &[Mirror(false)], &[])
34 | .set_view(45.0, 45.0);
35 |
36 | c.show(&mut fg, "example3_1");
37 |
38 | let mut fg = Figure::new();
39 |
40 | fg.axes3d()
41 | .set_title("Map fg3.2", &[])
42 | .surface(z1.iter(), w, h, None, &[])
43 | .set_x_label("X", &[])
44 | .set_y_label("Y", &[])
45 | .set_view_map();
46 |
47 | c.show(&mut fg, "example3_2");
48 |
49 | let mut fg = Figure::new();
50 |
51 | fg.axes3d()
52 | .set_pos_grid(2, 2, 0)
53 | .set_title("Base fg3.3", &[])
54 | .show_contours(true, false, Cubic(10), Fix(""), Auto)
55 | .surface(z1.iter(), w, h, Some((-4.0, -4.0, 4.0, 4.0)), &[])
56 | .set_view(45.0, 45.0);
57 |
58 | fg.axes3d()
59 | .set_pos_grid(2, 2, 1)
60 | .set_title("Surface", &[])
61 | .show_contours(false, true, Linear, Fix(""), Auto)
62 | .surface(z1.iter(), w, h, Some((-4.0, -4.0, 4.0, 4.0)), &[])
63 | .set_view(45.0, 45.0);
64 |
65 | fg.axes3d()
66 | .set_pos_grid(2, 2, 2)
67 | .set_title("Both + Fix Levels", &[])
68 | .show_contours(true, true, Linear, Fix("%f"), Fix(1))
69 | .surface(z1.iter(), w, h, Some((-4.0, -4.0, 4.0, 4.0)), &[])
70 | .set_view(45.0, 45.0);
71 |
72 | fg.axes3d()
73 | .set_pos_grid(2, 2, 3)
74 | .set_title("Custom Levels", &[])
75 | .show_contours_custom(true, false, Linear, Fix(""), Some(0f32).iter())
76 | .surface(z1.iter(), w, h, Some((-4.0, -4.0, 4.0, 4.0)), &[])
77 | .set_view(45.0, 45.0);
78 |
79 | c.show(&mut fg, "example3_3");
80 | }
81 |
82 | fn main()
83 | {
84 | Common::new().map(|c| example(c));
85 | }
86 |
--------------------------------------------------------------------------------
/gnuplot/examples/example4.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 |
5 | mod common;
6 |
7 | fn example(c: Common)
8 | {
9 | let zw = 61;
10 | let zh = 61;
11 | let mut z1 = Vec::with_capacity((zw * zh) as usize);
12 | for i in 0..zh
13 | {
14 | for j in 0..zw
15 | {
16 | let y = 8.0 * (i as f64) / zh as f64 - 4.0;
17 | let x = 8.0 * (j as f64) / zw as f64 - 4.0;
18 | z1.push(x.cos() * y.cos() / ((x * x + y * y).sqrt() + 1.0));
19 | }
20 | }
21 |
22 | let mut fg = Figure::new();
23 |
24 | fg.axes2d()
25 | .set_title("Image fg4.1", &[])
26 | .set_cb_range(Fix(-1.0), Fix(1.0))
27 | .set_cb_ticks(Some((Fix(0.25), 1)), &[], &[])
28 | .set_cb_label("Label", &[Rotate(0.0)])
29 | .image(z1.iter(), zw, zh, Some((-4.0, -4.0, 4.0, 4.0)), &[]);
30 |
31 | c.show(&mut fg, "example4_1");
32 |
33 | let mut fg = Figure::new();
34 |
35 | fg.axes3d()
36 | .set_title("Surface fg4.2", &[])
37 | .surface(z1.iter(), zw, zh, Some((-4.0, -4.0, 4.0, 4.0)), &[])
38 | .set_x_label("X", &[])
39 | .set_y_label("Y", &[])
40 | .set_z_label("Z", &[])
41 | .set_z_range(Fix(-1.0), Fix(1.0))
42 | .set_z_ticks(Some((Fix(1.0), 1)), &[Mirror(false)], &[])
43 | .set_cb_range(Fix(-1.0), Fix(1.0))
44 | .set_view(45.0, 45.0);
45 |
46 | c.show(&mut fg, "example4_2");
47 |
48 | let mut fg = Figure::new();
49 |
50 | fg.axes3d()
51 | .set_title("Cube Helix Palette fg4.3", &[])
52 | .surface(z1.iter(), zw, zh, Some((-4.0, -4.0, 4.0, 4.0)), &[])
53 | .set_x_label("X", &[])
54 | .set_y_label("Y", &[])
55 | .set_z_label("Z", &[])
56 | .set_z_range(Fix(-1.0), Fix(1.0))
57 | .set_z_ticks(Some((Fix(1.0), 1)), &[Mirror(false)], &[])
58 | .set_cb_range(Fix(-1.0), Fix(1.0))
59 | .set_palette(HELIX)
60 | .set_view(45.0, 45.0);
61 |
62 | c.show(&mut fg, "example4_3");
63 |
64 | let mut fg = Figure::new();
65 |
66 | fg.axes3d()
67 | .set_title("Gray Palette fg4.4", &[])
68 | .surface(z1.iter(), zw, zh, Some((-4.0, -4.0, 4.0, 4.0)), &[])
69 | .set_x_label("X", &[])
70 | .set_y_label("Y", &[])
71 | .set_z_label("Z", &[])
72 | .set_z_range(Fix(-1.0), Fix(1.0))
73 | .set_z_ticks(Some((Fix(1.0), 1)), &[Mirror(false)], &[])
74 | .set_palette(GRAY)
75 | .set_view(45.0, 45.0);
76 |
77 | c.show(&mut fg, "example4_4");
78 |
79 | let mut fg = Figure::new();
80 |
81 | fg.axes3d()
82 | .set_title("Black Body Palette fg4.5", &[])
83 | .surface(z1.iter(), zw, zh, Some((-4.0, -4.0, 4.0, 4.0)), &[])
84 | .set_x_label("X", &[])
85 | .set_y_label("Y", &[])
86 | .set_z_label("Z", &[])
87 | .set_z_range(Fix(-1.0), Fix(1.0))
88 | .set_z_ticks(Some((Fix(1.0), 1)), &[Mirror(false)], &[])
89 | .set_palette(HOT)
90 | .set_view(45.0, 45.0);
91 |
92 | c.show(&mut fg, "example4_5");
93 |
94 | let palette = vec![
95 | (0.00, 1.0, 0.0, 0.0),
96 | (0.33, 1.0, 0.0, 0.0),
97 | (0.33, 0.0, 1.0, 0.0),
98 | (0.66, 0.0, 1.0, 0.0),
99 | (0.66, 0.0, 0.0, 1.0),
100 | (1.00, 0.0, 0.0, 1.0),
101 | ];
102 |
103 | let mut fg = Figure::new();
104 |
105 | fg.axes3d()
106 | .set_title("Custom Palette fg4.5", &[])
107 | .surface(z1.iter(), zw, zh, Some((-4.0, -4.0, 4.0, 4.0)), &[])
108 | .set_x_label("X", &[])
109 | .set_y_label("Y", &[])
110 | .set_z_label("Z", &[])
111 | .set_z_range(Fix(-1.0), Fix(1.0))
112 | .set_z_ticks(Some((Fix(1.0), 1)), &[Mirror(false)], &[])
113 | .set_palette(Custom(&palette))
114 | .set_view(45.0, 45.0);
115 |
116 | c.show(&mut fg, "example4_5");
117 | }
118 |
119 | fn main()
120 | {
121 | Common::new().map(|c| example(c));
122 | }
123 |
--------------------------------------------------------------------------------
/gnuplot/examples/gif.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use gnuplot::*;
3 | use std::f32;
4 |
5 | fn main()
6 | {
7 | let mut fg = Figure::new();
8 | let mut x = vec![];
9 | for i in 0..100i32
10 | {
11 | x.push(i as f32 * 0.1 - 5.0);
12 | }
13 |
14 | let mut t = 0.0;
15 | fg.set_terminal("gif animate optimize delay 2 size 480,360", "gif.gif");
16 | for i in 0..100
17 | {
18 | if i > 0
19 | {
20 | fg.new_page();
21 | }
22 | let ax = fg.axes2d().set_y_range(Fix(-1.0), Fix(1.0));
23 | ax.lines(
24 | x.iter(),
25 | x.iter()
26 | .map(|&x| (x + t as f32 * 0.1 * 2. * f32::consts::PI).sin()),
27 | &[Color("blue".into())],
28 | );
29 | ax.lines(
30 | x.iter(),
31 | x.iter()
32 | .map(|&x| (x + t as f32 * 0.1 * 2. * f32::consts::PI).cos()),
33 | &[Color("red".into())],
34 | );
35 | t += 0.1;
36 | }
37 | fg.echo_to_file("gif.gnuplot");
38 | fg.show().unwrap();
39 | }
40 |
--------------------------------------------------------------------------------
/gnuplot/examples/inverse_api.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot as gp;
4 | use gnuplot::*;
5 |
6 | mod common;
7 |
8 | trait PlotElement
9 | {
10 | fn convert(&self, axes: &mut gp::Axes2D);
11 | fn to_axes2d(&self) -> Axes2D;
12 | }
13 |
14 | #[derive(Clone)]
15 | struct Lines
16 | {
17 | x: Vec,
18 | y: Vec,
19 | options: Vec>,
20 | }
21 |
22 | impl PlotElement for Lines
23 | {
24 | fn convert(&self, axes: &mut gp::Axes2D)
25 | {
26 | let mut options: Vec> = vec![];
27 | for o in &self.options
28 | {
29 | options.push(match o
30 | {
31 | PointSymbol(v) => PointSymbol(*v),
32 | PointSize(v) => PointSize(*v),
33 | Caption(v) => Caption(&v),
34 | LineWidth(v) => LineWidth(*v),
35 | Color(v) => Color(v.to_ref()),
36 | BorderColor(v) => BorderColor(v.to_ref()),
37 | LineStyle(v) => LineStyle(*v),
38 | FillAlpha(v) => FillAlpha(*v),
39 | FillRegion(v) => FillRegion(*v),
40 | ArrowType(v) => ArrowType(*v),
41 | ArrowSize(v) => ArrowSize(*v),
42 | WhiskerBars(v) => WhiskerBars(*v),
43 | FillPattern(v) => FillPattern(*v),
44 | Axes(v1, v2) => Axes(*v1, *v2),
45 | BoxWidth(v) => BoxWidth(v.to_vec()),
46 | });
47 | }
48 |
49 | axes.lines(self.x.clone(), self.y.clone(), &options);
50 | }
51 |
52 | fn to_axes2d(&self) -> Axes2D
53 | {
54 | Axes2D::new(vec![Box::new(self.clone())])
55 | }
56 | }
57 |
58 | impl PlotElement for (T, T)
59 | {
60 | fn convert(&self, axes: &mut gp::Axes2D)
61 | {
62 | self.0.convert(axes);
63 | self.1.convert(axes);
64 | }
65 |
66 | fn to_axes2d(&self) -> Axes2D
67 | {
68 | Axes2D::new(vec![Box::new(self.0.clone()), Box::new(self.1.clone())])
69 | }
70 | }
71 |
72 | fn lines<'l, Tx: IntoIterator- , Ty: IntoIterator
- >(x: Tx, y: Ty) -> Lines
73 | {
74 | Lines {
75 | x: x.into_iter().collect(),
76 | y: y.into_iter().collect(),
77 | options: vec![],
78 | }
79 | }
80 |
81 | #[allow(dead_code)]
82 | impl Lines
83 | {
84 | fn show(&self)
85 | {
86 | self.to_axes2d().show();
87 | }
88 | }
89 |
90 | struct Axes2D
91 | {
92 | plot_elements: Vec>,
93 | title: String,
94 | x_axis: Axis,
95 | }
96 |
97 | impl Axes2D
98 | {
99 | fn new(plot_elements: Vec>) -> Axes2D
100 | {
101 | Axes2D {
102 | plot_elements: plot_elements,
103 | title: "".into(),
104 | x_axis: axis(),
105 | }
106 | }
107 |
108 | fn title(&mut self, title: &str) -> &mut Axes2D
109 | {
110 | self.title = title.into();
111 | self
112 | }
113 |
114 | fn x(&mut self, axis: &Axis) -> &mut Axes2D
115 | {
116 | self.x_axis = axis.clone();
117 | self
118 | }
119 |
120 | fn show(&self)
121 | {
122 | let mut fg = Figure::new();
123 | let mut ax = fg.axes2d();
124 | ax.set_title(&self.title, &[]);
125 | ax.set_x_log(self.x_axis.log_scale);
126 | for pe in &self.plot_elements
127 | {
128 | pe.convert(&mut ax);
129 | }
130 | fg.show().unwrap();
131 | }
132 | }
133 |
134 | #[derive(Clone)]
135 | struct Axis
136 | {
137 | log_scale: Option,
138 | }
139 |
140 | impl Axis
141 | {
142 | fn log_scale(&mut self, log_scale: Option) -> &mut Self
143 | {
144 | self.log_scale = log_scale;
145 | self
146 | }
147 | }
148 |
149 | fn axis() -> Axis
150 | {
151 | Axis { log_scale: None }
152 | }
153 |
154 | fn example(c: Common)
155 | {
156 | let z = (1..100).map(|z| z as f32 / 10.0);
157 | let x = z.clone().map(|z| z.cos());
158 | let y = z.clone().map(|z| z.sin());
159 |
160 | let mut fg = Figure::new();
161 |
162 | fg.axes2d().lines(z.clone(), y.clone(), &[]);
163 |
164 | c.show(&mut fg, "inverse_api_old_1");
165 |
166 | //~ fg.axes2d().set_title("Old API", &[]).lines(
167 | //~ z.clone(),
168 | //~ y.clone(),
169 | //~ &[LineWidth(2.), Color("#ffaa77".into())],
170 | //~ ).lines(
171 | //~ z.clone(),
172 | //~ x.clone(),
173 | //~ &[],
174 | //~ );
175 |
176 | //~ c.show(&mut fg, "inverse_api_old_2");
177 |
178 | //~ lines(z.clone(), y.clone()).show();
179 |
180 | let mut axes = (lines(z.clone(), y.clone()), lines(z.clone(), x.clone())).to_axes2d();
181 | axes.title("Test").x(axis().log_scale(Some(10.)));
182 |
183 | if !c.no_show
184 | {
185 | axes.show();
186 | }
187 | }
188 |
189 | fn main()
190 | {
191 | Common::new().map(|c| example(c));
192 | }
193 |
--------------------------------------------------------------------------------
/gnuplot/examples/lines_3d.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 |
5 | mod common;
6 |
7 | fn example(c: Common)
8 | {
9 | let z = (0..100).map(|z| z as f32 / 10.0);
10 | let x = z.clone().map(|z| z.cos());
11 | let y = z.clone().map(|z| z.sin());
12 |
13 | let mut fg = Figure::new();
14 |
15 | fg.axes3d().set_title("3D lines", &[]).lines(
16 | x,
17 | y,
18 | z,
19 | &[PointSymbol('o'), Color("#ffaa77".into()), PointSize(2.0)],
20 | );
21 |
22 | c.show(&mut fg, "lines_3d");
23 | }
24 |
25 | fn main()
26 | {
27 | Common::new().map(|c| example(c));
28 | }
29 |
--------------------------------------------------------------------------------
/gnuplot/examples/lines_points_3d.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 |
5 | mod common;
6 |
7 | fn example(c: Common)
8 | {
9 | let z = (0..100).map(|z| z as f32 / 10.0);
10 | let x = z.clone().map(|z| z.cos());
11 | let y = z.clone().map(|z| z.sin());
12 |
13 | let mut fg = Figure::new();
14 |
15 | fg.axes3d()
16 | .set_title(r"3D lines + points", &[])
17 | .lines_points(
18 | x,
19 | y,
20 | z,
21 | &[PointSymbol('o'), Color("#ffaa77".into()), PointSize(2.0)],
22 | );
23 |
24 | c.show(&mut fg, "lines_points_3d");
25 | }
26 |
27 | fn main()
28 | {
29 | Common::new().map(|c| example(c));
30 | }
31 |
--------------------------------------------------------------------------------
/gnuplot/examples/multiple_axes.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 |
5 | mod common;
6 |
7 | fn example(c: Common)
8 | {
9 | let mut fg = Figure::new();
10 |
11 | fg.axes2d()
12 | .set_title("Multiple axes", &[])
13 | .lines_points(
14 | [0.0f32, 1.0, 2.0].iter(),
15 | [-1.0f32, 0.0, 1.0].iter(),
16 | &[Axes(X1, Y1), Color("blue".into())],
17 | )
18 | .lines_points(
19 | [-0.6f32, 1.5, 2.5].iter(),
20 | [-5.0f32, 0.0, 5.0].iter(),
21 | &[Axes(X1, Y2), Color("red".into())],
22 | )
23 | .set_y_ticks(Some((Auto, 0)), &[Mirror(false)], &[TextColor("blue".into())]) // Make Y1 not mirror.
24 | .set_y2_ticks(Some((Auto, 0)), &[Mirror(false)], &[TextColor("red".into())]) // Make Y2 not mirror, and visible.
25 | .set_y_label("Blue", &[TextColor("blue".into())])
26 | .set_y2_label("Red", &[TextColor("red".into())])
27 | .label("Blue Label", Axis(1.), Axis(0.), &[TextColor("blue".into()), TextAlign(AlignRight)])
28 | .label("Red Label", Axis(2.0), Axis2(2.5), &[TextColor("red".into())]);
29 |
30 | c.show(&mut fg, "multiple_axes");
31 | }
32 |
33 | fn main()
34 | {
35 | Common::new().map(|c| example(c));
36 | }
37 |
--------------------------------------------------------------------------------
/gnuplot/examples/multiplot_options.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::{MultiplotFillDirection::*, MultiplotFillOrder::*};
4 |
5 | use gnuplot::*;
6 |
7 | mod common;
8 |
9 | fn example(c: Common)
10 | {
11 | let mut fg = Figure::new();
12 | fg.set_multiplot_layout(2, 2)
13 | .set_title("Multiple parabolas")
14 | .set_scale(0.8, 0.8)
15 | .set_offset(0.0, 0.0)
16 | .set_multiplot_fill_order(RowsFirst, Upwards);
17 |
18 | fg.axes2d()
19 | .lines(
20 | &[-3., -2., -1., 0., 1., 2., 3.],
21 | &[9., 4., 1., 0., 1., 4., 9.],
22 | &[Caption("Parabola 1")],
23 | )
24 | .set_x_label("X label", &[])
25 | .set_title("Parabola 1", &[])
26 | .label("Test 1", Axis(-3.), Axis(-3.), &[])
27 | .label("Test 2", Axis(3.), Axis(3.), &[])
28 | .arrow(Axis(-3.), Axis(-3.), Axis(3.), Axis(3.), &[]);
29 |
30 | fg.axes2d().lines(
31 | &[-3., -2., -1., 0., 1., 2., 3.],
32 | &[10., 5., 2., 0., 2., 5., 10.],
33 | &[Caption("Parabola 2")],
34 | );
35 |
36 | fg.axes2d().lines(
37 | &[-3., -2., -1., 0., 1., 2., 3.],
38 | &[11., 6., 3., 0., 3., 6., 11.],
39 | &[Caption("Parabola 3")],
40 | );
41 |
42 | c.show(&mut fg, "multiplot_options");
43 | }
44 |
45 | fn main()
46 | {
47 | Common::new().map(|c| example(c));
48 | }
49 |
--------------------------------------------------------------------------------
/gnuplot/examples/patterns.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 |
5 | mod common;
6 |
7 | fn example(c: Common)
8 | {
9 | let mut fg = Figure::new();
10 |
11 | let ax = fg.axes2d();
12 | ax.set_title("Patterns", &[]);
13 | ax.set_legend(Graph(1.), Graph(0.95), &[MaxRows(3)], &[]);
14 | ax.set_y_range(Auto, Fix(8.));
15 | ax.set_box_width(0.5, false);
16 | for i in 0..=8
17 | {
18 | ax.boxes(&[i], &[5], &[FillPattern(Auto)]);
19 | }
20 |
21 | for (i, &pattern) in [
22 | Pattern0,
23 | BigCrosses,
24 | SmallCrosses,
25 | Pattern3,
26 | BigBackSlashes,
27 | BigForwardSlashes,
28 | SmallForwardSlashes,
29 | SmallBackSlashes,
30 | Pattern8,
31 | ]
32 | .iter()
33 | .enumerate()
34 | {
35 | ax.boxes(
36 | &[i],
37 | &[-5],
38 | &[
39 | FillPattern(Fix(pattern)),
40 | Caption(&format!("{:?}", pattern)),
41 | ],
42 | );
43 | }
44 |
45 | c.show(&mut fg, "patterns");
46 | }
47 |
48 | fn main()
49 | {
50 | Common::new().map(|c| example(c));
51 | }
52 |
--------------------------------------------------------------------------------
/gnuplot/examples/points_3d.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 |
5 | mod common;
6 |
7 | fn example(c: Common)
8 | {
9 | let z = (0..100).map(|z| z as f32 / 10.0);
10 | let x = z.clone().map(|z| z.cos());
11 | let y = z.clone().map(|z| z.sin());
12 |
13 | let mut fg = Figure::new();
14 |
15 | fg.axes3d().set_title("3D points", &[]).points(
16 | x,
17 | y,
18 | z,
19 | &[PointSymbol('o'), Color("#ffaa77".into()), PointSize(2.0)],
20 | );
21 |
22 | c.show(&mut fg, "points_3d");
23 | }
24 |
25 | fn main()
26 | {
27 | Common::new().map(|c| example(c));
28 | }
29 |
--------------------------------------------------------------------------------
/gnuplot/examples/polygons.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 |
5 | mod common;
6 |
7 | fn example(c: Common)
8 | {
9 | let coords = [[0., 0.], [1., 1.], [2., 0.5], [2., -0.5], [1., -1.]];
10 |
11 | let mut fg = Figure::new();
12 | fg.set_title("Polygons");
13 |
14 | let ax = fg.axes2d();
15 | ax.polygon(
16 | coords.iter().map(|x| x[0]),
17 | coords.iter().map(|x| x[1]),
18 | &[],
19 | );
20 |
21 | ax.polygon(
22 | coords.iter().map(|x| x[0] + 2.),
23 | coords.iter().map(|x| x[1]),
24 | &[FillAlpha(0.), BorderColor("black".into()), LineWidth(4.)],
25 | );
26 | ax.polygon(
27 | coords.iter().map(|x| x[0]),
28 | coords.iter().map(|x| x[1] + 2.),
29 | &[
30 | Color("#FF0000".into()),
31 | BorderColor("black".into()),
32 | LineWidth(4.),
33 | ],
34 | );
35 | ax.polygon(
36 | coords.iter().map(|x| x[0] + 2.),
37 | coords.iter().map(|x| x[1] + 2.),
38 | &[
39 | FillPattern(Fix(BigCrosses)),
40 | Color("#FF0000".into()),
41 | BorderColor("black".into()),
42 | LineWidth(4.),
43 | LineStyle(Dash),
44 | ],
45 | );
46 | c.show(&mut fg, "polygons");
47 | }
48 |
49 | fn main()
50 | {
51 | Common::new().map(|c| example(c));
52 | }
53 |
--------------------------------------------------------------------------------
/gnuplot/examples/readme_example.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 |
4 | use gnuplot::*;
5 |
6 | mod common;
7 |
8 | fn example(c: Common)
9 | {
10 | let mut fg = Figure::new();
11 |
12 | fg.axes2d()
13 | .set_title("A plot", &[])
14 | .set_legend(Graph(0.5), Graph(0.9), &[], &[])
15 | .set_x_label("x", &[])
16 | .set_y_label("y^2", &[])
17 | .lines(
18 | &[-3., -2., -1., 0., 1., 2., 3.],
19 | &[9., 4., 1., 0., 1., 4., 9.],
20 | &[Caption("Parabola")],
21 | );
22 |
23 | c.show(&mut fg, "readme_example");
24 | if !c.no_show
25 | {
26 | fg.set_terminal("pngcairo", "readme_example.png");
27 | fg.show().unwrap();
28 | }
29 | }
30 |
31 | fn main()
32 | {
33 | Common::new().map(|c| example(c));
34 | }
35 |
--------------------------------------------------------------------------------
/gnuplot/examples/text.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 |
5 | mod common;
6 |
7 | fn example(c: Common)
8 | {
9 | let mut fg = Figure::new();
10 | let _ax = fg
11 | .axes2d()
12 | .label(
13 | "multi\nline string",
14 | Coordinate::Graph(0.5),
15 | Coordinate::Graph(0.9),
16 | &[],
17 | )
18 | .label(
19 | "x^2 x_2 {/Times*2 abc} \\{\\}\\^\\_",
20 | Coordinate::Graph(0.5),
21 | Coordinate::Graph(0.8),
22 | &[],
23 | )
24 | .label(
25 | "Monospace",
26 | Coordinate::Graph(0.5),
27 | Coordinate::Graph(0.6),
28 | &[Font("Monospace", 32.)],
29 | )
30 | .label(
31 | "Align Right",
32 | Coordinate::Graph(0.5),
33 | Coordinate::Graph(0.5),
34 | &[TextAlign(AlignRight)],
35 | )
36 | .label(
37 | "Align Centre",
38 | Coordinate::Graph(0.5),
39 | Coordinate::Graph(0.4),
40 | &[TextAlign(AlignCenter)],
41 | )
42 | .label(
43 | "~{Over}{Print}", // Why does gnuplot have this feature?
44 | Coordinate::Graph(0.5),
45 | Coordinate::Graph(0.3),
46 | &[TextAlign(AlignCenter)],
47 | )
48 | .label(
49 | "Tab\tCharacter", // Strange rendering on this one
50 | Coordinate::Graph(0.5),
51 | Coordinate::Graph(0.2),
52 | &[TextAlign(AlignCenter)],
53 | )
54 | .lines(&[-2., -2.], &[-3., 3.], &[])
55 | .set_x_ticks(None, &[], &[])
56 | .set_y_ticks(None, &[], &[])
57 | .set_border(true, &[], &[]);
58 |
59 | c.show(&mut fg, "text");
60 | }
61 |
62 | fn main()
63 | {
64 | Common::new().map(|c| example(c));
65 | }
66 |
--------------------------------------------------------------------------------
/gnuplot/examples/time.rs:
--------------------------------------------------------------------------------
1 | // This file is released into Public Domain.
2 | use crate::common::*;
3 | use gnuplot::*;
4 | use std::time::Duration;
5 |
6 | mod common;
7 |
8 | fn example(c: Common)
9 | {
10 | let x1 = &[
11 | Duration::from_secs(0),
12 | Duration::from_secs(3600 * 12),
13 | Duration::from_secs(3600 * 24),
14 | Duration::from_secs(3600 * 36),
15 | ];
16 | let x2 = &[
17 | Duration::from_millis(0),
18 | Duration::from_millis(500),
19 | Duration::from_millis(1000),
20 | Duration::from_millis(1500),
21 | ];
22 | let y = &[0i32, -1, 1, 0];
23 |
24 | let mut fg = Figure::new();
25 |
26 | fg.axes2d()
27 | .set_title("Time 1: Hours", &[])
28 | .lines(x1, y, &[])
29 | .set_x_ticks(Some((Auto, 1)), &[Format("%H hours")], &[])
30 | .set_x_time(true);
31 |
32 | c.show(&mut fg, "time_1");
33 |
34 | let mut fg = Figure::new();
35 | fg.axes2d()
36 | .set_title("Time 2: Seconds", &[])
37 | .lines(x2, y, &[])
38 | .set_x_ticks(Some((Auto, 1)), &[Format("%.1S secs")], &[])
39 | .set_x_time(true);
40 |
41 | c.show(&mut fg, "time_2");
42 | }
43 |
44 | fn main()
45 | {
46 | Common::new().map(|c| example(c));
47 | }
48 |
--------------------------------------------------------------------------------
/gnuplot/examples/variable_color.rs:
--------------------------------------------------------------------------------
1 | use std::iter;
2 |
3 | // This file is released into Public Domain.
4 | use crate::common::*;
5 | use gnuplot::{palettes::MAGMA, *};
6 |
7 | mod common;
8 |
9 | // https://github.com/gnuplot/gnuplot/blob/master/demo/candlesticks.dat
10 | #[rustfmt::skip]
11 | static CANDLESTICKS_STR: &str =
12 | "1 1.5 2 2.4 4 6.
13 | 2 1.5 3 3.5 4 5.5
14 | 3 4.5 5 5.5 6 6.5
15 | 4 3.7 4.5 5.0 5.5 6.1
16 | 5 3.1 3.5 4.2 5 6.1
17 | 6 1 4 5.0 6 9
18 | 7 4 4 4.8 6 6.1
19 | 8 4 5 5.1 6 6.1
20 | 9 1.5 2 2.4 3 3.5
21 | 10 2.7 3 3.5 4 4.3";
22 |
23 | fn example(c: Common)
24 | {
25 | let data: Vec> = CANDLESTICKS_STR
26 | .split("\n")
27 | .map(|line| {
28 | line.split("\t")
29 | .map(|v| v.trim().parse::().unwrap())
30 | .collect()
31 | })
32 | .collect();
33 | let extract_col = |i| data.iter().map(|l| l[i]).collect::>();
34 |
35 | let d1 = extract_col(0);
36 | let d2 = extract_col(1);
37 | let d5 = extract_col(4);
38 | let d6 = extract_col(5);
39 | let row_index: Vec<_> = (1..=d1.len() as u8).collect();
40 | let by3 = |x| (((x % 3.0) + 1.0) / 6.0);
41 | let by4 = |x| (((x % 4.0) + 1.0) / 7.0);
42 |
43 | let argb_formula = |x: &f64| {
44 | let a = 255.0 - 255.0 * (x - 5.5).abs() / 5.5;
45 | let r = x * 51.0 / 2.0;
46 | let g = (11.0 - x) * 51.0 / 2.0;
47 | let b = ((5.5 - x).abs() * 2.0 * 510.0 / 9.0).round();
48 | (a as u8, r as u8, g as u8, b as u8)
49 | };
50 | // Demo/test of variable color in many different plot styles
51 | // Inspired by https://gnuplot.sourceforge.net/demo_6.0/varcolor.html
52 | //
53 | // The loop is run four times with different color sets: each one sets all the elements of a given
54 | // plot to a different color, while making sure the colors align by x position: i.e. everything at x = 1
55 | // uses the first color, everything at x = 2 uses the second and so on.
56 | //
57 | //
58 | // The first color loop demonstrates usage of VariableIndexColor with indices to use gnuplot's default color styles,
59 | // but make them align for multiple plot items on the same axis. This is implicity constructed from a Vec using
60 | // the `IntoColor` trait but could equivalently be created explicitly using `Color(ColorType::VariableIndexColor(row_index.clone()))`
61 | //
62 | // The second color loop uses a `VariablePaletteColor`: this selects the color based on the current color palette and the
63 | // input value for each data point. The palette is scaled to the maximum value in the `Vec` passed
64 | // to the `VariablePaletteColor`.
65 | //
66 | // The third color loop uses an (implicit) `VariableARGBInteger`. The `Vec<(u8, u8, u8, u8)>` needed to construct the color
67 | // is calculated in this case by the `argb_formula()` closure. An explicit `VariableARGBInteger` could also be constructed using
68 | // `Color(ColorType::VariableARGBInteger(data)`.
69 | // As an alternative, `VariableRGBInteger` is also defined that takes a 3-tuple of u8, rather than
70 | // a 4 tuple.
71 | for (color, label) in [
72 | (Color(row_index.clone().into()), "VariableIndexColor"),
73 | (
74 | Color(VariablePaletteColor(
75 | row_index.iter().map(|v| *v as f64).collect(),
76 | )),
77 | "VariablePaletteColor",
78 | ),
79 | (
80 | Color(d1.iter().map(argb_formula).collect::>().into()),
81 | "VariableARGBInteger",
82 | ),
83 | ]
84 | {
85 | let mut fg = Figure::new();
86 | let ax = fg.axes2d();
87 | ax.set_title(
88 | &format!("variable color boxerror, points, xyerrorbars, and boxxyerror.\nColor used is a {label}"),
89 | &[],
90 | )
91 | .set_y_range(Fix(-4.0), Fix(11.5))
92 | .set_box_width(0.5, true)
93 | .box_error_low_high(
94 | &d1,
95 | &d5,
96 | &d2,
97 | &d6,
98 | &[
99 | color.clone(),
100 | FillAlpha(0.5),
101 | BorderColor(RGBString("black")),
102 | ],
103 | )
104 | .points(&d1, iter::repeat(1), &[color.clone(), PointSymbol('D')])
105 | .xy_error_bars(
106 | &d1,
107 | iter::repeat(8),
108 | d1.iter().map(by3),
109 | d1.iter().map(by4),
110 | &[color.clone()],
111 | )
112 | .points(
113 | &d1,
114 | d2.iter().map(|v| -v / 2.0),
115 | &[color.clone(), PointSymbol('O'), PointSize(3.0)],
116 | )
117 | .box_xy_error_delta(
118 | &d1,
119 | iter::repeat(10),
120 | d1.iter().map(by3),
121 | d1.iter().map(by4),
122 | &[color.clone(), BorderColor(RGBString("black"))],
123 | );
124 |
125 | c.show(&mut fg, "variable_color");
126 | }
127 |
128 | // #####################################################################
129 | // The example below shows the same graphs as in the loop, but using a set of saved colormaps
130 | // similar to palette in gnuplot terms, but the a single (current) palette is applied to all plots by default.
131 | // By contrast, you can create multiple named colormaps.
132 | //
133 | // As with `VariablePaletteColor``, this Color takes a `Vec` that says which point in the colormap to use,
134 | // but it also takes a the name of the colormap from which to draw the colors.
135 | //
136 | // Note that the Color range appears to be shared across plots: i.e. if one plot has
137 | // color data (the `Vec`) in the range 0-1, and another in the range 1-100, all the
138 | // colors in the first plot will be right at the bottom end of its colormap, even if that's
139 | // a different colormap to the one used in the second plot.
140 | let mut fg = Figure::new();
141 | let ax = fg.axes2d();
142 |
143 | // First create the colormaps we will later refer to
144 | // MAGMA is one of the colormaps provided with rust gnuplot
145 | ax.create_colormap("magma", MAGMA);
146 | // HOT is one of the colormaps provided with rust gnuplot
147 | ax.create_colormap("hot", HOT);
148 | // ocean (green-blue-white) as per the gnuplot documentation
149 | ax.create_colormap("ocean", PaletteType::Formula(23, 28, 3));
150 |
151 | let color_values: Vec = row_index.iter().map(|v| *v as f64).collect();
152 |
153 | ax.set_title(
154 | &format!("variable color boxerror, points, xyerrorbars, and boxxyerror.\nColor used is a SavedColormap"),
155 | &[],
156 | )
157 | .set_y_range(Fix(-4.0), Fix(11.5))
158 | .set_box_width(0.8, false)
159 | .box_error_low_high(
160 | &d1,
161 | &d5,
162 | &d2,
163 | &d6,
164 | &[
165 | Color(SavedColorMap("magma", color_values.clone())),
166 | FillAlpha(0.5),
167 | BorderColor(RGBString("black")),
168 | ],
169 | )
170 | .points(
171 | &d1,
172 | iter::repeat(1),
173 | &[
174 | Color(SavedColorMap(
175 | "hot",
176 | color_values.iter().map(|v| 11.0 - *v).collect(),
177 | )),
178 | PointSymbol('D'),
179 | ],
180 | )
181 | .xy_error_bars(
182 | &d1,
183 | iter::repeat(8),
184 | d1.iter().map(by3),
185 | d1.iter().map(by4),
186 | &[Color(SavedColorMap("ocean", color_values.clone()))],
187 | )
188 | .points(
189 | &d1,
190 | d2.iter().map(|v| -v / 2.0),
191 | &[
192 | Color(SavedColorMap("magma", color_values.clone())),
193 | PointSymbol('O'),
194 | PointSize(3.0),
195 | ],
196 | )
197 | .box_xy_error_delta(
198 | &d1,
199 | iter::repeat(10),
200 | d1.iter().map(by3),
201 | d1.iter().map(by4),
202 | &[
203 | Color(SavedColorMap("hot", color_values.clone())),
204 | BorderColor(RGBString("black")),
205 | ],
206 | );
207 |
208 | c.show(&mut fg, "variable_palette");
209 | }
210 |
211 | fn main()
212 | {
213 | Common::new().map(|c| example(c));
214 | }
215 |
--------------------------------------------------------------------------------
/gnuplot/src/axes3d.rs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013-2014 by SiegeLord
2 | //
3 | // All rights reserved. Distributed under LGPL 3.0. For full terms see the file LICENSE.
4 |
5 | use crate::axes_common::*;
6 | use crate::datatype::*;
7 | use crate::options::*;
8 | use crate::util::OneWayOwned;
9 | use crate::writer::Writer;
10 | use std::borrow::Borrow;
11 |
12 | enum View
13 | {
14 | PitchYaw(f64, f64),
15 | Map,
16 | }
17 |
18 | impl View
19 | {
20 | fn write_out(&self, writer: &mut dyn Writer)
21 | {
22 | match self
23 | {
24 | Self::PitchYaw(pitch, yaw) =>
25 | {
26 | writeln!(writer, "set view {:.12e},{:.12e}", pitch, yaw);
27 | }
28 | Self::Map =>
29 | {
30 | writer.write_str("set view map\n");
31 | }
32 | }
33 | }
34 |
35 | fn reset_state(&self, writer: &mut dyn Writer)
36 | {
37 | writer.write_str("unset view\n");
38 | }
39 | }
40 |
41 | /// 3D axes that is used for drawing 3D plots
42 | pub struct Axes3D
43 | {
44 | common: AxesCommonData,
45 | z_axis: AxisData,
46 | contour_base: bool,
47 | contour_surface: bool,
48 | contour_auto: AutoOption,
49 | contour_levels: Option>,
50 | contour_style: ContourStyle,
51 | contour_label: AutoOption,
52 | view: Option,
53 | }
54 |
55 | impl Axes3D
56 | {
57 | pub(crate) fn new() -> Axes3D
58 | {
59 | Axes3D {
60 | common: AxesCommonData::new(),
61 | z_axis: AxisData::new(TickAxis::Z),
62 | contour_base: false,
63 | contour_surface: false,
64 | contour_auto: Auto,
65 | contour_levels: None,
66 | contour_style: Linear,
67 | contour_label: Auto,
68 | view: None,
69 | }
70 | }
71 |
72 | /// Draws a 3D surface from a rectangular array of data by connecting the individual datapoints with polygons.
73 | ///
74 | /// #Arguments:
75 | /// * `mat` - Row-major 2D array signifying the Z coordinate of the datapoints. The X and Y coordinates of the datapoints are determined automatically,
76 | /// and optionally scaled using the `dimensions` argument.
77 | /// * `num_rows` - Number of rows in the data array
78 | /// * `num_cols` - Number of columns in the data array
79 | /// * `dimensions` - Optional X and Y coordinates of the first and last data points (with the rest of the coordinates spaced evenly between).
80 | /// By default this will be `(0, 0)` and `(num_rows - 1, num_cols - 1)`.
81 | /// * `options` - Array of PlotOption controlling the appearance of the surface. Relevant options are:
82 | /// * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
83 | pub fn surface<'l, T: DataType, X: IntoIterator
- >(
84 | &'l mut self, mat: X, num_rows: usize, num_cols: usize,
85 | dimensions: Option<(f64, f64, f64, f64)>, options: &[PlotOption<&str>],
86 | ) -> &'l mut Self
87 | {
88 | self.common.elems.push(PlotElement::new_plot_matrix(
89 | Pm3D,
90 | true,
91 | mat,
92 | num_rows,
93 | num_cols,
94 | dimensions,
95 | options.to_one_way_owned(),
96 | ));
97 | self
98 | }
99 |
100 | /// Plot a 3D scatter-plot with a point standing in for each data point
101 | /// # Arguments
102 | /// * `x` - x values
103 | /// * `y` - y values
104 | /// * `z` - z values
105 | /// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
106 | /// * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
107 | /// * `PointSymbol` - Sets symbol for each point
108 | /// * `PointSize` - Sets the size of each point
109 | /// * `Color` - Sets the color
110 | pub fn points<
111 | 'l,
112 | Tx: DataType,
113 | X: IntoIterator
- ,
114 | Ty: DataType,
115 | Y: IntoIterator
- ,
116 | Tz: DataType,
117 | Z: IntoIterator
- ,
118 | >(
119 | &'l mut self, x: X, y: Y, z: Z, options: &[PlotOption<&str>],
120 | ) -> &'l mut Self
121 | {
122 | let (data, num_rows, num_cols) = generate_data!(options, x, y, z);
123 | self.common.elems.push(PlotElement::new_plot(
124 | Points, data, num_rows, num_cols, options,
125 | ));
126 | self
127 | }
128 |
129 | /// Plot a 3D scatter-plot with lines connecting each data point
130 | /// # Arguments
131 | /// * `x` - x values
132 | /// * `y` - y values
133 | /// * `z` - z values
134 | /// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
135 | /// * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
136 | /// * `PointSymbol` - Sets symbol for each point
137 | /// * `PointSize` - Sets the size of each point
138 | /// * `Color` - Sets the color
139 | pub fn lines<
140 | 'l,
141 | Tx: DataType,
142 | X: IntoIterator
- ,
143 | Ty: DataType,
144 | Y: IntoIterator
- ,
145 | Tz: DataType,
146 | Z: IntoIterator
- ,
147 | >(
148 | &'l mut self, x: X, y: Y, z: Z, options: &[PlotOption<&str>],
149 | ) -> &'l mut Self
150 | {
151 | let (data, num_rows, num_cols) = generate_data!(options, x, y, z);
152 | self.common.elems.push(PlotElement::new_plot(
153 | Lines, data, num_rows, num_cols, options,
154 | ));
155 | self
156 | }
157 |
158 | /// A combination of lines and points methods (drawn in that order).
159 | /// # Arguments
160 | /// * `x` - x values
161 | /// * `y` - y values
162 | /// * `z` - z values
163 | /// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element
164 | pub fn lines_points<
165 | 'l,
166 | Tx: DataType,
167 | X: IntoIterator
- ,
168 | Ty: DataType,
169 | Y: IntoIterator
- ,
170 | Tz: DataType,
171 | Z: IntoIterator
- ,
172 | >(
173 | &'l mut self, x: X, y: Y, z: Z, options: &[PlotOption<&str>],
174 | ) -> &'l mut Self
175 | {
176 | let (data, num_rows, num_cols) = generate_data!(options, x, y, z);
177 | self.common.elems.push(PlotElement::new_plot(
178 | LinesPoints,
179 | data,
180 | num_rows,
181 | num_cols,
182 | options,
183 | ));
184 | self
185 | }
186 |
187 | /// Sets the 3D view.
188 | ///
189 | /// #Arguments:
190 | /// * `pitch` - Pitch, in degrees. Value of 0 is looking straight down on the XY plane, Z pointing out of the screen.
191 | /// * `yaw` - Yaw, in degrees. Value of 0 is looking at the XZ plane, Y point into the screen.
192 | pub fn set_view(&mut self, pitch: f64, yaw: f64) -> &mut Self
193 | {
194 | self.view = Some(View::PitchYaw(pitch, yaw));
195 | self
196 | }
197 |
198 | /// Sets the view to be a map. Useful for images and contour plots.
199 | pub fn set_view_map(&mut self) -> &mut Self
200 | {
201 | self.view = Some(View::Map);
202 | self
203 | }
204 |
205 | /// Set the label for the Z axis
206 | ///
207 | /// # Arguments
208 | /// * `text` - Text of the label. Pass an empty string to hide the label
209 | /// * `options` - Array of LabelOption controlling the appearance of the label. Relevant options are:
210 | /// * `Offset` - Specifies the offset of the label
211 | /// * `Font` - Specifies the font of the label
212 | /// * `TextColor` - Specifies the color of the label
213 | /// * `Rotate` - Specifies the rotation of the label
214 | /// * `Align` - Specifies how to align the label
215 | pub fn set_z_label<'l>(&'l mut self, text: &str, options: &[LabelOption<&str>])
216 | -> &'l mut Self
217 | {
218 | self.z_axis
219 | .label
220 | .set(text.into(), options.to_one_way_owned());
221 | self
222 | }
223 |
224 | /// Sets the properties of x axis.
225 | ///
226 | /// # Arguments
227 | ///
228 | /// * `show` - Whether or not draw the axis
229 | /// * `options` - Array of PlotOption<&str> controlling the appearance of the axis. Relevant options are:
230 | /// * `Color` - Specifies the color of the border
231 | /// * `LineStyle` - Specifies the style of the border
232 | /// * `LineWidth` - Specifies the width of the border
233 | pub fn set_x_axis<'l>(&'l mut self, show: bool, options: &[PlotOption<&str>]) -> &'l mut Self
234 | {
235 | self.common.x_axis.show = show;
236 | self.common.x_axis.options = options.to_one_way_owned();
237 | self
238 | }
239 |
240 | /// Like `set_x_axis` but for the y axis.
241 | pub fn set_y_axis<'l>(&'l mut self, show: bool, options: &[PlotOption<&str>]) -> &'l mut Self
242 | {
243 | self.common.y_axis.show = show;
244 | self.common.y_axis.options = options.to_one_way_owned();
245 | self
246 | }
247 |
248 | /// Like `set_x_axis` but for the z axis.
249 | pub fn set_z_axis<'l>(&'l mut self, show: bool, options: &[PlotOption<&str>]) -> &'l mut Self
250 | {
251 | self.z_axis.show = show;
252 | self.z_axis.options = options.to_one_way_owned();
253 | self
254 | }
255 |
256 | /// Like `set_x_ticks` but for the Z axis.
257 | pub fn set_z_ticks<'l>(
258 | &'l mut self, tick_placement: Option<(AutoOption, u32)>,
259 | tick_options: &[TickOption<&str>], label_options: &[LabelOption<&str>],
260 | ) -> &'l mut Self
261 | {
262 | self.z_axis.set_ticks(
263 | tick_placement,
264 | tick_options.to_one_way_owned(),
265 | label_options.to_one_way_owned(),
266 | );
267 | self
268 | }
269 |
270 | /// Like `set_x_ticks_custom` but for the the Y axis.
271 | pub fn set_z_ticks_custom<
272 | 'l,
273 | T: DataType,
274 | S: ToString,
275 | TickT: Borrow>,
276 | TL: IntoIterator
- ,
277 | >(
278 | &'l mut self, ticks: TL, tick_options: &[TickOption<&str>],
279 | label_options: &[LabelOption<&str>],
280 | ) -> &'l mut Self
281 | {
282 | self.z_axis.set_ticks_custom(
283 | ticks.into_iter().map(|e| e.borrow().to_one_way_owned()),
284 | tick_options.to_one_way_owned(),
285 | label_options.to_one_way_owned(),
286 | );
287 | self
288 | }
289 |
290 | /// Set the range of values for the Z axis
291 | ///
292 | /// # Arguments
293 | /// * `min` - Minimum Z value
294 | /// * `max` - Maximum Z value
295 | pub fn set_z_range(&mut self, min: AutoOption, max: AutoOption) -> &mut Self
296 | {
297 | self.z_axis.set_range(min, max);
298 | self
299 | }
300 |
301 | /// Sets z axis to reverse.
302 | pub fn set_z_reverse(&mut self, reverse: bool) -> &mut Self
303 | {
304 | self.z_axis.set_reverse(reverse);
305 | self
306 | }
307 |
308 | /// Sets the Z axis be logarithmic. Note that the range must be non-negative for this to be valid.
309 | ///
310 | /// # Arguments
311 | /// * `base` - If Some, then specifies base of the logarithm, if None makes the axis not be logarithmic
312 | pub fn set_z_log(&mut self, base: Option) -> &mut Self
313 | {
314 | self.z_axis.set_log(base);
315 | self
316 | }
317 |
318 | /// Shows the grid on the Z axis.
319 | ///
320 | /// # Arguments
321 | /// * `show` - Whether to show the grid.
322 | pub fn set_z_grid(&mut self, show: bool) -> &mut Self
323 | {
324 | self.z_axis.set_grid(show);
325 | self
326 | }
327 |
328 | /// Sets the Z axis be time. Note that the range must be non-negative for this to be valid.
329 | ///
330 | /// If true, the axis is interpreted as seconds from the Unix epoch. Use the `Format` TickOption to
331 | /// specify the formatting of the ticks (see strftime format spec for valid values).
332 | ///
333 | /// # Arguments
334 | /// * `is_time` - Whether this axis is time or not.
335 | pub fn set_z_time(&mut self, is_time: bool) -> &mut Self
336 | {
337 | self.z_axis.set_time(is_time);
338 | self
339 | }
340 |
341 | /// Show contours (lines of equal Z value) at automatically determined levels.
342 | ///
343 | /// # Arguments
344 | /// * `base` - Show contours on the base of the plot (XY plane)
345 | /// * `surface` - Show the contours on the surface itself
346 | /// * `style` - Style of the contours
347 | /// * `label` - Auto sets the label automatically and enables the legend, Fix() allows you specify a format string (using C style formatting),
348 | /// otherwise an empty string disables the legend and labels.
349 | /// * `levels` - Auto picks some default number of levels, otherwise you can pass a set nominal number instead. The number is nominal as
350 | /// contours are placed at nice values of Z, and thus there may be fewer of them than this number.
351 | pub fn show_contours(
352 | &mut self, base: bool, surface: bool, style: ContourStyle, label: AutoOption<&str>,
353 | levels: AutoOption,
354 | ) -> &mut Self
355 | {
356 | self.contour_base = base;
357 | self.contour_surface = surface;
358 | self.contour_style = style;
359 | self.contour_auto = levels;
360 | self.contour_levels = None;
361 | self.contour_label = label.map(|l| l.to_string());
362 | self
363 | }
364 |
365 | /// Show contours (lines of equal Z value) at specific levels.
366 | ///
367 | /// # Arguments
368 | /// * `base` - Show contours on the base of the plot (XY plane)
369 | /// * `surface` - Show the contours on the surface itself
370 | /// * `style` - Style of the contours
371 | /// * `label` - Auto sets the label automatically and enables the legend, Fix() allows you specify a format string (using C style formatting),
372 | /// otherwise an empty string disables the legend and labels.
373 | /// * `levels` - A set of levels.
374 | pub fn show_contours_custom>(
375 | &mut self, base: bool, surface: bool, style: ContourStyle, label: AutoOption<&str>,
376 | levels: TC,
377 | ) -> &mut Self
378 | {
379 | self.contour_base = base;
380 | self.contour_surface = surface;
381 | self.contour_style = style;
382 | self.contour_auto = Auto;
383 | self.contour_levels = Some(levels.into_iter().map(|l| l.get()).collect());
384 | self.contour_label = label.map(|l| l.to_string());
385 | self
386 | }
387 |
388 | pub(crate) fn reset_state(&self, writer: &mut dyn Writer)
389 | {
390 | self.common.reset_state(writer);
391 | if let Some(v) = self.view.as_ref()
392 | {
393 | v.reset_state(writer)
394 | };
395 | }
396 |
397 | pub(crate) fn write_out(
398 | &self, data_directory: Option<&str>, w: &mut dyn Writer, auto_layout: bool,
399 | version: GnuplotVersion,
400 | )
401 | {
402 | fn clamp(val: T, min: T, max: T) -> T
403 | {
404 | if val < min
405 | {
406 | min
407 | }
408 | else if val > max
409 | {
410 | max
411 | }
412 | else
413 | {
414 | val
415 | }
416 | }
417 |
418 | if self.contour_base || self.contour_surface
419 | {
420 | write!(w, "set contour ");
421 | write!(
422 | w,
423 | "{}",
424 | match (self.contour_base, self.contour_surface)
425 | {
426 | (true, false) => "base",
427 | (false, true) => "surface",
428 | (true, true) => "both",
429 | _ => unreachable!(),
430 | }
431 | );
432 | writeln!(w);
433 |
434 | match self.contour_label
435 | {
436 | Auto => writeln!(w, "set clabel"),
437 | Fix(ref s) =>
438 | {
439 | if s.is_empty()
440 | {
441 | writeln!(w, "unset clabel")
442 | }
443 | else
444 | {
445 | writeln!(w, r#"set clabel "{}""#, s)
446 | }
447 | }
448 | };
449 |
450 | fn set_cntrparam(w: &mut dyn Writer, wr: F)
451 | {
452 | write!(w, "set cntrparam ");
453 | wr(w);
454 | writeln!(w);
455 | }
456 |
457 | set_cntrparam(w, |w| {
458 | write!(
459 | w,
460 | "{}",
461 | match self.contour_style
462 | {
463 | Linear => "linear ",
464 | Cubic(..) => "cubicspline",
465 | Spline(..) => "bspline",
466 | }
467 | );
468 | });
469 |
470 | set_cntrparam(w, |w| {
471 | let pt = match self.contour_style
472 | {
473 | Cubic(pt) => Some(pt),
474 | Spline(pt, _) => Some(pt),
475 | _ => None,
476 | };
477 |
478 | if let Some(pt) = pt
479 | {
480 | write!(w, "points {}", clamp(pt, 2, 100));
481 | };
482 | });
483 |
484 | set_cntrparam(w, |w| {
485 | let ord = match self.contour_style
486 | {
487 | Spline(_, ord) => Some(ord),
488 | _ => None,
489 | };
490 |
491 | if let Some(ord) = ord
492 | {
493 | write!(w, "order {}", clamp(ord, 2, 10));
494 | };
495 | });
496 |
497 | set_cntrparam(w, |w| {
498 | write!(w, "levels ");
499 | match self.contour_levels
500 | {
501 | Some(ref ls) =>
502 | {
503 | write!(w, "discrete ");
504 | let mut left = ls.len();
505 | for &l in ls.iter()
506 | {
507 | write!(w, "{:.12e}", l);
508 | if left > 1
509 | {
510 | write!(w, ",");
511 | }
512 | left -= 1;
513 | }
514 | }
515 | None =>
516 | {
517 | match self.contour_auto
518 | {
519 | Auto => write!(w, "auto "),
520 | Fix(f) => write!(w, "{}", f),
521 | };
522 | }
523 | };
524 | });
525 | }
526 |
527 | self.common.write_out_commands(w, auto_layout, version);
528 | self.z_axis.write_out_commands(w, version);
529 | let mut grid_axes = vec![];
530 | if self.common.x_axis.grid
531 | {
532 | grid_axes.push(self.common.x_axis.axis);
533 | }
534 | if self.common.y_axis.grid
535 | {
536 | grid_axes.push(self.common.y_axis.axis);
537 | }
538 | if self.common.cb_axis.grid
539 | {
540 | grid_axes.push(self.common.cb_axis.axis);
541 | }
542 | if self.z_axis.grid
543 | {
544 | grid_axes.push(self.z_axis.axis);
545 | }
546 | if let Some(v) = self.view.as_ref()
547 | {
548 | v.write_out(w)
549 | };
550 | self.common.write_grid_options(w, &grid_axes, version);
551 | self.common
552 | .write_out_elements("splot", data_directory, w, version);
553 | }
554 | }
555 |
556 | impl AxesCommonPrivate for Axes3D
557 | {
558 | fn get_common_data(&self) -> &AxesCommonData
559 | {
560 | &self.common
561 | }
562 |
563 | fn get_common_data_mut(&mut self) -> &mut AxesCommonData
564 | {
565 | &mut self.common
566 | }
567 | }
568 |
569 | impl AxesCommon for Axes3D {}
570 |
--------------------------------------------------------------------------------
/gnuplot/src/color.rs:
--------------------------------------------------------------------------------
1 | pub use self::ColorType::*;
2 | use crate::util::OneWayOwned;
3 | use std::fmt::{Debug, Display};
4 |
5 | pub type ColorIndex = u8;
6 | pub type ColorComponent = u8;
7 | pub type ColorInt = u32;
8 | pub type RGBInts = (ColorComponent, ColorComponent, ColorComponent);
9 | pub type ARGBInts = (
10 | ColorComponent,
11 | ColorComponent,
12 | ColorComponent,
13 | ColorComponent,
14 | );
15 |
16 | /// Option type (for plots, borders, and text) that allows the various different gnuplot
17 | /// color formats. The gnuplot [colorspec reference](http://gnuplot.info/docs_6.0/loc3640.html)
18 | /// also explains these.
19 | ///
20 | /// **NOTE**: Gnuplot interprets the alpha channel in an unusual way, where 0 is fully opaque and
21 | /// 255 is fully transparent. This wrapper inverts the meaning (as described below) to match the
22 | /// more common interpretation.
23 | ///
24 | /// There are many equivalent ways of specifying colors, and this allows the user to chose the most convenient.
25 | /// For example, all the following will produce the same blue color:
26 | /// `RGBColor("blue".into())`, `RGBColor("0x0000ff".into())`, `RGBColor("#0000ff".into())`, `RGBColor("0xff0000ff".into())`,
27 | /// `RGBColor("#ff0000ff".into())`, `RGBIntegerColor(0, 0, 255)`, `ARGBColor(255, 0, 0, 255)`,
28 | ///
29 | /// See example usages of these colors in `color.rs` and `variable_color.rs` in the
30 | /// [Examples folder](https://github.com/SiegeLord/RustGnuplot/tree/master/gnuplot/examples) on Github
31 | #[derive(Debug, Clone, PartialEq, PartialOrd)]
32 | pub enum ColorType
33 | {
34 | /// string (`&str` or `String`, but usually created with `&str`) in one of the following gnuplot-supported formats
35 | /// - colorname --- e.g. "blue" [See the gnuplot
36 | /// [list of colornames](http://gnuplot.info/docs_6.0/loc11229.html)]
37 | /// - 0xRRGGBB --- string containing hexadecimal constant
38 | /// - 0xAARRGGBB --- string containing hexadecimal constant
39 | /// - #RRGGBB --- string containing hexadecimal in x11 format
40 | /// - #AARRGGBB --- string containing hexadecimal in x11 format
41 | ///
42 | /// "#AARRGGBB" represents an RGB color with an alpha channel value in the high bits.
43 | /// An alpha value of 255 (FF) represents a fully opaque color; i.e., "#FFRRGGBB" is the same as "#RRGGBB".
44 | /// An alpha value of 0 represents full transparency.
45 | RGBString(T),
46 | /// tuple of u8 representing red, green and blue values as 0-255
47 | RGBInteger(ColorComponent, ColorComponent, ColorComponent),
48 | /// tuple of u8 representing alpha, red, green and blue values as 0-255.
49 | /// As with `RGBColor`, an alpha value of 255 (FF) represents a fully opaque color;
50 | /// an alpha value of 0 represents full transparency.
51 | ARGBInteger(
52 | ColorComponent,
53 | ColorComponent,
54 | ColorComponent,
55 | ColorComponent,
56 | ),
57 | /// Vector of tuples of `u8` (as per `RGBColor`), but instead of a single color for the whole
58 | /// plot, the vector should contain a separte color for each data point.
59 | VariableRGBInteger(Vec),
60 | /// Vector of tuples of `u8` (as per `ARGBColor`), but as with `VariableRGBColor`, a separate
61 | /// color value is given for each data point.
62 | VariableARGBInteger(Vec),
63 | /// Sets the color of the plot element to a value picked from the current palette (see
64 | /// [set_palette()](crate::AxesCommon::set_palette())). The value supplied to this color type
65 | /// selects the color within the color range of the palette: i.e. it if the color bar range had been
66 | /// set with `ax.set_cb_range(Fix(min), Fix(max))`, the value would be expected to be between
67 | /// `min` and `max`.
68 | ///
69 | /// Example of usage is give in the `color` example.
70 | ///
71 | /// Compare with [PaletteFracColor]
72 | PaletteFracColor(f64),
73 | /// Sets the color of the plot element to a value picked from the current palette (see
74 | /// [set_palette()](crate::AxesCommon::set_palette()) . The value supplied to this color type
75 | /// selects the color as a fraction of the current color range i.e. it is expected to be
76 | /// between `0` and `1`.
77 | ///
78 | /// Example of usage is give in the `color` example.
79 | ///
80 | /// Comparing with [PaletteCBColor]: given the following code
81 | /// ```
82 | /// use gnuplot::{PaletteCBColor, PaletteFracColor, Fix, Figure, AxesCommon, Color};
83 | ///# let min = -5.0; // or any value
84 | ///# let max = 12.0; // or any value
85 | ///
86 | ///# let frac = 0.5; // or any value 0.0 <= frac <= 1.0
87 | ///# let x = [1,2,3];
88 | ///# let y = [4,5,6];
89 | /// assert!(frac >= 0.0);
90 | /// assert!(frac <= 1.0);
91 | ///
92 | /// let mut fg = Figure::new();
93 | /// let ax = fg.axes2d();
94 | /// ax.set_cb_range(Fix(min), Fix(max));
95 | /// let col1 = Color(PaletteFracColor(frac));
96 | /// let cb_range = max - min;
97 | /// let col2 = Color(PaletteCBColor(min + (frac * cb_range)));
98 | /// ax.lines(x, y, &[col1]);
99 | /// ax.lines(x, y, &[col2]);
100 | /// ```
101 | /// the two lines should give the same color for any values of `max` and `min`, and `0 <= frac <= 1`.
102 | PaletteCBColor(f64),
103 | /// Vector of `f64` values which act as indexes into the current palette to set the color of
104 | /// each data point. These variable values work in the same was as the single fixed value supplied
105 | /// to a [PaletteCBColor]
106 | VariablePaletteColor(Vec),
107 | /// Similar to `VariablePaletteColor` in that it takes a `Vec` to set the indexes into the
108 | /// color map for each data point, but in addition to the color data it takes a string hold the name
109 | /// of the colormap to use. This should have been previously created in the workspace using the
110 | /// [create_colormap()](crate::AxesCommon::create_colormap) function.
111 | SavedColorMap(T, Vec),
112 | /// Set the color of all elements of the plot to the `n`th color in the current gnuplot color cycle.
113 | Index(ColorIndex),
114 | /// A color type that sets the color per element using a index `n` which represents the `n`th
115 | /// color in the current gnuplot color scheme. In gnuplot this is the last element in the plot command,
116 | /// in Rust gnuplot, the color type takes a vector of u8, where each index is treated the same as the
117 | /// fixed `IndexColor`.
118 | /// This is useful for setting bars/boxes etc to be
119 | /// the same color from multiple plot commands. The `variable_color` example has examples of this usage.
120 | VariableIndex(Vec),
121 | /// Set the color of the plot to the current background color.
122 | Background,
123 | /// Fixed black color
124 | Black,
125 | }
126 |
127 | impl ColorType
128 | {
129 | /// Returns the gnuplot string that will produce the requested color
130 | pub fn command(&self) -> String
131 | {
132 | match self
133 | {
134 | RGBString(s) => format!(r#"rgb "{}""#, from_string(s.to_string())),
135 | RGBInteger(r, g, b) => format!(r#"rgb {}"#, from_argb(255, *r, *g, *b)),
136 | ARGBInteger(a, r, g, b) => format!(r#"rgb {}"#, from_argb(*a, *r, *g, *b)),
137 | VariableRGBInteger(_) => "rgb variable".into(),
138 | VariableARGBInteger(_) => "rgb variable".into(),
139 | PaletteFracColor(v) => format!("palette frac {v}"),
140 | PaletteCBColor(v) => format!("palette cb {v}"),
141 | VariablePaletteColor(_) => "palette z".into(),
142 | SavedColorMap(s, _) => format!("palette {s}"),
143 | VariableIndex(_) => "variable".into(),
144 | Background => "bgnd".into(),
145 | Index(n) => format!("{}", n),
146 | Black => "black".into(),
147 | }
148 | }
149 |
150 | pub fn data(&self) -> Vec
151 | {
152 | match self
153 | {
154 | VariableRGBInteger(items) => items
155 | .iter()
156 | .map(|(r, g, b)| from_argb(255, *r, *g, *b) as f64)
157 | .collect(),
158 | VariableARGBInteger(items) => items
159 | .iter()
160 | .map(|(a, r, g, b)| from_argb(*a, *r, *g, *b) as f64)
161 | .collect(),
162 | VariablePaletteColor(items) => items.clone(),
163 | SavedColorMap(_, items) => items.clone(),
164 | VariableIndex(items) => items.iter().map(|v| *v as f64).collect(),
165 | c => panic!("data() called on non-variable color type: {:?}", *c),
166 | }
167 | }
168 |
169 | pub fn is_variable(&self) -> bool
170 | {
171 | matches!(
172 | self,
173 | VariableRGBInteger(_)
174 | | VariableARGBInteger(_)
175 | | VariableIndex(_)
176 | | VariablePaletteColor(_)
177 | | SavedColorMap(_, _)
178 | )
179 | }
180 |
181 | pub fn has_alpha(&self) -> bool
182 | {
183 | match self
184 | {
185 | RGBString(s) =>
186 | {
187 | let s = s.to_string();
188 | s.starts_with("0x") && s.len() == 10 || s.starts_with("#") && s.len() == 9
189 | }
190 | ARGBInteger(_, _, _, _) | VariableARGBInteger(_) => true,
191 | _ => false,
192 | }
193 | }
194 | }
195 |
196 | fn from_argb(a: ColorComponent, r: ColorComponent, g: ColorComponent, b: ColorComponent)
197 | -> ColorInt
198 | {
199 | ((255 - a as ColorInt) << 24)
200 | + ((r as ColorInt) << 16)
201 | + ((g as ColorInt) << 8)
202 | + (b as ColorInt)
203 | }
204 |
205 | fn from_string(argb: String) -> String
206 | {
207 | if let Some(trimmed_argb) = argb.strip_prefix("0x").or_else(|| argb.strip_prefix("#"))
208 | {
209 | if trimmed_argb.len() == 8
210 | {
211 | if let Ok(argb_int) = ColorInt::from_str_radix(trimmed_argb, 16)
212 | {
213 | let a = 255 - ((argb_int >> 24) & 0xff);
214 | let argb_int = (a << 24) + (argb_int & 0xffffff);
215 | format!("#{:08x}", argb_int)
216 | }
217 | else
218 | {
219 | // Let gnuplot sort it out.
220 | argb
221 | }
222 | }
223 | else
224 | {
225 | argb
226 | }
227 | }
228 | else
229 | {
230 | argb
231 | }
232 | }
233 |
234 | fn float_color_to_int(v: f64) -> Result
235 | {
236 | if !(0.0..=1.0).contains(&v)
237 | {
238 | Err(format!(
239 | "Float value must be greater than zero and less than one. Actual value: {}",
240 | v
241 | ))
242 | }
243 | else
244 | {
245 | Ok(((v * 255.0).round()) as u8)
246 | }
247 | }
248 |
249 | /// Converts a set of `f64` red, green and blue values in the range `0 <= x <= 1` to a 3-tuple of `u8` suitable for use as
250 | /// an [RGBInteger]
251 | ///
252 | /// Returns an error String if any of the arguments are not in the range `0 <= x <= 1`
253 | ///
254 | /// Ses also [floats_to_argb]
255 | ///
256 | /// # Arguments
257 | /// * r - red. 0: no red, 1: fully red
258 | /// * g - green. 0: no green, 1: fully green
259 | /// * b - blue. 0: no blue, 1: fully blue
260 | fn floats_to_rgb(r: f64, g: f64, b: f64) -> Result
261 | {
262 | Ok((
263 | float_color_to_int(r)?,
264 | float_color_to_int(g)?,
265 | float_color_to_int(b)?,
266 | ))
267 | }
268 |
269 | /// Converts a set of `f64` red, green and blue values in the range `0 <= x <= 1` to a 3-tuple of `u8` suitable for use as
270 | /// an [ARGBInteger]
271 | ///
272 | /// Returns an error String if any of the arguments are not in the range `0 <= x <= 1`
273 | ///
274 | /// Ses also [floats_to_rgb]
275 | ///
276 | /// # Arguments
277 | /// * a - alpha (transparency) value. 0: completely opaque, 1: completely transparent.
278 | /// * r - red. 0: no red, 1: fully red
279 | /// * g - green. 0: no green, 1: fully green
280 | /// * b - blue. 0: no blue, 1: fully blue
281 | fn floats_to_argb(a: f64, r: f64, g: f64, b: f64) -> Result
282 | {
283 | Ok((
284 | float_color_to_int(a)?,
285 | float_color_to_int(r)?,
286 | float_color_to_int(g)?,
287 | float_color_to_int(b)?,
288 | ))
289 | }
290 |
291 | impl<'l> From<&'l str> for ColorType
292 | {
293 | /// Converts `&str` into [RGBString]
294 | fn from(value: &'l str) -> Self
295 | {
296 | ColorType::RGBString(String::from(value))
297 | }
298 | }
299 |
300 | impl<'l> From for ColorType
301 | {
302 | /// Converts `String` into [RGBString]
303 | fn from(value: String) -> Self
304 | {
305 | ColorType::RGBString(value)
306 | }
307 | }
308 |
309 | impl<'l> From<&'l str> for ColorType<&'l str>
310 | {
311 | /// Converts `&str` into [RGBString]
312 | fn from(value: &'l str) -> Self
313 | {
314 | ColorType::RGBString(value)
315 | }
316 | }
317 |
318 | impl From for ColorType
319 | {
320 | /// Converts `(u8, u8, u8, u8)` into [ARGBInteger]
321 | fn from(value: ARGBInts) -> Self
322 | {
323 | ColorType::ARGBInteger(value.0, value.1, value.2, value.3)
324 | }
325 | }
326 |
327 | impl From for ColorType
328 | {
329 | /// Converts `(u8, u8, u8)` into [RGBInteger]
330 | fn from(value: RGBInts) -> Self
331 | {
332 | ColorType::RGBInteger(value.0, value.1, value.2)
333 | }
334 | }
335 |
336 | impl TryFrom<(f64, f64, f64)> for ColorType
337 | {
338 | type Error = String;
339 | /// Converts `(f64, f64, f64)` into [RGBInteger].
340 | /// Returns an error unless all values are in the range `0 <= v <= 1`.
341 | fn try_from(value: (f64, f64, f64)) -> Result
342 | {
343 | let ints = floats_to_rgb(value.0, value.1, value.2)?;
344 | Ok(ColorType::RGBInteger(ints.0, ints.1, ints.2))
345 | }
346 | }
347 |
348 | impl TryFrom<(f64, f64, f64, f64)> for ColorType
349 | {
350 | type Error = String;
351 | /// Converts `(f64, f64, f64, f64)` into [ARGBInteger].
352 | /// Returns an error unless all values are in the range `0 <= v <= 1`.
353 | fn try_from(value: (f64, f64, f64, f64)) -> Result
354 | {
355 | let ints = floats_to_argb(value.0, value.1, value.2, value.3)?;
356 | Ok(ColorType::ARGBInteger(ints.0, ints.1, ints.2, ints.3))
357 | }
358 | }
359 |
360 | impl From> for ColorType
361 | {
362 | /// Converts `Vec<(u8, u8, u8)>` into [VariableRGBInteger]
363 | fn from(value: Vec) -> Self
364 | {
365 | ColorType::VariableRGBInteger(value)
366 | }
367 | }
368 |
369 | impl From> for ColorType
370 | {
371 | /// Converts `Vec<(u8, u8, u8, u8)>` into [VariableARGBInteger]
372 | fn from(value: Vec) -> Self
373 | {
374 | ColorType::VariableARGBInteger(value)
375 | }
376 | }
377 |
378 | impl From for ColorType
379 | {
380 | /// Converts `u8` into [Index]
381 | fn from(value: ColorIndex) -> Self
382 | {
383 | ColorType::Index(value)
384 | }
385 | }
386 |
387 | impl From> for ColorType
388 | {
389 | /// Converts `Vec` into [VariableIndex]
390 | fn from(value: Vec) -> Self
391 | {
392 | ColorType::VariableIndex(value)
393 | }
394 | }
395 |
396 | impl OneWayOwned for ColorType
397 | {
398 | type Output = ColorType;
399 |
400 | fn to_one_way_owned(&self) -> ColorType
401 | {
402 | match self
403 | {
404 | RGBString(s) => RGBString(s.to_string()),
405 | RGBInteger(r, g, b) => RGBInteger(*r, *g, *b),
406 | VariableRGBInteger(d) => VariableRGBInteger(d.clone()),
407 | PaletteFracColor(v) => PaletteFracColor(*v),
408 | PaletteCBColor(v) => PaletteCBColor(*v),
409 | VariablePaletteColor(d) => VariablePaletteColor(d.clone()),
410 | SavedColorMap(s, d) => SavedColorMap(s.to_string(), d.clone()),
411 | VariableIndex(d) => VariableIndex(d.clone()),
412 | Background => Background,
413 | Index(n) => Index(*n),
414 | Black => Black,
415 | ARGBInteger(a, r, g, b) => ARGBInteger(*a, *r, *g, *b),
416 | VariableARGBInteger(d) => VariableARGBInteger(d.clone()),
417 | }
418 | }
419 | }
420 |
421 | impl ColorType
422 | {
423 | pub fn to_ref(&self) -> ColorType<&str>
424 | {
425 | match self
426 | {
427 | RGBString(s) => RGBString(s),
428 | RGBInteger(r, g, b) => RGBInteger(*r, *g, *b),
429 | VariableRGBInteger(d) => VariableRGBInteger(d.to_vec()),
430 | VariableARGBInteger(d) => VariableARGBInteger(d.to_vec()),
431 | PaletteFracColor(v) => PaletteFracColor(*v),
432 | PaletteCBColor(v) => PaletteCBColor(*v),
433 | VariablePaletteColor(d) => VariablePaletteColor(d.to_vec()),
434 | SavedColorMap(s, d) => SavedColorMap(s, d.to_vec()),
435 | VariableIndex(d) => VariableIndex(d.to_vec()),
436 | Background => Background,
437 | Index(n) => Index(*n),
438 | Black => Black,
439 | ARGBInteger(a, r, g, b) => ARGBInteger(*a, *r, *g, *b),
440 | }
441 | }
442 | }
443 |
--------------------------------------------------------------------------------
/gnuplot/src/coordinates.rs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013-2014 by SiegeLord
2 | //
3 | // All rights reserved. Distributed under LGPL 3.0. For full terms see the file LICENSE.
4 |
5 | pub use self::Coordinate::*;
6 | use std::fmt;
7 |
8 | /// Specifies how to interpret the coordinate passed to a plotting command
9 | #[derive(Copy, Clone)]
10 | pub enum Coordinate
11 | {
12 | /// Coordinates are done relative to a graph (i.e. an axis set). (0, 0) is the bottom left corner and (1, 1) is the top right corner.
13 | /// You'd use this to place labels and other objects so that they remain in the same place relative to the graph no matter what you have plotted.
14 | Graph(f64),
15 | /// Coordinates match those on the axes. You'd use this to place labels and other objects relative to regions of interest in the graph (e.g. labeling the peak of a function)
16 | Axis(f64),
17 | /// Coordinates match those on the secondary axes. You'd use this to place labels and other objects relative to regions of interest in the graph (e.g. labeling the peak of a function)
18 | Axis2(f64),
19 | }
20 |
21 | impl fmt::Display for Coordinate
22 | {
23 | fn fmt(&self, buf: &mut fmt::Formatter) -> fmt::Result
24 | {
25 | let (name, x) = match *self
26 | {
27 | Graph(x) => (" graph ", x),
28 | Axis(x) => (" first ", x),
29 | Axis2(x) => (" second ", x),
30 | };
31 | write!(buf, "{}{:.16e}", name, x)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/gnuplot/src/datatype.rs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013-2014 by SiegeLord
2 | //
3 | // All rights reserved. Distributed under LGPL 3.0. For full terms see the file LICENSE.
4 |
5 | use std::time::Duration;
6 |
7 | pub trait DataType: Clone
8 | {
9 | fn get(&self) -> f64;
10 | }
11 |
12 | macro_rules! impl_data_type {
13 | ($T:ty) => {
14 | impl<'l> DataType for &'l $T
15 | {
16 | fn get(&self) -> f64
17 | {
18 | **self as f64
19 | }
20 | }
21 | };
22 | }
23 |
24 | macro_rules! impl_data_type_ref {
25 | ($T:ty) => {
26 | impl DataType for $T
27 | {
28 | fn get(&self) -> f64
29 | {
30 | *self as f64
31 | }
32 | }
33 | };
34 | }
35 |
36 | impl_data_type!(u8);
37 | impl_data_type!(u16);
38 | impl_data_type!(u32);
39 | impl_data_type!(u64);
40 | impl_data_type!(usize);
41 |
42 | impl_data_type!(i8);
43 | impl_data_type!(i16);
44 | impl_data_type!(i32);
45 | impl_data_type!(i64);
46 | impl_data_type!(isize);
47 |
48 | impl_data_type!(f32);
49 | impl_data_type!(f64);
50 |
51 | impl_data_type_ref!(u8);
52 | impl_data_type_ref!(u16);
53 | impl_data_type_ref!(u32);
54 | impl_data_type_ref!(u64);
55 | impl_data_type_ref!(usize);
56 |
57 | impl_data_type_ref!(i8);
58 | impl_data_type_ref!(i16);
59 | impl_data_type_ref!(i32);
60 | impl_data_type_ref!(i64);
61 | impl_data_type_ref!(isize);
62 |
63 | impl_data_type_ref!(f32);
64 | impl_data_type_ref!(f64);
65 |
66 | impl DataType for Duration
67 | {
68 | fn get(&self) -> f64
69 | {
70 | // GnuPlot can't handle precision lower than milliseconds.
71 | self.as_secs() as f64 + self.subsec_millis() as f64 / 1000.0
72 | }
73 | }
74 |
75 | impl<'l> DataType for &'l Duration
76 | {
77 | fn get(&self) -> f64
78 | {
79 | // GnuPlot can't handle precision lower than milliseconds.
80 | self.as_secs() as f64 + self.subsec_millis() as f64 / 1000.0
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/gnuplot/src/error_types.rs:
--------------------------------------------------------------------------------
1 | use std::error;
2 | use std::fmt;
3 | use std::io;
4 |
5 | pub struct GnuplotInitError
6 | {
7 | inner: Box,
8 | }
9 |
10 | impl From for GnuplotInitError
11 | {
12 | fn from(error: io::Error) -> Self
13 | {
14 | GnuplotInitError {
15 | inner: Box::new(error),
16 | }
17 | }
18 | }
19 |
20 | impl fmt::Display for GnuplotInitError
21 | {
22 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
23 | {
24 | write!(
25 | f,
26 | "Couldn't spawn gnuplot. Make sure it is installed and available in PATH.\nCause: {}",
27 | self.inner
28 | )
29 | }
30 | }
31 |
32 | impl fmt::Debug for GnuplotInitError
33 | {
34 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
35 | {
36 | write!(f, "{}", self)
37 | }
38 | }
39 |
40 | impl error::Error for GnuplotInitError
41 | {
42 | fn source(&self) -> Option<&(dyn error::Error + 'static)>
43 | {
44 | Some(&*self.inner)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/gnuplot/src/figure.rs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013-2014 by SiegeLord
2 | //
3 | // All rights reserved. Distributed under LGPL 3.0. For full terms see the file LICENSE.
4 |
5 | use crate::error_types::*;
6 |
7 | use self::AxesVariant::*;
8 | use crate::axes2d::*;
9 | use crate::axes3d::*;
10 |
11 | use crate::options::{GnuplotVersion, MultiplotFillDirection, MultiplotFillOrder};
12 | use crate::util::escape;
13 | use crate::writer::Writer;
14 | use std::fs::File;
15 | use std::io::{BufWriter, Write};
16 | use std::path::{Path, PathBuf};
17 | use std::process::{Child, Command, Stdio};
18 | use std::str;
19 | use tempfile;
20 |
21 | enum AxesVariant
22 | {
23 | Axes2DType(Axes2D),
24 | Axes3DType(Axes3D),
25 | NewPage,
26 | }
27 |
28 | impl AxesVariant
29 | {
30 | fn write_out(
31 | &self, data_directory: Option<&str>, writer: &mut dyn Writer, auto_layout: bool,
32 | version: GnuplotVersion,
33 | )
34 | {
35 | match *self
36 | {
37 | Axes2DType(ref a) => a.write_out(data_directory, writer, auto_layout, version),
38 | Axes3DType(ref a) => a.write_out(data_directory, writer, auto_layout, version),
39 | NewPage =>
40 | {
41 | writeln!(writer, "unset multiplot");
42 | writeln!(writer, "set multiplot");
43 | }
44 | }
45 | }
46 |
47 | fn reset_state(&self, writer: &mut dyn Writer)
48 | {
49 | match *self
50 | {
51 | Axes2DType(ref a) => a.reset_state(writer),
52 | Axes3DType(ref a) => a.reset_state(writer),
53 | _ => (),
54 | }
55 | }
56 | }
57 |
58 | /// A struct that contains all the multiplot layout options
59 | struct MultiplotOptions
60 | {
61 | rows: usize,
62 | columns: usize,
63 | title: Option,
64 | scale_x: Option,
65 | scale_y: Option,
66 | offset_x: Option,
67 | offset_y: Option,
68 | fill_order: Option,
69 | fill_direction: Option,
70 | }
71 |
72 | impl MultiplotOptions
73 | {
74 | pub fn new() -> MultiplotOptions
75 | {
76 | MultiplotOptions {
77 | rows: 1,
78 | columns: 1,
79 | title: None,
80 | scale_x: None,
81 | scale_y: None,
82 | offset_x: None,
83 | offset_y: None,
84 | fill_order: None,
85 | fill_direction: None,
86 | }
87 | }
88 | }
89 |
90 | /// A sentinel that represents a gnuplot waiting to close.
91 | pub struct CloseSentinel
92 | {
93 | gnuplot: Child,
94 | }
95 |
96 | impl CloseSentinel
97 | {
98 | fn new(gnuplot: Child) -> Self
99 | {
100 | CloseSentinel { gnuplot }
101 | }
102 |
103 | /// Waits until the gnuplot process exits. See `std::process::Child::wait`.
104 | pub fn wait(&mut self) -> std::io::Result
105 | {
106 | self.gnuplot.wait()
107 | }
108 |
109 | /// Waits until the gnuplot process exits. See
110 | /// `std::process::Child::try_wait`.
111 | pub fn try_wait(&mut self) -> std::io::Result