Skip to content

Commit af14084

Browse files
committed
Merge branch 'v0.3-pre-devs/3d' into v0.3-pre
2 parents 9a6c2c0 + 870ac3e commit af14084

File tree

21 files changed

+1216
-24
lines changed

21 files changed

+1216
-24
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ default = [
6161
"image",
6262
"deprecated_items", "all_series", "all_elements"
6363
]
64-
all_series = ["area_series", "line_series", "point_series"]
64+
all_series = ["area_series", "line_series", "point_series", "surface_series"]
6565
all_elements = ["errorbar", "candlestick", "boxplot", "histogram"]
6666

6767
# Tier 1 Backends
@@ -80,6 +80,7 @@ histogram = []
8080
area_series = []
8181
line_series = []
8282
point_series = []
83+
surface_series = []
8384

8485
# Font implemnetation
8586
ttf = ["font-kit", "rusttype", "lazy_static"]

examples/3d-plot.rs

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use plotters::prelude::*;
2+
fn main() -> Result<(), Box<dyn std::error::Error>> {
3+
let area = SVGBackend::new("plotters-doc-data/3d-plot.svg", (1024, 760)).into_drawing_area();
4+
5+
area.fill(&WHITE)?;
6+
7+
let x_axis = (-3.0..3.0).step(0.1);
8+
let z_axis = (-3.0..3.0).step(0.1);
9+
10+
let mut chart = ChartBuilder::on(&area)
11+
.caption(format!("3D Plot Test"), ("sans", 20))
12+
.build_cartesian_3d(x_axis.clone(), -3.0..3.0, z_axis.clone())?;
13+
14+
chart.with_projection(|mut pb| {
15+
pb.yaw = 0.5;
16+
pb.scale = 0.9;
17+
pb.into_matrix()
18+
});
19+
20+
chart.configure_axes().draw()?;
21+
22+
chart
23+
.draw_series(SurfaceSeries::<f64, _, f64>::new(
24+
x_axis.values(),
25+
z_axis.values(),
26+
|&x, &z| (x * x + z * z).cos(),
27+
&BLUE.mix(0.2),
28+
))?
29+
.label("Surface")
30+
.legend(|(x, y)| Rectangle::new([(x + 5, y - 5), (x + 15, y + 5)], BLUE.mix(0.5).filled()));
31+
32+
chart
33+
.draw_series(LineSeries::new(
34+
(-100..100)
35+
.map(|y| y as f64 / 40.0)
36+
.map(|y| ((y * 10.0).sin(), y, (y * 10.0).cos())),
37+
&BLACK,
38+
))?
39+
.label("Line")
40+
.legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &BLACK));
41+
42+
chart
43+
.configure_series_labels()
44+
.border_style(&BLACK)
45+
.draw()?;
46+
Ok(())
47+
}

examples/wasm-demo/src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use web_sys::HtmlCanvasElement;
33

44
mod func_plot;
55
mod mandelbrot;
6+
mod plot3d;
67

78
#[global_allocator]
89
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
@@ -44,6 +45,11 @@ impl Chart {
4445
})
4546
}
4647

