fun createMapperProvider()

in plot-stem/src/commonMain/kotlin/org/jetbrains/letsPlot/core/spec/config/ScaleConfig.kt [87:215]


    fun createMapperProvider(): MapperProvider<T> {
        var mapperProvider: MapperProvider<*> = DefaultMapperProvider[aes]

        val naValue: T = when {
            has(NA_VALUE) -> getValue(aes, NA_VALUE, aopConversion)!!
            else -> DefaultNaValue[aes]
        }

        // all 'manual' scales
        if (has(OUTPUT_VALUES)) {
            val outputValues = getList(OUTPUT_VALUES)
            mapperProvider = if (aes.isColor) {
                val outputColors = aopConversion.applyToList(Aes.COLOR, outputValues)
                ColorManualMapperProvider(
                    colors = outputColors.filterNotNull(),
                    naValue = naValue as Color
                )
            } else {
                val convertedValues = aopConversion.applyToList(aes, outputValues)
                DefaultMapperProviderUtil.createWithDiscreteOutput(convertedValues, naValue)
            }
        }

        if (aes == Aes.SHAPE) {
            val solid = get(SHAPE_SOLID)
            // False - show only hollow shapes, otherwise - all (default)
            if (solid is Boolean && solid == false) {
                mapperProvider = DefaultMapperProviderUtil.createWithDiscreteOutput(
                    ShapeMapper.hollowShapes(), ShapeMapper.NA_VALUE
                )
            }
        } else if ((aes == Aes.ALPHA || aes == Aes.SEGMENT_ALPHA) && has(RANGE)) {
            mapperProvider = AlphaMapperProvider(getRange(RANGE), (naValue as Double))
        } else if ((aes == Aes.SIZE || aes == Aes.SIZE_START || aes == Aes.SIZE_END || aes == Aes.POINT_SIZE || aes == Aes.POINT_STROKE || aes == Aes.SEGMENT_SIZE) && has(
                RANGE
            )
        ) {
            mapperProvider = SizeMapperProvider(getRange(RANGE), (naValue as Double))
        } else if (aes == Aes.LINEWIDTH && has(RANGE)) {
            mapperProvider = LinewidthMapperProvider(getRange(RANGE), (naValue as Double))
        } else if ((aes == Aes.STROKE || aes == Aes.STROKE_START || aes == Aes.STROKE_END) && has(RANGE)) {
            mapperProvider = StrokeMapperProvider(getRange(RANGE), (naValue as Double))
        }

        val scaleMapperKind = getString(SCALE_MAPPER_KIND) ?: if (
            !has(OUTPUT_VALUES) &&
            enforceDiscreteDomain() &&
            Aes.isColor(aes)
        ) {
            // Default palette type for discrete colors
            COLOR_BREWER
        } else {
            null
        }

        when (scaleMapperKind) {
            null -> {} // Nothing
            IDENTITY ->
                mapperProvider = createIdentityMapperProvider(aes, naValue, aopConversion)

            COLOR_GRADIENT ->
                mapperProvider = ColorGradientMapperProvider(
                    getColor(LOW, aopConversion),
                    getColor(HIGH, aopConversion),
                    (naValue as Color)
                )

            COLOR_GRADIENT2 ->
                mapperProvider = ColorGradient2MapperProvider(
                    getColor(LOW, aopConversion),
                    getColor(MID, aopConversion),
                    getColor(HIGH, aopConversion),
                    getDouble(MIDPOINT), naValue as Color
                )

            COLOR_GRADIENTN ->
                mapperProvider = ColorGradientnMapperProvider(
                    getStringList(COLORS).map(Colors::parseColor),
                    naValue as Color
                )

            COLOR_HUE ->
                mapperProvider = ColorHueMapperProvider(
                    hueRange = getRangeOrNull(HUE_RANGE) ?: ColorMapperDefaults.Hue.DEF_HUE_RANGE,
                    chroma = (getDouble(CHROMA) ?: ColorMapperDefaults.Hue.DEF_CHROMA),
                    luminance = (getDouble(LUMINANCE) ?: ColorMapperDefaults.Hue.DEF_LUMINANCE),
                    startHue = getDouble(START_HUE) ?: ColorMapperDefaults.Hue.DEF_START_HUE,
                    reversed = getDouble(DIRECTION)?.let { it < 0 } ?: false,
                    naValue = naValue as Color
                )

            COLOR_GREY ->
                mapperProvider = GreyscaleLightnessMapperProvider(
                    getDouble(START) ?: ColorMapperDefaults.GreyscaleLightness.DEF_START,
                    getDouble(END) ?: ColorMapperDefaults.GreyscaleLightness.DEF_END,
                    naValue as Color
                )

            COLOR_BREWER ->
                mapperProvider = ColorBrewerMapperProvider(
                    getString(PALETTE_TYPE),
                    get(PALETTE),
                    getDouble(DIRECTION),
                    naValue as Color
                )

            COLOR_CMAP ->
                mapperProvider = ColormapMapperProvider(
                    getString(Viridis.CMAP_NAME),
                    getDouble(Viridis.ALPHA),
                    getDouble(Viridis.BEGIN),
                    getDouble(Viridis.END),
                    getDouble(Viridis.DIRECTION),
                    naValue as Color
                )

            SIZE_AREA ->
                mapperProvider = SizeAreaMapperProvider(
                    getDouble(MAX_SIZE),
                    naValue as Double
                )

            else ->
                throw IllegalArgumentException("Aes '" + aes.name + "' - unexpected scale mapper kind: '" + scaleMapperKind + "'")
        }

        @Suppress("UNCHECKED_CAST")
        return mapperProvider as MapperProvider<T>
    }