diff --git a/avenger-vega-test-data/vega-scenegraphs/clip/bar_rounded.png b/avenger-vega-test-data/vega-scenegraphs/clip/bar_rounded.png new file mode 100644 index 0000000..12ea28a Binary files /dev/null and b/avenger-vega-test-data/vega-scenegraphs/clip/bar_rounded.png differ diff --git a/avenger-vega-test-data/vega-scenegraphs/clip/bar_rounded.sg.json b/avenger-vega-test-data/vega-scenegraphs/clip/bar_rounded.sg.json new file mode 100644 index 0000000..d771182 --- /dev/null +++ b/avenger-vega-test-data/vega-scenegraphs/clip/bar_rounded.sg.json @@ -0,0 +1,1903 @@ +{ + "width": 352, + "height": 242, + "origin": [ + 44, + 5 + ], + "scenegraph": { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 200, + "x2": 240 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 169, + "x2": 240 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 138, + "x2": 240 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 108, + "x2": 240 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 77, + "x2": 240 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 46, + "x2": 240 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 15, + "x2": 240 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "left", + "offset": 0, + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 10 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 30 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 50 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 70 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 90 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 110 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 130 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 150 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 170 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 190 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 210 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 230 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 9.5, + "y": 7, + "angle": 0, + "limit": 180, + "text": "Jan", + "align": "center", + "baseline": "top" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 29.5, + "y": 7, + "angle": 0, + "limit": 180, + "text": "Feb", + "align": "center", + "baseline": "top" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 49.5, + "y": 7, + "angle": 0, + "limit": 180, + "text": "Mar", + "align": "center", + "baseline": "top" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 69.5, + "y": 7, + "angle": 0, + "limit": 180, + "text": "Apr", + "align": "center", + "baseline": "top" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 89.5, + "y": 7, + "angle": 0, + "limit": 180, + "text": "May", + "align": "center", + "baseline": "top" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 109.5, + "y": 7, + "angle": 0, + "limit": 180, + "text": "Jun", + "align": "center", + "baseline": "top" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 129.5, + "y": 7, + "angle": 0, + "limit": 180, + "text": "Jul", + "align": "center", + "baseline": "top" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 149.5, + "y": 7, + "angle": 0, + "limit": 180, + "text": "Aug", + "align": "center", + "baseline": "top" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 169.5, + "y": 7, + "angle": 0, + "limit": 180, + "text": "Sep", + "align": "center", + "baseline": "top" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 189.5, + "y": 7, + "angle": 0, + "limit": 180, + "text": "Oct", + "align": "center", + "baseline": "top" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 209.5, + "y": 7, + "angle": 0, + "limit": 180, + "text": "Nov", + "align": "center", + "baseline": "top" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 229.5, + "y": 7, + "angle": 0, + "limit": 180, + "text": "Dec", + "align": "center", + "baseline": "top" + } + ], + "marktype": "text", + "role": "axis-label", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "x2": 240, + "y": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 11, + "fontWeight": "bold", + "opacity": 1, + "align": "center", + "angle": 0, + "baseline": "top", + "text": "date (month)", + "x": 120, + "y": 21 + } + ], + "marktype": "text", + "role": "axis-title", + "zindex": 0 + } + ], + "orient": "bottom", + "offset": 0, + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 200, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 169, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 138, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 108, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 77, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 46, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 15, + "x": 0, + "x2": -5 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": -7, + "y": 200, + "angle": 0, + "limit": 180, + "text": "0", + "align": "right", + "baseline": "middle" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": -7, + "y": 169.23076923076923, + "angle": 0, + "limit": 180, + "text": "20", + "align": "right", + "baseline": "middle" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": -7, + "y": 138.46153846153845, + "angle": 0, + "limit": 180, + "text": "40", + "align": "right", + "baseline": "middle" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": -7, + "y": 107.6923076923077, + "angle": 0, + "limit": 180, + "text": "60", + "align": "right", + "baseline": "middle" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": -7, + "y": 76.92307692307692, + "angle": 0, + "limit": 180, + "text": "80", + "align": "right", + "baseline": "middle" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": -7, + "y": 46.153846153846146, + "angle": 0, + "limit": 180, + "text": "100", + "align": "right", + "baseline": "middle" + }, + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": -7, + "y": 15.384615384615374, + "angle": 0, + "limit": 180, + "text": "120", + "align": "right", + "baseline": "middle" + } + ], + "marktype": "text", + "role": "axis-label", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "y": 200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 11, + "fontWeight": "bold", + "opacity": 1, + "align": "center", + "angle": -90, + "baseline": "bottom", + "text": "Count of Records", + "y": 100, + "x": -27.6845703125 + } + ], + "marktype": "text", + "role": "axis-title", + "zindex": 0 + } + ], + "orient": "left", + "offset": 0, + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "fill": "#4c78a8", + "ariaRoleDescription": "bar", + "description": "date (month): Dec; Count of Records: 3; weather: drizzle", + "width": 18, + "y": 9.23076923076922, + "y2": 13.846153846153841, + "height": 4.615384615384622 + }, + { + "fill": "#e45756", + "ariaRoleDescription": "bar", + "description": "date (month): Dec; Count of Records: 73; weather: rain", + "width": 18, + "y": 26.15384615384615, + "y2": 138.46153846153845, + "height": 112.3076923076923 + }, + { + "fill": "#54a24b", + "ariaRoleDescription": "bar", + "description": "date (month): Dec; Count of Records: 34; weather: sun", + "width": 18, + "y": 147.6923076923077, + "y2": 200, + "height": 52.30769230769229 + }, + { + "fill": "#72b7b2", + "ariaRoleDescription": "bar", + "description": "date (month): Dec; Count of Records: 6; weather: snow", + "width": 18, + "y": 138.46153846153845, + "y2": 147.6923076923077, + "height": 9.230769230769255 + }, + { + "fill": "#f58518", + "ariaRoleDescription": "bar", + "description": "date (month): Dec; Count of Records: 8; weather: fog", + "width": 18, + "y": 13.846153846153841, + "y2": 26.15384615384615, + "height": 12.307692307692308 + } + ], + "marktype": "rect", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "y": -9.23076923076922, + "width": 18 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 221, + "width": 18, + "y": 9.23076923076922, + "y2": 200, + "clip": true, + "cornerRadiusTopLeft": 10, + "cornerRadiusTopRight": 5, + "height": 190.76923076923077 + }, + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "fill": "#e45756", + "ariaRoleDescription": "bar", + "description": "date (month): Jan; Count of Records: 65; weather: rain", + "width": 18, + "y": 49.23076923076923, + "y2": 149.23076923076923, + "height": 100 + }, + { + "fill": "#54a24b", + "ariaRoleDescription": "bar", + "description": "date (month): Jan; Count of Records: 25; weather: sun", + "width": 18, + "y": 161.53846153846155, + "y2": 200, + "height": 38.46153846153845 + }, + { + "fill": "#72b7b2", + "ariaRoleDescription": "bar", + "description": "date (month): Jan; Count of Records: 8; weather: snow", + "width": 18, + "y": 149.23076923076923, + "y2": 161.53846153846155, + "height": 12.30769230769232 + }, + { + "fill": "#4c78a8", + "ariaRoleDescription": "bar", + "description": "date (month): Jan; Count of Records: 9; weather: drizzle", + "width": 18, + "y": 9.23076923076922, + "y2": 23.076923076923084, + "height": 13.846153846153864 + }, + { + "fill": "#f58518", + "ariaRoleDescription": "bar", + "description": "date (month): Jan; Count of Records: 17; weather: fog", + "width": 18, + "y": 23.076923076923084, + "y2": 49.23076923076923, + "height": 26.15384615384615 + } + ], + "marktype": "rect", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "y": -9.23076923076922, + "width": 18 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 1, + "width": 18, + "y": 9.23076923076922, + "y2": 200, + "clip": true, + "cornerRadiusTopLeft": 10, + "cornerRadiusTopRight": 5, + "height": 190.76923076923077 + }, + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "fill": "#54a24b", + "ariaRoleDescription": "bar", + "description": "date (month): Feb; Count of Records: 29; weather: sun", + "width": 18, + "y": 155.3846153846154, + "y2": 200, + "height": 44.61538461538461 + }, + { + "fill": "#e45756", + "ariaRoleDescription": "bar", + "description": "date (month): Feb; Count of Records: 73; weather: rain", + "width": 18, + "y": 36.92307692307693, + "y2": 149.23076923076923, + "height": 112.30769230769229 + }, + { + "fill": "#4c78a8", + "ariaRoleDescription": "bar", + "description": "date (month): Feb; Count of Records: 4; weather: drizzle", + "width": 18, + "y": 26.15384615384615, + "y2": 32.30769230769231, + "height": 6.153846153846157 + }, + { + "fill": "#72b7b2", + "ariaRoleDescription": "bar", + "description": "date (month): Feb; Count of Records: 4; weather: snow", + "width": 18, + "y": 149.23076923076923, + "y2": 155.3846153846154, + "height": 6.15384615384616 + }, + { + "fill": "#f58518", + "ariaRoleDescription": "bar", + "description": "date (month): Feb; Count of Records: 3; weather: fog", + "width": 18, + "y": 32.30769230769231, + "y2": 36.92307692307693, + "height": 4.61538461538462 + } + ], + "marktype": "rect", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "y": -26.15384615384615, + "width": 18 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 21, + "width": 18, + "y": 26.15384615384615, + "y2": 200, + "clip": true, + "cornerRadiusTopLeft": 10, + "cornerRadiusTopRight": 5, + "height": 173.84615384615384 + }, + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "fill": "#e45756", + "ariaRoleDescription": "bar", + "description": "date (month): Mar; Count of Records: 73; weather: rain", + "width": 18, + "y": 23.076923076923084, + "y2": 135.3846153846154, + "height": 112.3076923076923 + }, + { + "fill": "#54a24b", + "ariaRoleDescription": "bar", + "description": "date (month): Mar; Count of Records: 36; weather: sun", + "width": 18, + "y": 144.6153846153846, + "y2": 200, + "height": 55.38461538461539 + }, + { + "fill": "#72b7b2", + "ariaRoleDescription": "bar", + "description": "date (month): Mar; Count of Records: 6; weather: snow", + "width": 18, + "y": 135.3846153846154, + "y2": 144.6153846153846, + "height": 9.230769230769226 + }, + { + "fill": "#4c78a8", + "ariaRoleDescription": "bar", + "description": "date (month): Mar; Count of Records: 3; weather: drizzle", + "width": 18, + "y": 9.23076923076922, + "y2": 13.846153846153841, + "height": 4.615384615384622 + }, + { + "fill": "#f58518", + "ariaRoleDescription": "bar", + "description": "date (month): Mar; Count of Records: 6; weather: fog", + "width": 18, + "y": 13.846153846153841, + "y2": 23.076923076923084, + "height": 9.230769230769242 + } + ], + "marktype": "rect", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "y": -9.23076923076922, + "width": 18 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 41, + "width": 18, + "y": 9.23076923076922, + "y2": 200, + "clip": true, + "cornerRadiusTopLeft": 10, + "cornerRadiusTopRight": 5, + "height": 190.76923076923077 + }, + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "fill": "#54a24b", + "ariaRoleDescription": "bar", + "description": "date (month): Apr; Count of Records: 53; weather: sun", + "width": 18, + "y": 118.46153846153847, + "y2": 200, + "height": 81.53846153846153 + }, + { + "fill": "#e45756", + "ariaRoleDescription": "bar", + "description": "date (month): Apr; Count of Records: 60; weather: rain", + "width": 18, + "y": 24.615384615384617, + "y2": 116.9230769230769, + "height": 92.30769230769229 + }, + { + "fill": "#72b7b2", + "ariaRoleDescription": "bar", + "description": "date (month): Apr; Count of Records: 1; weather: snow", + "width": 18, + "y": 116.9230769230769, + "y2": 118.46153846153847, + "height": 1.5384615384615614 + }, + { + "fill": "#4c78a8", + "ariaRoleDescription": "bar", + "description": "date (month): Apr; Count of Records: 3; weather: drizzle", + "width": 18, + "y": 15.384615384615374, + "y2": 19.999999999999996, + "height": 4.615384615384622 + }, + { + "fill": "#f58518", + "ariaRoleDescription": "bar", + "description": "date (month): Apr; Count of Records: 3; weather: fog", + "width": 18, + "y": 19.999999999999996, + "y2": 24.615384615384617, + "height": 4.61538461538462 + } + ], + "marktype": "rect", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "y": -15.384615384615374, + "width": 18 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 61, + "width": 18, + "y": 15.384615384615374, + "y2": 200, + "clip": true, + "cornerRadiusTopLeft": 10, + "cornerRadiusTopRight": 5, + "height": 184.6153846153846 + }, + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "fill": "#e45756", + "ariaRoleDescription": "bar", + "description": "date (month): May; Count of Records: 41; weather: rain", + "width": 18, + "y": 18.461538461538463, + "y2": 81.53846153846153, + "height": 63.076923076923066 + }, + { + "fill": "#54a24b", + "ariaRoleDescription": "bar", + "description": "date (month): May; Count of Records: 77; weather: sun", + "width": 18, + "y": 81.53846153846153, + "y2": 200, + "height": 118.46153846153847 + }, + { + "fill": "#4c78a8", + "ariaRoleDescription": "bar", + "description": "date (month): May; Count of Records: 1; weather: drizzle", + "width": 18, + "y": 9.23076923076922, + "y2": 10.769230769230775, + "height": 1.538461538461556 + }, + { + "fill": "#f58518", + "ariaRoleDescription": "bar", + "description": "date (month): May; Count of Records: 5; weather: fog", + "width": 18, + "y": 10.769230769230775, + "y2": 18.461538461538463, + "height": 7.692307692307688 + } + ], + "marktype": "rect", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "y": -9.23076923076922, + "width": 18 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 81, + "width": 18, + "y": 9.23076923076922, + "y2": 200, + "clip": true, + "cornerRadiusTopLeft": 10, + "cornerRadiusTopRight": 5, + "height": 190.76923076923077 + }, + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "fill": "#e45756", + "ariaRoleDescription": "bar", + "description": "date (month): Jun; Count of Records: 41; weather: rain", + "width": 18, + "y": 19.999999999999996, + "y2": 83.07692307692307, + "height": 63.076923076923066 + }, + { + "fill": "#54a24b", + "ariaRoleDescription": "bar", + "description": "date (month): Jun; Count of Records: 76; weather: sun", + "width": 18, + "y": 83.07692307692307, + "y2": 200, + "height": 116.92307692307693 + }, + { + "fill": "#4c78a8", + "ariaRoleDescription": "bar", + "description": "date (month): Jun; Count of Records: 2; weather: drizzle", + "width": 18, + "y": 15.384615384615374, + "y2": 18.461538461538463, + "height": 3.076923076923089 + }, + { + "fill": "#f58518", + "ariaRoleDescription": "bar", + "description": "date (month): Jun; Count of Records: 1; weather: fog", + "width": 18, + "y": 18.461538461538463, + "y2": 19.999999999999996, + "height": 1.538461538461533 + } + ], + "marktype": "rect", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "y": -15.384615384615374, + "width": 18 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 101, + "width": 18, + "y": 15.384615384615374, + "y2": 200, + "clip": true, + "cornerRadiusTopLeft": 10, + "cornerRadiusTopRight": 5, + "height": 184.6153846153846 + }, + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "fill": "#e45756", + "ariaRoleDescription": "bar", + "description": "date (month): Jul; Count of Records: 15; weather: rain", + "width": 18, + "y": 38.46153846153846, + "y2": 61.53846153846154, + "height": 23.07692307692308 + }, + { + "fill": "#54a24b", + "ariaRoleDescription": "bar", + "description": "date (month): Jul; Count of Records: 90; weather: sun", + "width": 18, + "y": 61.53846153846154, + "y2": 200, + "height": 138.46153846153845 + }, + { + "fill": "#4c78a8", + "ariaRoleDescription": "bar", + "description": "date (month): Jul; Count of Records: 9; weather: drizzle", + "width": 18, + "y": 9.23076923076922, + "y2": 23.076923076923084, + "height": 13.846153846153864 + }, + { + "fill": "#f58518", + "ariaRoleDescription": "bar", + "description": "date (month): Jul; Count of Records: 10; weather: fog", + "width": 18, + "y": 23.076923076923084, + "y2": 38.46153846153846, + "height": 15.384615384615376 + } + ], + "marktype": "rect", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "y": -9.23076923076922, + "width": 18 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 121, + "width": 18, + "y": 9.23076923076922, + "y2": 200, + "clip": true, + "cornerRadiusTopLeft": 10, + "cornerRadiusTopRight": 5, + "height": 190.76923076923077 + }, + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "fill": "#54a24b", + "ariaRoleDescription": "bar", + "description": "date (month): Aug; Count of Records: 86; weather: sun", + "width": 18, + "y": 67.6923076923077, + "y2": 200, + "height": 132.30769230769232 + }, + { + "fill": "#e45756", + "ariaRoleDescription": "bar", + "description": "date (month): Aug; Count of Records: 25; weather: rain", + "width": 18, + "y": 29.230769230769237, + "y2": 67.6923076923077, + "height": 38.46153846153845 + }, + { + "fill": "#4c78a8", + "ariaRoleDescription": "bar", + "description": "date (month): Aug; Count of Records: 7; weather: drizzle", + "width": 18, + "y": 9.23076923076922, + "y2": 19.999999999999996, + "height": 10.769230769230777 + }, + { + "fill": "#f58518", + "ariaRoleDescription": "bar", + "description": "date (month): Aug; Count of Records: 6; weather: fog", + "width": 18, + "y": 19.999999999999996, + "y2": 29.230769230769237, + "height": 9.23076923076924 + } + ], + "marktype": "rect", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "y": -9.23076923076922, + "width": 18 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 141, + "width": 18, + "y": 9.23076923076922, + "y2": 200, + "clip": true, + "cornerRadiusTopLeft": 10, + "cornerRadiusTopRight": 5, + "height": 190.76923076923077 + }, + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "fill": "#54a24b", + "ariaRoleDescription": "bar", + "description": "date (month): Sep; Count of Records: 64; weather: sun", + "width": 18, + "y": 101.53846153846153, + "y2": 200, + "height": 98.46153846153847 + }, + { + "fill": "#e45756", + "ariaRoleDescription": "bar", + "description": "date (month): Sep; Count of Records: 36; weather: rain", + "width": 18, + "y": 46.153846153846146, + "y2": 101.53846153846153, + "height": 55.38461538461539 + }, + { + "fill": "#f58518", + "ariaRoleDescription": "bar", + "description": "date (month): Sep; Count of Records: 15; weather: fog", + "width": 18, + "y": 23.076923076923084, + "y2": 46.153846153846146, + "height": 23.076923076923062 + }, + { + "fill": "#4c78a8", + "ariaRoleDescription": "bar", + "description": "date (month): Sep; Count of Records: 5; weather: drizzle", + "width": 18, + "y": 15.384615384615374, + "y2": 23.076923076923084, + "height": 7.692307692307709 + } + ], + "marktype": "rect", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "y": -15.384615384615374, + "width": 18 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 161, + "width": 18, + "y": 15.384615384615374, + "y2": 200, + "clip": true, + "cornerRadiusTopLeft": 10, + "cornerRadiusTopRight": 5, + "height": 184.6153846153846 + }, + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "fill": "#54a24b", + "ariaRoleDescription": "bar", + "description": "date (month): Oct; Count of Records: 37; weather: sun", + "width": 18, + "y": 143.07692307692307, + "y2": 200, + "height": 56.923076923076934 + }, + { + "fill": "#4c78a8", + "ariaRoleDescription": "bar", + "description": "date (month): Oct; Count of Records: 4; weather: drizzle", + "width": 18, + "y": 9.23076923076922, + "y2": 15.384615384615374, + "height": 6.153846153846155 + }, + { + "fill": "#e45756", + "ariaRoleDescription": "bar", + "description": "date (month): Oct; Count of Records: 64; weather: rain", + "width": 18, + "y": 44.61538461538461, + "y2": 143.07692307692307, + "height": 98.46153846153845 + }, + { + "fill": "#f58518", + "ariaRoleDescription": "bar", + "description": "date (month): Oct; Count of Records: 19; weather: fog", + "width": 18, + "y": 15.384615384615374, + "y2": 44.61538461538461, + "height": 29.23076923076924 + } + ], + "marktype": "rect", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "y": -9.23076923076922, + "width": 18 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 181, + "width": 18, + "y": 9.23076923076922, + "y2": 200, + "clip": true, + "cornerRadiusTopLeft": 10, + "cornerRadiusTopRight": 5, + "height": 190.76923076923077 + }, + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": true, + "items": [ + { + "fill": "#e45756", + "ariaRoleDescription": "bar", + "description": "date (month): Nov; Count of Records: 75; weather: rain", + "width": 18, + "y": 32.30769230769231, + "y2": 147.6923076923077, + "height": 115.3846153846154 + }, + { + "fill": "#54a24b", + "ariaRoleDescription": "bar", + "description": "date (month): Nov; Count of Records: 33; weather: sun", + "width": 18, + "y": 149.23076923076923, + "y2": 200, + "height": 50.769230769230774 + }, + { + "fill": "#4c78a8", + "ariaRoleDescription": "bar", + "description": "date (month): Nov; Count of Records: 3; weather: drizzle", + "width": 18, + "y": 15.384615384615374, + "y2": 19.999999999999996, + "height": 4.615384615384622 + }, + { + "fill": "#f58518", + "ariaRoleDescription": "bar", + "description": "date (month): Nov; Count of Records: 8; weather: fog", + "width": 18, + "y": 19.999999999999996, + "y2": 32.30769230769231, + "height": 12.30769230769231 + }, + { + "fill": "#72b7b2", + "ariaRoleDescription": "bar", + "description": "date (month): Nov; Count of Records: 1; weather: snow", + "width": 18, + "y": 147.6923076923077, + "y2": 149.23076923076923, + "height": 1.5384615384615188 + } + ], + "marktype": "rect", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "y": -15.384615384615374, + "width": 18 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 201, + "width": 18, + "y": 15.384615384615374, + "y2": 200, + "clip": true, + "cornerRadiusTopLeft": 10, + "cornerRadiusTopRight": 5, + "height": 184.6153846153846 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "x": 6, + "y": 6, + "shape": "square", + "size": 100, + "strokeWidth": 1.5, + "fill": "#4c78a8" + } + ], + "marktype": "symbol", + "role": "legend-symbol", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 16, + "y": 6, + "align": "left", + "baseline": "middle", + "limit": 160, + "text": "drizzle" + } + ], + "marktype": "text", + "role": "legend-label", + "zindex": 0 + } + ], + "width": 44.896484375, + "height": 11, + "opacity": 1, + "x": 0, + "y": 0 + }, + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "x": 6, + "y": 6, + "shape": "square", + "size": 100, + "strokeWidth": 1.5, + "fill": "#f58518" + } + ], + "marktype": "symbol", + "role": "legend-symbol", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 16, + "y": 6, + "align": "left", + "baseline": "middle", + "limit": 160, + "text": "fog" + } + ], + "marktype": "text", + "role": "legend-label", + "zindex": 0 + } + ], + "width": 44.896484375, + "height": 11, + "opacity": 1, + "x": 0, + "y": 13 + }, + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "x": 6, + "y": 6, + "shape": "square", + "size": 100, + "strokeWidth": 1.5, + "fill": "#e45756" + } + ], + "marktype": "symbol", + "role": "legend-symbol", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 16, + "y": 6, + "align": "left", + "baseline": "middle", + "limit": 160, + "text": "rain" + } + ], + "marktype": "text", + "role": "legend-label", + "zindex": 0 + } + ], + "width": 44.896484375, + "height": 11, + "opacity": 1, + "x": 0, + "y": 26 + }, + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "x": 6, + "y": 6, + "shape": "square", + "size": 100, + "strokeWidth": 1.5, + "fill": "#72b7b2" + } + ], + "marktype": "symbol", + "role": "legend-symbol", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 16, + "y": 6, + "align": "left", + "baseline": "middle", + "limit": 160, + "text": "snow" + } + ], + "marktype": "text", + "role": "legend-label", + "zindex": 0 + } + ], + "width": 44.896484375, + "height": 11, + "opacity": 1, + "x": 0, + "y": 39 + }, + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "x": 6, + "y": 6, + "shape": "square", + "size": 100, + "strokeWidth": 1.5, + "fill": "#54a24b" + } + ], + "marktype": "symbol", + "role": "legend-symbol", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 10, + "opacity": 1, + "x": 16, + "y": 6, + "align": "left", + "baseline": "middle", + "limit": 160, + "text": "sun" + } + ], + "marktype": "text", + "role": "legend-label", + "zindex": 0 + } + ], + "width": 44.896484375, + "height": 11, + "opacity": 1, + "x": 0, + "y": 52 + } + ], + "marktype": "group", + "role": "scope", + "zindex": 0 + } + ], + "x": 0, + "y": 16 + } + ], + "marktype": "group", + "role": "legend-entry", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "fill": "#000", + "font": "sans-serif", + "fontSize": 11, + "fontWeight": "bold", + "opacity": 1, + "orient": "top", + "text": "weather", + "limit": 180, + "x": 0, + "y": 0, + "angle": 0, + "align": "left", + "baseline": "top" + } + ], + "marktype": "text", + "role": "legend-title", + "zindex": 0 + } + ], + "orient": "right", + "x": 258, + "y": 0, + "width": 45, + "height": 79 + } + ], + "marktype": "group", + "role": "legend", + "zindex": 0 + } + ], + "fill": "transparent", + "stroke": "#ddd", + "x": 0, + "y": 0, + "width": 240, + "height": 200 + } + ], + "marktype": "group", + "name": "root", + "role": "frame", + "zindex": 0 + } +} \ No newline at end of file diff --git a/avenger-vega-test-data/vega-specs/clip/bar_rounded.vg.json b/avenger-vega-test-data/vega-specs/clip/bar_rounded.vg.json new file mode 100644 index 0000000..da49eb7 --- /dev/null +++ b/avenger-vega-test-data/vega-specs/clip/bar_rounded.vg.json @@ -0,0 +1,179 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "background": "white", + "padding": 5, + "height": 200, + "style": "cell", + "data": [ + { + "name": "source_0", + "url": "data/seattle-weather.csv", + "format": {"type": "csv", "parse": {"date": "date"}}, + "transform": [ + { + "field": "date", + "type": "timeunit", + "units": ["month"], + "as": ["month_date", "month_date_end"] + }, + { + "type": "aggregate", + "groupby": ["month_date", "weather"], + "ops": ["count"], + "fields": [null], + "as": ["__count"] + }, + { + "type": "stack", + "groupby": ["month_date"], + "field": "__count", + "sort": {"field": ["weather"], "order": ["descending"]}, + "as": ["__count_start", "__count_end"], + "offset": "zero" + } + ] + } + ], + "signals": [ + {"name": "x_step", "value": 20}, + { + "name": "width", + "update": "bandspace(domain('x').length, 0.1, 0.05) * x_step" + } + ], + "marks": [ + { + "type": "group", + "from": { + "facet": { + "data": "source_0", + "name": "stack_group_main", + "groupby": ["month_date", "month_date_end"], + "aggregate": { + "fields": [ + "__count_start", + "__count_start", + "__count_end", + "__count_end" + ], + "ops": ["min", "max", "min", "max"] + } + } + }, + "encode": { + "update": { + "x": {"scale": "x", "field": "month_date"}, + "width": {"signal": "max(0.25, bandwidth('x'))"}, + "y": { + "signal": "min(scale('y',datum[\"min___count_start\"]),scale('y',datum[\"max___count_start\"]),scale('y',datum[\"min___count_end\"]),scale('y',datum[\"max___count_end\"]))" + }, + "y2": { + "signal": "max(scale('y',datum[\"min___count_start\"]),scale('y',datum[\"max___count_start\"]),scale('y',datum[\"min___count_end\"]),scale('y',datum[\"max___count_end\"]))" + }, + "clip": {"value": true}, + "cornerRadiusTopLeft": {"value": 10}, + "cornerRadiusTopRight": {"value": 5} + } + }, + "marks": [ + { + "type": "group", + "encode": { + "update": { + "y": {"field": {"group": "y"}, "mult": -1}, + "width": {"field": {"group": "width"}} + } + }, + "marks": [ + { + "name": "marks", + "type": "rect", + "style": ["bar"], + "from": {"data": "stack_group_main"}, + "encode": { + "update": { + "fill": {"scale": "color", "field": "weather"}, + "ariaRoleDescription": {"value": "bar"}, + "description": { + "signal": "\"date (month): \" + (timeFormat(datum[\"month_date\"], timeUnitSpecifier([\"month\"], {\"year-month\":\"%b %Y \",\"year-month-date\":\"%b %d, %Y \"}))) + \"; Count of Records: \" + (format(datum[\"__count\"], \"\")) + \"; weather: \" + (isValid(datum[\"weather\"]) ? datum[\"weather\"] : \"\"+datum[\"weather\"])" + }, + "width": {"field": {"group": "width"}}, + "y": {"scale": "y", "field": "__count_end"}, + "y2": {"scale": "y", "field": "__count_start"} + } + } + } + ] + } + ] + } + ], + "scales": [ + { + "name": "x", + "type": "band", + "domain": {"data": "source_0", "field": "month_date", "sort": true}, + "range": {"step": {"signal": "x_step"}}, + "paddingInner": 0.1, + "paddingOuter": 0.05 + }, + { + "name": "y", + "type": "linear", + "domain": { + "data": "source_0", + "fields": ["__count_start", "__count_end"] + }, + "range": [{"signal": "height"}, 0], + "nice": true, + "zero": true + }, + { + "name": "color", + "type": "ordinal", + "domain": {"data": "source_0", "field": "weather", "sort": true}, + "range": "category" + } + ], + "axes": [ + { + "scale": "y", + "orient": "left", + "gridScale": "x", + "grid": true, + "tickCount": {"signal": "ceil(height/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "x", + "orient": "bottom", + "grid": false, + "title": "date (month)", + "format": { + "signal": "timeUnitSpecifier([\"month\"], {\"year-month\":\"%b %Y \",\"year-month-date\":\"%b %d, %Y \"})" + }, + "formatType": "time", + "labelOverlap": true, + "tickMinStep": { + "signal": "datetime(2001, 1, 1, 0, 0, 0, 0) - datetime(2001, 0, 1, 0, 0, 0, 0)" + }, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "grid": false, + "title": "Count of Records", + "labelOverlap": true, + "tickCount": {"signal": "ceil(height/40)"}, + "zindex": 0 + } + ], + "legends": [{"fill": "color", "symbolType": "square", "title": "weather"}] +} \ No newline at end of file diff --git a/avenger-vega/src/marks/arc.rs b/avenger-vega/src/marks/arc.rs index 037f327..c017496 100644 --- a/avenger-vega/src/marks/arc.rs +++ b/avenger-vega/src/marks/arc.rs @@ -29,10 +29,10 @@ pub struct VegaArcItem { impl VegaMarkItem for VegaArcItem {} impl VegaMarkContainer { - pub fn to_scene_graph(&self) -> Result { + pub fn to_scene_graph(&self, force_clip: bool) -> Result { // Init mark with scalar defaults let mut mark = ArcMark { - clip: self.clip, + clip: self.clip || force_clip, zindex: self.zindex, ..Default::default() }; diff --git a/avenger-vega/src/marks/area.rs b/avenger-vega/src/marks/area.rs index b5f07f5..3bd359d 100644 --- a/avenger-vega/src/marks/area.rs +++ b/avenger-vega/src/marks/area.rs @@ -29,7 +29,7 @@ pub struct VegaAreaItem { impl VegaMarkItem for VegaAreaItem {} impl VegaMarkContainer { - pub fn to_scene_graph(&self) -> Result { + pub fn to_scene_graph(&self, force_clip: bool) -> Result { // Get shape of first item and use that for all items for now let first = self.items.first(); let stroke_cap = first.and_then(|item| item.stroke_cap).unwrap_or_default(); @@ -61,7 +61,7 @@ impl VegaMarkContainer { } let mut mark = AreaMark { - clip: self.clip, + clip: self.clip || force_clip, zindex: self.zindex, orientation, fill, diff --git a/avenger-vega/src/marks/group.rs b/avenger-vega/src/marks/group.rs index 56eda75..354c271 100644 --- a/avenger-vega/src/marks/group.rs +++ b/avenger-vega/src/marks/group.rs @@ -13,6 +13,7 @@ use serde::{Deserialize, Serialize}; #[serde(rename_all = "camelCase")] pub struct VegaGroupItem { pub items: Vec, + pub clip: Option, pub x: Option, pub y: Option, pub name: Option, @@ -22,6 +23,10 @@ pub struct VegaGroupItem { pub stroke: Option, pub stroke_width: Option, pub corner_radius: Option, + pub corner_radius_top_left: Option, + pub corner_radius_top_right: Option, + pub corner_radius_bottom_left: Option, + pub corner_radius_bottom_right: Option, pub opacity: Option, pub fill_opacity: Option, pub stroke_opacity: Option, @@ -32,49 +37,50 @@ pub struct VegaGroupItem { impl VegaMarkItem for VegaGroupItem {} impl VegaMarkContainer { - pub fn to_scene_graph(&self) -> Result, AvengerVegaError> { + pub fn to_scene_graph(&self, force_clip: bool) -> Result, AvengerVegaError> { let mut groups: Vec = Vec::new(); for group_item in &self.items { + let should_clip = group_item.clip.unwrap_or(false) || force_clip; let mut marks: Vec = Vec::new(); for item in &group_item.items { let item_marks: Vec = match item { VegaMark::Group(mark) => mark - .to_scene_graph()? + .to_scene_graph(should_clip)? .into_iter() .map(SceneMark::Group) .collect(), VegaMark::Rect(mark) => { - vec![mark.to_scene_graph()?] + vec![mark.to_scene_graph(should_clip)?] } VegaMark::Rule(mark) => { - vec![mark.to_scene_graph()?] + vec![mark.to_scene_graph(should_clip)?] } VegaMark::Symbol(mark) => { - vec![mark.to_scene_graph()?] + vec![mark.to_scene_graph(should_clip)?] } VegaMark::Text(mark) => { - vec![mark.to_scene_graph()?] + vec![mark.to_scene_graph(should_clip)?] } VegaMark::Arc(mark) => { - vec![mark.to_scene_graph()?] + vec![mark.to_scene_graph(should_clip)?] } VegaMark::Path(mark) => { - vec![mark.to_scene_graph()?] + vec![mark.to_scene_graph(should_clip)?] } VegaMark::Shape(mark) => { - vec![mark.to_scene_graph()?] + vec![mark.to_scene_graph(should_clip)?] } VegaMark::Line(mark) => { - vec![mark.to_scene_graph()?] + vec![mark.to_scene_graph(should_clip)?] } VegaMark::Area(mark) => { - vec![mark.to_scene_graph()?] + vec![mark.to_scene_graph(should_clip)?] } VegaMark::Trail(mark) => { - vec![mark.to_scene_graph()?] + vec![mark.to_scene_graph(should_clip)?] } VegaMark::Image(mark) => { - vec![mark.to_scene_graph()?] + vec![mark.to_scene_graph(should_clip)?] } }; marks.extend(item_marks); @@ -97,12 +103,33 @@ impl VegaMarkContainer { }; let clip = if let (Some(width), Some(height)) = (group_item.width, group_item.height) { - if let Some(corner_radius) = group_item.corner_radius { + let corner_radius = group_item.corner_radius.unwrap_or(0.0); + let corner_radius_top_left = + group_item.corner_radius_top_left.unwrap_or(corner_radius); + let corner_radius_top_right = + group_item.corner_radius_top_right.unwrap_or(corner_radius); + let corner_radius_bottom_left = group_item + .corner_radius_bottom_left + .unwrap_or(corner_radius); + let corner_radius_bottom_right = group_item + .corner_radius_bottom_right + .unwrap_or(corner_radius); + + if corner_radius_top_left > 0.0 + || corner_radius_top_right > 0.0 + || corner_radius_bottom_left > 0.0 + || corner_radius_bottom_right > 0.0 + { // Rounded rectange path let mut builder = lyon_path::Path::builder(); builder.add_rounded_rectangle( &Box2D::new(Point2D::new(0.0, 0.0), Point2D::new(width, height)), - &BorderRadii::new(corner_radius), + &BorderRadii { + top_left: corner_radius_top_left, + top_right: corner_radius_top_right, + bottom_left: corner_radius_bottom_left, + bottom_right: corner_radius_bottom_right, + }, Winding::Positive, ); Clip::Path(builder.build()) diff --git a/avenger-vega/src/marks/image.rs b/avenger-vega/src/marks/image.rs index 75639ad..72711ed 100644 --- a/avenger-vega/src/marks/image.rs +++ b/avenger-vega/src/marks/image.rs @@ -33,7 +33,7 @@ fn default_true() -> bool { impl VegaMarkItem for VegaImageItem {} impl VegaMarkContainer { - pub fn to_scene_graph(&self) -> Result { + pub fn to_scene_graph(&self, force_clip: bool) -> Result { let name = self .name .clone() @@ -96,7 +96,7 @@ impl VegaMarkContainer { Ok(SceneMark::Image(Box::new(ImageMark { name, - clip: self.clip, + clip: self.clip || force_clip, len: self.items.len() as u32, aspect, smooth, diff --git a/avenger-vega/src/marks/line.rs b/avenger-vega/src/marks/line.rs index 8cca85c..6655db1 100644 --- a/avenger-vega/src/marks/line.rs +++ b/avenger-vega/src/marks/line.rs @@ -24,7 +24,7 @@ pub struct VegaLineItem { impl VegaMarkItem for VegaLineItem {} impl VegaMarkContainer { - pub fn to_scene_graph(&self) -> Result { + pub fn to_scene_graph(&self, force_clip: bool) -> Result { // Get shape of first item and use that for all items for now let first = self.items.first(); let stroke_width = first.and_then(|item| item.stroke_width).unwrap_or(1.0); @@ -47,7 +47,7 @@ impl VegaMarkContainer { } let mut mark = LineMark { - clip: self.clip, + clip: self.clip || force_clip, zindex: self.zindex, stroke, stroke_width, diff --git a/avenger-vega/src/marks/path.rs b/avenger-vega/src/marks/path.rs index 41467e4..5085d30 100644 --- a/avenger-vega/src/marks/path.rs +++ b/avenger-vega/src/marks/path.rs @@ -33,7 +33,7 @@ pub struct VegaPathItem { impl VegaMarkItem for VegaPathItem {} impl VegaMarkContainer { - pub fn to_scene_graph(&self) -> Result { + pub fn to_scene_graph(&self, force_clip: bool) -> Result { // Get shape of first item and use that for all items for now let first = self.items.first(); let first_has_stroke = first.map(|item| item.stroke.is_some()).unwrap_or(false); @@ -49,7 +49,7 @@ impl VegaMarkContainer { // Init mark with scalar defaults let mut mark = PathMark { - clip: self.clip, + clip: self.clip || force_clip, zindex: self.zindex, stroke_cap: first_cap, stroke_join: first_join, diff --git a/avenger-vega/src/marks/rect.rs b/avenger-vega/src/marks/rect.rs index 9fd0cb6..fce192e 100644 --- a/avenger-vega/src/marks/rect.rs +++ b/avenger-vega/src/marks/rect.rs @@ -28,9 +28,9 @@ pub struct VegaRectItem { impl VegaMarkItem for VegaRectItem {} impl VegaMarkContainer { - pub fn to_scene_graph(&self) -> Result { + pub fn to_scene_graph(&self, force_clip: bool) -> Result { let mut mark = RectMark { - clip: self.clip, + clip: self.clip || force_clip, zindex: self.zindex, ..Default::default() }; diff --git a/avenger-vega/src/marks/rule.rs b/avenger-vega/src/marks/rule.rs index 503e708..21ef98a 100644 --- a/avenger-vega/src/marks/rule.rs +++ b/avenger-vega/src/marks/rule.rs @@ -25,10 +25,10 @@ pub struct VegaRuleItem { impl VegaMarkItem for VegaRuleItem {} impl VegaMarkContainer { - pub fn to_scene_graph(&self) -> Result { + pub fn to_scene_graph(&self, force_clip: bool) -> Result { // Init mark with scalar defaults let mut mark = RuleMark { - clip: self.clip, + clip: self.clip || force_clip, zindex: self.zindex, ..Default::default() }; diff --git a/avenger-vega/src/marks/shape.rs b/avenger-vega/src/marks/shape.rs index 7d6b142..aac8c64 100644 --- a/avenger-vega/src/marks/shape.rs +++ b/avenger-vega/src/marks/shape.rs @@ -28,7 +28,7 @@ pub struct VegaShapeItem { impl VegaMarkItem for VegaShapeItem {} impl VegaMarkContainer { - pub fn to_scene_graph(&self) -> Result { + pub fn to_scene_graph(&self, force_clip: bool) -> Result { // Get shape of first item and use that for all items for now let first = self.items.first(); let first_has_stroke = first.map(|item| item.stroke.is_some()).unwrap_or(false); @@ -44,7 +44,7 @@ impl VegaMarkContainer { // Init mark with scalar defaults let mut mark = PathMark { - clip: self.clip, + clip: self.clip || force_clip, zindex: self.zindex, stroke_cap: first_cap, stroke_join: first_join, diff --git a/avenger-vega/src/marks/symbol.rs b/avenger-vega/src/marks/symbol.rs index 686e33d..b17d9f5 100644 --- a/avenger-vega/src/marks/symbol.rs +++ b/avenger-vega/src/marks/symbol.rs @@ -35,7 +35,7 @@ pub struct VegaSymbolItem { impl VegaMarkItem for VegaSymbolItem {} impl VegaMarkContainer { - pub fn to_scene_graph(&self) -> Result { + pub fn to_scene_graph(&self, force_clip: bool) -> Result { // Get shape of first item and use that for all items for now let first = self.items.first(); let first_shape = first @@ -108,7 +108,7 @@ impl VegaMarkContainer { // Init mark with scalar defaults let mut mark = SymbolMark { stroke_width, - clip: self.clip, + clip: self.clip || force_clip, zindex: self.zindex, ..Default::default() }; diff --git a/avenger-vega/src/marks/text.rs b/avenger-vega/src/marks/text.rs index ad44971..9857077 100644 --- a/avenger-vega/src/marks/text.rs +++ b/avenger-vega/src/marks/text.rs @@ -38,10 +38,10 @@ pub struct VegaTextItem { impl VegaMarkItem for VegaTextItem {} impl VegaMarkContainer { - pub fn to_scene_graph(&self) -> Result { + pub fn to_scene_graph(&self, force_clip: bool) -> Result { // Init mark with scalar defaults let mut mark = TextMark { - clip: self.clip, + clip: self.clip || force_clip, zindex: self.zindex, ..Default::default() }; diff --git a/avenger-vega/src/marks/trail.rs b/avenger-vega/src/marks/trail.rs index 8ed5f90..f565e77 100644 --- a/avenger-vega/src/marks/trail.rs +++ b/avenger-vega/src/marks/trail.rs @@ -21,7 +21,7 @@ pub struct VegaTrailItem { impl VegaMarkItem for VegaTrailItem {} impl VegaMarkContainer { - pub fn to_scene_graph(&self) -> Result { + pub fn to_scene_graph(&self, force_clip: bool) -> Result { // Get shape of first item and use that for all items for now let first = self.items.first(); let mut gradients = Vec::::new(); @@ -37,7 +37,7 @@ impl VegaMarkContainer { } let mut mark = TrailMark { - clip: self.clip, + clip: self.clip || force_clip, zindex: self.zindex, gradients, stroke, diff --git a/avenger-vega/src/scene_graph.rs b/avenger-vega/src/scene_graph.rs index f8ecc1b..b42f7b7 100644 --- a/avenger-vega/src/scene_graph.rs +++ b/avenger-vega/src/scene_graph.rs @@ -16,7 +16,7 @@ impl VegaSceneGraph { #[tracing::instrument(skip_all)] pub fn to_scene_graph(&self) -> Result { Ok(SceneGraph { - groups: self.scenegraph.to_scene_graph()?, + groups: self.scenegraph.to_scene_graph(false)?, width: self.width, height: self.height, origin: self.origin, diff --git a/avenger-wgpu/src/canvas.rs b/avenger-wgpu/src/canvas.rs index 51b1d62..aae464f 100644 --- a/avenger-wgpu/src/canvas.rs +++ b/avenger-wgpu/src/canvas.rs @@ -206,6 +206,7 @@ pub trait Canvas { &mut self, group: &SceneGroup, parent_origin: [f32; 2], + parent_clip: &Clip, ) -> Result<(), AvengerWgpuError> { // Maybe add rect around group boundary if let Some(rect) = group.make_path_mark() { @@ -224,7 +225,13 @@ pub trait Canvas { ]; // Compute new clip - let clip = group.clip.translate(origin[0], origin[1]); + let clip = if let Clip::None = group.clip { + // No clip defined for this group, propagate parent clip down + parent_clip.clone() + } else { + // Translate clip to absolute coordinates + group.clip.translate(origin[0], origin[1]) + }; for mark_ind in indices { let mark = &group.marks[mark_ind]; @@ -260,7 +267,7 @@ pub trait Canvas { self.add_image_mark(mark, origin, &clip)?; } SceneMark::Group(group) => { - self.add_group_mark(group, origin)?; + self.add_group_mark(group, origin, &clip)?; } } } @@ -283,7 +290,7 @@ pub trait Canvas { for group_ind in &indices { let group = &scene_graph.groups[*group_ind]; - self.add_group_mark(group, scene_graph.origin)?; + self.add_group_mark(group, scene_graph.origin, &Clip::None)?; } Ok(()) diff --git a/avenger-wgpu/tests/test_image_baselines.rs b/avenger-wgpu/tests/test_image_baselines.rs index 944f202..24b3037 100644 --- a/avenger-wgpu/tests/test_image_baselines.rs +++ b/avenger-wgpu/tests/test_image_baselines.rs @@ -180,6 +180,7 @@ mod test_image_baselines { case("clip", "text_clip", 0.02), case("clip", "clip_rounded", 0.0001), case("clip", "text_clip_rounded", 0.02), + case("clip", "bar_rounded", 0.02), )] fn test_image_baseline(category: &str, spec_name: &str, tolerance: f64) { initialize();