FlowPlotPy 0.9.6__tar.gz → 0.9.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13462,25 +13462,76 @@ namespace FlowPlot
13462
13462
  float lineGap = 0.0f;
13463
13463
  };
13464
13464
 
13465
+ /**
13466
+ * @brief Interface used by FlowPlot to register, measure, and lay out fonts.
13467
+ *
13468
+ * FlowPlot resolves text sizes while compiling a template and stores the resulting
13469
+ * glyph positions in its render commands. Applications that need their own text
13470
+ * backend can supply an implementation with PlotBuilder::useTextEngine.
13471
+ *
13472
+ * When FLOW_PLOT_RENDERER is enabled, FlowPlot provides StbTextEngine and creates a
13473
+ * temporary instance automatically when no engine was supplied. It registers the
13474
+ * template's fonts before rendering. Supply an engine when font state must be shared,
13475
+ * cached, or implemented by another rendering backend.
13476
+ */
13465
13477
  class ITextEngine
13466
13478
  {
13467
13479
  public:
13468
13480
  virtual ~ITextEngine() = default;
13481
+
13482
+ /**
13483
+ * @brief Register a TrueType font face under a FlowPlot font family.
13484
+ *
13485
+ * FlowPlot calls this for every entry in a template's @c fonts array. Implementations
13486
+ * should retain enough font data to serve later measurement and layout requests.
13487
+ * @param familyName Family name used by templates, for example "Default".
13488
+ * @param ttfPath Path to a .ttf file.
13489
+ * @param weight Numeric font weight, normally 400 for regular or 700 for bold.
13490
+ * @param style Font style for this face.
13491
+ */
13469
13492
  virtual void registerFont(
13470
13493
  std::string_view familyName,
13471
13494
  const std::filesystem::path& ttfPath,
13472
13495
  std::uint16_t weight = 400,
13473
13496
  FontStyle style = FontStyle::Normal) = 0;
13497
+
13498
+ /**
13499
+ * @brief Return whether a registered face exists for the requested font attributes.
13500
+ *
13501
+ * This query lets callers inspect an engine before a template is compiled. The exact
13502
+ * fallback policy is implementation-defined; StbTextEngine falls back to its
13503
+ * @c Default regular face when an exact match is unavailable.
13504
+ */
13474
13505
  virtual bool hasFont(
13475
13506
  std::string_view familyName,
13476
13507
  std::uint16_t weight = 400,
13477
13508
  FontStyle style = FontStyle::Normal) const = 0;
13509
+
13510
+ /**
13511
+ * @brief Measure text without producing glyph positions.
13512
+ *
13513
+ * FlowPlot uses these metrics when resolving automatically sized text boxes. Return
13514
+ * dimensions in the same pixel coordinate system used by @ref layoutText.
13515
+ */
13478
13516
  virtual TextMeasurement measureText(
13479
13517
  std::string_view familyName,
13480
13518
  std::uint16_t weight,
13481
13519
  FontStyle style,
13482
13520
  float fontSizePx,
13483
13521
  std::string_view text) const = 0;
13522
+
13523
+ /**
13524
+ * @brief Lay out text and return glyph placements for rendering.
13525
+ *
13526
+ * Each placement is relative to the text origin. FlowPlot consumes the returned
13527
+ * metrics and placements directly when it constructs a TextCommand.
13528
+ * @param familyName Font family requested by the template.
13529
+ * @param weight Numeric font weight requested by the template.
13530
+ * @param style Font style requested by the template.
13531
+ * @param fontSizePx Font size in pixels.
13532
+ * @param text UTF-8 text to lay out.
13533
+ * @param maxWidth Maximum layout width in pixels, or infinity for unbounded text.
13534
+ */
13484
13535
  virtual LaidOutText layoutText(
13485
13536
  std::string_view familyName,
13486
13537
  std::uint16_t weight,
@@ -13556,11 +13607,47 @@ namespace FlowPlot
13556
13607
  std::vector<RenderCommand> commands{};
13557
13608
  };
13558
13609
 
13559
- inline FontStyle parseFontStyle(std::string_view rawStyle);
13560
- inline const char* fontStyleName(FontStyle style) noexcept;
13561
-
13562
13610
  } // namespace FlowPlot
