Skip to content

Commit

Permalink
Support rule opacity
Browse files Browse the repository at this point in the history
  • Loading branch information
jonmmease committed Jan 11, 2024
1 parent b26fd07 commit 3b5ac4f
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"width": 210,
"height": 211,
"origin_x": 5,
"origin_y": 6
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"marktype": "group",
"name": "root",
"role": "frame",
"interactive": true,
"clip": false,
"items": [
{
"items": [
{
"marktype": "rule",
"name": "marks",
"role": "mark",
"interactive": true,
"clip": false,
"items": [
{
"x": 140,
"y": 15,
"opacity": 0.5,
"stroke": "orange",
"strokeWidth": 16,
"strokeCap": "butt",
"x2": 60,
"y2": 180
},
{
"x": 20,
"y": 15,
"opacity": 0.5,
"stroke": "blue",
"strokeWidth": 16,
"strokeCap": "butt",
"x2": 120,
"y2": 140
},
{
"x": 50,
"y": 15,
"opacity": 0.5,
"stroke": "green",
"strokeWidth": 16,
"strokeCap": "butt",
"x2": 120,
"y2": 180
}
],
"zindex": 0
}
],
"x": 0,
"y": 0,
"width": 200,
"height": 200,
"fill": "transparent",
"stroke": "transparent"
}
],
"zindex": 0
}
54 changes: 54 additions & 0 deletions sg2d-vega-test-data/vega-specs/rule/wide_transparent_butt.vg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A scatterplot showing horsepower and miles per gallons for various cars.",
"background": "white",
"padding": 5,
"width": 200,
"height": 200,
"style": "cell",
"config": {"style": {"cell": {"stroke": "transparent"}}},
"data": [{
"name": "source_0",
"values": [
{"x": 140, "x2": 60, "y": 15, "y2": 180, "fill": "orange"},
{"x": 20, "x2": 120, "y": 15, "y2": 140, "fill": "blue"},
{"x": 50, "x2": 120, "y": 15, "y2": 180, "fill": "green"}
]
}],
"marks": [
{
"name": "marks",
"type": "rule",
"style": ["rule"],
"from": {"data": "source_0"},
"encode": {
"update": {
"strokeWidth": {"value": 16},
"stroke": {"field": "fill"},
"x": {"field": "x" },
"x2": {"field": "x2"},
"y": {"field": "y"},
"y2": {"field": "y2"},
"opacity": {"value": 0.5},
"strokeCap": {"value": "butt"}
}
}
}
],
"scales": [
{
"name": "x",
"type": "linear",
"domain": [0, 100],
"range": [0, {"signal": "width"}],
"zero": true
},
{
"name": "y",
"type": "linear",
"domain": [0, 100],
"range": [{"signal": "height"}, 0],
"zero": true
}
]
}
7 changes: 5 additions & 2 deletions sg2d-vega/src/marks/rule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub struct VegaRuleItem {
pub stroke: Option<String>,
pub stroke_width: Option<f32>,
pub stroke_cap: Option<StrokeCap>,
pub stroke_opacity: Option<f32>,
pub opacity: Option<f32>,
pub zindex: Option<i32>,
}

