我有一个结构
Band
:
pub struct Band{
pub name: String,
pub start_dt: NaiveDateTime,
pub end_dt: NaiveDateTime,
pub stage: String,
pub selected: bool,
}
我正在使用 plotters 板条箱进行绘图。 我有一个由
Band
对象组成的向量,想要绘制矩形。我的绘图图表的 y 轴上有 DateTime
,x 轴上有阶段名称的分段值:
let mut chart = ChartBuilder::on(&drawing_area)
.caption(current_day, ("Arial", 30))
.set_label_area_size(LabelAreaPosition::Left, 40)
.set_label_area_size(LabelAreaPosition::Bottom, 60)
// the x axis are the sages. we want the names centered
// on an entry (i.e. it starts with half in front of a segment
// and ends half after a segment, rather than matching segments
// exactle)
// ----|---------------|-------------|-------
// main stage t stage wera stage
// for that behaviour, we need the into_segmented() command
.build_cartesian_2d(stages.into_segmented(), first_utc..last_utc)
.unwrap();
如何让我的整个向量绘制它们的矩形?无论我做什么,Rust 都会抱怨我使用了不正确的字符串,因此没有满足特征界限。我已经在这上面浪费了两个小时,而且不知道如何取得进展。
以下是我的一些尝试(不是按我尝试的顺序,但无论如何)。
for band in bands{
let stage = band.stage.clone();
chart.draw_series(vec![
Rectangle::new(
[
(SegmentValue::Exact(&stage), band.start_dt.and_utc()),
(SegmentValue::CenterOf(&stage), band.end_dt.and_utc())
],
Into::<ShapeStyle>::into(BLACK)
)
]).unwrap();
}
|| the trait bound `for<'b> &'b plotters::element::Rectangle<(plotters::prelude::SegmentValue<&String>, DateTime<Utc>)>: PointCollection<'b, (plotters::prelude::SegmentValue<&&str>, DateTime<Utc>)>` is not satisfied
|| |
|| 97 | chart.draw_series(vec![
|| | ^^^^^^^^^^^ the trait `for<'b> PointCollection<'b, (plotters::prelude::SegmentValue<&&str>, DateTime<Utc>)>` is not implemented for `&'b plotters::element::Rectangle<(plotters::prelude::SegmentValue<&String>, DateTime<Utc>)>`
|| |
|| = help: the trait `PointCollection<'_, (plotters::prelude::SegmentValue<&String>, DateTime<Utc>)>` is implemented for `&plotters::element::Rectangle<(plotters::prelude::SegmentValue<&String>, DateTime<Utc>)>`
|| = help: for that trait implementation, expected `String`, found `&str`
|| required by a bound in `ChartContext::<'a, DB, CT>::draw_series`
|| |
|| 120 | pub fn draw_series<B, E, R, S>(
|| | ----------- required by a bound in this associated function
|| ...
|| 126 | for<'b> &'b E: PointCollection<'b, CT::From, B>,
|| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ChartContext::<'a, DB, CT>::draw_series`
for band in bands{
let stage = band.stage.clone();
chart.draw_series(vec![
Rectangle::new(
[
(SegmentValue::Exact(&stage.as_str()), band.start_dt.and_utc()),
(SegmentValue::CenterOf(&band.stage.as_str()), band.end_dt.and_utc())
],
Into::<ShapeStyle>::into(BLACK)
)
]).unwrap();
}
舞台的寿命不够
|| `stage` does not live long enough
|| |
|| 96 | let stage = band.stage.clone();
|| | ----- binding `stage` declared here
|| 97 | chart.draw_series(vec![
|| |
||
----- borrow later used here
|| ...
|| 100 | (SegmentValue::Exact(&stage.as_str()), band.start_dt.and_utc()),
|| | ^^^^^ borrowed value does not live long enough
|| ...
|| 106 | }
|| | - `stage` dropped here while still borrowed
|| temporary value dropped while borrowed
|| |
|| 97 | chart.draw_series(vec![
|| |
----- borrow later used here
|| ...
|| 100 | (SegmentValue::Exact(&stage.as_str()), band.start_dt.and_utc()),
|| | ^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
|| ...
|| 105 | ]).unwrap();
|| | - temporary value is freed at the end of this statement
|| |
|| = note: consider using a `let` binding to create a longer lived value
|| `band.stage` does not live long enough
|| |
|| 95 | for band in bands{
|| |
---- binding `band` declared here
|| 96 | let stage = band.stage.clone();
|| 97 | chart.draw_series(vec![
|| |
----- borrow later used here
|| ...
|| 101 | (SegmentValue::CenterOf(&band.stage.as_str()), band.end_dt.and_utc())
|| | ^^^^^^^^^^ borrowed value does not live long enough
|| ...
|| 106 | }
|| | - `band.stage` dropped here while still borrowed
|| temporary value dropped while borrowed
|| |
|| 97 | chart.draw_series(vec![
|| | ----- borrow later used here
|| ...
|| 101 | (SegmentValue::CenterOf(&band.stage.as_str()), band.end_dt.and_utc())
|| | ^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
|| ...
|| 105 | ]).unwrap();
|| |
- temporary value is freed at the end of this statement
|| |
|| = note: consider using a `let` binding to create a longer lived value
chart.draw_series(
bands.iter().map(|band| {
Rectangle::new(
[((SegmentValue::Exact(&band.stage.as_str())).clone(), band.start_dt.and_utc()),
((SegmentValue::CenterOf(&band.stage.as_str())).clone(), band.end_dt.and_utc())],
Into::<ShapeStyle>::into(BLACK).filled()
)
})
).unwrap();
返回仍然引用临时值的值
|| cannot return value referencing temporary value
|| |
|| 99 | / Rectangle::new(
|| 100 | | [((SegmentValue::Exact(&band.stage.as_str())).clone(), band.start_dt.and_utc()),
|| 101
|| | | ((SegmentValue::CenterOf(&band.stage.as_str())).clone(), band.end_dt.and_utc())],
|| | |
------------------- temporary value created here
|| 102 | | Into::<ShapeStyle>::into(BLACK).filled()
|| 103 | | )
|| | |_____________^ returns a value referencing data owned by the current function
|| cannot return value referencing temporary value
|| |
|| 99 | / Rectangle::new(
|| 100 | | [((SegmentValue::Exact(&band.stage.as_str())).clone(), band.start_dt.and_utc()),
|| | |
------------------- temporary value created here
|| 101 | | ((SegmentValue::CenterOf(&band.stage.as_str())).clone(), band.end_dt.and_utc())],
|| 102 | | Into::<ShapeStyle>::into(BLACK).filled()
|| 103 | | )
|| | |_____________^ returns a value referencing data owned by the current function
这个板条箱有一个(GitHub)论坛,你在其中得不到答案,否则我会在那里问......
我遇到的问题主要是关于输入数据。最初,为了测试我使用了
stages.into_segmented()' where
stageswas an array of
&str` 元素:
let stages = [
"Main Stage",
"T Stage",
"Wera Stage"
];
因此,
into_segmented()
调用创建了SegmentValue(&&str)
元素,但我仍然不知道如何解决此数据类型的问题。
但是,当我意识到这种数据类型有问题时,我将其更改为字符串向量:
let stages: Vec<String> = vec![
String::from("Main Stage"),
String::from("T Stage"),
String::from("Wera Stage")
];
有了这个,让
SegmentValue
接受我的动态输入就变得相当简单了。我现在可以从我的 stage
结构中借用 Band
字符串并完成它。使用闭包,它看起来像这样:
// draw all bands into the chart
chart.draw_series(
bands.iter().map(|band| {
Rectangle::new(
[
(SegmentValue::Exact(&band.stage), band.start_dt.and_utc()),
(SegmentValue::CenterOf(&band.stage), band.end_dt.and_utc()),
],
Into::<ShapeStyle>::into(BLACK).filled()
)
})
).unwrap();