13563
13611
 
13612
+ namespace FlowInternal
13613
+ {
13614
+ inline FlowPlot::FontStyle parseFontStyle(std::string_view rawStyle)
13615
+ {
13616
+ std::string style;
13617
+ style.reserve(rawStyle.size());
13618
+ for (const char c : rawStyle)
13619
+ {
13620
+ if (c >= 'A' && c <= 'Z')
13621
+ style.push_back(static_cast<char>(c - 'A' + 'a'));
13622
+ else
13623
+ style.push_back(c);
13624
+ }
13625
+
13626
+ if (style.empty() || style == "normal")
13627
+ return FlowPlot::FontStyle::Normal;
13628
+ if (style == "italic")
13629
+ return FlowPlot::FontStyle::Italic;
13630
+ if (style == "oblique")
13631
+ return FlowPlot::FontStyle::Oblique;
13632
+
13633
+ throw std::invalid_argument("parseFontStyle: unsupported font style '" + std::string(rawStyle) + "'");
13634
+ }
13635
+
13636
+ inline const char* fontStyleName(FlowPlot::FontStyle style) noexcept
13637
+ {
13638
+ switch (style)
13639
+ {
13640
+ case FlowPlot::FontStyle::Italic:
13641
+ return "italic";
13642
+ case FlowPlot::FontStyle::Oblique:
13643
+ return "oblique";
13644
+ case FlowPlot::FontStyle::Normal:
13645
+ default:
13646
+ return "normal";
13647
+ }
13648
+ }
13649
+ } // namespace FlowInternal
13650
+
13564
13651
  // ===== BEGIN inlined FlowPlot_Internal.hpp =====
13565
13652
 
13566
13653
  #include <cctype>
@@ -15084,7 +15171,7 @@ namespace FlowInternal
15084
15171
  textEngine,
15085
15172
  textSpec.fontFamily,
15086
15173
  textSpec.fontWeight,
15087
- FlowPlot::parseFontStyle(textSpec.fontStyle),
15174
+ FlowInternal::parseFontStyle(textSpec.fontStyle),
15088
15175
  textSpec.fontSize,
15089
15176
  textSpec.text,
15090
15177
  path);
@@ -15124,7 +15211,7 @@ namespace FlowInternal
15124
15211
  resolved.fontFamily = titleSpec.fontFamily;
15125
15212
  resolved.fontSize = titleSpec.fontSize;
15126
15213
  resolved.fontWeight = titleSpec.fontWeight;
15127
- resolved.fontStyle = FlowPlot::parseFontStyle(titleSpec.fontStyle);
15214
+ resolved.fontStyle = FlowInternal::parseFontStyle(titleSpec.fontStyle);
15128
15215
  resolved.color = parseColor(titleSpec.color, "figure.title.color");
15129
15216
  resolved.hAlign = parseHorizontalAlign(titleSpec.hAlign, "figure.title.hAlign");
15130
15217
  resolved.vAlign = parseVerticalAlign(titleSpec.vAlign, "figure.title.vAlign");
@@ -15160,7 +15247,7 @@ namespace FlowInternal
15160
15247
  textEngine,
15161
15248
  elementSpec.fontFamily,
15162
15249
  elementSpec.fontWeight,
15163
- FlowPlot::parseFontStyle(elementSpec.fontStyle),
15250
+ FlowInternal::parseFontStyle(elementSpec.fontStyle),
15164
15251
  elementSpec.fontSize,
15165
15252
  elementSpec.text,
15166
15253
  path + ".box");
@@ -15184,7 +15271,7 @@ namespace FlowInternal
15184
15271
  cache.label.fontFamily = elementSpec.fontFamily;
15185
15272
  cache.label.fontSize = elementSpec.fontSize;
15186
15273
  cache.label.fontWeight = elementSpec.fontWeight;
15187
- cache.label.fontStyle = FlowPlot::parseFontStyle(elementSpec.fontStyle);
15274
+ cache.label.fontStyle = FlowInternal::parseFontStyle(elementSpec.fontStyle);
15188
15275
  cache.label.color = parseColor(elementSpec.color, path + ".color");
15189
15276
  cache.label.clipToBox = elementSpec.clip;
