Given a Dimension creates bokeh widgets to select along that
        dimension. For numeric data a slider widget is created which
        may be either discrete, if a holomap is supplied or the
        Dimension.values are set, or a continuous widget for
        DynamicMaps. If the slider is discrete the returned mapping
        defines a mapping between values and labels making it possible
        sync the two slider and label widgets. For non-numeric data
        a simple dropdown selection widget is generated.

def create_widget(self, dim, holomap=None, editable=False):
        """"
        Given a Dimension creates bokeh widgets to select along that
        dimension. For numeric data a slider widget is created which
        may be either discrete, if a holomap is supplied or the
        Dimension.values are set, or a continuous widget for
        DynamicMaps. If the slider is discrete the returned mapping
        defines a mapping between values and labels making it possible
        sync the two slider and label widgets. For non-numeric data
        a simple dropdown selection widget is generated.
        """
        label, mapping = None, None
        if holomap is None:
            if dim.values:
                if dim.default is None:
                    default = dim.values[0]
                elif dim.default not in dim.values:
                    raise ValueError("%s dimension default %r is not in dimension values: %s"
                                     % (dim, dim.default, dim.values))
                else:
                    default = dim.default
                value = dim.values.index(default)

                if all(isnumeric(v) for v in dim.values):
                    values = sorted(dim.values)
                    labels = [unicode(dim.pprint_value(v)) for v in values]
                    if editable:
                        label = AutocompleteInput(value=labels[value], completions=labels,
                                                  title=dim.pprint_label)
                    else:
                        label = Div(text='<b>%s</b>' % dim.pprint_value_string(labels[value]))
                    widget = Slider(value=value, start=0, end=len(dim.values)-1, title=None, step=1)
                    mapping = list(enumerate(zip(values, labels)))
                else:
                    values = [(v, dim.pprint_value(v)) for v in dim.values]
                    widget = Select(title=dim.pprint_label, value=values[value][0],
                                    options=values)
            else:
                start = dim.soft_range[0] if dim.soft_range[0] else dim.range[0]
                end = dim.soft_range[1] if dim.soft_range[1] else dim.range[1]
                dim_range = end - start
                int_type = isinstance(dim.type, type) and issubclass(dim.type, int)
                if dim.step is not None:
                    step = dim.step
                elif isinstance(dim_range, int) or int_type:
                    step = 1
                else:
                    step = 10**((round(math.log10(dim_range))-3))

                if dim.default is None:
                    default = start
                elif (dim.default < start or dim.default > end):
                    raise ValueError("%s dimension default %r is not in the provided range: %s"
                                     % (dim, dim.default, (start, end)))
                else:
                    default = dim.default

                if editable:
                    label = TextInput(value=str(default), title=dim.pprint_label)
                else:
                    label = Div(text='<b>%s</b>' % dim.pprint_value_string(default))
                widget = Slider(value=default, start=start,
                                end=end, step=step, title=None)
        else:
            values = (dim.values if dim.values else
                      list(unique_array(holomap.dimension_values(dim.name))))
            if dim.default is None:
                default = values[0]
            elif dim.default not in values:
                raise ValueError("%s dimension default %r is not in dimension values: %s"
                                 % (dim, dim.default, values))
            else:
                default = dim.default
            if isinstance(values[0], np.datetime64) or isnumeric(values[0]):
                values = sorted(values)
                labels = [dim.pprint_value(v) for v in values]
                value = values.index(default)
                if editable:
                    label = AutocompleteInput(value=labels[value], completions=labels,
                                              title=dim.pprint_label)
                else:
                    label = Div(text='<b>%s</b>' % (dim.pprint_value_string(labels[value])))
                widget = Slider(value=value, start=0, end=len(values)-1, title=None, step=1)
            else:
                labels = [dim.pprint_value(v) for v in values]
                widget = Select(title=dim.pprint_label, value=default,
                                options=list(zip(values, labels)))
            mapping = list(enumerate(zip(values, labels)))
        return widget, label, mapping