yuankunzhang / charming Goto Github PK
View Code? Open in Web Editor NEWA visualization library for Rust
License: Apache License 2.0
A visualization library for Rust
License: Apache License 2.0
There is already support for default decals, but the method to set them individually is missing from element::item_style::ItemStyle
.
Hi,
What are the differences between rust polars dataframe/ndarray and charming dataframe ? The polars and charming dataframe are both created with df! macro. Can I use polars/ndarray instead of charming dataframe ? If not, how to convert them to charming dataframe ?
Thanks for creating such a great crate. I tried to run your example on windows-gnu, but encountered error below. Upon tracing the error, there is no windows-gnu version of deno rusty. Not sure if I want to switch my rust to msvc version. Appreciate your help. Thanks.
Code:
use charming::{
component::Legend,
element::ItemStyle,
series::{Pie, PieRoseType},
Chart, ImageRenderer
};
fn main() {
let chart = Chart::new()
.legend(Legend::new().top("bottom"))
.series(
Pie::new()
.name("Nightingale Chart")
.rose_type(PieRoseType::Radius)
.radius(vec!["50", "250"])
.center(vec!["50%", "50%"])
.item_style(ItemStyle::new().border_radius(8))
.data(vec![
(40.0, "rose 1"),
(38.0, "rose 2"),
(32.0, "rose 3"),
(30.0, "rose 4"),
(28.0, "rose 5"),
(26.0, "rose 6"),
(22.0, "rose 7"),
(18.0, "rose 8"),
]),
);
let mut renderer = ImageRenderer::new(1000, 800);
renderer.save(&chart, "/tmp/nightingale.svg");
}
Error messages
Compiling if_chain v1.0.2
Compiling lebe v0.5.2
error: failed to run custom build command for `v8 v0.81.0`
Caused by:
process didn't exit successfully: `C:\Users\User1\elements\charm\rust\charming_ex1\target\debug\build\v8-37ec31db2e529d0e\build-script-build` (exit code: 101)
--- stdout
cargo:rerun-if-changed=.gn
cargo:rerun-if-changed=BUILD.gn
cargo:rerun-if-changed=src/binding.cc
cargo:rerun-if-env-changed=CCACHE
cargo:rerun-if-env-changed=CLANG_BASE_PATH
cargo:rerun-if-env-changed=CXXSTDLIB
cargo:rerun-if-env-changed=DENO_TRYBUILD
cargo:rerun-if-env-changed=DOCS_RS
cargo:rerun-if-env-changed=GN
cargo:rerun-if-env-changed=GN_ARGS
cargo:rerun-if-env-changed=HOST
cargo:rerun-if-env-changed=NINJA
cargo:rerun-if-env-changed=OUT_DIR
cargo:rerun-if-env-changed=RUSTY_V8_ARCHIVE
cargo:rerun-if-env-changed=RUSTY_V8_MIRROR
cargo:rerun-if-env-changed=SCCACHE
cargo:rerun-if-env-changed=V8_FORCE_DEBUG
cargo:rerun-if-env-changed=V8_FROM_SOURCE
cargo:rerun-if-env-changed=PYTHON
cargo:rerun-if-env-changed=DISABLE_CLANG
cargo:rerun-if-env-changed=EXTRA_GN_ARGS
cargo:rerun-if-env-changed=NO_PRINT_GN_ARGS
cargo:rustc-link-lib=static=rusty_v8
cargo:rustc-link-lib=dylib=winmm
cargo:rustc-link-lib=dylib=dbghelp
download lockfile: "C:\\Users\\User1\\elements\\charm\\rust\\charming_ex1\\target\\debug\\build\\lib_download.fslock"
static lib URL: https://github.com/denoland/rusty_v8/releases/download/v0.81.0/rusty_v8_release_x86_64-pc-windows-gnu.lib
cargo:rustc-link-search=C:\Users\User1\elements\charm\rust\charming_ex1\target\debug\gn_out\obj
Downloading https://github.com/denoland/rusty_v8/releases/download/v0.81.0/rusty_v8_release_x86_64-pc-windows-gnu.lib
Downloading https://github.com/denoland/rusty_v8/releases/download/v0.81.0/rusty_v8_release_x86_64-pc-windows-gnu.lib...
HTTP Error 404: Not Found
Python downloader failed, trying with curl.
--- stderr
Traceback (most recent call last):
File "C:\Users\User1\.cargo\registry\src\index.crates.io-6f17d22bba15001f\v8-0.81.0\tools\download_file.py", line 64, in <module>
sys.exit(main())
^^^^^^
File "C:\Users\User1\.cargo\registry\src\index.crates.io-6f17d22bba15001f\v8-0.81.0\tools\download_file.py", line 59, in main
DownloadUrl(args.url, f)
File "C:\Users\User1\.cargo\registry\src\index.crates.io-6f17d22bba15001f\v8-0.81.0\tools\download_file.py", line 45, in DownloadUrl
raise e
File "C:\Users\User1\.cargo\registry\src\index.crates.io-6f17d22bba15001f\v8-0.81.0\tools\download_file.py", line 29, in DownloadUrl
response = urlopen(url)
^^^^^^^^^^^^
File "C:\Users\User1\msys2\clang64\lib\python3.11\urllib\request.py", line 216, in urlopen
return opener.open(url, data, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\User1\msys2\clang64\lib\python3.11\urllib\request.py", line 525, in open
response = meth(req, response)
^^^^^^^^^^^^^^^^^^^
File "C:\Users\User1\msys2\clang64\lib\python3.11\urllib\request.py", line 634, in http_response
response = self.parent.error(
^^^^^^^^^^^^^^^^^^
File "C:\Users\User1\msys2\clang64\lib\python3.11\urllib\request.py", line 563, in error
return self._call_chain(*args)
^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\User1\msys2\clang64\lib\python3.11\urllib\request.py", line 496, in _call_chain
result = func(*args)
^^^^^^^^^^^
File "C:\Users\User1\msys2\clang64\lib\python3.11\urllib\request.py", line 643, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 404: Not Found
thread 'main' panicked at C:\Users\User1\.cargo\registry\src\index.crates.io-6f17d22bba15001f\v8-0.81.0\build.rs:431:3:
assertion failed: status.success()
stack backtrace:
0: 0x7ff6c22e80da - std::backtrace_rs::backtrace::dbghelp::trace::h1e6812ea8adba5fb
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src\..\..\backtrace\src\backtrace/dbghelp.rs:131:5
1: 0x7ff6c22e80da - std::backtrace_rs::backtrace::trace_unsynchronized::hb8761428bdde6a3f
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src\..\..\backtrace\src\backtrace/mod.rs:66:5
2: 0x7ff6c22e80da - std::sys_common::backtrace::_print_fmt::ha78d891bef73c841
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src\sys_common/backtrace.rs:68:5
3: 0x7ff6c22e80da - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h0391ff925c868418
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src\sys_common/backtrace.rs:44:22
4: 0x7ff6c231ab3d - core::fmt::rt::Argument::fmt::h10da764d6b07683e
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\core\src\fmt/rt.rs:142:9
5: 0x7ff6c231ab3d - core::fmt::write::h0d1a74662b4aa5bf
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\core\src\fmt/mod.rs:1120:17
6: 0x7ff6c22de8ed - std::io::Write::write_fmt::h3d21beac8e0d2508
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src\io/mod.rs:1810:15
7: 0x7ff6c22e7f03 - std::sys_common::backtrace::_print::h9d61df6a0aa75173
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src\sys_common/backtrace.rs:47:5
8: 0x7ff6c22e7f03 - std::sys_common::backtrace::print::h7d2e30433fe4fbf0
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src\sys_common/backtrace.rs:34:9
9: 0x7ff6c22eacc9 - std::panicking::default_hook::{{closure}}::h31917a5ba9296998
10: 0x7ff6c22ea9c8 - std::panicking::default_hook::h10d6ca42cdc89de3
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src/panicking.rs:292:9
11: 0x7ff6c22eb3b8 - std::panicking::rust_panic_with_hook::ha7d78ac18835b62c
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src/panicking.rs:779:13
12: 0x7ff6c22eb251 - std::panicking::begin_panic_handler::{{closure}}::h928711b767762e1f
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src/panicking.rs:649:13
13: 0x7ff6c22e8879 - std::sys_common::backtrace::__rust_end_short_backtrace::h933c5e8d5174ab9e
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src\sys_common/backtrace.rs:171:18
14: 0x7ff6c22eafd2 - rust_begin_unwind
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src/panicking.rs:645:5
15: 0x7ff6c2317157 - core::panicking::panic_fmt::hc685bd5fdf74c15e
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\core\src/panicking.rs:72:14
16: 0x7ff6c2317212 - core::panicking::panic::haa5ab648900af052
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\core\src/panicking.rs:144:5
17: 0x7ff6c227b242 - build_script_build::download_file::h8f4cf28df0dbae98
18: 0x7ff6c227b99c - build_script_build::download_static_lib_binaries::h88a22d18555d4de0
19: 0x7ff6c2276e3c - build_script_build::main::ha511d5763763ac70
20: 0x7ff6c228b4d6 - core::ops::function::FnOnce::call_once::h122611c92be75012
21: 0x7ff6c2294279 - std::sys_common::backtrace::__rust_begin_short_backtrace::hc272eadac412c9c7
22: 0x7ff6c22888ac - std::rt::lang_start::{{closure}}::h59b8aadf7afc35d0
23: 0x7ff6c22d1a14 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h9c9a98f97d582a39
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\core\src\ops/function.rs:284:13
24: 0x7ff6c22d1a14 - std::panicking::try::do_call::hcdc83a0ea6591991
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src/panicking.rs:552:40
25: 0x7ff6c22d1a14 - std::panicking::try::h5ea3e86c54fef019
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src/panicking.rs:516:19
26: 0x7ff6c22d1a14 - std::panic::catch_unwind::h72ff0f43651fef39
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src/panic.rs:142:14
27: 0x7ff6c22d1a14 - std::rt::lang_start_internal::{{closure}}::he26c620c3984b7f8
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src/rt.rs:148:48
28: 0x7ff6c22d1a14 - std::panicking::try::do_call::h2d75c103da858a58
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src/panicking.rs:552:40
29: 0x7ff6c22d1a14 - std::panicking::try::h82d3d3826c0310a7
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src/panicking.rs:516:19
30: 0x7ff6c22d1a14 - std::panic::catch_unwind::hc04bca4bf5b3cc1d
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src/panic.rs:142:14
31: 0x7ff6c22d1a14 - std::rt::lang_start_internal::h6cebd8dd02653fdc
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library\std\src/rt.rs:148:20
32: 0x7ff6c2288887 - std::rt::lang_start::haa6170a8085366d2
33: 0x7ff6c228047f - main
34: 0x7ff6c22712ee - __tmainCRTStartup
at C:\M\B\src\build-UCRT64\C:/M/B/src/mingw-w64/mingw-w64-crt/crt\crtexe.c:267:15
35: 0x7ff6c2271406 - mainCRTStartup
at C:\M\B\src\build-UCRT64\C:/M/B/src/mingw-w64/mingw-w64-crt/crt\crtexe.c:188:9
36: 0x7ffbd6ea257d - <unknown>
37: 0x7ffbd84aaa58 - <unknown>
warning: build failed, waiting for other jobs to finish...
Hi,
Charts-rs is a charting library for rust. It's simple and fast. Charming is a powerful and versatile chart rendering library for Rust that leverages the power of ECharts to deliver high-quality data visualizations. Hope you guys can help each other and move rust visualization forward.
In JavaScript, if an image is too large, we can use mouse movements to pan and zoom the image. However, this is not possible in charming.
Will there be support for decal patterns?
PS: Thank you for the library, it's great to work with. I wanted to use it for plots in publications, but could not find any option for decal patterns. It makes little difference on screen, but the bars are much easier to distinguish in B&W print when using patterns, so I wonder if they will be added later.
Hi,
Thanks for your great work! I am looking for rust visualization library for a long time. I have tried plotters (https://github.com/plotters-rs/plotters) and plotly (https://github.com/igiagkiozis/plotly), both of them are disappointing cannot meet my demand. Charming is the best one of all the rust visualization library I have ever seen and worth trying!
Do you have a roadmap of charming and will you maintain this project ? Though I am not a developer, I can test charming for you. And can I convert charming chart to json now using something like Chart.to_json() ? if so, I can send the json to web front end and render it. Besides, can I use charming in vscode jupyter and render them ?
When I used a Vec containing u64 or usize to draw a graph, the following error is reported:
the trait bound NumericValue: From<u64>
is not satisfied
the following other types implement trait From<T>
:
<NumericValue as From>
<NumericValue as From>
required for u64
to implement Into<NumericValue>
required for CompositeValue
to implement From<u64>
3 redundant requirements hidden
required for u64
to implement Into<DataPoint>
Would like to request table plot like table by charts-rs.
The crate has "MIT/Apache-2.0" license but its missing on the repository itself
I would love to have this heatmap: https://echarts.apache.org/examples/en/editor.html?c=heatmap-cartesian
Would like to request logarithmic scaled histogram like this example or this alternative format. Thanks.
Hi,
how to show customized x-axis label for boxplot ? The example of boxplot of charming only show "expr 1", "expr2" ... for the boxes, which is meaningless.
Reproducer:
use std::iter;
use charming::{component::Axis, element::AxisType, series::Scatter, Chart, ImageRenderer};
fn main() {
let c = Chart::new()
.x_axis(Axis::new().type_(AxisType::Value))
.y_axis(Axis::new().type_(AxisType::Value))
.series(
Scatter::new().data(
(0..=100)
.flat_map(|x| iter::zip(iter::repeat(x), 0..=100))
.map(|(x, y)| vec![x, y])
.collect(),
),
);
let mut renderer: ImageRenderer = ImageRenderer::new(1200, 1200);
renderer.save(&c, format!("/tmp/chc.svg")).unwrap();
}
Expected result (a screenshot from html page made by HtmlRenderer
):
I may be missing something, but I did not find a way to build a ChartResize structure since all of its fields are private.
Something as simple as
--- a/charming/src/renderer/wasm_renderer.rs
+++ b/charming/src/renderer/wasm_renderer.rs
@@ -76,6 +76,17 @@ pub struct ChartResize {
animation: Option<Animation>,
}
+impl ChartResize {
+ pub fn new(width: u32, height: u32, silent: bool, animation: Option<Animation>) -> Self {
+ ChartResize {
+ width,
+ height,
+ silent,
+ animation,
+ }
+ }
+}
+
#[derive(Serialize)]
pub struct Animation {
would solve the issue.
I'm unable to use the renderer (and I can't find it anywhere else)
charming = { version = "0.1.2", feature = "wasm" }
But same for 0.2.1
error[E0432]: unresolved import `charming::WasmRenderer`
--> src/main.rs:3:5
|
3 | use charming::WasmRenderer;
| ^^^^^^^^^^------------
| | |
| | help: a similar name exists in the module: `HtmlRenderer`
| no `WasmRenderer` in the root
quick q, how do I set the theme?
I want to suggest deriving Clone
and PartialEq
for charts and containing structs. Serialize
and Deserialize
for example could also be feature gated, if necessary. What do you think?
Is there any leptos example?
doc is here:
https://echarts.apache.org/en/option.html#series-line.label
can not add label for Line:
charming/examples/leptos-demo/src/main.rs
Line 20 in dbf7e05
I have converted some polars dataframes into the underlying Vec types to pass into the charming df! macro and managed to build a working pipeline for making charts.
Running into an issue with a chart that starts from YTD for daily bars, and it compiles and saves the data into an html file.
When it comes to opening the file in the web browser it only renders a few bars and then nothing more. Even though the date axis and raw html data is fully available in the file.
Hey, I've tried implementing a dynamic approach to initializing the x axis with a polars series of "Datetime" objects and my code compiles but panics when unwrapping the result of the chart creation. I screenshotted the ErrString, "expected Date got str"
I will fork and try to fix this issue, hopefully you may have some insight too.
if I recall correctly, I remember at one point seeing an example for how to load data for candlesticks, but the example is now gone. Adding this back would be great since there's only the svg examples. I have a Polars Dataframe as my source.
Compiling charm v0.1.0 (/home/xxx/rust/charm)
error[E0432]: unresolved import charming::ImageRenderer
--> src/main.rs:5:12
|
5 | Chart, ImageRenderer,
| ^^^^^^^^^^^^^ no ImageRenderer
in the root
For more information about this error, try rustc --explain E0432
.
error: could not compile charm
(bin "charm") due to previous error
// here is the code
use charming::{
component::Legend,
element::ItemStyle,
series::{Pie, PieRoseType},
Chart, ImageRenderer,
};
fn main() {
let chart = Chart::new().legend(Legend::new().top("bottom")).series(
Pie::new()
.name("Nightingale Chart")
.rose_type(PieRoseType::Radius)
.radius(vec!["50", "250"])
.center(vec!["50%", "50%"])
.item_style(ItemStyle::new().border_radius(8))
.data(vec![
(40.0, "rose 1"),
(38.0, "rose 2"),
(32.0, "rose 3"),
(30.0, "rose 4"),
(28.0, "rose 5"),
(26.0, "rose 6"),
(22.0, "rose 7"),
(18.0, "rose 8"),
]),
);
let mut renderer = ImageRenderer::new(1000, 800);
renderer.save(&chart, "/tmp/nightingale.svg");
}
Or other ways for communication?
Hi,
I just wanted to point out that the recently committed discord invite is broken
(there also does not seem to be a charming server on discord)
Is live plotting of candlestick can be achieved through this library
I am embedding charming graphs inside leptos components. To handle canvas resizes correctly, I need to keep track of the Echart object in the reactive effect by inserting it in a leptos Read/WriteSignal. This requires Echart to be Clone, unless I am missing a a simpler solution.
Something like this would solve the issue:
--- a/charming/src/renderer/wasm_renderer.rs
+++ b/charming/src/renderer/wasm_renderer.rs
@@ -144,6 +155,8 @@ impl Animation {
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_name = echarts)]
+ #[derive(Clone)]
pub type Echarts;
#[wasm_bindgen(js_namespace = echarts, js_name = init)]
Are there any drawbacks with this change?
The JavaScript V8 engine was too difficult to download during initial compilation, are there any other solutions?
Implement Clone
on everything that allows it simply because there is nothing that speaks against it. Some third party libraries (like Leptos) require it.
It would be nice to be able to use custom themes defined in a JSON or .toml file by deserialzing these into a custom theme struct.
A possible way to achieve this is by creating a CustomTheme
struct with fields corresponding to the settings, while using preexisting structs from the crate. As those struct already has most of (if not all) of the needed fields, e.g the Line
struct has line_style
which is needed. The problem however is that the Line
struct also has fields which are not required, nor wanted (?), for a theme struct - i.e the type_
(?) and the data
field.
Is this something that is in the works? If wanted I could try to implement this, however, then there would be need for some guidance what needs to be done.
A small example of what I'm getting at..
use serde::{Serialize, Deserialize};
use charming::element::Color;
use charming::series::Line;
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct CustomTheme {
#[serde(skip_serializing_if = "Option::is_none")]
color: Option<Vec<Color>>,
#[serde(skip_serializing_if = "Option::is_none")]
line: Option<Line>,
// and then more...
}
let theme: &str = r#"
{
"color": ["\#ff0000", "\#00ff00", "\#0000ff"],
"line": {
"lineStyle" : {
"width": 3
},
"symbolSize": 8
}
}
"#;
let my_custom_theme: CustomTheme = serde_json::from_str(theme).unwrap();
// Then set theme....
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.