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 965cdce..0987efe 100644 --- a/lib/matplotex.ex +++ b/lib/matplotex.ex @@ -114,6 +114,51 @@ 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 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 + 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 + ``` + * 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. + """ 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..87ea348 100644 --- a/lib/matplotex/figure/areal/bar_chart.ex +++ b/lib/matplotex/figure/areal/bar_chart.ex @@ -48,8 +48,7 @@ defmodule Matplotex.Figure.Areal.BarChart do @impl Areal def materialize(figure) do - __MODULE__.materialized_by_region(figure) - |> materialize_bars() + 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..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 d8bc9f8..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 474daba..07ae2d6 100644 --- a/lib/matplotex/figure/areal/scatter.ex +++ b/lib/matplotex/figure/areal/scatter.ex @@ -41,8 +41,7 @@ defmodule Matplotex.Figure.Areal.Scatter do @impl Areal def materialize(figure) do - __MODULE__.materialized_by_region(figure) - |> materialize_elements() + 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..2e2ba2a 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,6 @@ defmodule Matplotex.Figure.Areal.Spline do @impl Areal def materialize(figure) do figure - |> __MODULE__.materialized_by_region() |> materialize_spline() end @@ -100,7 +98,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