Как добавить больше метрик на карту страны в Apache-superset? - программирование

Как добавить больше метрик на карту страны в Apache-superset?

Я использую country_map в для целей визуализации. При увеличении полигона информация из столбцов появляется внутри многоугольника, например:

map

Для отображения доступна только одна доступная метрика: metric

Код для обновления метрики находится по этому пути:

надмножество/активы/SRC/Визуализация /CountryMap/CountryMap.js

Код:

const updateMetrics = function (region) {
  if (region.length > 0) {     
    resultText.text(format(region[0].metric));
  }
};

Метрики определены в controls.jsx:

/superset/static/assets/src/explore/controls.jsx

const metrics = {
  type: 'MetricsControl',
  multi: true,
  label: t('Metrics'),
  validators: [v.nonEmpty],
  default: (c) => {
    const metric = mainMetric(c.savedMetrics);
    return metric ? [metric] : null;
  },
  mapStateToProps: (state) => {
    const datasource = state.datasource;
    return {
      columns: datasource ? datasource.columns : [],
      savedMetrics: datasource ? datasource.metrics : [],
      datasourceType: datasource && datasource.type,
    };
  },
  description: t('One or many metrics to display'),
};
const metric = {
  ...metrics,
  multi: false,
  label: t('Metric'),
  default: props => mainMetric(props.savedMetrics),
};

Карта страны использует metric, которая не позволяет выбирать несколько метрик. Код находится здесь:

надмножеством/активы/SRC/ПОЗНАВАЙ /controlPanels/CountryMap.js

  controlPanelSections: [
    {
      label: t('Query'),
      expanded: true,
      controlSetRows: [
        ['entity'],
        ['metric'],
        ['adhoc_filters'],
      ],
    },
    {
      label: t('Options'),
      expanded: true,
      controlSetRows: [
        ['select_country', 'number_format'],
        ['linear_color_scheme'],
      ],
    },
  ],

Класс python для country_map находится по адресу viz.py:

class CountryMapViz(BaseViz):

    """A country centric"""

    viz_type = 'country_map'
    verbose_name = _('Country Map')
    is_timeseries = False
    credits = 'From bl.ocks.org By john-guerra'

    def query_obj(self):
        qry = super(CountryMapViz, self).query_obj()
        qry['metrics'] = [
            self.form_data['metric']]
        qry['groupby'] = [self.form_data['entity']]
        return qry

Изменение кода в CountryMap.js и viz.py с metric на metrics приводит к следующей ошибке:

Traceback (most recent call last):
  File "/Documents/superset/superset/superset/viz.py", line 410, in get_df_payload
    df = self.get_df(query_obj)
  File "/Documents/superset/superset/superset/viz.py", line 213, in get_df
    self.results = self.datasource.query(query_obj)
  File "/Documents/superset/superset/superset/connectors/sqla/models.py", line 797, in query
    sql = self.get_query_str(query_obj)
  File "/Documents/superset/superset/superset/connectors/sqla/models.py", line 471, in get_query_str
    qry = self.get_sqla_query(**query_obj)
  File "/Documents/superset/superset/superset/connectors/sqla/models.py", line 585, in get_sqla_query
    elif m in metrics_dict:
TypeError: unhashable type: 'list'

Как добавить больше метрик для отображения внутри многоугольника?

4b9b3361

Ответ 1

Непосредственной причиной ошибки TypeError: unhashable type: 'list' является ваша модификация файла "viz.py":

self.form_data['metric']] в self.form_data['metrics']] в query_obj(self).

Как вы можете видеть в исходном коде здесь, metrics данных формы - это объект list который содержит metric, где metric - это, вероятно, строка или другой хешируемый объект. На языке Python объект list не может быть хэшируемым. Поскольку вы заменяете хешируемый объект (metric) на не подлежащий хэшированию (metrics), возникает ошибка unhashable type.

Правильный способ изменить CoutryMapViz.query_obj() для принятия запроса metrics можно найти в других классах Viz. Раздел кода здесь является очень хорошим примером:


class CalHeatmapViz(BaseViz):

"""Calendar heatmap."""
...

    def query_obj(self):
        d = super(CalHeatmapViz, self).query_obj()
        fd = self.form_data
        d['metrics'] = fd.get('metrics')
        return d

Наконец, метод CoutryMapViz.query_obj() должен выглядеть следующим образом:

class CountryMapViz(BaseViz):

...

    def query_obj(self):
        qry = super(CountryMapViz, self).query_obj()
        qry['metrics'] = fd.get('metrics')
        qry['groupby'] = [self.form_data['entity']]
        return qry