Vega-Lite: персонализированные ярлыки легенды "1 в X" - PullRequest
0 голосов
/ 04 августа 2020

Я работаю над картограммой, которая показывает долю населения, подтвердившего положительный случай Covid-19 в каждой политической юрисдикции. Подобно этому примеру в диаграмме Mapbox на душу населения c на этой странице из The New York Times .

Я выяснил почти каждую деталь, кроме как для настройки легенды. В настоящее время метки отображают shareOfPop в виде числа. Хотя я хочу добавить к каждой метке префикс «1 в $ {shareOfPop}» и добавить суффикс к последней метке «1 в $ {shareOfPop} или более».

введите описание изображения здесь .

Я создал эту карту в Observable Notebook .

То, что я пробовал до сих пор ...

Создание нам пользовательских кодировок легенды

Чтобы указать текст метки:

vl.color()
  .fieldQ('shareOfPop')
  .scale(
    {
      scheme: "yelloworangered",
      domain: [250, 10],
      clamp: true,
    }
  )
  .legend({
    title: "Share of Pop.",
    encode: {
      labels: {text: "1 in ${datum.value}"}
    }
  })

Зарегистрируйте пользовательский форматировщик

Который Сомневаюсь, что сделал правильно.

Вот как выглядит моя конфигурация (которая основана на конфигурации из ноутбука Introduction to Vega-Lite ).

vl = {
  const [vega, vegalite, api, tooltip] = await Promise.all([
    'vega@5.13.0',
    'vega-lite@4.14.1',
    'vega-lite-api@0.11.0',
    'vega-tooltip@0.22.1'
  ].map(module => require(module)));

  const options = {
    config: {
      // allow custom format types
      customFormatTypes: true,
      config: {
        view: {continuousWidth: 400, continuousHeight: 300},
        mark: {tooltip: null}
      }
    },
    init: view => {
      // initialize tooltip handler
      view.tooltip(new tooltip.Handler().call);
      // enable horizontal scrolling for large plots
      if (view.container()) view.container().style['overflow-x'] = 'auto';
      // register a custom expression function...am I doing this right???       
      vega.expressionFunction('1inX', function(datum) {
        return `1 in ${datum}`
      })
    },
    view: {
      // view constructor options
      loader: vega.loader({baseURL: 'https://cdn.jsdelivr.net/npm/vega-datasets@1/'}),
      renderer: 'canvas'
    }
  };
  
  return api.register(vega, vegalite, options);
}

Затем я указываю этот пользовательский formatType при определении метки:

vl.color()
  .fieldQ('shareOfPop')
  .scale(
    {
      scheme: "yelloworangered",
      domain: [250, 10],
      clamp: true,
    }
  )
  .legend({
    title: "Share of Pop.",
    formatType: "1inX",
  })
)

Ни один из этих подходов не привел к заметным изменениям.

1 Ответ

1 голос
/ 06 августа 2020

Я отвечу здесь на свой вопрос.

Оказывается, Legend имеет общее свойство labelExpr, которое позволяет вам указать выражение Vega для настройки метки.

В моем случае я хотел всегда добавлять строку "1 in ", а также добавлять "+" при превышении лимита домена. Вот как я это сделал, используя функции join() и if().

...
vl.color()
  .legend(
    {
      labelExpr: "join(['1 in ', datum.value, if(datum.value >= 250, '+', '')], '')"
    }
  )

Это свойство не задокументировано для Legend, хотя оно предназначено для для оси ).

...