Search code examples
powerbivisualizationpowerbi-desktopvega-litedeneb

ArgMax and Color properties: Unable to encode BOTH line end point marks AND highest/lowest circle marks


** FINAL EDIT: Resolved by @DavideBacci - I'm indebted to you ** Final Image

EDIT: 3rd partial success attempt - closer yet again, but needed to use helper measures to display high and low points - ideally would love to achieve same result without extra DAX measures 3rd attempt

EDIT: 2nd failed attempt - closer but still having encoding issues 2nd_Attempt

EDIT: 1st failed attempt:

I have become stuck again with Vega-lite, attempting to layer points for the line end circle marks and text labels, AND also layer the highest/lowest point marks, using filter and color properties:

Line chart using "color": and "argmax": expressions - attempting to get highest/lowest marks AND latest mark points and text labels

I'm almost there, but I'm missing something fundamental as I am unable to get the marks to encode correctly -

Any help is greatly appreciated. - PBIX available here: Temperature_DEV_argmax_PAGE2 IdealSolution

Latest code: latest code

{
  "data": {"name": "dataset"},
  "encoding": {
    "x": {
      "field": "DayOfYear",
      "type": "temporal"
    },
    "y": {
      "field": "_temp",
      "type": "quantitative",
      "scale": {"zero": false}
    },
    "color": {
      "field": "Year",
      "type": "nominal"
    }
  },
  "layer": [
    {
      "transform": [
        {
          "filter": {
            "field": "Year",
            "oneOf": [
              "2023",
              "2022",
              "2021",
              "1979-2000 mean"
            ]
          }
        }
      ],
      "layer": [
        {
          "mark": {"type": "line"},
          "encoding": {
            "x": {
              "field": "DayOfYear",
              "type": "temporal"
            },
            "y": {
              "field": "_temp",
              "type": "quantitative",
              "scale": {"zero": false}
            },
            "color": {
              "field": "Year",
              "type": "nominal"
            }
          }
        },
        {
          "description": "COLOR_LINES_BLUE_RED",
          "layer": [
            {
              "mark": {"type": "line"},
              "encoding": {
                "x": {
                  "field": "DayOfYear",
                  "type": "temporal"
                },
                "y": {
                  "field": "_temp",
                  "type": "quantitative",
                  "scale": {
                    "zero": false
                  }
                },
                "color": {
                  "field": "Year",
                  "type": "nominal",
                  "scale": {
                    "domain": [
                      "2023",
                      "2022",
                      "2021",
                      "1979-2000 mean"
                    ],
                    "range": [
                      "crimson",
                      "#000FFF50",
                      "#000FFF80",
                      "orange"
                    ]
                  }
                }
              }
            }
          ]
        },
        {
          "transform": [
            {
              "filter": "datum['_temp'] == datum['_highpoints'] || datum['_temp'] == datum['_lowpoints']"
            }
          ],
          "mark": {
            "type": "point",
            "filled": true,
            "stroke": "black",
            "strokeWidth": 0.8,
            "shape": {
              "expr": "datum['_temp'] == datum['_highpoints'] ? 'triangle-down' : 'triangle-up'"
            },
            "size": 250,
            "opacity": 1,
            "yOffset": {
              "expr": "datum['_temp'] == datum['_highpoints'] ? -10 : 10"
            }
          },
          "encoding": {
            "x": {
              "field": "DayOfYear",
              "type": "temporal"
            },
            "y": {
              "field": "_temp",
              "type": "quantitative",
              "scale": {"zero": false}
            },
            "color": {
              "field": "Year",
              "type": "nominal"
            }
          }
        },
        {
          "transform": [
            {
              "filter": "datum['_temp'] == datum['_highpoints'] || datum['_temp'] == datum['_lowpoints']"
            }
          ],
          "mark": {
            "type": "text",
            "filled": true,
            "stroke": "whitesmoke",
            "strokeWidth": 8,
            "size": 15,
            "fontWeight": "1000",
            "opacity": 1,
            "yOffset": {
              "expr": "datum['_temp'] == datum['_highpoints'] ? -30 : 30"
            }
          },
          "encoding": {
            "x": {
              "field": "DayOfYear",
              "type": "temporal"
            },
            "y": {
              "field": "_temp",
              "type": "quantitative",
              "scale": {"zero": false}
            },
            "color": {
              "field": "Year",
              "type": "nominal"
            },
            "text": {
              "field": "_temp",
              "format": ",.3~s"
            }
          }
        },
        {
          "transform": [
            {
              "filter": "datum['_temp'] == datum['_highpoints'] || datum['_temp'] == datum['_lowpoints']"
            }
          ],
          "mark": {
            "type": "text",
            "filled": true,
            "size": 15,
            "fontWeight": "1000",
            "opacity": 1,
            "yOffset": {
              "expr": "datum['_temp'] == datum['_highpoints'] ? -30 : 30"
            }
          },
          "encoding": {
            "text": {
              "field": "_temp",
              "format": ",.3~s"
            }
          }
        }
      ]
    }
  ]
}

