예제 #1
0
 def _determine_breakdown_label(
     self,
     breakdown_value: int,
     breakdown_type: Optional[str],
     breakdown: Union[str, List[Union[str, int]], None],
     value: Union[str, int],
 ) -> str:
     breakdown = breakdown if breakdown and isinstance(breakdown, list) else []
     if breakdown_type == "cohort":
         return get_breakdown_cohort_name(breakdown_value)
     else:
         return str(value) or "none"
예제 #2
0
    def _format_single_funnel(self, result, with_breakdown=False):
        # Format of this is [step order, person count (that reached that step), array of person uuids]
        steps = []
        relevant_people = []
        total_people = 0

        num_entities = len(self._filter.entities)

        for step in reversed(self._filter.entities):

            if result and len(result) > 0:
                total_people += result[step.order]
                relevant_people += result[cast(int, step.order) + num_entities]

            serialized_result = self._serialize_step(step, total_people,
                                                     relevant_people[0:100])
            if cast(int, step.order) > 0:
                serialized_result.update({
                    "average_conversion_time":
                    result[cast(int, step.order) + num_entities * 2 - 1],
                    "median_conversion_time":
                    result[cast(int, step.order) + num_entities * 3 - 2],
                })
            else:
                serialized_result.update({
                    "average_conversion_time": None,
                    "median_conversion_time": None
                })

            if with_breakdown:
                # breakdown will return a display ready value
                # breakdown_value will return the underlying id if different from display ready value (ex: cohort id)
                serialized_result.update({
                    "breakdown":
                    get_breakdown_cohort_name(result[-1])
                    if self._filter.breakdown_type == "cohort" else result[-1],
                    "breakdown_value":
                    result[-1],
                })
                # important to not try and modify this value any how - as these are keys for fetching persons

            steps.append(serialized_result)

        return steps[::-1]  #  reverse
예제 #3
0
    def _format_single_funnel(self, result, with_breakdown=False):
        # Format of this is [step order, person count (that reached that step), array of person uuids]
        steps = []
        total_people = 0

        num_entities = len(self._filter.entities)

        for step in reversed(self._filter.entities):

            if result and len(result) > 0:
                total_people += result[step.order]

            serialized_result = self._serialize_step(
                step, total_people, [])  # persons not needed on initial return
            if cast(int, step.order) > 0:

                serialized_result.update({
                    "average_conversion_time":
                    result[cast(int, step.order) + num_entities * 1 - 1],
                    "median_conversion_time":
                    result[cast(int, step.order) + num_entities * 2 - 2],
                })
            else:
                serialized_result.update({
                    "average_conversion_time": None,
                    "median_conversion_time": None
                })

            # Construct converted and dropped people urls. Previously this logic was
            # part of
            # https://github.com/PostHog/posthog/blob/e8d7b2fe6047f5b31f704572cd3bebadddf50e0f/frontend/src/scenes/insights/InsightTabs/FunnelTab/FunnelStepTable.tsx#L483:L483
            funnel_step = step.index + 1
            converted_people_filter = self._filter.with_data(
                {"funnel_step": funnel_step})
            dropped_people_filter = self._filter.with_data(
                {"funnel_step": -funnel_step})

            if with_breakdown:
                # breakdown will return a display ready value
                # breakdown_value will return the underlying id if different from display ready value (ex: cohort id)
                serialized_result.update({
                    "breakdown":
                    get_breakdown_cohort_name(result[-1])
                    if self._filter.breakdown_type == "cohort" else result[-1],
                    "breakdown_value":
                    result[-1],
                })
                # important to not try and modify this value any how - as these
                # are keys for fetching persons

                # Add in the breakdown to people urls as well
                converted_people_filter = converted_people_filter.with_data(
                    {"funnel_step_breakdown": result[-1]})
                dropped_people_filter = dropped_people_filter.with_data(
                    {"funnel_step_breakdown": result[-1]})

            serialized_result.update({
                "converted_people_url":
                f"{self._base_uri}api/person/funnel/?{urllib.parse.urlencode(converted_people_filter.to_params())}",
                "dropped_people_url": (
                    f"{self._base_uri}api/person/funnel/?{urllib.parse.urlencode(dropped_people_filter.to_params())}"
                    # NOTE: If we are looking at the first step, there is no drop off,
                    # everyone converted, otherwise they would not have been
                    # included in the funnel.
                    if step.index > 0 else None),
            })

            steps.append(serialized_result)

        return steps[::-1]  #  reverse
예제 #4
0
 def _label(self, filter: Filter, item: List, team_id: int) -> str:
     if filter.breakdown:
         if filter.breakdown_type == "cohort":
             return get_breakdown_cohort_name(item[2])
         return item[2]
     return "Formula ({})".format(filter.formula)