Skip to content

Commit 2022924

Browse files
Merge pull request #22 from BigThinkcode/legend_areal
Solution to bring Legends to Areal Plots
2 parents 92a3536 + d3225cd commit 2022924

19 files changed

Lines changed: 328 additions & 97 deletions

File tree

lib/matplotex.ex

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -196,19 +196,19 @@ defmodule Matplotex do
196196
197197
"""
198198

199-
@spec legend(Figure.t(), keyword() | map()) :: Figure.t()
200-
def legend(figure, opts) when is_map(opts) do
201-
Figure.add_legend(figure, opts)
202-
end
203-
204-
def legend(figure, [h | _t] = opts) when is_tuple(h) do
205-
params = Enum.into(opts, %{})
206-
Figure.add_legend(figure, params)
207-
end
208-
209-
def legend(figure, labels) when is_list(labels) do
210-
Figure.add_legend(figure, %{labels: labels})
211-
end
199+
# @spec legend(Figure.t(), keyword() | map()) :: Figure.t()
200+
# def legend(figure, opts) when is_map(opts) do
201+
# Figure.add_legend(figure, opts)
202+
# end
203+
204+
# def legend(figure, [h | _t] = opts) when is_tuple(h) do
205+
# params = Enum.into(opts, %{})
206+
# Figure.add_legend(figure, params)
207+
# end
208+
209+
# def legend(figure, labels) when is_list(labels) do
210+
# Figure.add_legend(figure, %{labels: labels})
211+
# end
212212

213213
@doc """
214214
Function to update figure params

lib/matplotex/element/circle.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ defmodule Matplotex.Element.Circle do
2121
type="#{circle.type}"
2222
cx="#{get_cx(circle)}px"
2323
cy="#{get_cy(circle)}px"
24-
r="#{circle.r}"
24+
r="#{get_r(circle)}"
2525
fill="#{circle.fill}" stroke="#{circle.stroke}"
2626
stroke_width="#{circle.stroke_width}"
2727
>
@@ -31,7 +31,7 @@ defmodule Matplotex.Element.Circle do
3131

3232
def get_cx(%{cx: x}), do: to_pixel(x)
3333
def get_cy(%{cy: y}), do: to_pixel(y)
34-
34+
def get_r(%{r: r}), do: to_pixel(r)
3535
@impl Element
3636
def flipy(%__MODULE__{cy: y} = circle, height) do
3737
%__MODULE__{circle | cy: height - y}

lib/matplotex/element/legend.ex

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
defmodule Matplotex.Element.Legend do
2+
alias Matplotex.Element.Label
3+
alias Matplotex.Element
4+
5+
use Element
6+
7+
@stroke_width 1
8+
@stroke "rgba(0,0,0,0)"
9+
@legend_size 20 / 96
10+
@label_type "legend.label"
11+
defstruct [
12+
:type,
13+
:x,
14+
:y,
15+
:color,
16+
:label,
17+
:handle,
18+
width: @legend_size,
19+
height: @legend_size,
20+
label_margin: @legend_size,
21+
stroke: @stroke,
22+
stroke_width: @stroke_width
23+
]
24+
25+
@impl Element
26+
def assemble(legend) do
27+
"""
28+
#{handle(legend)}
29+
#{Element.assemble(legend.label)}
30+
"""
31+
end
32+
33+
@impl Element
34+
def flipy(%__MODULE__{y: y} = legend, height) do
35+
%__MODULE__{legend | y: height - y, label: Label.flipy(legend.label, height)}
36+
end
37+
38+
defp handle(%__MODULE__{handle: %handle_element{} = handle}) do
39+
handle_element.assemble(handle)
40+
end
41+
42+
def with_label(
43+
%__MODULE__{
44+
label: text,
45+
x: x,
46+
y: y,
47+
width: width,
48+
height: height
49+
} = legend,
50+
legend_font,
51+
padding
52+
) do
53+
%{
54+
legend
55+
| label:
56+
%Label{
57+
x: x + width + padding,
58+
y: y + height / 2,
59+
text: text,
60+
type: @label_type
61+
}
62+
|> Label.cast_label(legend_font)
63+
}
64+
end
65+
end

lib/matplotex/element/polygon.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ defmodule Matplotex.Element.Polygon do
1010
~s(
1111
<polygon points="#{assemble_point(polygon)}"
1212
fill="#{polygon.fill}"
13+
type="#{polygon.type}"
1314
/>
1415
)
1516
end

