示例#1
0
    def transform_row_index(index_values, field_map,
                            dimension_hyperlink_templates):
        # Add the index to the row
        row = {}
        for key, value in index_values.items():
            if key is None:
                continue

            field_alias = key
            field = field_map[field_alias]

            data = {RAW_VALUE: raw_value(value, field)}
            display = _display_value(value, field)
            if display is not None:
                data["display"] = display

            # If the dimension has a hyperlink template, then apply the template by formatting it with the dimension
            # values for this row. The values contained in `index_values` will always contain all of the required values
            # at this point, otherwise the hyperlink template will not be included.
            if key in dimension_hyperlink_templates:
                data["hyperlink"] = dimension_hyperlink_templates[key].format(
                    **index_values)

            safe_key = safe_value(key)
            row[safe_key] = data

        return row
示例#2
0
    def transform_row_values(series, fields, is_transposed):
        # Add the values to the row
        index_names = series.index.names or []

        row = {}
        for key, value in series.iteritems():
            key = wrap_list(key)

            # Get the field for the metric
            metric_alias = wrap_list(
                series.name)[0] if is_transposed else key[0]
            field = fields[metric_alias]

            data = {RAW_VALUE: raw_value(value, field)}
            display = _display_value(value, field, date_as=return_none)
            if display is not None:
                data["display"] = display

            accessor_fields = [
                fields[field_alias] for field_alias in index_names
                if field_alias is not None
            ]

            accessor = [
                safe_value(value)
                for value, field in zip(key, accessor_fields)
            ] or key

            setdeepattr(row, accessor, data)

        return row
示例#3
0
 def test_totals_markers_are_returned_as_text_totals_marker(self):
     for marker, field in [
         (TEXT_TOTALS, text_field),
         (NUMBER_TOTALS, number_field),
         (DATE_TOTALS, date_field),
     ]:
         with self.subTest(field.data_type):
             self.assertEqual("$totals", formats.raw_value(marker, field))
示例#4
0
    def transform_row_values(self, series, fields: Dict[str, Field],
                             is_transposed: bool, is_pivoted: bool,
                             hide_aliases: List[str]):
        row = {}
        row_colors = None

        for key, value in series.items():
            if key in hide_aliases:
                continue

            key = wrap_list(key)

            # Get the field for the metric
            metric_alias = wrap_list(
                series.name)[0] if is_transposed else key[0]
            field = fields[metric_alias]
            data = {
                RAW_VALUE: raw_value(value, field),
            }
            if not row_colors:
                # No color for this field yet
                rule = find_rule_to_apply(
                    self.formatting_rules_map[metric_alias], value)
                if rule is not None:
                    colors = rule.determine_colors(value)
                    data["color"], data["text_color"] = colors
                    if not is_transposed and not is_pivoted and rule.covers_row:
                        # No transposing or pivoting going on so set as row color if it's specified for the rule
                        row_colors = colors

            display = _display_value(value, field, date_as=return_none)
            if display is not None:
                data["display"] = display

            accessor = self._get_row_value_accessor(series, fields, key)
            setdeepattr(row, accessor, data)

        # Assign the row colors to fields that aren't colored yet
        if row_colors:
            for key in series.keys():
                accessor = self._get_row_value_accessor(
                    series, fields, wrap_list(key))
                data = getdeepattr(row, accessor)
                if "color" not in data:
                    data["color"], data["text_color"] = row_colors

        return row, row_colors
示例#5
0
    def _render_category_data(group_df, field_alias, metric):
        categories = (list(group_df.index.levels[0]) if isinstance(
            group_df.index, pd.MultiIndex) else list(group_df.index))

        series = []
        for labels, y in group_df[field_alias].iteritems():
            label = labels[0] if isinstance(labels, tuple) else labels
            if pd.isnull(label):
                # ignore nans in index
                continue

            series.append({
                "x": categories.index(label),
                "y": formats.raw_value(y, metric)
            })

        return series
示例#6
0
    def _render_timeseries_data(group_df, metric_alias, metric):
        series = []
        for dimension_values, y in group_df[metric_alias].iteritems():
            first_dimension_value = utils.wrap_list(dimension_values)[0]

            # Ignore empty result sets where the only row is totals
            if first_dimension_value in TOTALS_MARKERS:
                continue

            if pd.isnull(first_dimension_value):
                # Ignore totals on the x-axis.
                continue

            series.append((
                formats.date_as_millis(first_dimension_value),
                formats.raw_value(y, metric),
            ))
        return series