Solution

  • Try this:

    enter image description here

    {
      "data": {"name": "dataset"},
      "encoding": {
        "x": {
          "field": "DayOfYear",
          "type": "temporal"
        },
        "y": {
          "field": "_temp",
          "type": "quantitative",
          "scale": {"zero": false}
        },
        "color": {
          "field": "Year",
          "type": "nominal"
        }
      },
      "layer": [
        {
          "transform": [
            {
              "filter": {
                "field": "Year",
                "oneOf": [
                  "2023",
                  "2022",
                  "2021",
                  "1979-2000 mean"
                ]
              }
            },
            {
              "joinaggregate": [
                {
                  "op": "max",
                  "field": "_temp",
                  "as": "highest"
                }
              ],
              "groupby": ["Year"]
            },
              {
              "joinaggregate": [
                {
                  "op": "min",
                  "field": "_temp",
                  "as": "lowest"
                }
              ],
              "groupby": ["Year"]
            }
          ],
          "layer": [
            {
              "mark": {"type": "line"},
              "encoding": {
                "x": {
                  "field": "DayOfYear",
                  "type": "temporal"
                },
                "y": {
                  "field": "_temp",
                  "type": "quantitative",
                  "scale": {"zero": false}
                },
                "color": {
                  "field": "Year",
                  "type": "nominal",
                  "scale": {
                    "domain": [
                      "2023",
                      "2022",
                      "2021",
                      "1979-2000 mean"
                    ],
                    "range": [
                      "crimson",
                      "#000FFF50",
                      "#000FFF80",
                      "orange"
                    ]
                  }
                }
              }
            },
            {
              "transform": [
                {
                  "filter": "datum['_temp'] == datum['highest'] || datum['_temp'] == datum['lowest']"
                }
              ],
              "mark": {
                "type": "point",
                "filled": true,
                "stroke": "black",
                "strokeWidth": 0.8,
                "shape": {
                  "expr": "datum['_temp'] == datum['highest'] ? 'triangle-down' : 'triangle-up'"
                },
                "size": 250,
                "opacity": 1,
                "yOffset": {
                  "expr": "datum['_temp'] == datum['highest'] ? -10 : 10"
                }
              },
              "encoding": {
                "x": {
                  "field": "DayOfYear",
                  "type": "temporal"
                },
                "y": {
                  "field": "_temp",
                  "type": "quantitative",
                  "scale": {"zero": false}
                },
                "color": {
                  "field": "Year",
                  "type": "nominal"
                }
              }
            },
            {
              "transform": [
                {
                  "filter": "datum['_temp'] == datum['highest'] || datum['_temp'] == datum['lowest']"
                }
              ],
              "mark": {
                "type": "text",
                "filled": true,
                "stroke": "whitesmoke",
                "strokeWidth": 8,
                "size": 15,
                "fontWeight": "1000",
                "opacity": 1,
                "yOffset": {
                  "expr": "datum['_temp'] == datum['highest'] ? -30 : 30"
                }
              },
              "encoding": {
                "x": {
                  "field": "DayOfYear",
                  "type": "temporal"
                },
                "y": {
                  "field": "_temp",
                  "type": "quantitative",
                  "scale": {"zero": false}
                },
                "color": {
                  "field": "Year",
                  "type": "nominal"
                },
                "text": {
                  "field": "_temp",
                  "format": ",.3~s"
                }
              }
            },
            {
              "transform": [
                {
                  "filter": "datum['_temp'] == datum['highest'] || datum['_temp'] == datum['lowest']"
                }
              ],
              "mark": {
                "type": "text",
                "filled": true,
                "size": 15,
                "fontWeight": "1000",
                "opacity": 1,
                "yOffset": {
                  "expr": "datum['_temp'] == datum['highest'] ? -30 : 30"
                }
              },
              "encoding": {
                "text": {
                  "field": "_temp",
                  "format": ",.3~s"
                }
              }
            }
          ]
        }
      ]
    }