From 2e5cb814c7c19c8c8727c3056ddee0ff2c47b529 Mon Sep 17 00:00:00 2001 From: yoshibox Date: Fri, 25 Apr 2025 14:39:14 +0200 Subject: [PATCH 1/4] Update to Zig 0.14 --- build.zig | 2 +- build.zig.zon | 5 +++-- example/scatter.zig | 4 ++-- src/core/intf.zig | 24 ++++++++++++------------ src/util/range.zig | 4 ++-- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/build.zig b/build.zig index 8fd1daf..f0fdb85 100644 --- a/build.zig +++ b/build.zig @@ -73,7 +73,7 @@ pub fn build(b: *std.Build) void { .optimize = optimize, }); - const lib_module = &lib.root_module; + const lib_module = lib.root_module; _ = b.addModule("zigplotlib", .{ .root_source_file = b.path("src/root.zig"), diff --git a/build.zig.zon b/build.zig.zon index 09f8213..81e2378 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,7 +1,8 @@ .{ - .name = "zigplotlib", + .name = .zigplotlib, .version = "0.1.4", - .minimum_zig_version = "0.13.0", + .fingerprint = 0x1220c9f9d7b4cb25, + .minimum_zig_version = "0.14.0", .dependencies = .{}, .paths = .{ diff --git a/example/scatter.zig b/example/scatter.zig index 2def7c4..2e882e8 100644 --- a/example/scatter.zig +++ b/example/scatter.zig @@ -14,7 +14,7 @@ pub fn main() !void { defer _ = gpa.deinit(); const allocator = gpa.allocator(); - var xoshiro = std.rand.Xoshiro256.init(100); + var xoshiro = std.Random.Xoshiro256.init(100); var rand = xoshiro.random(); var x: [28]f32 = undefined; @@ -65,4 +65,4 @@ pub fn main() !void { defer file.close(); try svg.writeTo(file.writer()); -} \ No newline at end of file +} diff --git a/src/core/intf.zig b/src/core/intf.zig index 23f0ddc..870a1b7 100644 --- a/src/core/intf.zig +++ b/src/core/intf.zig @@ -13,32 +13,32 @@ fn checkFunctionImplementation( const Function = Field.type; const function = @typeInfo(Function); - if (function != .Fn) @compileError("The Interface should only contains functions (as field)"); - if (function.Fn.is_generic) @compileError("Generic functions are not supported!"); - if (function.Fn.is_var_args) @compileError("Variadic functions are not supported!"); + if (function != .@"fn") @compileError("The Interface should only contains functions (as field)"); + if (function.@"fn".is_generic) @compileError("Generic functions are not supported!"); + if (function.@"fn".is_var_args) @compileError("Variadic functions are not supported!"); const actual = @typeInfo(Actual); - if (actual != .Struct) @compileError(comptimePrint("'{s}' should be a struct that implements '{s}'", .{ + if (actual != .@"struct") @compileError(comptimePrint("'{s}' should be a struct that implements '{s}'", .{ @typeName(Actual), @typeName(Interface), })); - inline for (actual.Struct.decls) |decl| { + inline for (actual.@"struct".decls) |decl| { if (comptime std.mem.eql(u8, decl.name, Field.name)) { const decl_ = @field(Actual, decl.name); const Decl = @TypeOf(decl_); const decl_info = @typeInfo(Decl); - if (decl_info != .Fn) @compileError(comptimePrint("Invalid Type for '{s}', should be {s}", .{ + if (decl_info != .@"fn") @compileError(comptimePrint("Invalid Type for '{s}', should be {s}", .{ Field.name, @typeName(Function), })); - if (decl_info.Fn.is_generic or decl_info.Fn.is_var_args) @compileError(comptimePrint("Invalid Type for '{s}', should be {s}", .{ + if (decl_info.@"fn".is_generic or decl_info.@"fn".is_var_args) @compileError(comptimePrint("Invalid Type for '{s}', should be {s}", .{ Field.name, @typeName(Function), })); - inline for (function.Fn.params, decl_info.Fn.params, 0..) |expected_param, actual_param, i| { + inline for (function.@"fn".params, decl_info.@"fn".params, 0..) |expected_param, actual_param, i| { if (i == 0) { if (expected_param.type == *const anyopaque) { if (actual_param.type != *const Actual) @compileError(comptimePrint("'self' (the 1st argument) should be of type '*const {s}'\nDefinition for '{s}':\n{s}", .{ @@ -66,7 +66,7 @@ fn checkFunctionImplementation( })); } - if (function.Fn.return_type != decl_info.Fn.return_type) @compileError(comptimePrint("Invalid return type for '{s}', should be {s}\nDefinition for '{s}':\n{s}", .{ + if (function.@"fn".return_type != decl_info.@"fn".return_type) @compileError(comptimePrint("Invalid return type for '{s}', should be {s}\nDefinition for '{s}':\n{s}", .{ Field.name, @typeName(Function), Field.name, @@ -93,9 +93,9 @@ pub fn ensureImplement( ) void { const interface = @typeInfo(Interface); - if (interface != .Struct) @compileError("The Interface should be a struct containing the functions as fields"); + if (interface != .@"struct") @compileError("The Interface should be a struct containing the functions as fields"); - inline for (interface.Struct.fields) |field| { + inline for (interface.@"struct".fields) |field| { checkFunctionImplementation(Interface, field, Actual); } -} \ No newline at end of file +} diff --git a/src/util/range.zig b/src/util/range.zig index cb86b66..8d6add2 100644 --- a/src/util/range.zig +++ b/src/util/range.zig @@ -18,7 +18,7 @@ pub fn Range(comptime T: type) type { /// Initialize a range with the minimum and maximum values set to the same value. [-∞; ∞] pub fn inf() Self { - if (@typeInfo(T) != .Float) @compileError("Only floating point types can have infinite ranges"); + if (@typeInfo(T) != .@"float") @compileError("Only floating point types can have infinite ranges"); return Self{ .min = -std.math.inf(T), @@ -28,7 +28,7 @@ pub fn Range(comptime T: type) type { /// Initialize a range with the minimum and maximum values set to the same value. [∞; -∞] pub fn invInf() Self { - if (@typeInfo(T) != .Float) @compileError("Only floating point types can have infinite ranges"); + if (@typeInfo(T) != .@"float") @compileError("Only floating point types can have infinite ranges"); return Self{ .min = std.math.inf(T), From 814432491ea9637f426b8cdff2c7367ce631ba6c Mon Sep 17 00:00:00 2001 From: yoshibox Date: Thu, 23 Oct 2025 12:18:28 +0200 Subject: [PATCH 2/4] Zig 0.15 --- build.zig | 35 +++++++++++------- build.zig.zon | 2 +- example/area.zig | 8 +++- example/candle_stick.zig | 6 ++- example/line.zig | 6 ++- example/logarithmic.zig | 6 ++- example/out/area.svg | 4 +- example/out/candlestick.svg | 24 ++++++------ example/out/line.svg | 6 +-- example/out/logarithmic.svg | 4 +- example/out/scatter.svg | 4 +- example/out/stem.svg | 4 +- example/out/step.svg | 4 +- example/scatter.zig | 6 ++- example/stem.zig | 8 +++- example/step.zig | 8 +++- out.svg | 4 +- readme.md | 34 ++++++++++++++--- src/main.zig | 6 ++- src/plot/Area.zig | 26 ++++++------- src/plot/Figure.zig | 74 ++++++++++++++++++++----------------- src/plot/Line.zig | 10 ++--- src/plot/formatters.zig | 10 ++--- src/svg/Circle.zig | 10 ++--- src/svg/Line.zig | 18 ++++----- src/svg/Path.zig | 2 +- src/svg/Polyline.zig | 2 +- src/svg/Rect.zig | 16 ++++---- src/svg/SVG.zig | 11 +++--- src/svg/Text.zig | 38 ++++++++----------- src/svg/util/length.zig | 10 ++--- 31 files changed, 231 insertions(+), 175 deletions(-) diff --git a/build.zig b/build.zig index f0fdb85..2d0116c 100644 --- a/build.zig +++ b/build.zig @@ -11,9 +11,11 @@ fn addStartPoint( ) *std.Build.Step { const exe = b.addExecutable(.{ .name = name, - .root_source_file = b.path(path), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path(path), + .target = target, + .optimize = optimize, + }), }); exe.root_module.addImport("zigplotlib", module); @@ -64,13 +66,16 @@ pub fn build(b: *std.Build) void { // set a preferred release mode, allowing the user to decide how to optimize. const optimize = b.standardOptimizeOption(.{}); - const lib = b.addStaticLibrary(.{ + const lib = b.addLibrary(.{ .name = "zigplotlib", + .linkage = .static, // In this case the main source file is merely a path, however, in more // complicated build scripts, this could be a generated file. - .root_source_file = b.path("src/root.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("src/root.zig"), + .target = target, + .optimize = optimize, + }), }); const lib_module = lib.root_module; @@ -106,17 +111,21 @@ pub fn build(b: *std.Build) void { // Creates a step for unit testing. This only builds the test executable // but does not run it. const lib_unit_tests = b.addTest(.{ - .root_source_file = b.path("src/root.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }), }); const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests); const exe_unit_tests = b.addTest(.{ - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }), }); const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); diff --git a/build.zig.zon b/build.zig.zon index 81e2378..162f15b 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -2,7 +2,7 @@ .name = .zigplotlib, .version = "0.1.4", .fingerprint = 0x1220c9f9d7b4cb25, - .minimum_zig_version = "0.14.0", + .minimum_zig_version = "0.15.2", .dependencies = .{}, .paths = .{ diff --git a/example/area.zig b/example/area.zig index bf42864..eb2377f 100644 --- a/example/area.zig +++ b/example/area.zig @@ -52,5 +52,9 @@ pub fn main() !void { var file = try std.fs.cwd().createFile("example/out/area.svg", .{}); defer file.close(); - try svg.writeTo(file.writer()); -} \ No newline at end of file + var file_buffer: [1024]u8 = undefined; + var file_writer = file.writer(&file_buffer); + const file_int = &file_writer.interface; + + try svg.writeTo(file_int); +} diff --git a/example/candle_stick.zig b/example/candle_stick.zig index dbd6f1d..f8a316f 100644 --- a/example/candle_stick.zig +++ b/example/candle_stick.zig @@ -100,5 +100,9 @@ pub fn main() !void { var file = try std.fs.cwd().createFile("example/out/candlestick.svg", .{}); defer file.close(); - try svg.writeTo(file.writer()); + var file_buffer: [1024]u8 = undefined; + var file_writer = file.writer(&file_buffer); + const file_int = &file_writer.interface; + + try svg.writeTo(file_int); } diff --git a/example/line.zig b/example/line.zig index b861de9..e351462 100644 --- a/example/line.zig +++ b/example/line.zig @@ -72,5 +72,9 @@ pub fn main() !void { var file = try std.fs.cwd().createFile("example/out/line.svg", .{}); defer file.close(); - try svg.writeTo(file.writer()); + var file_buffer: [1024]u8 = undefined; + var file_writer = file.writer(&file_buffer); + const file_int = &file_writer.interface; + + try svg.writeTo(file_int); } diff --git a/example/logarithmic.zig b/example/logarithmic.zig index 7ca67d5..036b46d 100644 --- a/example/logarithmic.zig +++ b/example/logarithmic.zig @@ -71,5 +71,9 @@ pub fn main() !void { var file = try std.fs.cwd().createFile("example/out/logarithmic.svg", .{}); defer file.close(); - try svg.writeTo(file.writer()); + var file_buffer: [1024]u8 = undefined; + var file_writer = file.writer(&file_buffer); + const file_int = &file_writer.interface; + + try svg.writeTo(file_int); } diff --git a/example/out/area.svg b/example/out/area.svg index 321cb69..f7f39d8 100644 --- a/example/out/area.svg +++ b/example/out/area.svg @@ -1,7 +1,7 @@ - + @@ -20,7 +20,7 @@ - + 0.00 4.50 9.00 diff --git a/example/out/candlestick.svg b/example/out/candlestick.svg index 4bd3afc..5f5f843 100644 --- a/example/out/candlestick.svg +++ b/example/out/candlestick.svg @@ -1,30 +1,30 @@ - + CandleStick example - + - + - + - + - + - + - + - + - + - + - + 0.81 1.24 1.68 diff --git a/example/out/line.svg b/example/out/line.svg index c77cc9a..56623a8 100644 --- a/example/out/line.svg +++ b/example/out/line.svg @@ -1,7 +1,7 @@ - + @@ -20,7 +20,7 @@ - + 0.00 4.67 9.33 @@ -38,5 +38,5 @@ -1.10 -Bottom +Bottom \ No newline at end of file diff --git a/example/out/logarithmic.svg b/example/out/logarithmic.svg index ea728b4..f4c8321 100644 --- a/example/out/logarithmic.svg +++ b/example/out/logarithmic.svg @@ -1,7 +1,7 @@ - + @@ -17,7 +17,7 @@ - + 0.00 2.00 4.00 diff --git a/example/out/scatter.svg b/example/out/scatter.svg index c2e89f3..14e9491 100644 --- a/example/out/scatter.svg +++ b/example/out/scatter.svg @@ -1,7 +1,7 @@ - + @@ -70,7 +70,7 @@ - + 0.00 4.67 9.33 diff --git a/example/out/stem.svg b/example/out/stem.svg index bd8f019..0374723 100644 --- a/example/out/stem.svg +++ b/example/out/stem.svg @@ -1,7 +1,7 @@ - + @@ -48,7 +48,7 @@ - + 0.00 2.33 4.67 diff --git a/example/out/step.svg b/example/out/step.svg index 1bf8029..ce4475f 100644 --- a/example/out/step.svg +++ b/example/out/step.svg @@ -1,7 +1,7 @@ - + @@ -61,7 +61,7 @@ - + 0.00 2.33 4.67 diff --git a/example/scatter.zig b/example/scatter.zig index 2e882e8..21b4969 100644 --- a/example/scatter.zig +++ b/example/scatter.zig @@ -64,5 +64,9 @@ pub fn main() !void { var file = try std.fs.cwd().createFile("example/out/scatter.svg", .{}); defer file.close(); - try svg.writeTo(file.writer()); + var file_buffer: [1024]u8 = undefined; + var file_writer = file.writer(&file_buffer); + const file_int = &file_writer.interface; + + try svg.writeTo(file_int); } diff --git a/example/stem.zig b/example/stem.zig index d77d0d5..492d937 100644 --- a/example/stem.zig +++ b/example/stem.zig @@ -47,5 +47,9 @@ pub fn main() !void { var file = try std.fs.cwd().createFile("example/out/stem.svg", .{}); defer file.close(); - try svg.writeTo(file.writer()); -} \ No newline at end of file + var file_buffer: [1024]u8 = undefined; + var file_writer = file.writer(&file_buffer); + const file_int = &file_writer.interface; + + try svg.writeTo(file_int); +} diff --git a/example/step.zig b/example/step.zig index 329b51c..53cfe06 100644 --- a/example/step.zig +++ b/example/step.zig @@ -66,5 +66,9 @@ pub fn main() !void { var file = try std.fs.cwd().createFile("example/out/step.svg", .{}); defer file.close(); - try svg.writeTo(file.writer()); -} \ No newline at end of file + var file_buffer: [1024]u8 = undefined; + var file_writer = file.writer(&file_buffer); + const file_int = &file_writer.interface; + + try svg.writeTo(file_int); +} diff --git a/out.svg b/out.svg index baaa6a4..b24ab57 100644 --- a/out.svg +++ b/out.svg @@ -1,7 +1,7 @@ - + Example plot @@ -49,7 +49,7 @@ - + 0.00 4.00 8.00 diff --git a/readme.md b/readme.md index f2a4a4d..d58fcf9 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,5 @@ # Zig Plot Lib +> > This project is currently stalled as I don't have much time to work on it. Anybody can freely create a PR to add new features and I'll review it; or you can also fork it yourself and add whatever you would like. The Zig Plot Lib is a library for plotting data in Zig. It is designed to be easy to use and to have a simple API. @@ -8,7 +9,9 @@ The Zig Plot Lib is a library for plotting data in Zig. It is designed to be eas I'm developping this library with version 0.13.0. ## Installation + You can install the library by adding it to the `build.zig.zon` file, either manually like so: + ```zig .{ ... @@ -23,16 +26,19 @@ You can install the library by adding it to the `build.zig.zon` file, either man ``` The hash can be found using the builtin command: + ```sh zig fetch https://github.com/Remy2701/zigplotlib/archive/main.tar.gz ``` Or you can also add it automatically like so: + ```sh zig fetch --save https://github.com/Remy2701/zigplotlib/archive/main.tar.gz ``` Then in the `build.zig`, you can add the following: + ```zig const zigplotlib = b.dependency("zigplotlib", .{ .target = target, @@ -45,6 +51,7 @@ exe.root_module.addImport("plotlib", zigplotlib.module("zigplotlib")); The name of the module (`plotlib`) can be changed to whatever you want. Finally in your code you can import the module using the following: + ```zig const plotlib = @import("plotlib"); ``` @@ -151,7 +158,11 @@ pub fn main() !void { var file = try std.fs.cwd().createFile("out.svg", .{}); defer file.close(); - try svg.writeTo(file.writer()); + var file_buffer: [1024]u8 = undefined; + var file_writer = file.writer(&file_buffer); + const file_int = &file_writer.interface; + + try svg.writeTo(file_int); } ``` @@ -188,6 +199,7 @@ The figure takes two arguments, the allocator (used to store the plot and genera | `legend` | `...` | The style for the legend | The `title` option contains the following parameters: + | Option | Type | Description | | --- | --- | --- | | `text` | `[]const u8` | The title of the figure | @@ -197,6 +209,7 @@ The `title` option contains the following parameters: | `padding` | `f32` | The padding between the plot and the title | The `value_padding` option is defined like so: + ```zig pub const ValuePercent = union(enum) { value: f32, @@ -223,7 +236,7 @@ The `axis` option contains more parameters: | `width` | `f32` | The width of the axis | | `label_color` | `RGB (u48)` | The color of the labels | | `label_size` | `f32` | The font size of the labels | -| `label_padding` | `f32` | The padding between the labels and the axis | +| `label_padding` | `f32` | The padding between the labels and the axis | | `label_font` | `[]const u8` | The font to use for the labels | | `tick_count_x` | `...` | The number of ticks to use on the x axis | | `tick_count_y` | `...` | The number of ticks to use on the y axis | @@ -236,6 +249,7 @@ The `axis` option contains more parameters: | `frame_width` | `f32` | The width of the frame | The `tick_count_x` and `tick_count_y` options are defined like so: + ```zig tick_count_x: union(enum) { count: usize, @@ -317,7 +331,7 @@ The available shapes are: | Shape | Description | | --- | --- | | `circle` | A circle | -| `circle_outline` | The outline of a circle | +| `circle_outline` | The outline of a circle | | `square` | A square | | `square_outline` | The outline of a square | | `triangle` | A triangle (facing upwards) | @@ -383,10 +397,12 @@ The parameters for the candle are as follows: | `color` | `?RGB (u48)` | The color of the candle (overrides the default one) | ## Supported Markers + You can add a marker to the plot using the `addMarker` function. There are currently 2 types of markers supported: ### ShapeMarker + The shape marker allows you to write the plot with a shape. The options for the shape marker are: @@ -403,8 +419,8 @@ The options for the shape marker are: | `label_size` | `f32` | The size of the label | | `label_weight` | `FontWeight` | The weight of the label | - ### TextMarker + The Text marker is similar to the shape marker, but there is no shape, only text. The options for the text marker are: @@ -419,6 +435,7 @@ The options for the text marker are: | `weight` | `FontWeight` | The weight of the text | ## Create a new plot type + In order to create a new type of plot, all that is needed is to create a struct that contains an `interface` function, defined as follows: ```zig @@ -428,6 +445,7 @@ pub fn interface(self: *const Self) Plot { ``` The `Plot` object, contains the following fields: + - a pointer to the data (`*const anyopaque`) - the title of the plot (`?[]const u8`) (used for the legend) - the color of the plot (`RGB (u48)`) (used for the legend) @@ -438,6 +456,7 @@ The `Plot` object, contains the following fields: You can look at the implementation of the `Line`, `Scatter`, `Area`, `Step`, `Stem`, or `CandleStick` plots for examples. ## Create a new marker type + Same as for the plots, to create a new type of marker, all that is needed is to create a struct that contains an `interface` function, defined as follows: ```zig @@ -447,19 +466,22 @@ pub fn interface(self: *const Self) Marker { ``` The `Marker` object, contains the following fields: + - a pointer to the data (`*const anyopaque`) - a pointer to the draw function `*const fn(*const anyopaque, Allocator, *SVG, FigureInfo) anyerror!void` You can look at the implementation of the `ShapeMarker` or `TextMarker` for examples. ## Roadmap + - Ability to set the title of the axis - Ability to add arrows at the end of axis - More plot types - - Bar - - Histogram + - Bar + - Histogram - Linear Interpolation with the figure border - Themes ### Known issue(s) + - Imperfect text width calculation for the legend (only when the legend is positioned on the right) diff --git a/src/main.zig b/src/main.zig index b728b6f..1122772 100644 --- a/src/main.zig +++ b/src/main.zig @@ -78,5 +78,9 @@ pub fn main() !void { var file = try std.fs.cwd().createFile("out.svg", .{}); defer file.close(); - try svg.writeTo(file.writer()); + var file_buffer: [1024]u8 = undefined; + var file_writer = file.writer(&file_buffer); + const file_int = &file_writer.interface; + + try svg.writeTo(file_int); } diff --git a/src/plot/Area.zig b/src/plot/Area.zig index c80fa7b..9522c89 100644 --- a/src/plot/Area.zig +++ b/src/plot/Area.zig @@ -63,8 +63,8 @@ fn draw(impl: *const anyopaque, allocator: Allocator, svg: *SVG, info: FigureInf const self: *const Area = @ptrCast(@alignCast(impl)); if (self.x) |x_| { - var points = std.ArrayList(f32).init(allocator); - try points.appendSlice(&[_]f32 {info.computeX(x_[0]), info.getBaseY()}); + var points = std.ArrayList(f32).empty; + try points.appendSlice(allocator, &[_]f32 {info.computeX(x_[0]), info.getBaseY()}); var last_x: ?f32 = null; for (x_, self.y) |x, y| { if (!info.x_range.contains(x)) continue; @@ -77,21 +77,21 @@ fn draw(impl: *const anyopaque, allocator: Allocator, svg: *SVG, info: FigureInf const x2 = info.computeX(x); const y2 = info.computeY(y); - try points.append(x2); - try points.append(y2); + try points.append(allocator, x2); + try points.append(allocator, y2); } - if (last_x) |last_x_| try points.appendSlice(&[_]f32 {info.computeX(last_x_), info.getBaseY()}); + if (last_x) |last_x_| try points.appendSlice(svg.allocator, &[_]f32 {info.computeX(last_x_), info.getBaseY()}); try svg.addPolyline(.{ - .points = try points.toOwnedSlice(), + .points = try points.toOwnedSlice(allocator), .fill = self.style.color, .fill_opacity = self.style.opacity, .stroke = self.style.color, .stroke_width = .{ .pixel = self.style.width }, }); } else { - var points = std.ArrayList(f32).init(allocator); - try points.appendSlice(&[_]f32 {info.computeX(0.0), info.getBaseY()}); + var points = std.ArrayList(f32).empty; + try points.appendSlice(allocator, &[_]f32 {info.computeX(0.0), info.getBaseY()}); var last_x: ?f32 = null; for (self.y, 0..) |y, x| { if (!info.x_range.contains(@floatFromInt(x))) continue; @@ -104,13 +104,13 @@ fn draw(impl: *const anyopaque, allocator: Allocator, svg: *SVG, info: FigureInf const x2 = info.computeX(@floatFromInt(x)); const y2 = info.computeY(y); - try points.append(x2); - try points.append(y2); + try points.append(allocator, x2); + try points.append(allocator, y2); } - if (last_x) |last_x_| try points.appendSlice(&[_]f32 {info.computeX(last_x_), info.getBaseY()}); + if (last_x) |last_x_| try points.appendSlice(allocator, &[_]f32 {info.computeX(last_x_), info.getBaseY()}); try svg.addPolyline(.{ - .points = try points.toOwnedSlice(), + .points = try points.toOwnedSlice(allocator), .fill = self.style.color, .fill_opacity = self.style.opacity, .stroke = self.style.color, @@ -129,4 +129,4 @@ pub fn interface(self: *const Area) Plot { &getYRange, &draw ); -} \ No newline at end of file +} diff --git a/src/plot/Figure.zig b/src/plot/Figure.zig index 9631693..4aa0def 100644 --- a/src/plot/Figure.zig +++ b/src/plot/Figure.zig @@ -108,9 +108,9 @@ pub const Style = struct { /// Whether to show the labels on the y-axis show_y_labels: bool = true, /// The formatter for the data on the x-axis - x_labels_formatter: ?*const fn (*std.ArrayList(u8), f32) anyerror!void = null, + x_labels_formatter: ?*const fn (Allocator, *std.ArrayList(u8), f32) anyerror!void = null, /// The formatter for the data on the y-axis - y_labels_formatter: ?*const fn (*std.ArrayList(u8), f32) anyerror!void = null, + y_labels_formatter: ?*const fn (Allocator, *std.ArrayList(u8), f32) anyerror!void = null, /// Whether to show the grid on the x-axis show_grid_x: bool = true, /// Whether to show the grid on the y-axis @@ -157,30 +157,30 @@ pub fn init(allocator: Allocator, style: Style) Figure { return Figure{ .allocator = allocator, .arena = std.heap.ArenaAllocator.init(allocator), - .plots = Plot.List.init(allocator), - .markers = Marker.List.init(allocator), + .plots = .empty, + .markers = .empty, .style = style, }; } /// Deinitialize the figure. -pub fn deinit(self: *const Figure) void { +pub fn deinit(self: *Figure) void { self.arena.deinit(); - self.plots.deinit(); - self.markers.deinit(); + self.plots.deinit(self.allocator); + self.markers.deinit(self.allocator); } /// Add a plot to the figure, the given `plot` should be of type `Plot` or have the interface method that returns a /// `Plot`. pub fn addPlot(self: *Figure, plot: anytype) !void { if (@TypeOf(plot) == Plot) { - try self.plots.append(plot); + try self.plots.append(self.allocator, plot); } else { intf.ensureImplement(struct { interface: fn (*const anyopaque) Plot }, @TypeOf(plot)); const mem = try self.arena.allocator().create(@TypeOf(plot)); mem.* = plot; - try self.plots.append(mem.interface()); + try self.plots.append(self.allocator, mem.interface()); } } @@ -194,7 +194,7 @@ pub fn addMarker(self: *Figure, marker: anytype) !void { const mem = try self.arena.allocator().create(@TypeOf(marker)); mem.* = marker; - try self.markers.append(mem.interface()); + try self.markers.append(self.allocator, mem.interface()); } } @@ -563,12 +563,12 @@ fn drawYLabelsLinear(self: *Figure, svg: *SVG, info: FigureInfo) !void { const y_value = info.computeYInv(y); - var buffer = std.ArrayList(u8).init(self.arena.allocator()); + var buffer = std.ArrayList(u8).empty; if (self.style.axis.y_labels_formatter) |formatter| { - try formatter(&buffer, y_value); + try formatter(self.allocator, &buffer, y_value); } else { - try buffer.writer().print("{d:.2}", .{y_value}); + try buffer.print(self.allocator, "{d:.2}", .{y_value}); } try svg.addText(.{ @@ -579,7 +579,8 @@ fn drawYLabelsLinear(self: *Figure, svg: *SVG, info: FigureInfo) !void { .font_family = self.style.axis.label_font, .font_size = .{ .pixel = self.style.axis.label_size }, .fill = self.style.axis.label_color, - .text = try buffer.toOwnedSlice(), + .text = try buffer.toOwnedSlice(self.allocator), + .allocator = self.allocator, }); } @@ -589,11 +590,11 @@ fn drawYLabelsLinear(self: *Figure, svg: *SVG, info: FigureInfo) !void { const y_value = info.computeYInv(y); - var buffer = std.ArrayList(u8).init(self.arena.allocator()); + var buffer = std.ArrayList(u8).empty; if (self.style.axis.y_labels_formatter) |formatter| { - try formatter(&buffer, y_value); + try formatter(self.allocator, &buffer, y_value); } else { - try buffer.writer().print("{d:.2}", .{y_value}); + try buffer.print(self.allocator, "{d:.2}", .{y_value}); } try svg.addText(.{ @@ -604,7 +605,8 @@ fn drawYLabelsLinear(self: *Figure, svg: *SVG, info: FigureInfo) !void { .font_family = self.style.axis.label_font, .font_size = .{ .pixel = self.style.axis.label_size }, .fill = self.style.axis.label_color, - .text = try buffer.toOwnedSlice(), + .text = try buffer.toOwnedSlice(self.allocator), + .allocator = self.allocator, }); } } @@ -625,11 +627,11 @@ fn drawYLabelsLog(self: *Figure, svg: *SVG, info: FigureInfo) !void { const y_value = std.math.pow(f32, 10, i); - var buffer = std.ArrayList(u8).init(self.arena.allocator()); + var buffer = std.ArrayList(u8).empty; if (self.style.axis.y_labels_formatter) |formatter| { - try formatter(&buffer, y_value); + try formatter(self.allocator, &buffer, y_value); } else { - try buffer.writer().print("{d:.2}", .{y_value}); + try buffer.print(self.allocator, "{d:.2}", .{y_value}); } try svg.addText(.{ @@ -640,7 +642,8 @@ fn drawYLabelsLog(self: *Figure, svg: *SVG, info: FigureInfo) !void { .font_family = self.style.axis.label_font, .font_size = .{ .pixel = self.style.axis.label_size }, .fill = self.style.axis.label_color, - .text = try buffer.toOwnedSlice(), + .text = try buffer.toOwnedSlice(self.allocator), + .allocator = self.allocator, }); } } @@ -666,11 +669,11 @@ fn drawXLabelsLinear(self: *Figure, svg: *SVG, info: FigureInfo) !void { const x_value = info.computeXInv(x); - var buffer = std.ArrayList(u8).init(self.arena.allocator()); + var buffer = std.ArrayList(u8).empty; if (self.style.axis.x_labels_formatter) |formatter| { - try formatter(&buffer, x_value); + try formatter(self.allocator, &buffer, x_value); } else { - try buffer.writer().print("{d:.2}", .{x_value}); + try buffer.print(svg.allocator, "{d:.2}", .{x_value}); } try svg.addText(.{ @@ -681,7 +684,8 @@ fn drawXLabelsLinear(self: *Figure, svg: *SVG, info: FigureInfo) !void { .font_family = self.style.axis.label_font, .font_size = .{ .pixel = self.style.axis.label_size }, .fill = self.style.axis.label_color, - .text = try buffer.toOwnedSlice(), + .text = try buffer.toOwnedSlice(self.allocator), + .allocator = self.allocator, }); } @@ -691,11 +695,11 @@ fn drawXLabelsLinear(self: *Figure, svg: *SVG, info: FigureInfo) !void { const x_value = info.computeXInv(x); - var buffer = std.ArrayList(u8).init(self.arena.allocator()); + var buffer = std.ArrayList(u8).empty; if (self.style.axis.x_labels_formatter) |formatter| { - try formatter(&buffer, x_value); + try formatter(self.allocator, &buffer, x_value); } else { - try buffer.writer().print("{d:.2}", .{x_value}); + try buffer.print(svg.allocator, "{d:.2}", .{x_value}); } try svg.addText(.{ @@ -706,7 +710,8 @@ fn drawXLabelsLinear(self: *Figure, svg: *SVG, info: FigureInfo) !void { .font_family = self.style.axis.label_font, .font_size = .{ .pixel = self.style.axis.label_size }, .fill = self.style.axis.label_color, - .text = try buffer.toOwnedSlice(), + .text = try buffer.toOwnedSlice(self.allocator), + .allocator = self.allocator, }); } } @@ -727,11 +732,11 @@ fn drawXLabelsLog(self: *Figure, svg: *SVG, info: FigureInfo) !void { const x_value = std.math.pow(f32, 10, i); - var buffer = std.ArrayList(u8).init(self.arena.allocator()); + var buffer = std.ArrayList(u8).empty; if (self.style.axis.x_labels_formatter) |formatter| { - try formatter(&buffer, x_value); + try formatter(self.allocator, &buffer, x_value); } else { - try buffer.writer().print("{d:.2}", .{x_value}); + try buffer.print(self.allocator, "{d:.2}", .{x_value}); } try svg.addText(.{ @@ -742,7 +747,8 @@ fn drawXLabelsLog(self: *Figure, svg: *SVG, info: FigureInfo) !void { .font_family = self.style.axis.label_font, .font_size = .{ .pixel = self.style.axis.label_size }, .fill = self.style.axis.label_color, - .text = try buffer.toOwnedSlice(), + .text = try buffer.toOwnedSlice(self.allocator), + .allocator = self.allocator, }); } } diff --git a/src/plot/Line.zig b/src/plot/Line.zig index 281d56f..1afa00a 100644 --- a/src/plot/Line.zig +++ b/src/plot/Line.zig @@ -66,7 +66,7 @@ fn draw(impl: *const anyopaque, allocator: Allocator, svg: *SVG, info: FigureInf const stroke_dash_array: ?[]const f32 = if (self.style.dash) |dash| try allocator.dupe(f32, &[_]f32{dash}) else null; - var commands = std.ArrayList(SVG.Path.Command).init(allocator); + var commands = std.ArrayList(SVG.Path.Command).empty; var started = false; if (self.x) |x_| { for (x_, self.y, 0..) |x, y, i| { @@ -78,7 +78,7 @@ fn draw(impl: *const anyopaque, allocator: Allocator, svg: *SVG, info: FigureInf const y1 = info.computeY(y); if (!started) { - try commands.append(.{ + try commands.append(allocator, .{ .MoveTo = .{ .x = x1, .y = y1, @@ -104,7 +104,7 @@ fn draw(impl: *const anyopaque, allocator: Allocator, svg: *SVG, info: FigureInf const cpe_x = p_end_x + self.style.smooth * (p_start_x - p_next_x); const cpe_y = p_end_y + self.style.smooth * (p_start_y - p_next_y); - try commands.append(.{ + try commands.append(allocator, .{ .CubicBezierCurveTo = .{ .x1 = cps_x, .y1 = cps_y, @@ -125,7 +125,7 @@ fn draw(impl: *const anyopaque, allocator: Allocator, svg: *SVG, info: FigureInf const y1 = info.computeY(y); if (!started) { - try commands.append(.{ + try commands.append(allocator, .{ .MoveTo = .{ .x = x1, .y = y1, @@ -151,7 +151,7 @@ fn draw(impl: *const anyopaque, allocator: Allocator, svg: *SVG, info: FigureInf const cpe_x = p_end_x + self.style.smooth * (p_start_x - p_next_x); const cpe_y = p_end_y + self.style.smooth * (p_start_y - p_next_y); - try commands.append(.{ + try commands.append(allocator, .{ .CubicBezierCurveTo = .{ .x1 = cps_x, .y1 = cps_y, diff --git a/src/plot/formatters.zig b/src/plot/formatters.zig index ec1df40..a903023 100644 --- a/src/plot/formatters.zig +++ b/src/plot/formatters.zig @@ -5,19 +5,19 @@ pub fn default( options: struct { comptime precision: ?u8 = 2, }, -) *const fn (*std.ArrayList(u8), f32) anyerror!void { +) *const fn (std.mem.Allocator, *std.ArrayList(u8), f32) anyerror!void { if (options.precision == null) { return &struct { - pub fn lambda(buffer: *std.ArrayList(u8), value: f32) anyerror!void { - try buffer.writer().print("{d}", .{value}); + pub fn lambda(allocator: std.mem.Allocator, buffer: *std.ArrayList(u8), value: f32) anyerror!void { + try buffer.print(allocator, "{d}", .{value}); } }.lambda; } else { const precision_str = std.fmt.comptimePrint("{}", .{options.precision.?}); return &struct { - pub fn lambda(buffer: *std.ArrayList(u8), value: f32) anyerror!void { - try buffer.writer().print("{d:." ++ precision_str ++ "}", .{value}); + pub fn lambda(allocator: std.mem.Allocator, buffer: *std.ArrayList(u8), value: f32) anyerror!void { + try buffer.print(allocator, "{d:." ++ precision_str ++ "}", .{value}); } }.lambda; } diff --git a/src/svg/Circle.zig b/src/svg/Circle.zig index 6580325..53e6dcf 100644 --- a/src/svg/Circle.zig +++ b/src/svg/Circle.zig @@ -46,16 +46,16 @@ pub fn init(options: Options) Circle { /// Write the circle to the given writer pub fn writeTo(self: *const Circle, writer: anytype) anyerror!void { try writer.writeAll("6}\" ", .{fill}) else try writer.writeAll("fill=\"none\" "); try writer.print("fill-opacity=\"{d}\" ", .{self.options.fill_opacity}); if (self.options.stroke) |stroke| try writer.print("stroke=\"#{X:0>6}\" ", .{stroke}) else try writer.writeAll("stroke=\"none\" "); try writer.print("stroke-opacity=\"{d}\" ", .{self.options.stroke_opacity}); - try writer.print("stroke-width=\"{}\" ", .{self.options.stroke_width}); + try writer.print("stroke-width=\"{f}\" ", .{self.options.stroke_width}); try writer.print("opacity=\"{d}\" ", .{self.options.opacity}); try writer.writeAll("/>"); } @@ -65,4 +65,4 @@ pub fn wrap(self: *const Circle) Kind { return Kind { .circle = self.* }; -} \ No newline at end of file +} diff --git a/src/svg/Line.zig b/src/svg/Line.zig index 705c6f4..99de75b 100644 --- a/src/svg/Line.zig +++ b/src/svg/Line.zig @@ -18,9 +18,7 @@ pub const LineCap = enum { round, square, - pub fn format(self: LineCap, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { - _ = fmt; - _ = options; + pub fn format(self: LineCap, writer: anytype) !void { switch (self) { .butt => try writer.writeAll("butt"), .round => try writer.writeAll("round"), @@ -66,15 +64,15 @@ pub fn init(options: Options) Line { /// Write the line to the given writer pub fn writeTo(self: *const Line, writer: anytype) anyerror!void { try writer.writeAll("6}\" ", .{stroke}) else try writer.writeAll("stroke=\"none\" "); try writer.print("stroke-opacity=\"{d}\" ", .{self.options.stroke_opacity}); - try writer.print("stroke-width=\"{}\" ", .{self.options.stroke_width}); - try writer.print("stroke-linecap=\"{}\" ", .{self.options.stroke_linecap}); + try writer.print("stroke-width=\"{f}\" ", .{self.options.stroke_width}); + try writer.print("stroke-linecap=\"{f}\" ", .{self.options.stroke_linecap}); if (self.options.stroke_dasharray) |stroke_dash_array| { try writer.writeAll("stroke-dasharray=\" "); for (stroke_dash_array) |dash| { @@ -91,4 +89,4 @@ pub fn wrap(self: *const Line) Kind { return Kind { .line = self.* }; -} \ No newline at end of file +} diff --git a/src/svg/Path.zig b/src/svg/Path.zig index deade42..4287902 100644 --- a/src/svg/Path.zig +++ b/src/svg/Path.zig @@ -297,7 +297,7 @@ pub fn writeTo(self: *const Path, writer: anytype) anyerror!void { try writer.print("fill-opacity=\"{d}\" ", .{self.options.fill_opacity}); if (self.options.stroke) |stroke| try writer.print("stroke=\"#{X:0>6}\" ", .{stroke}) else try writer.writeAll("stroke=\"none\" "); try writer.print("stroke-opacity=\"{d}\" ", .{self.options.stroke_opacity}); - try writer.print("stroke-width=\"{}\" ", .{self.options.stroke_width}); + try writer.print("stroke-width=\"{f}\" ", .{self.options.stroke_width}); if (self.options.stroke_dasharray) |dasharray| { try writer.writeAll("stroke-dasharray=\""); for (dasharray) |dash| { diff --git a/src/svg/Polyline.zig b/src/svg/Polyline.zig index cc21fb5..0e092fd 100644 --- a/src/svg/Polyline.zig +++ b/src/svg/Polyline.zig @@ -64,7 +64,7 @@ pub fn writeTo(self: *const Polyline, writer: anytype) anyerror!void { try writer.print("fill-opacity=\"{d}\" ", .{self.options.fill_opacity}); if (self.options.stroke) |stroke| try writer.print("stroke=\"#{X:0>6}\" ", .{stroke}) else try writer.writeAll("stroke=\"none\" "); try writer.print("stroke-opacity=\"{d}\" ", .{self.options.stroke_opacity}); - try writer.print("stroke-width=\"{}\" ", .{self.options.stroke_width}); + try writer.print("stroke-width=\"{f}\" ", .{self.options.stroke_width}); try writer.print("opacity=\"{d}\" ", .{self.options.opacity}); try writer.writeAll("/>"); } diff --git a/src/svg/Rect.zig b/src/svg/Rect.zig index a420d05..43d1134 100644 --- a/src/svg/Rect.zig +++ b/src/svg/Rect.zig @@ -52,19 +52,19 @@ pub fn init(options: Options) Rect { /// Write the rectangle to the given writer pub fn writeTo(self: *const Rect, writer: anytype) anyerror!void { try writer.writeAll("6}\" ", .{fill}) else try writer.writeAll("fill=\"none\" "); try writer.print("fill-opacity=\"{}\" ", .{self.options.fill_opacity}); if (self.options.stroke) |stroke| try writer.print("stroke=\"#{X:0>6}\" ", .{stroke}) else try writer.writeAll("stroke=\"none\" "); try writer.print("stroke-opacity=\"{}\" ", .{self.options.stroke_opacity}); - try writer.print("stroke-width=\"{}\" ", .{self.options.stroke_width}); + try writer.print("stroke-width=\"{f}\" ", .{self.options.stroke_width}); try writer.print("opacity=\"{}\" ", .{self.options.opacity}); try writer.writeAll("/>"); } @@ -74,4 +74,4 @@ pub fn wrap(self: *const Rect) Kind { return Kind { .rect = self.*, }; -} \ No newline at end of file +} diff --git a/src/svg/SVG.zig b/src/svg/SVG.zig index 0338962..b3f2075 100644 --- a/src/svg/SVG.zig +++ b/src/svg/SVG.zig @@ -8,7 +8,7 @@ pub const Polyline = @import("Polyline.zig"); pub const Text = @import("Text.zig"); pub const Path = @import("Path.zig"); -pub usingnamespace @import("kind.zig"); +pub const Kind = @import("kind.zig").Kind; const SVG = @This(); @@ -29,7 +29,7 @@ viewbox: ViewBox, /// Initialize the SVG with the given allocator, width and height pub fn init(allocator: Allocator, width: f32, height: f32) SVG { - return SVG{ .allocator = allocator, .data = SVG.Kind.List.init(allocator), .width = width, .height = height, .viewbox = ViewBox{ + return SVG{ .allocator = allocator, .data = .empty, .width = width, .height = height, .viewbox = ViewBox{ .x = 0, .y = 0, .width = width, @@ -38,16 +38,16 @@ pub fn init(allocator: Allocator, width: f32, height: f32) SVG { } /// Deintiialize the SVG -pub fn deinit(self: *const SVG) void { +pub fn deinit(self: *SVG) void { for (self.data.items) |kind| { kind.deinit(); } - self.data.deinit(); + self.data.deinit(self.allocator); } /// Add a Kind to the SVG pub fn add(self: *SVG, kind: SVG.Kind) !void { - try self.data.append(kind); + try self.data.append(self.allocator, kind); } /// Add a Line to the SVG @@ -106,4 +106,5 @@ pub fn writeTo(self: *const SVG, writer: anytype) anyerror!void { } // End of the SVG try writer.writeAll(""); + try writer.flush(); } diff --git a/src/svg/Text.zig b/src/svg/Text.zig index c334221..3d3ffb4 100644 --- a/src/svg/Text.zig +++ b/src/svg/Text.zig @@ -46,9 +46,7 @@ pub const FontSize = union(enum) { /// Math value math: void, - pub fn format(self: FontSize, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { - _ = fmt; - _ = options; + pub fn format(self: FontSize, writer: anytype) !void { switch (self) { .pixel => |value| try writer.print("{d}px", .{value}), .em => |value| try writer.print("{d}em", .{value}), @@ -97,9 +95,7 @@ pub const FontWeight = enum { /// The bolder font weight bolder, - pub fn format(self: FontWeight, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { - _ = fmt; - _ = options; + pub fn format(self: FontWeight, writer: anytype) !void { switch (self) { .normal => try writer.writeAll("normal"), .bold => try writer.writeAll("bold"), @@ -127,9 +123,7 @@ pub const TextAnchor = enum { /// The end anchor end, - pub fn format(self: TextAnchor, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { - _ = fmt; - _ = options; + pub fn format(self: TextAnchor, writer: anytype) !void { switch (self) { .start => try writer.writeAll("start"), .middle => try writer.writeAll("middle"), @@ -165,9 +159,7 @@ pub const DominantBaseline = enum { /// The text before edge baseline text_before_edge, - pub fn format(self: DominantBaseline, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { - _ = fmt; - _ = options; + pub fn format(self: DominantBaseline, writer: anytype) !void { switch (self) { .auto => try writer.writeAll("auto"), .use_script => try writer.writeAll("use-script"), @@ -245,11 +237,11 @@ pub fn deinit(self: *const Text) void { /// Write the text to the given writer pub fn writeTo(self: *const Text, writer: anytype) anyerror!void { try writer.writeAll("6}\" ", .{fill}) else try writer.writeAll("fill=\"none\" "); @@ -257,13 +249,13 @@ pub fn writeTo(self: *const Text, writer: anytype) anyerror!void { if (self.options.stroke) |stroke| try writer.print("stroke=\"#{X:0>6}\" ", .{stroke}) else try writer.writeAll("stroke=\"none\" "); try writer.print("stroke-opacity=\"{d}\" ", .{self.options.stroke_opacity}); - try writer.print("stroke-width=\"{}\" ", .{self.options.stroke_width}); + try writer.print("stroke-width=\"{f}\" ", .{self.options.stroke_width}); try writer.print("opacity=\"{d}\" ", .{self.options.opacity}); try writer.print("font-family=\"{s}\" ", .{self.options.font_family}); - try writer.print("font-size=\"{}\" ", .{self.options.font_size}); - try writer.print("font-weight=\"{}\" ", .{self.options.font_weight}); - try writer.print("text-anchor=\"{}\" ", .{self.options.text_anchor}); - try writer.print("dominant-baseline=\"{}\" ", .{self.options.dominant_baseline}); + try writer.print("font-size=\"{f}\" ", .{self.options.font_size}); + try writer.print("font-weight=\"{f}\" ", .{self.options.font_weight}); + try writer.print("text-anchor=\"{f}\" ", .{self.options.text_anchor}); + try writer.print("dominant-baseline=\"{f}\" ", .{self.options.dominant_baseline}); try writer.print(">{s}", .{self.options.text}); } @@ -272,4 +264,4 @@ pub fn wrap(self: *const Text) Kind { return Kind { .text = self.* }; -} \ No newline at end of file +} diff --git a/src/svg/util/length.zig b/src/svg/util/length.zig index 3784b7b..16305fa 100644 --- a/src/svg/util/length.zig +++ b/src/svg/util/length.zig @@ -9,9 +9,7 @@ pub const LengthPercentAuto = union(enum) { /// Automatic length auto: void, - pub fn format(self: LengthPercentAuto, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { - _ = fmt; - _ = options; + pub fn format(self: LengthPercentAuto, writer: anytype) !void { switch (self) { .pixel => |value| try writer.print("{d}", .{value}), .percent => |value| try writer.print("{d}%", .{value}), @@ -27,12 +25,10 @@ pub const LengthPercent = union(enum) { /// The length in percent (of the parent). percent: f32, - pub fn format(self: LengthPercent, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { - _ = fmt; - _ = options; + pub fn format(self: LengthPercent, writer: anytype) !void { switch (self) { .pixel => |value| try writer.print("{d}", .{value}), .percent => |value| try writer.print("{d}%", .{value}), } } -}; \ No newline at end of file +}; From c84b2a1b9316b1b2289e1c5052062bfc0d9057cc Mon Sep 17 00:00:00 2001 From: yoshibox Date: Sun, 14 Dec 2025 20:12:59 +0100 Subject: [PATCH 3/4] Change writeTo's functions signature to accept an Io.Writer explicitly --- src/svg/Circle.zig | 2 +- src/svg/Line.zig | 2 +- src/svg/Path.zig | 4 ++-- src/svg/Polyline.zig | 2 +- src/svg/Rect.zig | 2 +- src/svg/SVG.zig | 2 +- src/svg/Text.zig | 2 +- src/svg/kind.zig | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/svg/Circle.zig b/src/svg/Circle.zig index 53e6dcf..5bd26d2 100644 --- a/src/svg/Circle.zig +++ b/src/svg/Circle.zig @@ -44,7 +44,7 @@ pub fn init(options: Options) Circle { } /// Write the circle to the given writer -pub fn writeTo(self: *const Circle, writer: anytype) anyerror!void { +pub fn writeTo(self: *const Circle, writer: *std.Io.Writer) std.Io.Writer.Error!void { try writer.writeAll(" { try writer.print("M {d} {d}", .{ self.MoveTo.x, self.MoveTo.y }); @@ -283,7 +283,7 @@ pub fn deinit(self: *const Path) void { } /// Write the path to the given writer -pub fn writeTo(self: *const Path, writer: anytype) anyerror!void { +pub fn writeTo(self: *const Path, writer: *std.Io.Writer) std.Io.Writer.Error!void { try writer.writeAll(" |line| line.writeTo(writer), .rect => |rect| rect.writeTo(writer), From e6f8955cd1677e577b3151aca8be08691b1e253d Mon Sep 17 00:00:00 2001 From: yoshibox Date: Mon, 15 Dec 2025 11:46:48 +0100 Subject: [PATCH 4/4] Correct zig version in readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index d58fcf9..1f0bbb3 100644 --- a/readme.md +++ b/readme.md @@ -6,7 +6,7 @@ The Zig Plot Lib is a library for plotting data in Zig. It is designed to be eas **Note:** This library is still in development and is not yet ready for production use. -I'm developping this library with version 0.13.0. +I'm developping this library with version 0.15.2. ## Installation