示例#7
0
    def transform_row_index(
        index_values,
        field_map: Dict[str, Field],
        dimension_hyperlink_templates: Dict[str, str],
        hide_dimension_aliases: List[str],
        row_colors: List[str],
    ):
        # Add the index to the row
        row = {}
        for key, value in index_values.items():
            if key is None or key not in field_map:
                continue

            field_alias = key
            field = field_map[field_alias]

            data = {RAW_VALUE: raw_value(value, field)}
            display = _display_value(value, field)
            if display is not None:
                data["display"] = display
            if row_colors is not None:
                data["color"], data["text_color"] = row_colors

            is_totals = display == TOTALS_LABEL

            # If the dimension has a hyperlink template, then apply the template by formatting it with the dimension
            # values for this row. The values contained in `index_values` will always contain all of the required values
            # at this point, otherwise the hyperlink template will not be included.
            if not is_totals and key in dimension_hyperlink_templates:
                try:
                    data["hyperlink"] = dimension_hyperlink_templates[
                        key].format(**index_values)
                except KeyError:
                    pass

            safe_key = safe_value(key)
            row[safe_key] = data

        for dimension_alias in hide_dimension_aliases:
            if dimension_alias in row:
                del row[dimension_alias]

        return row
示例#8
0
    def _render_pie_series(self, metric: Field, reference: Reference,
                           data_frame: pd.DataFrame,
                           dimension_fields: List[Field]) -> dict:
        metric_alias = utils.alias_selector(metric.alias)

        if self.split_dimension:
            dimension_fields = [
                dimension for dimension in dimension_fields
                if dimension != self.split_dimension
            ]
            data_frame = data_frame.reset_index(alias_selector(
                self.split_dimension.alias),
                                                drop=True)

        data = []
        for dimension_values, y in data_frame[metric_alias].iteritems():
            dimension_values = utils.wrap_list(dimension_values)
            name = self._format_dimension_values(dimension_fields,
                                                 dimension_values)

            data.append({
                "name": name or metric.label,
                "y": formats.raw_value(y, metric)
            })

        return {
            "name": reference_label(metric, reference),
            "type": "pie",
            "data": data,
            "tooltip": {
                "pointFormat":
                '<span style="color:{point.color}">\u25CF</span> {series.name}: '
                "<b>{point.y} ({point.percentage:.1f}%)</b><br/>",
                "valueDecimals":
                metric.precision,
                "valuePrefix":
                reference_prefix(metric, reference),
                "valueSuffix":
                reference_suffix(metric, reference),
            },
        }
示例#9
0
    def _render_pie_series(self, metric, reference, data_frame, dimension_fields):
        metric_alias = utils.alias_selector(metric.alias)

        data = []
        for dimension_values, y in data_frame[metric_alias].iteritems():
            dimension_values = utils.wrap_list(dimension_values)
            name = self._format_dimension_values(dimension_fields, dimension_values)

            data.append(
                {"name": name or metric.label, "y": formats.raw_value(y, metric),}
            )

        return {
            "name": reference_label(metric, reference),
            "type": "pie",
            "data": data,
            "tooltip": {
                "pointFormat": '<span style="color:{point.color}">\u25CF</span> {series.name}: '
                "<b>{point.y} ({point.percentage:.1f}%)</b><br/>",
                "valueDecimals": metric.precision,
                "valuePrefix": reference_prefix(metric, reference),
                "valueSuffix": reference_suffix(metric, reference),
            },
        }
示例#10
0
 def test_inf_returned_as_inf_label(self):
     with self.subTest("positive inf"):
         self.assertIsNone(formats.raw_value(np.inf, None))
     with self.subTest("negative inf"):
         self.assertIsNone(formats.raw_value(-np.inf, None))
示例#11
0
 def test_datetime_value_is_returned_as_iso_date_string(self):
     self.assertEqual(
         "2019-01-01T12:30:02",
         formats.raw_value(datetime(2019, 1, 1, 12, 30, 2), date_field),
     )
示例#12
0
 def test_date_value_is_returned_as_iso_date_string(self):
     self.assertEqual("2019-01-01T00:00:00",
                      formats.raw_value(date(2019, 1, 1), date_field))
示例#13
0
 def test_boolean_value_is_returned_as_self(self):
     for value in (True, False):
         with self.subTest("using value" + str(value)):
             self.assertEqual(value,
                              formats.raw_value(value, boolean_field))
示例#14
0
 def test_num_value_is_returned_as_self(self):
     for value in (0, -1, 1, 100, 0.0, -1.1, 1.1, 0.123456789,
                   -0.123456789):
         with self.subTest("using value" + str(value)):
             self.assertEqual(value, formats.raw_value(value, number_field))
示例#15
0
 def test_text_value_is_returned_as_self(self):
     for value in ("abc", " dc23d- 0f30fi", ""):
         with self.subTest("using value" + value):
             self.assertEqual(value, formats.raw_value(value, text_field))
示例#16
0
 def test_none_returned_as_none(self):
     self.assertIsNone(formats.raw_value(None, None))
示例#17
0
 def test_nan_returned_as_none(self):
     self.assertIsNone(formats.raw_value(np.nan, None))