15190
15277
  cache.label.box.w = textWidth;
@@ -15358,7 +15445,7 @@ namespace FlowInternal
15358
15445
  resolved.fontFamily = titleSpec.fontFamily;
15359
15446
  resolved.fontSize = titleSpec.fontSize;
15360
15447
  resolved.fontWeight = titleSpec.fontWeight;
15361
- resolved.fontStyle = FlowPlot::parseFontStyle(titleSpec.fontStyle);
15448
+ resolved.fontStyle = FlowInternal::parseFontStyle(titleSpec.fontStyle);
15362
15449
  resolved.color = parseColor(titleSpec.color, path + ".color");
15363
15450
  resolved.hAlign = parseHorizontalAlign(titleSpec.hAlign, path + ".hAlign");
15364
15451
  resolved.vAlign = parseVerticalAlign(titleSpec.vAlign, path + ".vAlign");
@@ -16316,7 +16403,7 @@ namespace FlowInternal
16316
16403
  textEngine,
16317
16404
  axisSpec.tickLabelFontFamily,
16318
16405
  axisSpec.tickLabelFontWeight,
16319
- FlowPlot::parseFontStyle(axisSpec.tickLabelFontStyle),
16406
+ FlowInternal::parseFontStyle(axisSpec.tickLabelFontStyle),
16320
16407
  axisSpec.tickLabelFontSize,
16321
16408
  tickText,
16322
16409
  path + ".tickLabels[" + std::to_string(majorIdx) + "]");
@@ -16358,7 +16445,7 @@ namespace FlowInternal
16358
16445
  textEngine,
16359
16446
  titleSpec.fontFamily,
16360
16447
  titleSpec.fontWeight,
16361
- FlowPlot::parseFontStyle(titleSpec.fontStyle),
16448
+ FlowInternal::parseFontStyle(titleSpec.fontStyle),
16362
16449
  titleSpec.fontSize,
16363
16450
  titleSpec.text,
16364
16451
  path + ".title.box");
@@ -16601,7 +16688,7 @@ namespace FlowInternal
16601
16688
  textEngine,
16602
16689
  axisSpec.tickLabelFontFamily,
16603
16690
  axisSpec.tickLabelFontWeight,
16604
- FlowPlot::parseFontStyle(axisSpec.tickLabelFontStyle),
16691
+ FlowInternal::parseFontStyle(axisSpec.tickLabelFontStyle),
16605
16692
  axisSpec.tickLabelFontSize,
16606
16693
  tickText,
16607
16694
  path + ".tickLabels[" + std::to_string(majorIdx) + "]");
@@ -16617,7 +16704,7 @@ namespace FlowInternal
16617
16704
  label.fontFamily = axisSpec.tickLabelFontFamily;
16618
16705
  label.fontSize = axisSpec.tickLabelFontSize;
16619
16706
  label.fontWeight = axisSpec.tickLabelFontWeight;
16620
- label.fontStyle = FlowPlot::parseFontStyle(axisSpec.tickLabelFontStyle);
16707
+ label.fontStyle = FlowInternal::parseFontStyle(axisSpec.tickLabelFontStyle);
16621
16708
  label.color = tickLabelColor;
16622
16709
  label.hAlign = FlowPlot::HorizontalAlign::Left;
16623
16710
  label.vAlign = FlowPlot::VerticalAlign::Top;
@@ -16657,7 +16744,7 @@ namespace FlowInternal
16657
16744
  textEngine,
16658
16745
  titleSpec.fontFamily,
16659
16746
  titleSpec.fontWeight,
16660
- FlowPlot::parseFontStyle(titleSpec.fontStyle),
16747
+ FlowInternal::parseFontStyle(titleSpec.fontStyle),
16661
16748
  titleSpec.fontSize,
16662
16749
  titleSpec.text,
16663
16750
  path + ".title.box");
@@ -16688,7 +16775,7 @@ namespace FlowInternal
16688
16775
  title.fontFamily = titleSpec.fontFamily;
16689
16776
  title.fontSize = titleSpec.fontSize;
16690
16777
  title.fontWeight = titleSpec.fontWeight;