48+
pub fn plot3d(canvas: HtmlCanvasElement, pitch: f64, yaw: f64) -> Result<(), JsValue> {
49+
plot3d::draw(canvas, pitch, yaw).map_err(|err| err.to_string())?;
50+
Ok(())
51+
}
52+
4753
/// This function can be used to convert screen coordinates to
4854
/// chart coordinates.
4955
pub fn coord(&self, x: i32, y: i32) -> Option<Point> {

examples/wasm-demo/src/mandelbrot.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::DrawResult;
22
use plotters::prelude::*;
3+
use plotters_canvas::CanvasBackend;
34
use std::ops::Range;
45
use web_sys::HtmlCanvasElement;
5-
use plotters_canvas::CanvasBackend;
66

77
/// Draw Mandelbrot set
88
pub fn draw(element: HtmlCanvasElement) -> DrawResult<impl Fn((i32, i32)) -> Option<(f64, f64)>> {

examples/wasm-demo/src/plot3d.rs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use crate::DrawResult;
2+
use plotters::prelude::*;
3+
use plotters_canvas::CanvasBackend;
4+
use web_sys::HtmlCanvasElement;
5+
6+
pub fn draw(canvas: HtmlCanvasElement, pitch: f64, yaw: f64) -> DrawResult<()> {
7+
let area = CanvasBackend::with_canvas_object(canvas)
8+
.unwrap()
9+
.into_drawing_area();
10+
area.fill(&WHITE)?;
11+
12+
let x_axis = (-3.0..3.0).step(0.1);
13+
let z_axis = (-3.0..3.0).step(0.1);
14+
15+
let mut chart =
16+
ChartBuilder::on(&area).build_cartesian_3d(x_axis.clone(), -3.0..3.0, z_axis.clone())?;
17+
18+
chart.with_projection(|mut pb| {
19+
pb.yaw = yaw;
20+
pb.pitch = pitch;
21+
pb.scale = 0.7;
22+
pb.into_matrix()
23+
});
24+
25+
chart.configure_axes().draw()?;
26+
27+
chart.draw_series(SurfaceSeries::<f64, _, f64>::new(
28+
x_axis.values(),
29+
z_axis.values(),
30+
|&x, &z| (x * x + z * z).cos(),
31+
&BLUE.mix(0.2),
32+
))?;
33+
34+
chart.draw_series(LineSeries::new(
35+
(-100..100)
36+
.map(|y| y as f64 / 40.0)
37+
.map(|y| ((y * 10.0).sin(), y, (y * 10.0).cos())),
38+
&BLACK,
39+
))?;
40+
41+
Ok(())
42+
}

examples/wasm-demo/www/index.html

+15-10
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,21 @@ <h1>Plotters WebAssembly Demo</h1>
1515
<canvas id="canvas" width="600" height="400"></canvas>
1616
<div id="status">Loading WebAssembly...</div>
1717
<div id="control">
18-
<label for="plot-type">Demo: </label>
19-
<select id="plot-type">
20-
<option value="0">Graph of y=1</option>
21-
<option value="1">Graph of y=x</option>
22-
<option value="2">Graph of y=x^2</option>
23-
<option value="3">Graph of y=x^3</option>
24-
<option value="4">Graph of y=x^4</option>
25-
<option value="5">Graph of y=x^5</option>
26-
<option value="mandelbrot">Mandelbrot Set</option>
27-
</select>
18+
<label for="plot-type">Demo: </label>
19+
<select id="plot-type">
20+
<option value="0">Graph of y=1</option>
21+
<option value="1">Graph of y=x</option>
22+
<option value="2">Graph of y=x^2</option>
23+
<option value="3">Graph of y=x^3</option>
24+
<option value="4">Graph of y=x^4</option>
25+
<option value="5">Graph of y=x^5</option>
26+
<option value="mandelbrot">Mandelbrot Set</option>
27+
<option value="3d-plot">3D Plot Demo</option>
28+
</select>
29+
<div id="3d-control" class="hide">
30+
<label for="pitch">Pitch: </label> <input type="range" min="0" max="157" id="pitch" value="10"> <br/>
31+
<label for="yaw">Yaw: </label> <input type="range" min="0" max="314" id="yaw" value="50">
32+
</div>
2833
</div>
2934
</main>
3035
<footer>

examples/wasm-demo/www/index.js

+34-3
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,21 @@ class Chart {}
55
const canvas = document.getElementById("canvas");
66
const coord = document.getElementById("coord");
77
const plotType = document.getElementById("plot-type");
8+
const pitch = document.getElementById("pitch");
9+
const yaw = document.getElementById("yaw");
10+
const control = document.getElementById("3d-control");
811
const status = document.getElementById("status");
912

1013
let chart = null;
1114

1215
/** Main entry point */
1316
export function main() {
17+
let hash = location.hash.substr(1);
18+
for(var i = 0; i < plotType.options.length; i++) {
19+
if(hash == plotType.options[i].value) {
20+
plotType.value = hash;
21+
}
22+
}
1423
setupUI();
1524
setupCanvas();
1625
}
@@ -24,6 +33,10 @@ export function setup(WasmChart) {
2433
function setupUI() {
2534
status.innerText = "WebAssembly loaded!";
2635
plotType.addEventListener("change", updatePlot);
36+
yaw.addEventListener("change", updatePlot);
37+
pitch.addEventListener("change", updatePlot);
38+
yaw.addEventListener("input", updatePlot);
39+
pitch.addEventListener("input", updatePlot);
2740
window.addEventListener("resize", setupCanvas);
2841
window.addEventListener("mousemove", onMouseMove);
2942
}
@@ -58,15 +71,33 @@ function onMouseMove(event) {
5871
}
5972
}
6073

74+
function updatePlot3d() {
75+
let yaw_value = Number(yaw.value) / 100.0;
76+
let pitch_value = Number(pitch.value) / 100.0;
77+
Chart.plot3d(canvas, pitch_value, yaw_value);
78+
coord.innerText = `Pitch:${pitch_value}, Yaw:${yaw_value}`
79+
}
80+
6181
/** Redraw currently selected plot. */
6282
function updatePlot() {
6383
const selected = plotType.selectedOptions[0];
6484
status.innerText = `Rendering ${selected.innerText}...`;
6585
chart = null;
6686
const start = performance.now();
67-
chart = (selected.value == "mandelbrot")
68-
? Chart.mandelbrot(canvas)
69-
: Chart.power("canvas", Number(selected.value));
87+
switch(selected.value) {
88+
case "mandelbrot":
89+
control.classList.add("hide");
90+
chart = Chart.mandelbrot(canvas);
91+
break;
92+
case "3d-plot":
93+
control.classList.remove("hide");
94+
updatePlot3d();
95+
break;
96+
default:
97+
control.classList.add("hide");
98+
chart = Chart.power("canvas", Number(selected.value))
99+
}
100+
70101
const end = performance.now();
71102
status.innerText = `Rendered ${selected.innerText} in ${Math.ceil(end - start)}ms`;
72103
}

examples/wasm-demo/www/style.css

+5
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,8 @@ footer {
4848
font-size: 12px;
4949
text-align: center;
5050
}
51+
52+
.hide {
53+
visibility: hidden;
54+
height: 0px;
55+
}

0 commit comments

Comments
 (0)