1#-----------------------------------------------------------------------------
2# Copyright (c) 2012 - 2021, Anaconda, Inc., and Bokeh Contributors.
3# All rights reserved.
4#
5# The full license is in the file LICENSE.txt, distributed with this software.
6#-----------------------------------------------------------------------------
7''' Display a variety of visual shapes whose attributes can be associated
8with data columns from ``ColumnDataSources``.
9
10All these glyphs share a minimal common interface through their base class
11``Glyph``:
12
13.. autoclass:: Glyph
14    :members:
15
16'''
17
18#-----------------------------------------------------------------------------
19# Boilerplate
20#-----------------------------------------------------------------------------
21import logging # isort:skip
22log = logging.getLogger(__name__)
23
24#-----------------------------------------------------------------------------
25# Imports
26#-----------------------------------------------------------------------------
27
28# Standard library imports
29from inspect import Parameter
30
31# Bokeh imports
32from ..core.has_props import abstract
33from ..model import Model
34
35#-----------------------------------------------------------------------------
36# Globals and constants
37#-----------------------------------------------------------------------------
38
39__all__ = (
40    'ConnectedXYGlyph',
41    'Glyph',
42    'XYGlyph',
43)
44
45#-----------------------------------------------------------------------------
46# General API
47#-----------------------------------------------------------------------------
48
49@abstract
50class Glyph(Model):
51    ''' Base class for all glyph models.
52
53    '''
54
55    # a canonical order for positional args that can be
56    # used for any functions derived from this class
57    _args = ()
58
59    _extra_kws = {}
60
61    @classmethod
62    def parameters(cls):
63        ''' Generate Python ``Parameter`` values suitable for functions that are
64        derived from the glyph.
65
66        Returns:
67            list(Parameter)
68
69        '''
70        arg_params = []
71        no_more_defaults = False
72
73        for arg in reversed(cls._args):
74            descriptor = cls.lookup(arg)
75            default = descriptor.class_default(cls)
76            if default is None:
77                no_more_defaults = True
78            param = Parameter(
79                name=arg,
80                kind=Parameter.POSITIONAL_OR_KEYWORD,
81                # For positional arg properties, default=None means no default.
82                default=Parameter.empty if no_more_defaults else default
83            )
84            typ = descriptor.property._sphinx_type()
85            arg_params.insert(0, (param, typ, descriptor.__doc__))
86
87        # these are not really useful, and should also really be private, just skip them
88        omissions = {'js_event_callbacks', 'js_property_callbacks', 'subscribed_events'}
89
90        kwarg_params = []
91
92        kws = cls.properties() - set(cls._args) - omissions
93        for kw in kws:
94            descriptor = cls.lookup(kw)
95            param = Parameter(
96                name=kw,
97                kind=Parameter.KEYWORD_ONLY,
98                default=descriptor.class_default(cls)
99            )
100            typ = descriptor.property._sphinx_type()
101            kwarg_params.append((param, typ, descriptor.__doc__))
102
103        for kw, (typ, doc) in cls._extra_kws.items():
104            param = Parameter(
105                name=kw,
106                kind=Parameter.KEYWORD_ONLY,
107            )
108            kwarg_params.append((param, typ, doc))
109
110        kwarg_params.sort(key=lambda x: x[0].name)
111
112        return arg_params + kwarg_params
113
114@abstract
115class XYGlyph(Glyph):
116    ''' Base class of glyphs with `x` and `y` coordinate attributes.
117
118    '''
119
120@abstract
121class ConnectedXYGlyph(XYGlyph):
122    ''' Base class of glyphs with `x` and `y` coordinate attributes and
123    a connected topology.
124
125    '''
126
127@abstract
128class LineGlyph(Glyph):
129    ''' Glyphs with line properties
130    '''
131
132@abstract
133class FillGlyph(Glyph):
134    ''' Glyphs with fill properties
135    '''
136
137@abstract
138class TextGlyph(Glyph):
139    ''' Glyphs with text properties
140    '''
141
142@abstract
143class HatchGlyph(Glyph):
144    ''' Glyphs with Hatch properties
145    '''
146
147#-----------------------------------------------------------------------------
148# Dev API
149#-----------------------------------------------------------------------------
150
151#-----------------------------------------------------------------------------
152# Private API
153#-----------------------------------------------------------------------------
154
155#-----------------------------------------------------------------------------
156# Code
157#-----------------------------------------------------------------------------
158