16691
- title.fontStyle = FlowPlot::parseFontStyle(titleSpec.fontStyle);
16778
+ title.fontStyle = FlowInternal::parseFontStyle(titleSpec.fontStyle);
16692
16779
  title.color = parseColor(titleSpec.color, path + ".title.color");
16693
16780
  title.hAlign = parseHorizontalAlign(titleSpec.hAlign, path + ".title.hAlign");
16694
16781
  title.vAlign = parseVerticalAlign(titleSpec.vAlign, path + ".title.vAlign");
@@ -18359,42 +18446,23 @@ namespace FlowInternal
18359
18446
 
18360
18447
  namespace FlowPlot
18361
18448
  {
18362
- inline FontStyle parseFontStyle(std::string_view rawStyle)
18363
- {
18364
- std::string style;
18365
- style.reserve(rawStyle.size());
18366
- for (const char c : rawStyle)
18367
- {
18368
- if (c >= 'A' && c <= 'Z')
18369
- style.push_back(static_cast<char>(c - 'A' + 'a'));
18370
- else
18371
- style.push_back(c);
18372
- }
18373
-
18374
- if (style.empty() || style == "normal")
18375
- return FontStyle::Normal;
18376
- if (style == "italic")
18377
- return FontStyle::Italic;
18378
- if (style == "oblique")
18379
- return FontStyle::Oblique;
18380
-
18381
- throw std::invalid_argument("parseFontStyle: unsupported font style '" + std::string(rawStyle) + "'");
18382
- }
18383
-
18384
- inline const char* fontStyleName(FontStyle style) noexcept
18385
- {
18386
- switch (style)
18387
- {
18388
- case FontStyle::Italic:
18389
- return "italic";
18390
- case FontStyle::Oblique:
18391
- return "oblique";
18392
- case FontStyle::Normal:
18393
- default:
18394
- return "normal";
18395
- }
18396
- }
18397
-
18449
+ /**
18450
+ * @brief Register every font listed in a parsed FlowPlot template.
18451
+ *
18452
+ * Reads the optional top-level @c fonts array and registers each face with
18453
+ * @p textEngine. This is useful when an application manages an ITextEngine itself
18454
+ * rather than using the renderer-provided default.
18455
+ *
18456
+ * @code{.cpp}
18457
+ * FlowPlot::StbTextEngine fonts;
18458
+ * rapidjson::Document templateJson;
18459
+ * templateJson.Parse(R"({"fonts":[]})");
18460
+ * FlowPlot::registerFonts(fonts, templateJson);
18461
+ * @endcode
18462
+ * @param textEngine Text engine that will receive the registered font faces.
18463
+ * @param templateJson Parsed template JSON object containing an optional fonts array.
18464
+ * @throws std::runtime_error if the fonts array is malformed.
18465
+ */
18398
18466
  inline void registerFonts(ITextEngine& textEngine, const rapidjson::Value& templateJson)
18399
18467
  {
18400
18468
  if (!templateJson.IsObject())
@@ -18441,10 +18509,17 @@ namespace FlowPlot
18441
18509
  family,
18442
18510
  std::filesystem::path(fontPath),
18443
18511
  static_cast<std::uint16_t>(rawWeight),
18444
- parseFontStyle(style));
18512
+ FlowInternal::parseFontStyle(style));
18445
18513
  }
18446
18514
  }
18447
18515
 
18516
+ /**
18517
+ * @brief Parse a template JSON string and register every font listed in it.
18518
+ *
18519
+ * This overload parses @p templateJsonText and then behaves exactly like the
18520
+ * RapidJSON-value overload. Use it when the template has not already been parsed.
18521
+ * @throws std::runtime_error if the JSON cannot be parsed or the fonts array is malformed.
18522
+ */
18448
18523
  inline void registerFonts(ITextEngine& textEngine, std::string_view templateJsonText)
