All files / owid-grapher/grapher/chart ChartUtils.tsx

94.52% Statements 69/73
52.38% Branches 11/21
100% Functions 5/5
94.52% Lines 69/73

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 811x 1x 1x 1x 1x 1x 1x 1x 81x 81x 81x 19x 19x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 106x 106x 106x 106x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x   2x     2x 2x 2x   2x 2x 1x 1x 47x 47x 47x 47x 47x 47x 47x 47x 47x 47x 47x 47x 47x                
import React from "react"
import { Box } from "../../clientUtils/owidTypes"
import { SeriesStrategy } from "../core/GrapherConstants"
import { LineChartSeries } from "../lineCharts/LineChartConstants"
import { SelectionArray } from "../selection/SelectionArray"
import { ChartManager } from "./ChartManager"
 
export const autoDetectYColumnSlugs = (manager: ChartManager): string[] => {
    if (manager.yColumnSlugs && manager.yColumnSlugs.length)
        return manager.yColumnSlugs
    if (manager.yColumnSlug) return [manager.yColumnSlug]
    return manager.table.numericColumnSlugs
}
 
export const getDefaultFailMessage = (manager: ChartManager): string => {
    if (manager.table.rootTable.isBlank) return `No table loaded yet.`
    if (manager.table.rootTable.entityNameColumn.isMissing)
        return `Table is missing an EntityName column.`
    if (manager.table.rootTable.timeColumn.isMissing)
        return `Table is missing a Time column.`
    const yColumnSlugs = autoDetectYColumnSlugs(manager)
    if (!yColumnSlugs.length) return "Missing Y axis column"
    const selection = makeSelectionArray(manager)
    if (!selection.hasSelection) return `No ${selection.entityType} selected`
    return ""
}
 
export const getSeriesKey = (series: LineChartSeries, suffix?: string) => {
    return `${series.seriesName}-${series.color}-${
        series.isProjection ? "projection" : ""
    }${suffix ? "-" + suffix : ""}`
}
 
export const autoDetectSeriesStrategy = (
    manager: ChartManager,
    handleProjections: boolean = false
): SeriesStrategy => {
    if (manager.seriesStrategy) return manager.seriesStrategy
 
    let columnThreshold: number = 1
 
    if (handleProjections && manager.transformedTable) {
        const yColumnSlugs = autoDetectYColumnSlugs(manager)
        const yColumns = yColumnSlugs.map((slug) =>
            manager.transformedTable!.get(slug)
        )
        const hasNormalAndProjectedSeries =
            yColumns.some((col) => col.isProjection) &&
            yColumns.some((col) => !col.isProjection)
        if (hasNormalAndProjectedSeries) {
            columnThreshold = 2
        }
    }
 
    return autoDetectYColumnSlugs(manager).length > columnThreshold
        ? SeriesStrategy.column
        : SeriesStrategy.entity
}
 
export const makeClipPath = (
    renderUid: number,
    box: Box
): { id: string; element: JSX.Element } => {
    const id = `boundsClip-${renderUid}`
    return {
        id: `url(#${id})`,
        element: (
            <defs>
                <clipPath id={id}>
                    <rect {...box}></rect>
                </clipPath>
            </defs>
        ),
    }
}
 
export const makeSelectionArray = (manager: ChartManager): SelectionArray =>
    manager.selection instanceof SelectionArray
        ? manager.selection
        : new SelectionArray(manager.selection ?? [])