Skip to content

imakris/vnm_plot

Repository files navigation

vnm_plot

A GPU-accelerated 2D time-series plotting library using Qt RHI and Qt Quick. Function Plotter function_plotter example

CI Status

CI Linux CI macOS CI Windows CI FreeBSD

Overview

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).

Architecture

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_core is the standalone rendering and data logic
  • vnm_plot is the Qt Quick wrapper (QML-friendly Plot_widget)
  • Plot_renderer runs on the Qt RHI render thread and coordinates the sub-renderers
  • Series_renderer handles lines, dots, and area fills with VBO management
  • Chrome_renderer draws the grid and axes
  • Font_renderer generates MSDF glyph atlases from FreeType

Usage

Plotting a Function

#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.

QML Quickstart

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 }
}

Custom Sample Types

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();

Display Styles

  • DOTS - points
  • LINE - connected line
  • AREA - filled area
  • COLORMAP_AREA - area colored by auxiliary metric
  • Combinations: DOTS_LINE, LINE_AREA, DOTS_LINE_AREA

Building

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

Qt 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 build

Examples

Enable examples with:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DVNM_PLOT_BUILD_EXAMPLES=ON
cmake --build build
  • vnm_plot_hello - renders a sine wave using Function_data_source
  • vnm_plot_preview_config - preview uses a separate data source and AREA style via preview_config
  • function_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=....

Configuration

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);

Integration

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)

Requirements

  • Qt 6.7+ with Qt Shader Tools

License

BSD-2-Clause

About

High-performance GPU-accelerated plotting library

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors