Skip to content

Commit

Permalink
framed axes and x/ylabel
Browse files Browse the repository at this point in the history
  • Loading branch information
davidaustinm committed Dec 9, 2024
1 parent bcb6809 commit 45f1ca2
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 9 deletions.
88 changes: 81 additions & 7 deletions prefig/core/grid_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ def axes(element, diagram, parent, outline_status):
top_labels = False
y_axis_location = 0
y_axis_offsets = (0,0)
h_zero_include = False
if bbox[1] * bbox[3] >= 0:
if bbox[3] <= 0:
top_labels = True
Expand All @@ -202,11 +203,24 @@ def axes(element, diagram, parent, outline_status):
if abs(bbox[1]) > 1e-10:
y_axis_location = bbox[1]
y_axis_offsets = (5,0)

h_frame = element.get('h-frame', None)
if h_frame == 'bottom':
y_axis_location = bbox[1]
y_axis_offsets = (0,0)
h_zero_include = True
if h_frame == 'top':
y_axis_location = bbox[3]
y_axis_offsets = (0,0)
h_zero_include = True
top_labels = True

y_axis_offsets = np.array(y_axis_offsets)

right_labels = False
x_axis_location = 0
x_axis_offsets = (0,0)
v_zero_include = False
if bbox[0] * bbox[2] >= 0:
if bbox[2] <= 0:
right_labels = True
Expand All @@ -217,8 +231,59 @@ def axes(element, diagram, parent, outline_status):
if abs(bbox[0]) > 1e-10:
x_axis_location = bbox[0]
x_axis_offsets = (10,0)

v_frame = element.get('v-frame', None)
if v_frame == 'left':
x_axis_location = bbox[0]
x_axis_offsets = (0,0)
v_zero_include = True
if v_frame == 'right':
x_axis_location = bbox[2]
x_axis_offsets = (0,0)
v_zero_include = True
right_labels = True

x_axis_offsets = np.array(x_axis_offsets)

try:
arrows = int(element.get('arrows', '0'))
except:
log.error(f"Error in <axes> parsing arrows={element.get('arrows')}")
arrows = 0

# process xlabel and ylabel
for child in element:
if child.tag == "xlabel":
child.tag = "label"
child.set("user-coords", "no")
anchor = diagram.transform((bbox[2], y_axis_location))
child.set("anchor", util.pt2str(anchor, spacer=","))
if child.get("alignment", None) is None:
child.set("alignment", "east")
if child.get("offset", None) is None:
if arrows > 0:
child.set("offset", "(2,0)")
else:
child.set("offset", "(1,0)")
label.label(child, diagram, parent)
continue
if child.tag == "ylabel":
child.tag = "label"
child.set("user-coords", "no")
anchor = diagram.transform((x_axis_location, bbox[3]))
child.set("anchor", util.pt2str(anchor, spacer=","))
if child.get("alignment", None) is None:
child.set("alignment", "north")
if child.get("offset", None) is None:
if arrows > 0:
child.set("offset", "(0,2)")
else:
child.set("offset", "(0,1)")
label.label(child, diagram, parent)
continue
log.info(f"{child.tag} element is not allowed inside a <label>")
continue

decorations = element.get('decorations', 'yes')

left_axis = diagram.transform((bbox[0], y_axis_location))
Expand Down Expand Up @@ -247,11 +312,6 @@ def axes(element, diagram, parent, outline_status):
v_line_el.set('stroke-width', thickness)
axes.append(v_line_el)

try:
arrows = int(element.get('arrows', '0'))
except:
log.error(f"Error in <axes> parsing arrows={element.get('arrows')}")
arrows = 0
if arrows > 0:
arrow.add_arrowhead_to_path(diagram, 'marker-end', h_line_el)
arrow.add_arrowhead_to_path(diagram, 'marker-end', v_line_el)
Expand Down Expand Up @@ -288,6 +348,10 @@ def axes(element, diagram, parent, outline_status):
)
diagram.add_id(g_hticks)

h_exclude = [bbox[0], bbox[2]]
if not h_zero_include:
h_exclude.append(0)

if diagram.output_format() == 'tactile':
ticksize = (18, 0)
else:
Expand Down Expand Up @@ -324,7 +388,7 @@ def axes(element, diagram, parent, outline_status):
if top_labels:
tick_direction = -1
while x <= hlabels[2]:
if any([abs(x*h_scale-p) < position_tolerance for p in [bbox[0], bbox[2],0]]):
if any([abs(x*h_scale-p) < position_tolerance for p in h_exclude]):
x += hlabels[1]
continue

Expand Down Expand Up @@ -382,6 +446,10 @@ def axes(element, diagram, parent, outline_status):
g_vticks = ET.SubElement(axes, 'g')
diagram.add_id(g_vticks)

v_exclude = [bbox[1], bbox[3]]
if not v_zero_include:
v_exclude.append(0)

