class_docstr: Graph super class containing generic common functions
class_docstr_tok: ["Graph","super","class","containing","generic","common","functions"]
docstr: Make the x axis: labels and guides
code: def _x_axis(self):
      """Make the x axis: labels and guides"""
      if not self._x_labels or not self.show_x_labels:
          return
      axis = self.svg.node(
          self.nodes["plot"],
          class_="axis x%s"
          % (" always_show" if self.show_x_guides else ""),
      )
      truncation = self.truncate_label
      if not truncation:
          if self.x_label_rotation or len(self._x_labels) <= 1:
              truncation = 25
          else:
              first_label_position = (
                  self.view.x(self._x_labels[0][1]) or 0
              )
              last_label_position = (
                  self.view.x(self._x_labels[-1][1]) or 0
              )
              available_space = (
                  last_label_position - first_label_position
              ) / len(self._x_labels) - 1
  
              truncation = reverse_text_len(
                  available_space, self.style.label_font_size
              )
              truncation = max(truncation, 1)
  
      lastlabel = self._x_labels[-1][0]
      if 0 not in [label[1] for label in self._x_labels]:
          self.svg.node(
              axis,
              "path",
              d="M%f %f v%f" % (0, 0, self.view.height),
              class_="line",
          )
          lastlabel = None
  
      for label, position in self._x_labels:
          if self.horizontal:
              major = position in self._x_labels_major
          else:
              major = label in self._x_labels_major
          if not (self.show_minor_x_labels or major):
              continue
          guides = self.svg.node(axis, class_="guides")
          x = self.view.x(position)
          if x is None:
              continue
          y = self.view.height + 5
          last_guide = self._y_2nd_labels and label == lastlabel
          self.svg.node(
              guides,
              "path",
              d="M%f %f v%f" % (x or 0, 0, self.view.height),
              class_="%s%s%sline"
              % (
                  "axis " if label == "0" else "",
                  "major " if major else "",
                  "guide " if position != 0 and not last_guide else "",
              ),
          )
          y += 0.5 * self.style.label_font_size + 5
          text = self.svg.node(
              guides, "text", x=x, y=y, class_="major" if major else ""
          )
  
          text.text = truncate(label, truncation)
          if text.text != label:
              self.svg.node(guides, "title").text = label
          elif self._dual:
              self.svg.node(
                  guides,
                  "title",
              ).text = self._x_format(position)
  
          if self.x_label_rotation:
              text.attrib["transform"] = "rotate(%d %f %f)" % (
                  self.x_label_rotation,
                  x,
                  y,
              )
              if self.x_label_rotation >= 180:
                  text.attrib["class"] = " ".join(
                      (
                          text.attrib["class"]
                          and text.attrib["class"].split(" ")
                          or []
                      )
                      + ["backwards"]
                  )
  
      if self._y_2nd_labels and 0 not in [
          label[1] for label in self._x_labels
      ]:
          self.svg.node(
              axis,
              "path",
              d="M%f %f v%f" % (self.view.width, 0, self.view.height),
              class_="line",
          )
  
      if self._x_2nd_labels:
          secondary_ax = self.svg.node(
              self.nodes["plot"],
              class_="axis x x2%s"
              % (" always_show" if self.show_x_guides else ""),
          )
          for label, position in self._x_2nd_labels:
              major = label in self._x_labels_major
              if not (self.show_minor_x_labels or major):
                  continue
              # it is needed, to have the same structure as primary axis
              guides = self.svg.node(secondary_ax, class_="guides")
              x = self.view.x(position)
              y = -5
              text = self.svg.node(
                  guides,
                  "text",
                  x=x,
                  y=y,
                  class_="major" if major else "",
              )
              text.text = label
              if self.x_label_rotation:
                  text.attrib["transform"] = "rotate(%d %f %f)" % (
                      -self.x_label_rotation,
                      x,
                      y,
                  )
                  if self.x_label_rotation >= 180:
                      text.attrib["class"] = " ".join(
                          (
                              text.attrib["class"]
                              and text.attrib["class"].split(" ")
                              or []
                          )
                          + ["backwards"]
                      )
  
imports: from math import ceil, cos, sin, sqrt
  from pygal import stats
  from pygal._compat import is_list_like
  from pygal.graph.public import PublicApi
  from pygal.interpolate import INTERPOLATIONS
  from pygal.util import cached_property, compute_scale, cut, decorate, filter_kwargs, get_text_box, get_texts_box, majorize, rad, reverse_text_len, split_title, truncate
  from pygal.view import LogView, ReverseView, View, XYLogView
label_desc: Use image node_id 5 for calling the Graph obj's underlying member method code with example usage: obj._x_axis() without return types