Source code for highcharts_core.options.plot_options.sankey

from typing import Optional
from decimal import Decimal

from validator_collection import validators

from highcharts_core import errors
from highcharts_core.options.plot_options.dependencywheel import DependencyWheelOptions


[docs]class SankeyOptions(DependencyWheelOptions): """General options to apply to all Sankey series types. A sankey diagram is a type of flow diagram, in which the width of the link between two nodes is shown proportionally to the flow quantity. .. tabs:: .. tab:: Standard Sankey .. figure:: ../../../_static/sankey-example.png :alt: Sankey Example Chart :align: center .. tab:: Inverted Sankey .. figure:: ../../../_static/sankey-example-inverted.png :alt: Inverted Sankey Example Chart :align: center .. tab:: Sankey with Outgoing Links .. figure:: ../../../_static/sankey-example-outgoing.png :alt: Sankey Example Chart with Outgoing Links :align: center """ def __init__(self, **kwargs): self._link_color_mode = None self._node_alignment = None self._node_distance = None self.link_color_mode = kwargs.get('link_color_mode', None) self.node_alignment = kwargs.get('node_alignment', None) self.node_distance = kwargs.get('node_distance', None) super().__init__(**kwargs) @property def link_color_mode(self) -> Optional[str]: """Determines color mode for sankey links. Available options: * ``'from'`` - color of the sankey link will be the same as the ``.from`` node * ``'gradient'`` - color of the sankey link will be set to gradient between colors of the ``.from`` node and the ``.to`` node * ``'to'`` - color of the sankey link will be same as the ``.to`` Defaults to ``'from'``. :rtype: :class:`str <python:str>` or :obj:`None <python:None>` """ return self._link_color_mode @link_color_mode.setter def link_color_mode(self, value): if not value: self._link_color_mode = None else: value = validators.string(value) value = value.lower() if value not in ['from', 'gradient', 'to']: raise errors.HighchartsValueError( f'link_color_mode expects a value of either "from", ' f'"gradient", or "to". Received "{value}"') self._link_color_mode = value @property def node_alignment(self) -> Optional[str]: """Determines on which side of the chart the nodes are to be aligned. Accepts: * ``'top'`` * ``'center'`` * ``'bottom'`` .. note:: When the chart is inverted, ``'top'`` aligns to the left and ``'bottom'`` to the right. :rtype: :class:`str <python:str>` or :obj:`None <python:None>` """ return self._node_alignment @node_alignment.setter def node_alignment(self, value): if not value: self._node_alignment = None else: value = validators.string(value) value = value.lower() if value not in ['top', 'center', 'bottom']: raise errors.HighchartsValueError(f'node_alignment expects a value' f'of either "top", "center", or ' f'"bottom". Received "{value}"') self._node_alignment = value @property def node_distance(self) -> Optional[str | int | float | Decimal]: """The distance between nodes in a sankey diagram in the longitudinal direction. Defaults to ``30``. .. note:: The longitudinal direction means the direction that the chart flows - in a horizontal chart the distance is horizontal, in an inverted chart (vertical), the distance is vertical. If a number is given, it denotes pixels. If a percentage string is given, the distance is a percentage of the rendered node width. A value of 100% will render equal widths for the nodes and the gaps between them. .. note:: This option applies only when the ``.node_width`` option is ``'auto'``, making the node width respond to the number of columns. :rtype: :class:`str <python:str>` or numeric or :obj:`None <python:None>` """ return self._node_distance @node_distance.setter def node_distance(self, value): if value is None: self._node_distance = None else: try: value = validators.string(value) if "%" not in value: raise ValueError except (TypeError, ValueError): value = validators.numeric(value) self._node_distance = value @property def node_width(self) -> Optional[str | int | float | Decimal]: """The pixel width of each node in a sankey diagram, or the height in case the chart is inverted. Defaults to ``20``. Can be a number, a percentage string, or ``'auto'``. If ``'auto'``, the nodes are sized to fill up the plot area in the longitudinal direction, regardless of the number of levels. :rtype: :class:`str <python:str>` or numeric or :obj:`None <python:None>` """ return self._node_width @node_width.setter def node_width(self, value): if value is None: self._node_width = None else: try: value = validators.string(value) value = value.lower() if value != 'auto' and "%" not in value: raise ValueError except (TypeError, ValueError): value = validators.numeric(value) self._node_width = value @classmethod def _get_kwargs_from_dict(cls, as_dict): kwargs = { 'accessibility': as_dict.get('accessibility', None), 'allow_point_select': as_dict.get('allowPointSelect', None), 'animation': as_dict.get('animation', None), 'class_name': as_dict.get('className', None), 'clip': as_dict.get('clip', None), 'color': as_dict.get('color', None), 'cursor': as_dict.get('cursor', None), 'custom': as_dict.get('custom', None), 'dash_style': as_dict.get('dashStyle', None), 'data_labels': as_dict.get('dataLabels', None), 'description': as_dict.get('description', None), 'enable_mouse_tracking': as_dict.get('enableMouseTracking', None), 'events': as_dict.get('events', None), 'include_in_data_export': as_dict.get('includeInDataExport', None), 'keys': as_dict.get('keys', None), 'label': as_dict.get('label', None), 'legend_symbol': as_dict.get('legendSymbol', None), 'linked_to': as_dict.get('linkedTo', None), 'marker': as_dict.get('marker', None), 'on_point': as_dict.get('onPoint', None), 'opacity': as_dict.get('opacity', None), 'point': as_dict.get('point', None), 'point_description_formatter': as_dict.get('pointDescriptionFormatter', None), 'selected': as_dict.get('selected', None), 'show_checkbox': as_dict.get('showCheckbox', None), 'show_in_legend': as_dict.get('showInLegend', None), 'skip_keyboard_navigation': as_dict.get('skipKeyboardNavigation', None), 'sonification': as_dict.get('sonification', None), 'states': as_dict.get('states', None), 'sticky_tracking': as_dict.get('stickyTracking', None), 'threshold': as_dict.get('threshold', None), 'tooltip': as_dict.get('tooltip', None), 'turbo_threshold': as_dict.get('turboThreshold', None), 'visible': as_dict.get('visible', None), 'border_color': as_dict.get('borderColor', None), 'border_width': as_dict.get('borderWidth', None), 'center': as_dict.get('center', None), 'center_in_category': as_dict.get('centerInCategory', None), 'color_by_point': as_dict.get('colorByPoint', None), 'color_index': as_dict.get('colorIndex', None), 'colors': as_dict.get('colors', None), 'curve_factor': as_dict.get('curveFactor', None), 'levels': as_dict.get('levels', None), 'link_opacity': as_dict.get('linkOpacity', None), 'min_link_width': as_dict.get('minLinkWidth', None), 'node_padding': as_dict.get('nodePadding', None), 'node_width': as_dict.get('nodeWidth', None), 'start_angle': as_dict.get('startAngle', None), 'link_color_mode': as_dict.get('linkColorMode', None), 'node_alignment': as_dict.get('nodeAlignment', None), 'node_distance': as_dict.get('nodeDistance', None), } return kwargs def _to_untrimmed_dict(self, in_cls = None) -> dict: untrimmed = { 'linkColorMode': self.link_color_mode, 'nodeAlignment': self.node_alignment, 'nodeDistance': self.node_distance, } parent_as_dict = super()._to_untrimmed_dict(in_cls = in_cls) for key in parent_as_dict: untrimmed[key] = parent_as_dict[key] return untrimmed