18449
18524
  {
18450
18525
  rapidjson::Document templateJson;
@@ -18468,6 +18543,23 @@ namespace FlowPlot
18468
18543
  friend PlotBuilder makePlot(const std::filesystem::path& path);
18469
18544
  friend PlotBuilder& plot(const std::filesystem::path& path);
18470
18545
 
18546
+ /**
18547
+ * @brief Set one template property to a scalar value.
18548
+ *
18549
+ * Property paths use dotted JSON paths and optional array indexes, for example
18550
+ * "figure.width" or "panels[0].axes.x.label".
18551
+ * The value is copied into the builder's template, so string arguments do not need
18552
+ * to outlive this call.
18553
+ *
18554
+ * @code{.cpp}
18555
+ * auto builder = FlowPlot::makePlot("Scatter")
18556
+ * .set("figure.width", 1280)
18557
+ * .set("panels[0].title.text", "Quarterly results");
18558
+ * @endcode
18559
+ *
18560
+ * @return This builder, so calls can be chained.
18561
+ * @throws std::invalid_argument if the property path is empty or invalid.
18562
+ */
18471
18563
  PlotBuilder& set(std::string_view property, value valueArg)
18472
18564
  {
18473
18565
  if (property.empty())
@@ -18516,6 +18608,21 @@ namespace FlowPlot
18516
18608
  return setJsonValue(property, std::move(normalizedValue));
18517
18609
  }
18518
18610
 
18611
+ /**
18612
+ * @brief Set one template property from a raw JSON value.
18613
+ *
18614
+ * Use this for arrays or objects that cannot be represented by FlowPlot::value.
18615
+ * FlowPlot parses and copies the value into its template; @p jsonText may therefore
18616
+ * be a temporary string.
18617
+ *
18618
+ * @code{.cpp}
18619
+ * builder.setJsonRaw("panels[0].axes.x.range", "[0.0, 100.0]");
18620
+ * @endcode
18621
+ *
18622
+ * @return This builder, so calls can be chained.
18623
+ * @throws std::invalid_argument if the property path is empty or invalid.
18624
+ * @throws std::runtime_error if jsonText is not a valid JSON value.
18625
+ */
18519
18626
  PlotBuilder& setJsonRaw(std::string_view property, std::string_view jsonText)
18520
18627
  {
18521
18628
  if (property.empty())
@@ -18679,6 +18786,26 @@ namespace FlowPlot
18679
18786
 
18680
18787
  public:
18681
18788
 
18789
+ /**
18790
+ * @brief Bind an external contiguous data span to a template dataset field.
18791
+ *
18792
+ * datasetField must use the form "dataset.field". The caller owns the data and
18793
+ * FlowPlot stores only a non-owning view of it.
18794
+ *
18795
+ * @warning @p data must remain valid and must not be reallocated until
18796
+ * getCommands() or writePng() has completed. Destroying, resizing, or moving its
18797
+ * backing storage first leaves the builder with a dangling view and causes invalid
18798
+ * plot execution.
18799
+ *
18800
+ * @code{.cpp}
18801
+ * std::vector<double> x{1.0, 2.0, 3.0};
18802
+ * auto builder = FlowPlot::makePlot("Scatter").withData("series.x", x);
18803
+ * FlowPlot::RenderPlot commands = builder.getCommands(); // x is still alive
18804
+ * @endcode
18805
+ *
18806
+ * @return This builder, so calls can be chained.
18807
+ * @throws std::invalid_argument if the field path or element type is unsupported.
18808
+ */
18682
18809
  template<typename T>
18683
18810
  PlotBuilder& withData(std::string_view datasetField, std::span<const T> data)
18684
18811
  {
@@ -18710,26 +18837,81 @@ namespace FlowPlot
18710
18837
  return *this;
18711
18838
  }
18712
18839
 
18840
+ /**
18841
+ * @brief Bind a std::vector to a template dataset field.
18842
+ *
18843
+ * This is a convenience overload for withData(datasetField, std::span<const T>).
18844
+ * It does not copy the vector's elements.
18845
+ *
18846
+ * @warning @p data must outlive getCommands() or writePng(), and it must not be
18847
+ * resized or otherwise reallocated before that operation completes. The builder
18848
+ * retains only @c data.data() and its element count.
18849
+ */
18713
18850
  template<typename T, typename Allocator>
18714
18851
  PlotBuilder& withData(std::string_view datasetField, const std::vector<T, Allocator>& data)
18715
18852
  {
18716
18853
  return withData<T>(datasetField, std::span<const T>(data.data(), data.size()));
18717
18854
  }
18718
18855
 
18856
+ /**
18857
+ * @brief Set the text engine used for font registration, text measurement, and rendering.
18858
+ *
18859
+ * The text engine is referenced, not copied, and must outlive calls to getCommands()
18860
+ * or writePng(). With FLOW_PLOT_RENDERER enabled, omitting this call selects a
18861
+ * temporary default StbTextEngine and automatically registers template fonts.
18862
+ * Provide an engine explicitly to reuse registered fonts or use a custom backend.
18863
+ *
18864
+ * @warning @p textEngine must remain alive until getCommands() or writePng() has
18865
+ * completed. The builder stores a non-owning pointer; destroying the engine first
18866
+ * leaves it dangling and causes invalid plot execution.
18867
+ *
18868
+ * @code{.cpp}
18869
+ * FlowPlot::StbTextEngine fonts{"/path/to/default.ttf"};
18870
+ * auto builder = FlowPlot::makePlot("Report").useTextEngine(fonts);
18871
+ * auto commands = builder.getCommands();
18872
+ * @endcode
18873
+ *
18874
+ * @return This builder, so calls can be chained.
18875
+ */
18719
18876
  PlotBuilder& useTextEngine(const ITextEngine& textEngine)
18720
18877
  {
18721
18878
  textEngine_ = &textEngine;
18722
18879
  return *this;
18723
18880
  }
18724
18881
 
18882
+ /**
18883
+ * @brief Register this template's fonts into the supplied text engine.
18884
+ *
18885
+ * This is useful when the application owns the text engine and wants FlowPlot to
18886
+ * load the template's fonts before rendering. It is not necessary when using the
18887
+ * default renderer text engine, because that registration happens automatically.
18888
+ */
18725
18889
  void registerTemplateFonts(ITextEngine& textEngine) const
18726
18890
  {
18727
18891
  registerFonts(textEngine, template_);
18728
18892
  }
18729
18893
 
18894
+ /**
18895
+ * @brief Compile the current template and bound data into renderer-independent commands.
18896
+ *
18897
+ * This resolves template defaults, data bindings, plot geometry, and text layout.
18898
+ * Use the returned commands with a custom renderer, or call writePng() when the
18899
+ * built-in renderer is enabled.
18900
+ * @return A RenderPlot containing plot dimensions, background, and drawing commands.
18901
+ * @throws std::runtime_error if the template, data bindings, or text setup are invalid.
18902
+ */
18730
18903
  RenderPlot getCommands() const;
18731
18904
 
18732
18905
  #ifdef FLOW_PLOT_RENDERER
18906
+ /**
18907
+ * @brief Render the current plot directly to a PNG file.
18908
+ *
18909
+ * This performs the same compilation as getCommands() and rasterizes the result with
18910
+ * the built-in renderer. If no text engine was supplied, it uses the temporary
18911
+ * StbTextEngine described in @ref ITextEngine.
18912
+ * @param outputPath Destination .png path.
18913
+ * @throws std::runtime_error if rendering, font setup, or file writing fails.
18914
+ */
18733
18915
  void writePng(const std::filesystem::path& outputPath) const;
18734
18916
  #endif
18735
18917
 
@@ -18739,6 +18921,23 @@ namespace FlowPlot
18739
18921
  const ITextEngine* textEngine_ = nullptr;
18740
18922
  };
18741
18923
 
18924
+ /**
18925
+ * @brief Load a JSON template and return an independent PlotBuilder by value.
18926
+ *
18927
+ * If path has no .json extension, ".json" is appended. Use this form when you want
18928
+ * multiple independent builders, need to keep a builder beyond another plot request,
18929
+ * or wrap FlowPlot from another language. The returned builder owns its template and
18930
+ * can be moved or stored normally.
18931
+ *
18932
+ * @code{.cpp}
18933
+ * auto left = FlowPlot::makePlot("Scatter");
18934
+ * auto right = FlowPlot::makePlot("Histogram");
18935
+ * left.withData("series.x", leftData);
18936
+ * right.withData("bins.values", rightData);
18937
+ * @endcode
18938
+ *
18939
+ * @throws std::runtime_error if the template file cannot be opened or parsed.
18940
+ */
18742
18941
  inline PlotBuilder makePlot(const std::filesystem::path& path)
18743
18942
  {
18744
18943
  std::filesystem::path jsonPath = path;
@@ -18773,6 +18972,27 @@ namespace FlowPlot
18773
18972
  return builder;
18774
18973
  }
18775
18974
 
18975
+ /**
18976
+ * @brief Load a JSON template into a thread-local builder and return it by reference.
18977
+ *
18978
+ * This supports compact chaining such as FlowPlot::plot("Scatter").withData(...).
18979
+ * Each call replaces the previous thread-local builder for the current thread. It is
18980
+ * convenient for one immediate build operation, but references and pointers to a
18981
+ * previous result become invalid after the next plot() call on that thread.
18982
+ *
18983
+ * The builder is thread-local: different threads receive different builders and do not
18984
+ * overwrite each other. Use makePlot() instead when two builders must coexist on the
18985
+ * same thread, when a builder must be retained, or when explicit ownership is clearer.
18986
+ *
18987
+ * @code{.cpp}
18988
+ * const auto commands = FlowPlot::plot("Scatter")
18989
+ * .withData("series.x", x)
18990
+ * .withData("series.y", y)
18991
+ * .getCommands();
18992
+ * @endcode
18993
+ *
18994
+ * @throws std::runtime_error if the template file cannot be opened or parsed.
18995
+ */
18776
18996
  inline PlotBuilder& plot(const std::filesystem::path& path)
18777
18997
  {
18778
18998
  static thread_local PlotBuilder builder;
@@ -18792,6 +19012,21 @@ namespace FlowPlot
18792
19012
  #endif
18793
19013
 
18794
19014
  #ifdef FLOW_PLOT_COMPLETE_JSON
19015
+ /**
19016
+ * @brief Expand a template JSON string with FlowPlot defaults.
19017
+ *
19018
+ * The input is normalized using the same defaulting rules applied during plot
19019
+ * compilation. This is useful for inspecting the effective template or persisting a
19020
+ * fully specified template.
19021
+ *
19022
+ * @code{.cpp}
19023
+ * std::string complete = FlowPlot::getCompleteJson(R"({"figure":{"width":800}})");
19024
+ * @endcode
19025
+ * @param templateJsonText Template JSON document.
19026
+ * @param pretty Whether to format the returned JSON with indentation.
19027
+ * @return A complete JSON template string with defaults filled in.
19028
+ * @throws std::runtime_error if the input JSON cannot be parsed.
19029
+ */
18795
19030
  inline std::string getCompleteJson(std::string_view templateJsonText, bool pretty = true)
18796
19031
  {
18797
19032
  rapidjson::Document templateJson;
@@ -26102,7 +26337,7 @@ namespace FlowPlot
26102
26337
  throw std::runtime_error(
26103
26338
  "StbTextEngine: no registered font for family '" + std::string(familyName) +
26104
26339
  "', weight " + std::to_string(weight) +
26105
- ", style '" + fontStyleName(style) +
26340
+ ", style '" + FlowInternal::fontStyleName(style) +
26106
26341
  "', and no registered 'Default' fallback");
26107
26342
  }
26108
26343
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: FlowPlotPy
3
- Version: 0.9.6
3
+ Version: 0.9.7
4
4
  Summary: Python bindings for the FlowPlot plotting library
5
5
  Author: FlowPlot contributors
6
6
  License: MIT License
@@ -163,7 +163,7 @@ namespace
163
163
  out["font_family"] = command.fontFamily;
164
164
  out["font_size"] = command.fontSize;
165
165
  out["font_weight"] = command.fontWeight;
166
- out["font_style"] = FlowPlot::fontStyleName(command.fontStyle);
166
+ out["font_style"] = FlowInternal::fontStyleName(command.fontStyle);
167
167
  out["h_align"] = horizontalAlignName(command.hAlign);
168
168
  out["v_align"] = verticalAlignName(command.vAlign);
169
169
  out["clip_to_box"] = command.clipToBox;
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "FlowPlotPy"
7
- version = "0.9.6"
7
+ version = "0.9.7"
8
8
  description = "Python bindings for the FlowPlot plotting library"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
File without changes
File without changes
File without changes