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