UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

223 lines (191 loc) 6.07 kB
const shader = ` precision mediump float; attribute vec2 a_position; attribute vec2 a_center; attribute float a_width; // or radius or outer_radius attribute float a_height; // or inner_radius attribute float a_angle; // or start_angle attribute float a_aux; // or end_angle attribute float a_linewidth; attribute vec4 a_line_color; attribute vec4 a_fill_color; attribute float a_line_cap; attribute float a_line_join; attribute float a_show; #ifdef HATCH attribute float a_hatch_pattern; attribute float a_hatch_scale; attribute float a_hatch_weight; attribute vec4 a_hatch_color; #endif uniform vec2 u_canvas_size; uniform float u_antialias; #ifdef MULTI_MARKER uniform float u_size_hint; #endif #ifdef USE_ROUND_RECT uniform vec4 u_border_radius; varying vec4 v_border_radius; #endif #ifdef USE_ANNULAR_WEDGE varying float v_outer_radius; varying float v_inner_radius; varying float v_start_angle; varying float v_end_angle; #endif #ifdef USE_ANNULUS varying float v_outer_radius; varying float v_inner_radius; #endif #ifdef USE_WEDGE varying float v_radius; varying float v_start_angle; varying float v_end_angle; #endif #if defined(USE_CIRCLE) || defined(USE_NGON) varying float v_radius; #endif #ifdef USE_NGON varying float v_n; #endif varying float v_linewidth; varying vec2 v_size; // 2D size for rects compared to 1D for markers. varying vec4 v_line_color; varying vec4 v_fill_color; varying float v_line_cap; varying float v_line_join; varying vec2 v_coords; #ifdef HATCH varying float v_hatch_pattern; varying float v_hatch_scale; varying float v_hatch_weight; varying vec4 v_hatch_color; varying vec2 v_hatch_coords; #endif #ifdef MULTI_MARKER #define M_DASH 1 #define M_DOT 2 #define M_DIAMOND 3 #define M_HEX 4 #define M_SQUARE_PIN 5 #define M_TRIANGLE 6 #define M_TRIANGLE_PIN 7 #define M_STAR 8 vec2 enclosing_size() { // Need extra size of (v_linewidth+u_antialias) if edge of marker parallel to // edge of bounding box. If symmetric spike towards edge then multiply by // 1/cos(theta) where theta is angle between spike and bbox edges. int size_hint = int(u_size_hint + 0.5); if (size_hint == M_DASH) return vec2(v_size.x + v_linewidth + u_antialias, v_linewidth + u_antialias); else if (size_hint == M_DOT) return 0.25*v_size + u_antialias; else if (size_hint == M_DIAMOND) return vec2(v_size.x*(2.0/3.0) + (v_linewidth + u_antialias)*1.20185, v_size.y + (v_linewidth + u_antialias)*1.80278); else if (size_hint == M_HEX) return v_size + (v_linewidth + u_antialias)*vec2(2.0/sqrt(3.0), 1.0); else if (size_hint == M_SQUARE_PIN) // Square pin return v_size + (v_linewidth + u_antialias)*3.1; else if (size_hint == M_TRIANGLE) return vec2(v_size.x + (v_linewidth + u_antialias)*sqrt(3.0), v_size.y*(2.0/sqrt(3.0)) + (v_linewidth + u_antialias)*2.0); else if (size_hint == M_TRIANGLE_PIN) return v_size + (v_linewidth + u_antialias)*vec2(4.8, 6.0); else if (size_hint == M_STAR) return vec2(v_size.x*0.95106 + (v_linewidth + u_antialias)*3.0, v_size.y + (v_linewidth + u_antialias)*3.2); else return v_size + v_linewidth + u_antialias; } #else vec2 enclosing_size() { return v_size + v_linewidth + u_antialias; } #endif void main() { #if defined(USE_RECT) || defined(USE_ROUND_RECT) || defined(USE_HEX_TILE) v_size = vec2(a_width, a_height); #elif defined(USE_ANNULUS) || defined(USE_ANNULAR_WEDGE) || defined(USE_WEDGE) v_size = vec2(2.0*a_width, 2.0*a_width); #else v_size = vec2(a_width, a_width); #endif #ifdef USE_NGON v_n = a_aux; #endif if (a_show < 0.5 || v_size.x < 0.0 || v_size.y < 0.0 || (v_size.x == 0.0 && v_size.y == 0.0) #ifdef USE_NGON || v_n < 3.0 #endif ) { // Do not show this marker. gl_Position = vec4(-2.0, -2.0, 0.0, 1.0); return; } #ifdef USE_ANNULAR_WEDGE v_outer_radius = a_width; v_inner_radius = a_height; v_start_angle = a_angle; v_end_angle = a_aux; #endif #ifdef USE_ANNULUS v_outer_radius = a_width; v_inner_radius = a_height; #endif #ifdef USE_WEDGE v_radius = a_width; v_start_angle = a_angle; v_end_angle = a_aux; #endif #if defined(USE_CIRCLE) || defined(USE_NGON) v_radius = 0.5*a_width; #endif #ifdef USE_ROUND_RECT // Scale corner radii if they are too large, the same as canvas // https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-roundrect // Order of border_radius is top_left, top_right, bottom_right, bottom_left const vec2 unit2 = vec2(1.0, 1.0); float scale = min(v_size.x / max(dot(u_border_radius.xy, unit2), dot(u_border_radius.zw, unit2)), v_size.y / max(dot(u_border_radius.yz, unit2), dot(u_border_radius.wx, unit2))); v_border_radius = u_border_radius*min(scale, 1.0); #endif v_linewidth = a_linewidth; v_line_color = a_line_color; v_fill_color = a_fill_color; v_line_cap = a_line_cap; v_line_join = a_line_join; if (v_linewidth < 1.0) { // Linewidth less than 1 is implemented as 1 but with reduced alpha. v_line_color.a *= v_linewidth; v_linewidth = 1.0; } #ifdef HATCH v_hatch_pattern = a_hatch_pattern; v_hatch_scale = a_hatch_scale; v_hatch_weight = a_hatch_weight; v_hatch_color = a_hatch_color; #endif // Coordinates in rotated frame with respect to center of marker, used for // distance functions in fragment shader. v_coords = a_position*enclosing_size(); #if defined(USE_CIRCLE) || defined(USE_ANNULUS) || defined(USE_ANNULAR_WEDGE) || defined(USE_WEDGE) vec2 pos = a_center + v_coords; #else float c = cos(-a_angle); float s = sin(-a_angle); mat2 rotation = mat2(c, -s, s, c); vec2 pos = a_center + rotation*v_coords; #endif #ifdef HATCH // Coordinates for hatching in unrotated frame of reference. v_hatch_coords = pos - 0.5; #endif pos += 0.5; // Make up for Bokeh's offset. pos /= u_canvas_size; // 0 to 1. gl_Position = vec4(2.0*pos.x - 1.0, 1.0 - 2.0*pos.y, 0.0, 1.0); } `; export default shader;