lib/matplotex/element/rad_legend.ex

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,19 @@ defmodule Matplotex.Element.RadLegend do
4242
y: y,
4343
width: width,
4444
height: height
45-
} = legend, legend_font
45+
} = legend,
46+
legend_font
4647
) do
47-
4848
%{
4949
legend
50-
| label: %Label{
51-
x: x + width ,
52-
y: y + height / 2,
53-
text: text,
54-
type: @label_type
55-
}
56-
|> Label.cast_label(legend_font)
50+
| label:
51+
%Label{
52+
x: x + width,
53+
y: y + height / 2,
54+
text: text,
55+
type: @label_type
56+
}
57+
|> Label.cast_label(legend_font)
5758
}
5859
end
5960
end

lib/matplotex/figure.ex

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ defmodule Matplotex.Figure do
3131
def new(opts) do
3232
struct(__MODULE__, opts)
3333
end
34+
3435
# TODO: put error message in error
3536
# def put_error(figure, opts) do
3637

@@ -114,6 +115,4 @@ defmodule Matplotex.Figure do
114115
defp update_rc_params(_, _) do
115116
raise Matplotex.InputError, keys: [:rc_params], message: "Invalid Input"
116117
end
117-
118-
119118
end

lib/matplotex/figure/areal.ex

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ defmodule Matplotex.Figure.Areal do
55
@callback create(struct(), any(), keyword()) :: struct()
66
@callback materialize(struct()) :: struct()
77
@callback plotify(number(), tuple(), number(), number(), list(), atom()) :: number()
8+
@callback with_legend_handle(struct(), struct()) :: struct()
89
defmacro __using__(_) do
910
quote do
1011
@behaviour Matplotex.Figure.Areal
1112
alias Matplotex.Figure.TwoD
1213
alias Matplotex.Figure.Dimension
1314
alias Matplotex.Figure.Coords
1415
alias Matplotex.Figure.Text
15-
alias Matplotex.Figure.Legend
1616

1717
import Matplotex.Figure.Areal, only: [transformation: 7, do_transform: 6]
1818
import Matplotex.Blueprint.Frame
@@ -154,6 +154,7 @@ defmodule Matplotex.Figure.Areal do
154154
|> Cast.cast_spines_by_region()
155155
|> Cast.cast_label_by_region()
156156
|> Cast.cast_title_by_region()
157+
|> Cast.cast_legends()
157158
end
158159

159160
defp update_tick(axes, tick) do
@@ -255,7 +256,6 @@ defmodule Matplotex.Figure.Areal do
255256

256257
def set_region_title(figure), do: figure
257258

258-
259259
def set_region_legend(
260260
%Figure{
261261
axes:
@@ -274,7 +274,7 @@ defmodule Matplotex.Figure.Areal do
274274
region_x_width_after_legend = region_x_width - region_legend_width
275275

276276
{x_region_legend, y_region_legend} =
277-
Algebra.transform_given_point(-region_legend_width, -region_title_height, rx, ty, 0)
277+
Algebra.transform_given_point(-region_legend_width, -region_title_height, rx, ty)
278278

279279
%Figure{
280280
figure
@@ -294,17 +294,19 @@ defmodule Matplotex.Figure.Areal do
294294
}
295295
}
296296
end
297+
297298
def set_region_legend(figure), do: figure
299+
298300
def set_region_content(
299-
%Figure{
300-
axes:
301-
%{
302-
region_x: %Region{x: x_region_x, width: region_x_width},
303-
region_y: %Region{y: y_region_y, height: region_y_height},
304-
region_content: region_content
305-
} = axes
306-
} = figure
307-
) do
301+
%Figure{
302+
axes:
303+
%{
304+
region_x: %Region{x: x_region_x, width: region_x_width},
305+
region_y: %Region{y: y_region_y, height: region_y_height},
306+
region_content: region_content
307+
} = axes
308+
} = figure
309+
) do
308310
%Figure{
309311
figure
310312
| axes: %{
@@ -319,6 +321,7 @@ defmodule Matplotex.Figure.Areal do
319321
}
320322
}
321323
end
324+
322325
def set_region_content(figure), do: figure
323326
end
324327
end

