A GPU-accelerated 2D time-series plotting library using Qt RHI and Qt Quick.
function_plotter example
vnm_plot renders time-series data through Qt RHI. It supports Level-of-Detail (LOD) for handling large datasets. The renderer automatically selects an appropriate resolution based on the current zoom level.
The library uses a type-erased data interface (vnm::plot::Data_source + vnm::plot::Data_access_policy) so it can work with any sample type without templates in the rendering code.
Data sources decide whether snapshots are copies or direct views; buffering, if needed, lives in the data source.
Public headers: #include <vnm_plot/vnm_plot.h> (umbrella), #include <vnm_plot/core.h> (core only), and
#include <vnm_plot/qt.h> (Qt wrapper when built with Qt, VNM_PLOT_WITH_QT).
vnm_plot_core (standalone core library)
-> Chrome_renderer (grid and axes)
-> Series_renderer (data series)
-> Text_renderer (labels)
-> Font_renderer (MSDF glyphs)
vnm_plot (Qt wrapper)
-> Plot_widget (QQuickRhiItem)
-> Plot_renderer (RHI render thread)
-> vnm_plot_core
vnm_plot_coreis the standalone rendering and data logicvnm_plotis the Qt Quick wrapper (QML-friendly Plot_widget)Plot_rendererruns on the Qt RHI render thread and coordinates the sub-renderersSeries_rendererhandles lines, dots, and area fills with VBO managementChrome_rendererdraws the grid and axesFont_renderergenerates MSDF glyph atlases from FreeType
#include <vnm_plot/vnm_plot.h>
// plot_widget is a vnm::plot::Plot_widget* from QML or C++
// Create data source and generate samples
auto source = std::make_shared<vnm::plot::Function_data_source>();
source->generate([](double x) { return std::sin(x); }, 0.0, 10.0, 1000);
// Create series
auto series = vnm::plot::Series_builder()
.style(vnm::plot::Display_style::LINE)
.color(vnm::plot::rgba_u8(51, 153, 255))
.data_source(source)
.access(vnm::plot::make_function_sample_policy_typed())
.build_shared();
// Add to widget
plot_widget->add_series(0, series);Thread Safety
Plot_widget renders on a separate RHI render thread. Treat series_data_t as immutable once added. To change series config (style, access policy, preview config, color), update a copy and call add_series again with the same id to replace it. Make sure your Data_source implementation is safe to read from the render thread.
Register the type in C++:
#include <vnm_plot/vnm_plot.h>
qmlRegisterType<vnm::plot::Plot_widget>("VnmPlot", 1, 0, "PlotWidget");
qmlRegisterType<vnm::plot::Plot_time_axis>("VnmPlot", 1, 0, "PlotTimeAxis");Use it in QML:
import VnmPlot 1.0
PlotWidget {
id: plot
anchors.fill: parent
}Shared time axis across plots:
import VnmPlot 1.0
PlotTimeAxis { id: sharedAxis }
Column {
PlotView { time_axis: sharedAxis }
PlotView { time_axis: sharedAxis }
}Implement a vnm::plot::Data_access_policy to tell the renderer how to read your samples:
struct my_sample_t {
double timestamp;
float value;
float low;
float high;
};
auto policy = vnm::plot::make_access_policy<my_sample_t>(
&my_sample_t::timestamp,
&my_sample_t::value,
&my_sample_t::low,
&my_sample_t::high);
// Assign policy to a series
auto series = std::make_shared<vnm::plot::series_data_t>();
series->access = policy.erase();DOTS- pointsLINE- connected lineAREA- filled areaCOLORMAP_AREA- area colored by auxiliary metric- Combinations:
DOTS_LINE,LINE_AREA,DOTS_LINE_AREA
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build buildQt 6 (Core, Gui, Quick, GuiPrivate, ShaderTools) is required. The build fetches glm, FreeType, and msdfgen if they are not already available as targets.
CI currently builds QRhi and QRhi+Text on Linux, macOS, Windows, and FreeBSD.
The GitHub Actions jobs use the Qt 6.10.1 SDK on Linux, macOS, and Windows so
the QRhi private headers and qsb shader compiler are available consistently.
To disable text rendering (skips FreeType + msdfgen):
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DVNM_PLOT_ENABLE_TEXT=OFF
cmake --build buildEnable examples with:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DVNM_PLOT_BUILD_EXAMPLES=ON
cmake --build buildvnm_plot_hello- renders a sine wave usingFunction_data_sourcevnm_plot_preview_config- preview uses a separate data source and AREA style viapreview_configfunction_plotter- multiple functions, per-series styles, expression evaluation via mexce
function_plotter depends on mexce. You can point at a local checkout by
configuring with -DMEXCE_LOCAL_PATH=....
Customize rendering via Plot_config:
vnm::plot::Plot_config config;
config.dark_mode = true;
config.line_width_px = 2.0;
config.auto_v_range_mode = vnm::plot::Auto_v_range_mode::VISIBLE;
config.format_timestamp = [](double ts, double range) {
return my_format_time(ts, range);
};
plot_widget->set_config(config);As a subdirectory:
add_subdirectory(vnm_plot)
target_link_libraries(your_app PRIVATE vnm_plot::vnm_plot)Via FetchContent:
include(FetchContent)
FetchContent_Declare(vnm_plot
GIT_REPOSITORY https://github.com/imakris/vnm_plot.git
GIT_TAG 1.0.4
)
FetchContent_MakeAvailable(vnm_plot)
target_link_libraries(your_app PRIVATE vnm_plot::vnm_plot)- Qt 6.7+ with Qt Shader Tools
BSD-2-Clause