From 3129ae8b0a4122a0934f0ca71ba6171e56b81a2a Mon Sep 17 00:00:00 2001 From: Mohammed Sadique Date: Mon, 20 Jan 2025 17:28:18 +0530 Subject: [PATCH 1/2] documentation --- lib/matplotex.ex | 52 +++++++++++++++++++ lib/matplotex/figure.ex | 2 +- lib/matplotex/figure/areal.ex | 1 + lib/matplotex/figure/areal/bar_chart.ex | 4 +- lib/matplotex/figure/areal/histogram.ex | 2 +- lib/matplotex/figure/areal/line_plot.ex | 2 +- lib/matplotex/figure/areal/scatter.ex | 4 +- lib/matplotex/figure/areal/spline.ex | 4 +- .../matplotex/figure/areal/bar_chart_test.exs | 2 +- .../matplotex/figure/areal/histogram_test.exs | 4 +- .../matplotex/figure/areal/line_plot_test.exs | 2 +- test/matplotex/figure/areal/spline_test.exs | 2 +- 12 files changed, 66 insertions(+), 15 deletions(-) diff --git a/lib/matplotex.ex b/lib/matplotex.ex index 965cdce..6ab7187 100644 --- a/lib/matplotex.ex +++ b/lib/matplotex.ex @@ -114,6 +114,58 @@ defmodule Matplotex do ## `M.show/1` After creating a figure using the functions provided, call M.show/1 to generate and display the final SVG representation of the plot. The show/1 function will convert the Matplotex.Figure data into a valid SVG string. + ## Matplotex.Figure.Areal behaviour + Matplotex.Figure.Areal is a behavior designed to facilitate the creation and management of areal plots. This module provides the functionality to produce data required for generating plots with essential components such as: + The frame, ticks, labels, title, etc, every areal charts requires such elements and user can disable if it wants to, the main agenda of this behavior is to reduce the complexity of production data for svg + Users interact with the module by implementing its callbacks to create and materialize data for custom SVG plots. + + Example usage: + ```elixir + defmodule MyCustomAreaChart do + @behaviour Matplotex.Figure.Areal + + frame( + tick: %TwoD{}, + limit: %TwoD{}, + label: %TwoD{}, + region_x: %Region{}, + region_y: %Region{}, + region_title: %Region{}, + region_legend: %Region{}, + region_content: %Region{} + ) + + + def create(figure, data, _opts) do + dataset = Dataset.cast(%Dataset{x: x, y: y}, opts) + + %Figure{figure | axes: %{axes | data: xydata, dataset: datasets}} + |> PlotOptions.set_options_in_figure(opts) + end + + def materialize(figure) do + materialize_chart_elements(figure) + end + defp materialize_chart_elements(%Figure{axes: %__MODULE__{elements: elements}}) do + elements ++ [%CustomElement{}] + end + ``` + The snippet shows a pseudo code to use this behavior couple of things needed to explain here + * Figure - The figure is a struct common to all charts for a convention all the apis in this library accepts figure as input and figure as output + * Axes - A struct contains all information about that particular chart + * Dataset - Modularizing input datas for further conveninence, the key dataset in axes expects a list of [%Dataset{}] for converting points to its svg equivalent elements + * custom elements - The main purpose of materializer function is generating list of structs that implements Matplotex.Element behaviour so the svg generator produces the appropriate tags + ## Matplotex.Element behaviour + This is the behavour containing one callback called assemble/1 that expect that structs as input and a equivalent svg tag as output, so the assemble funcion should interpolate the values of element to that particular svg element + ### Example + ```elixir + defmodule MyCustomElement do + @behaviour Matplotex.Element + + def assemble(%MyCustomElement{x: x, y: y, widht: width, height: height}) do + ~s() + end + ``` """ alias Matplotex.Figure.Areal.Spline diff --git a/lib/matplotex/figure.ex b/lib/matplotex/figure.ex index c93d0cc..4268fc0 100644 --- a/lib/matplotex/figure.ex +++ b/lib/matplotex/figure.ex @@ -74,7 +74,7 @@ defmodule Matplotex.Figure do %__MODULE__{figure | margin: margin, axes: %{axes | size: frame_size}} end - def materialize(%__MODULE__{axes: %module{}} = figure), do: module.materialize(figure) + def materialize(%__MODULE__{axes: %module{}} = figure), do: figure|> module.materialized_by_region()|>module.materialize() def update_figure(figure, params) do if valid_params?(params) do diff --git a/lib/matplotex/figure/areal.ex b/lib/matplotex/figure/areal.ex index 03701c2..261ad6c 100644 --- a/lib/matplotex/figure/areal.ex +++ b/lib/matplotex/figure/areal.ex @@ -360,4 +360,5 @@ defmodule Matplotex.Figure.Areal do %Dataset{dataset | transformed: transformed} end + end diff --git a/lib/matplotex/figure/areal/bar_chart.ex b/lib/matplotex/figure/areal/bar_chart.ex index d1d9a64..a237cbd 100644 --- a/lib/matplotex/figure/areal/bar_chart.ex +++ b/lib/matplotex/figure/areal/bar_chart.ex @@ -48,8 +48,8 @@ defmodule Matplotex.Figure.Areal.BarChart do @impl Areal def materialize(figure) do - __MODULE__.materialized_by_region(figure) - |> materialize_bars() + # __MODULE__.materialized_by_region(figure) + materialize_bars(figure) end defp materialize_bars( diff --git a/lib/matplotex/figure/areal/histogram.ex b/lib/matplotex/figure/areal/histogram.ex index 21258a8..5bdb3de 100644 --- a/lib/matplotex/figure/areal/histogram.ex +++ b/lib/matplotex/figure/areal/histogram.ex @@ -48,7 +48,7 @@ defmodule Matplotex.Figure.Areal.Histogram do def materialize(figure) do figure |> sanitize() - |> __MODULE__.materialized_by_region() + # |> __MODULE__.materialized_by_region() |> materialize_hist() end diff --git a/lib/matplotex/figure/areal/line_plot.ex b/lib/matplotex/figure/areal/line_plot.ex index d8bc9f8..efbef3d 100644 --- a/lib/matplotex/figure/areal/line_plot.ex +++ b/lib/matplotex/figure/areal/line_plot.ex @@ -48,7 +48,7 @@ defmodule Matplotex.Figure.Areal.LinePlot do @impl Areal def materialize(figure) do figure - |> __MODULE__.materialized_by_region() + # |> __MODULE__.materialized_by_region() |> materialize_lines() end diff --git a/lib/matplotex/figure/areal/scatter.ex b/lib/matplotex/figure/areal/scatter.ex index 474daba..42db3e2 100644 --- a/lib/matplotex/figure/areal/scatter.ex +++ b/lib/matplotex/figure/areal/scatter.ex @@ -41,8 +41,8 @@ defmodule Matplotex.Figure.Areal.Scatter do @impl Areal def materialize(figure) do - __MODULE__.materialized_by_region(figure) - |> materialize_elements() + # __MODULE__.materialized_by_region(figure) + materialize_elements(figure) end defp materialize_elements( diff --git a/lib/matplotex/figure/areal/spline.ex b/lib/matplotex/figure/areal/spline.ex index 3398a32..624cdca 100644 --- a/lib/matplotex/figure/areal/spline.ex +++ b/lib/matplotex/figure/areal/spline.ex @@ -30,7 +30,6 @@ defmodule Matplotex.Figure.Areal.Spline do ) do x = determine_numeric_value(x) y = determine_numeric_value(y) - opts = Keyword.put_new(opts, :color, "none") dataset = Dataset.cast(%Dataset{x: x, y: y}, opts) datasets = data ++ [dataset] xydata = flatten_for_data(datasets) @@ -42,7 +41,7 @@ defmodule Matplotex.Figure.Areal.Spline do @impl Areal def materialize(figure) do figure - |> __MODULE__.materialized_by_region() + # |> __MODULE__.materialized_by_region() |> materialize_spline() end @@ -100,7 +99,6 @@ defmodule Matplotex.Figure.Areal.Spline do {moveto, transformed} = List.pop_at(transformed, 0, move_to_def) cubic = Enum.slice(transformed, 0..2) smooths = blend(transformed, 3) - %Spline{ type: "figure.spline", moveto: moveto, diff --git a/test/matplotex/figure/areal/bar_chart_test.exs b/test/matplotex/figure/areal/bar_chart_test.exs index 701c4a7..1cb7473 100644 --- a/test/matplotex/figure/areal/bar_chart_test.exs +++ b/test/matplotex/figure/areal/bar_chart_test.exs @@ -12,7 +12,7 @@ defmodule Matplotex.Figure.Areal.BarChartTest do test "adds figure with rectangles for bars", %{ figure: %Figure{axes: %{data: {_x, y}}} = figure } do - assert %Figure{axes: %{element: elements}} = BarChart.materialize(figure) + assert %Figure{axes: %{element: elements}} = BarChart.materialized_by_region(figure)|>BarChart.materialize() assert assert Enum.filter(elements, fn x -> x.type == "figure.bar" end) |> length() == length(y) diff --git a/test/matplotex/figure/areal/histogram_test.exs b/test/matplotex/figure/areal/histogram_test.exs index 8c3f978..7e35919 100644 --- a/test/matplotex/figure/areal/histogram_test.exs +++ b/test/matplotex/figure/areal/histogram_test.exs @@ -1,6 +1,6 @@ defmodule Matplotex.Figure.Areal.HistogramTest do use Matplotex.PlotCase - alias Matplotex.Figure.Areal.Histogram + alias Matplotex.Figure setup do values = Nx.Random.key(12) |> Nx.Random.normal(0, 1, shape: {1000}) |> elem(0) |> Nx.to_list() @@ -14,7 +14,7 @@ defmodule Matplotex.Figure.Areal.HistogramTest do describe "materialyze/1" do test "materialyze with elements", %{figure: figure, bins: bins} do - assert figure = Histogram.materialize(figure) + assert figure = Figure.materialize(figure) elements = figure.axes.element assert title = elements |> Enum.filter(fn elem -> elem.type == "figure.title" end) |> hd assert title.text == "Histogram" diff --git a/test/matplotex/figure/areal/line_plot_test.exs b/test/matplotex/figure/areal/line_plot_test.exs index 6eadc75..26f2970 100644 --- a/test/matplotex/figure/areal/line_plot_test.exs +++ b/test/matplotex/figure/areal/line_plot_test.exs @@ -49,7 +49,7 @@ defmodule Matplotex.Figure.Areal.LinePlotTest do |> Matplotex.set_title("Title") |> Matplotex.set_xlabel("X-Axis") |> Matplotex.set_ylabel("Y-Axis") - |> LinePlot.materialize() + |> Figure.materialize() element = Enum.filter(element, fn elem -> elem.type == "plot.line" end) diff --git a/test/matplotex/figure/areal/spline_test.exs b/test/matplotex/figure/areal/spline_test.exs index 12d43cd..c6ddea1 100644 --- a/test/matplotex/figure/areal/spline_test.exs +++ b/test/matplotex/figure/areal/spline_test.exs @@ -13,7 +13,7 @@ defmodule Matplotex.Figure.Areal.SplineTest do end test "adds a spline element in a figure", %{figure: figure} do - assert %Figure{axes: %Spline{element: elements}} = Spline.materialize(figure) + assert %Figure{axes: %Spline{element: elements}} = Figure.materialize(figure) assert Enum.any?(elements, &(&1.type == "figure.spline")) end end From 706570c84a787b0b8a6db441b4b5d3ebc1cb5a8c Mon Sep 17 00:00:00 2001 From: Mohammed Sadique Date: Mon, 20 Jan 2025 21:38:32 +0530 Subject: [PATCH 2/2] convention --- docs/documentation.md | 1 + lib/matplotex.ex | 87 ++++++++++++------------- lib/matplotex/figure/areal/bar_chart.ex | 1 - lib/matplotex/figure/areal/histogram.ex | 1 - lib/matplotex/figure/areal/line_plot.ex | 1 - lib/matplotex/figure/areal/scatter.ex | 1 - lib/matplotex/figure/areal/spline.ex | 1 - 7 files changed, 41 insertions(+), 52 deletions(-) create mode 100644 docs/documentation.md diff --git a/docs/documentation.md b/docs/documentation.md new file mode 100644 index 0000000..ea58d13 --- /dev/null +++ b/docs/documentation.md @@ -0,0 +1 @@ +[for detailed documentation refer](https://hexdocs.pm/matplotex/Matplotex.html) \ No newline at end of file diff --git a/lib/matplotex.ex b/lib/matplotex.ex index 6ab7187..0987efe 100644 --- a/lib/matplotex.ex +++ b/lib/matplotex.ex @@ -115,57 +115,50 @@ defmodule Matplotex do After creating a figure using the functions provided, call M.show/1 to generate and display the final SVG representation of the plot. The show/1 function will convert the Matplotex.Figure data into a valid SVG string. ## Matplotex.Figure.Areal behaviour - Matplotex.Figure.Areal is a behavior designed to facilitate the creation and management of areal plots. This module provides the functionality to produce data required for generating plots with essential components such as: - The frame, ticks, labels, title, etc, every areal charts requires such elements and user can disable if it wants to, the main agenda of this behavior is to reduce the complexity of production data for svg - Users interact with the module by implementing its callbacks to create and materialize data for custom SVG plots. - + Matplotex goes beyond basic chart generation, offering a user-friendly interface for creating custom plots. It leverages two key behaviors: Matplotex.Figure.Areal and Matplotex.Element. The Areal module handles the underlying linear transformations, abstracting away unnecessary complexity. Users can seamlessly integrate SVG strings by defining structs that implement the Element behavior. Mapping data series to these elements is then achieved through the Matplotex.Figure.Areal behavior, making it a compelling tool for custom visualization. Example usage: ```elixir - defmodule MyCustomAreaChart do - @behaviour Matplotex.Figure.Areal - - frame( - tick: %TwoD{}, - limit: %TwoD{}, - label: %TwoD{}, - region_x: %Region{}, - region_y: %Region{}, - region_title: %Region{}, - region_legend: %Region{}, - region_content: %Region{} - ) - - - def create(figure, data, _opts) do - dataset = Dataset.cast(%Dataset{x: x, y: y}, opts) - - %Figure{figure | axes: %{axes | data: xydata, dataset: datasets}} - |> PlotOptions.set_options_in_figure(opts) - end - - def materialize(figure) do - materialize_chart_elements(figure) - end - defp materialize_chart_elements(%Figure{axes: %__MODULE__{elements: elements}}) do - elements ++ [%CustomElement{}] - end + defmodule MyCustomAreaChart do + use Matplotex.Figure.Areal + + frame( + tick: %TwoD{}, + limit: %TwoD{}, + label: %TwoD{}, + region_x: %Region{}, + region_y: %Region{}, + region_title: %Region{}, + region_legend: %Region{}, + region_content: %Region{} + ) + + + def create(figure, data, _opts) do + dataset = Dataset.cast(%Dataset{x: x, y: y}, opts) + + %Figure{figure | axes: %{axes | data: xydata, dataset: datasets}} + |> PlotOptions.set_options_in_figure(opts) + end + + def materialize(figure) do + materialize_chart_elements(figure) + end + defp materialize_chart_elements(%Figure{axes: %__MODULE__{elements: elements}}) do + elements ++ [%CustomElement{}] + end ``` - The snippet shows a pseudo code to use this behavior couple of things needed to explain here - * Figure - The figure is a struct common to all charts for a convention all the apis in this library accepts figure as input and figure as output - * Axes - A struct contains all information about that particular chart - * Dataset - Modularizing input datas for further conveninence, the key dataset in axes expects a list of [%Dataset{}] for converting points to its svg equivalent elements - * custom elements - The main purpose of materializer function is generating list of structs that implements Matplotex.Element behaviour so the svg generator produces the appropriate tags - ## Matplotex.Element behaviour - This is the behavour containing one callback called assemble/1 that expect that structs as input and a equivalent svg tag as output, so the assemble funcion should interpolate the values of element to that particular svg element - ### Example - ```elixir - defmodule MyCustomElement do - @behaviour Matplotex.Element + * Figure: A common struct used by all chart APIs in the library, serving as both input and output for consistent handling. + + * Axes: A struct containing all chart-specific information. + + * Dataset: A modular data input structure. The axes struct expects a list of %Dataset{} structs for converting data points into their SVG element equivalents. + + * Custom Elements: The materializer function's primary role is to generate a list of structs that implement the Matplotex.Element behavior. This enables the SVG generator to produce the appropriate tags for custom visualizations + + ### Matplotex.Element behaviour + + The Matplotex.Element behavior defines a callback function, assemble/1, which takes a struct as input and returns its corresponding SVG tag as a string. The assemble/1 function is responsible for interpolating the struct's values into the SVG element. - def assemble(%MyCustomElement{x: x, y: y, widht: width, height: height}) do - ~s() - end - ``` """ alias Matplotex.Figure.Areal.Spline diff --git a/lib/matplotex/figure/areal/bar_chart.ex b/lib/matplotex/figure/areal/bar_chart.ex index a237cbd..87ea348 100644 --- a/lib/matplotex/figure/areal/bar_chart.ex +++ b/lib/matplotex/figure/areal/bar_chart.ex @@ -48,7 +48,6 @@ defmodule Matplotex.Figure.Areal.BarChart do @impl Areal def materialize(figure) do - # __MODULE__.materialized_by_region(figure) materialize_bars(figure) end diff --git a/lib/matplotex/figure/areal/histogram.ex b/lib/matplotex/figure/areal/histogram.ex index 5bdb3de..f781e7f 100644 --- a/lib/matplotex/figure/areal/histogram.ex +++ b/lib/matplotex/figure/areal/histogram.ex @@ -48,7 +48,6 @@ defmodule Matplotex.Figure.Areal.Histogram do def materialize(figure) do figure |> sanitize() - # |> __MODULE__.materialized_by_region() |> materialize_hist() end diff --git a/lib/matplotex/figure/areal/line_plot.ex b/lib/matplotex/figure/areal/line_plot.ex index efbef3d..b39e62f 100644 --- a/lib/matplotex/figure/areal/line_plot.ex +++ b/lib/matplotex/figure/areal/line_plot.ex @@ -48,7 +48,6 @@ defmodule Matplotex.Figure.Areal.LinePlot do @impl Areal def materialize(figure) do figure - # |> __MODULE__.materialized_by_region() |> materialize_lines() end diff --git a/lib/matplotex/figure/areal/scatter.ex b/lib/matplotex/figure/areal/scatter.ex index 42db3e2..07ae2d6 100644 --- a/lib/matplotex/figure/areal/scatter.ex +++ b/lib/matplotex/figure/areal/scatter.ex @@ -41,7 +41,6 @@ defmodule Matplotex.Figure.Areal.Scatter do @impl Areal def materialize(figure) do - # __MODULE__.materialized_by_region(figure) materialize_elements(figure) end diff --git a/lib/matplotex/figure/areal/spline.ex b/lib/matplotex/figure/areal/spline.ex index 624cdca..2e2ba2a 100644 --- a/lib/matplotex/figure/areal/spline.ex +++ b/lib/matplotex/figure/areal/spline.ex @@ -41,7 +41,6 @@ defmodule Matplotex.Figure.Areal.Spline do @impl Areal def materialize(figure) do figure - # |> __MODULE__.materialized_by_region() |> materialize_spline() end