lib/matplotex/figure/areal/bar_chart.ex

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
defmodule Matplotex.Figure.Areal.BarChart do
22
import Matplotex.Figure.Numer
33
alias Matplotex.Figure.Areal.Region
4+
alias Matplotex.Element.Legend
45
alias Matplotex.Figure.Dataset
56
alias Matplotex.Element.Rect
67
alias Matplotex.Figure.RcParams
@@ -12,7 +13,6 @@ defmodule Matplotex.Figure.Areal.BarChart do
1213
@xmin_value 0
1314

1415
frame(
15-
legend: %Legend{},
1616
coords: %Coords{},
1717
dimension: %Dimension{},
1818
tick: %TwoD{},
@@ -100,6 +100,14 @@ defmodule Matplotex.Figure.Areal.BarChart do
100100
value * s + transition - minl * s
101101
end
102102

103+
@impl Areal
104+
def with_legend_handle(
105+
%Legend{x: x, y: y, color: color, width: width, height: height} = legend,
106+
_dataset
107+
) do
108+
%Legend{legend | handle: %Rect{x: x, y: y, color: color, width: width, height: height}}
109+
end
110+
103111
def generate_ticks([{_l, _v} | _] = data) do
104112
{data, min_max(data)}
105113
end

lib/matplotex/figure/areal/line_plot.ex

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
defmodule Matplotex.Figure.Areal.LinePlot do
2+
alias Matplotex.Utils.Algebra
23
alias Matplotex.Figure.Areal.Region
34
alias Matplotex.Figure.Areal.Ticker
45
alias Matplotex.Figure.Marker
@@ -8,11 +9,11 @@ defmodule Matplotex.Figure.Areal.LinePlot do
89
alias Matplotex.Element.Line
910
alias Matplotex.Figure.Coords
1011
alias Matplotex.Figure
12+
alias Matplotex.Element.Legend
1113

1214
use Matplotex.Figure.Areal
1315

1416
frame(
15-
legend: %Legend{},
1617
coords: %Coords{},
1718
dimension: %Dimension{},
1819
tick: %TwoD{},
@@ -95,6 +96,28 @@ defmodule Matplotex.Figure.Areal.LinePlot do
9596
value * s + transition - minl * s
9697
end
9798

99+
@impl Areal
100+
def with_legend_handle(
101+
%Legend{x: x, y: y, color: color, width: marker_size} = legend,
102+
%Dataset{linestyle: linestyle}
103+
) do
104+
{x2, y2} = Algebra.transform_given_point(x, y, marker_size, marker_size / 2)
105+
106+
%Legend{
107+
legend
108+
| handle: %Line{
109+
type: "plot.line",
110+
x1: x,
111+
y1: y + marker_size / 2,
112+
x2: x2,
113+
y2: y2,
114+
stroke: color,
115+
fill: color,
116+
linestyle: linestyle
117+
}
118+
}
119+
end
120+
98121
def generate_ticks([{_l, _v} | _] = data) do
99122
{data, min_max(data)}
100123
end

lib/matplotex/figure/areal/scatter.ex

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ defmodule Matplotex.Figure.Areal.Scatter do
33
alias Matplotex.Figure.Areal.Ticker
44
alias Matplotex.Figure.Marker
55
alias Matplotex.Figure.Dataset
6-
6+
alias Matplotex.Element.Legend
77
alias Matplotex.Figure.Areal
88
alias Matplotex.Figure.RcParams
99

@@ -13,7 +13,6 @@ defmodule Matplotex.Figure.Areal.Scatter do
1313
use Areal
1414

1515
frame(
16-
legend: %Legend{},
1716
coords: %Coords{},
1817
dimension: %Dimension{},
1918
tick: %TwoD{},
@@ -136,6 +135,14 @@ defmodule Matplotex.Figure.Areal.Scatter do
136135
value * s + transition - minl * s
137136
end
138137

138+
@impl Areal
139+
def with_legend_handle(
140+
%Legend{x: x, y: y, color: color, width: marker_size} = legend,
141+
%Dataset{marker: marker}
142+
) do
143+
%Legend{legend | handle: Marker.marker_legend(marker, x, y, color, marker_size)}
144+
end
145+
139146
def generate_ticks([{_l, _v} | _] = data) do
140147
{data, min_max(data)}
141148
end

0 commit comments

Comments
 (0)