if vticks is not None:
try:
vticks = un.valid_eval(vticks)
Expand Down Expand Up @@ -414,7 +482,7 @@ def axes(element, diagram, parent, outline_status):
if right_labels:
tick_direction = -1
while y <= vlabels[2]:
if any([abs(y*v_scale-p) < position_tolerance for p in [bbox[1], bbox[3], 0]]):
if any([abs(y*v_scale-p) < position_tolerance for p in v_exclude]):
y += vlabels[1]
continue

Expand Down Expand Up @@ -518,6 +586,12 @@ def grid_axes(element, diagram, parent, outline_status):
el.set('h-pi-format', element.get('h-pi-format'))
if element.get('v-pi-format') is not None:
el.set('v-pi-format', element.get('v-pi-format'))
if element.get('h-frame') is not None:
el.set('h-frame', element.get('h-frame'))
if element.get('v-frame') is not None:
el.set('v-frame', element.get('v-frame'))
for child in element:
el.append(child)

axes(el, diagram, group, outline_status)

Expand Down
24 changes: 22 additions & 2 deletions prefig/resources/schema/pf_schema.rnc
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,18 @@ Label = element label {
LabelText+
}

XLabel = element xlabel {
attribute at {text}?,
LabelAttributes,
LabelText+
}

YLabel = element ylabel {
attribute at {text}?,
LabelAttributes,
LabelText+
}

# elements that can go inside a path
PathElements = (
element moveto {
Expand Down Expand Up @@ -360,10 +372,14 @@ Axes = element axes {
attribute decorations {"yes"|"no"}?,
attribute h-pi-format {"yes"|"no"}?,
attribute v-pi-format {"yes"|"no"}?,
attribute h-frame {"bottom"|"top"}?,
attribute v-frame {"left"|"right"}?,
attribute labels {"yes"|"no"}?,
attribute stroke {text}?,
attribute thickness {text}?,
CommonAttributes
CommonAttributes,
XLabel?,
YLabel?
}

Grid = element grid {
Expand All @@ -386,14 +402,18 @@ Grid-Axes = element grid-axes {
attribute vspacing {text}?,
attribute h-pi-format {"yes"|"no"}?,
attribute v-pi-format {"yes"|"no"}?,
attribute h-frame {"bottom"|"top"}?,
attribute v-frame {"left"|"right"}?,
attribute hlabels {text}?,
attribute vlabels {text}?,
attribute xlabel {text}?,
attribute ylabel {text}?,
attribute arrows {text}?,
attribute decorations {"yes"|"no"}?,
attribute labels {"yes"|"no"}?,
CommonAttributes
CommonAttributes,
XLabel?,
YLabel?
}

Circle = element circle {
Expand Down
66 changes: 66 additions & 0 deletions prefig/resources/schema/pf_schema.rng
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,28 @@
</oneOrMore>
</element>
</define>
<define name="XLabel">
<element name="xlabel">
<optional>
<attribute name="at"/>
</optional>
<ref name="LabelAttributes"/>
<oneOrMore>
<ref name="LabelText"/>
</oneOrMore>
</element>
</define>
<define name="YLabel">
<element name="ylabel">
<optional>
<attribute name="at"/>
</optional>
<ref name="LabelAttributes"/>
<oneOrMore>
<ref name="LabelText"/>
</oneOrMore>
</element>
</define>
<!-- elements that can go inside a path -->
<define name="PathElements">
<interleave>
Expand Down Expand Up @@ -890,6 +912,22 @@
</choice>
</attribute>
</optional>
<optional>
<attribute name="h-frame">
<choice>
<value>bottom</value>
<value>top</value>
</choice>
</attribute>
</optional>
<optional>
<attribute name="v-frame">
<choice>
<value>left</value>
<value>right</value>
</choice>
</attribute>
</optional>
<optional>
<attribute name="labels">
<choice>
Expand All @@ -905,6 +943,12 @@
<attribute name="thickness"/>
</optional>
<ref name="CommonAttributes"/>
<optional>
<ref name="XLabel"/>
</optional>
<optional>
<ref name="YLabel"/>
</optional>
</element>
</define>
<define name="Grid">
Expand Down Expand Up @@ -979,6 +1023,22 @@
</choice>
</attribute>
</optional>
<optional>
<attribute name="h-frame">
<choice>
<value>bottom</value>
<value>top</value>
</choice>
</attribute>
</optional>
<optional>
<attribute name="v-frame">
<choice>
<value>left</value>
<value>right</value>
</choice>
</attribute>
</optional>
<optional>
<attribute name="hlabels"/>
</optional>
Expand Down Expand Up @@ -1011,6 +1071,12 @@
</attribute>
</optional>
<ref name="CommonAttributes"/>
<optional>
<ref name="XLabel"/>
</optional>
<optional>
<ref name="YLabel"/>
</optional>
</element>
</define>
<define name="Circle">
Expand Down

0 comments on commit 45f1ca2

Please sign in to comment.