Expand All @@ -36,7 +38,7 @@ impl VegaMarkContainer<VegaRuleItem> {
let mut y0 = Vec::<f32>::new();
let mut x1 = Vec::<f32>::new();
let mut y1 = Vec::<f32>::new();
let mut stroke = Vec::<[f32; 3]>::new();
let mut stroke = Vec::<[f32; 4]>::new();
let mut stroke_width = Vec::<f32>::new();
let mut stroke_cap = Vec::<StrokeCap>::new();
let mut zindex = Vec::<i32>::new();
Expand All @@ -50,7 +52,8 @@ impl VegaMarkContainer<VegaRuleItem> {

if let Some(s) = &item.stroke {
let c = csscolorparser::parse(s)?;
stroke.push([c.r as f32, c.g as f32, c.b as f32])
let opacity = item.stroke_opacity.unwrap_or(1.0) * item.opacity.unwrap_or(1.0);
stroke.push([c.r as f32, c.g as f32, c.b as f32, opacity]);
}

if let Some(s) = item.stroke_width {
Expand Down
4 changes: 2 additions & 2 deletions sg2d-wgpu/src/marks/rule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub struct RuleInstance {
pub y0: f32,
pub x1: f32,
pub y1: f32,
pub stroke: [f32; 3],
pub stroke: [f32; 4],
pub stroke_width: f32,
}

Expand All @@ -39,7 +39,7 @@ const INSTANCE_ATTRIBUTES: [wgpu::VertexAttribute; 6] = wgpu::vertex_attr_array!
2 => Float32, // y0
3 => Float32, // x1
4 => Float32, // y1
5 => Float32x3, // stroke
5 => Float32x4, // stroke
6 => Float32, // stroke_width
];

Expand Down
7 changes: 3 additions & 4 deletions sg2d-wgpu/src/marks/rule.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ struct InstanceInput {
@location(2) y0: f32,
@location(3) x1: f32,
@location(4) y1: f32,
@location(5) stroke: vec3<f32>,
@location(5) stroke: vec4<f32>,
@location(6) stroke_width: f32,
};

struct VertexOutput {
@builtin(position) clip_position: vec4<f32>,
@location(0) color: vec3<f32>,
@location(0) color: vec4<f32>,
};

const PI = 3.14159265359;
Expand Down Expand Up @@ -56,8 +56,7 @@ fn vs_main(
}

// Fragment shader

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
return vec4<f32>(in.color, 1.0);
return in.color;
}
57 changes: 29 additions & 28 deletions sg2d-wgpu/tests/test_image_baselines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,35 @@ mod test_image_baselines {
category,
spec_name,
tolerance,
case("rect", "stacked_bar", 0.001),
case("rect", "heatmap", 0.006),
case("symbol", "binned_scatter_diamonds", 0.001),
case("symbol", "binned_scatter_square", 0.001),
case("symbol", "binned_scatter_triangle-down", 0.001),
case("symbol", "binned_scatter_triangle-up", 0.001),
case("symbol", "binned_scatter_triangle-left", 0.001),
case("symbol", "binned_scatter_triangle-right", 0.001),
case("symbol", "binned_scatter_triangle", 0.001),
case("symbol", "binned_scatter_wedge", 0.001),
case("symbol", "binned_scatter_arrow", 0.001),
case("symbol", "binned_scatter_cross", 0.001),
case("symbol", "binned_scatter_circle", 0.001),
case("symbol", "binned_scatter_path", 0.001),
case("symbol", "binned_scatter_path_star", 0.001),
case("symbol", "binned_scatter_cross_stroke", 0.001),
case("symbol", "binned_scatter_circle_stroke", 0.001),
case("symbol", "binned_scatter_circle_stroke_no_fill", 0.001),
case("symbol", "binned_scatter_path_star_stroke_no_fill", 0.001),
case("symbol", "scatter_transparent_stroke", 0.001),
case("symbol", "scatter_transparent_stroke_star", 0.006),
case("symbol", "wind_vector", 0.0015),
case("symbol", "wedge_angle", 0.001),
case("symbol", "wedge_stroke_angle", 0.001),
case("symbol", "zindex_circles", 0.001),
case("symbol", "mixed_symbols", 0.001),
case("rule", "wide_rule_axes", 0.0001),
case("text", "bar_axis_labels", 0.025)
// case("rect", "stacked_bar", 0.001),
// case("rect", "heatmap", 0.006),
// case("symbol", "binned_scatter_diamonds", 0.001),
// case("symbol", "binned_scatter_square", 0.001),
// case("symbol", "binned_scatter_triangle-down", 0.001),
// case("symbol", "binned_scatter_triangle-up", 0.001),
// case("symbol", "binned_scatter_triangle-left", 0.001),
// case("symbol", "binned_scatter_triangle-right", 0.001),
// case("symbol", "binned_scatter_triangle", 0.001),
// case("symbol", "binned_scatter_wedge", 0.001),
// case("symbol", "binned_scatter_arrow", 0.001),
// case("symbol", "binned_scatter_cross", 0.001),
// case("symbol", "binned_scatter_circle", 0.001),
// case("symbol", "binned_scatter_path", 0.001),
// case("symbol", "binned_scatter_path_star", 0.001),
// case("symbol", "binned_scatter_cross_stroke", 0.001),
// case("symbol", "binned_scatter_circle_stroke", 0.001),
// case("symbol", "binned_scatter_circle_stroke_no_fill", 0.001),
// case("symbol", "binned_scatter_path_star_stroke_no_fill", 0.001),
// case("symbol", "scatter_transparent_stroke", 0.001),
// case("symbol", "scatter_transparent_stroke_star", 0.006),
// case("symbol", "wind_vector", 0.0015),
// case("symbol", "wedge_angle", 0.001),
// case("symbol", "wedge_stroke_angle", 0.001),
// case("symbol", "zindex_circles", 0.001),
// case("symbol", "mixed_symbols", 0.001),
// case("rule", "wide_rule_axes", 0.0001),
case("rule", "wide_transparent_butt", 0.0001),
// case("text", "bar_axis_labels", 0.025)
)]
fn test_image_baseline(category: &str, spec_name: &str, tolerance: f64) {
let specs_dir = format!(
Expand Down
6 changes: 3 additions & 3 deletions sg2d/src/marks/rule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub struct RuleMark {
pub y0: EncodingValue<f32>,
pub x1: EncodingValue<f32>,
pub y1: EncodingValue<f32>,
pub stroke: EncodingValue<[f32; 3]>,
pub stroke: EncodingValue<[f32; 4]>,
pub stroke_width: EncodingValue<f32>,
pub stroke_cap: EncodingValue<StrokeCap>,
pub indices: Option<Vec<usize>>,
Expand All @@ -30,7 +30,7 @@ impl RuleMark {
pub fn y1_iter(&self) -> Box<dyn Iterator<Item = &f32> + '_> {
self.y1.as_iter(self.len as usize, self.indices.as_ref())
}
pub fn stroke_iter(&self) -> Box<dyn Iterator<Item = &[f32; 3]> + '_> {
pub fn stroke_iter(&self) -> Box<dyn Iterator<Item = &[f32; 4]> + '_> {
self.stroke
.as_iter(self.len as usize, self.indices.as_ref())
}
Expand All @@ -55,7 +55,7 @@ impl Default for RuleMark {
x1: EncodingValue::Scalar { value: 0.0 },
y1: EncodingValue::Scalar { value: 0.0 },
stroke: EncodingValue::Scalar {
value: [0.0, 0.0, 0.0],
value: [0.0, 0.0, 0.0, 1.0],
},
stroke_width: EncodingValue::Scalar { value: 1.0 },
stroke_cap: EncodingValue::Scalar {
Expand Down
1 change: 1 addition & 0 deletions sg2d/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ impl<T> EncodingValue<T> {
}

#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum StrokeCap {
Butt,
Round,
Expand Down

0 comments on commit 3b5ac4f

Please sign in to comment.