dbt-selly/dbt-env/lib/python3.8/site-packages/leather/scales/ordinal.py

64 lines
1.9 KiB
Python

#!/usr/bin/env python
from decimal import Decimal
from leather.scales.base import Scale
class Ordinal(Scale):
"""
A scale that maps individual values (e.g. strings) to a range.
"""
def __init__(self, domain):
self._domain = domain
def contains(self, v):
"""
Return :code:`True` if a given value is contained within this scale's
displayed domain.
"""
return v in self._domain
def project(self, value, range_min, range_max):
"""
Project a value in this scale's domain to a target range.
"""
range_min = Decimal(range_min)
range_max = Decimal(range_max)
segments = len(self._domain)
segment_size = (range_max - range_min) / segments
try:
pos = range_min + (self._domain.index(value) * segment_size) + (segment_size / 2)
except ValueError:
raise ValueError('Value "%s" is not present in Ordinal scale domain' % value)
return pos
def project_interval(self, value, range_min, range_max):
"""
Project a value in this scale's domain to an interval in the target
range. This is used for places :class:`.Bars` and :class:`.Columns`.
"""
range_min = Decimal(range_min)
range_max = Decimal(range_max)
segments = len(self._domain)
segment_size = (range_max - range_min) / segments
gap = segment_size / Decimal(20)
try:
a = range_min + (self._domain.index(value) * segment_size) + gap
b = range_min + ((self._domain.index(value) + 1) * segment_size) - gap
except ValueError:
raise ValueError('Value "%s" is not present in Ordinal scale domain' % value)
return (a, b)
def ticks(self):
"""
Generate a series of ticks for this scale.
"""
return self._domain