All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlinx.ggdsl.dsl.internal.contextsMutable.kt Maven / Gradle / Ivy

There is a newer version: 0.4.0-dev-15
Show newest version
package org.jetbrains.kotlinx.ggdsl.dsl.internal

import org.jetbrains.kotlinx.ggdsl.dsl.*
import org.jetbrains.kotlinx.ggdsl.dsl.column.columnPointer
import org.jetbrains.kotlinx.ggdsl.ir.Layer
import org.jetbrains.kotlinx.ggdsl.ir.bindings.*
import org.jetbrains.kotlinx.ggdsl.ir.data.ColumnPointer
import org.jetbrains.kotlinx.ggdsl.ir.data.TableData
import org.jetbrains.kotlinx.ggdsl.ir.data.TypedList
import org.jetbrains.kotlinx.ggdsl.ir.feature.FeatureName
import org.jetbrains.kotlinx.ggdsl.ir.feature.LayerFeature
import org.jetbrains.kotlinx.ggdsl.ir.feature.PlotFeature
import org.jetbrains.kotlinx.ggdsl.ir.scale.NonPositionalScale
import org.jetbrains.kotlinx.ggdsl.ir.scale.NonPositionalUnspecifiedScale
import org.jetbrains.kotlinx.ggdsl.ir.scale.PositionalScale
import org.jetbrains.kotlinx.ggdsl.ir.scale.PositionalUnspecifiedScale
import kotlin.reflect.typeOf

/**
 * Context with mutable mappings (i.e. with dynamic dataset change - usage
 * iterable instead of prepared columns).
 *
 * @property data context dataset of type [TableData]. Consists of the dynamic data sources.
 * @property dataBuffer dataset buffer for dynamic data sources.
 * @property generateID internal method. Generates unique id (name of column in
 * dataframe) for an added source.
 */
public interface TableBindingContextInterfaceMutable : TableDataContext {
    public override val data: TableData
    public val dataBuffer: MutableTableData
    public fun generateID(): String
}

/**
 * Converts the given [Iterable] to the [ColumnPointer] (while adding it to the dataset as a new column).
 *
 * @receiver context into which the iterable will be added.
 * @param iterable converting [Iterable] that will be added as a column to context dataset.
 * @return [ColumnPointer] to a new column
 */
public inline fun  TableBindingContextInterfaceMutable.toColumnPointer(iterable: Iterable)
        : ColumnPointer = toColumnPointer(iterable, generateID())

/**
 * Converts the given [Iterable] to the [ColumnPointer] with the given id as
 * a column name (while adding it to the dataset).
 *
 * @receiver context into which the iterable will be added.
 * @param iterable converting [Iterable] that will be added as a column to context dataset.
 * @param id name of a new column.
 * @return [ColumnPointer] to a new column
 */
public inline fun  TableBindingContextInterfaceMutable.toColumnPointer(
    iterable: Iterable,
    id: String
): ColumnPointer {
    dataBuffer.map[id] = TypedList(typeOf(), iterable.toList())
    return columnPointer(id)
}

/**
 * Context with immutable bindings base implementation.
 *
 * In this context the mappings and scales with [Iterable] are defined. TODO arrays etc.
 */
public abstract class TableContextMutableBase : TableBindingContextInterfaceMutable {
    override val bindingCollector: BindingCollector = BindingCollector()
    public abstract override val dataBuffer: MutableTableData
    override val data: TableData
        get() = dataBuffer.toTableData()

    private var counter: Int = 0
    public override fun generateID(): String = "*gen${counter++}"

    /**
     * Adds an [Iterable] to context dataset as a column and applies default
     * (i.e. without specifying the type and parameters;
     * they will be defined automatically; can be both used for positional and non-positional
     * mappings) scale to a new column.
     *
     * @receiver [Iterable] that will be added as a column to context dataset.
     * @param DomainType type of the domain.
     * @return scaled added column.
     */
    public inline fun  Iterable.scaled(): ColumnScaledUnspecifiedDefault =
        ColumnScaledUnspecifiedDefault(toColumnPointer(this))

    /**
     * Adds an [Iterable] to context dataset as a column with given name and applies default
     * (i.e. without specifying the type and parameters;
     * they will be defined automatically; can be both used for positional and non-positional
     * mappings) scale to a new column.
     *
     * @receiver [Pair] of [Iterable] that will be added as a column to context dataset to [String]
     * that will be used as a new column name.
     * @param DomainType type of the domain.
     * @return scaled added column.
     */
    public inline fun  Pair, String>.scaled()
            : ColumnScaledUnspecifiedDefault =
        ColumnScaledUnspecifiedDefault(toColumnPointer(first, second))

    /**
     * Adds an [Iterable] to context dataset as a column and applies an unspecified
     * (i.e. without specifying the type and parameters;
     * they will be defined automatically) positional scale to a new column.
     *
     * @receiver [Iterable] that will be added as a column to context dataset.
     * @param DomainType type of the domain.
     * @param scale applying positional unspecified scale.
     * @return scaled added column.
     */
    public inline fun  Iterable.scaled(
        scale: PositionalUnspecifiedScale
    ): ColumnScaledPositionalUnspecified = ColumnScaledPositionalUnspecified(toColumnPointer(this), scale)

    /**
     * Adds an [Iterable] to context dataset as a column with given name and applies an unspecified
     * (i.e. without specifying the type and parameters;
     * they will be defined automatically) poistional scale to a new column.
     *
     * @receiver [Pair] of [Iterable] that will be added as a column to context dataset to [String]
     * that will be used as a new column name.
     * @param DomainType type of the domain.
     * @param scale applying positional unspecified scale.
     * @return scaled added column.
     */
    public inline fun  Pair, String>.scaled(
        scale: PositionalUnspecifiedScale
    ): ColumnScaledPositionalUnspecified =
        ColumnScaledPositionalUnspecified(toColumnPointer(first, second), scale)

    /**
     * Adds an [Iterable] to context dataset as a column and applies an unspecified
     * (i.e. without specifying the type and parameters;
     * they will be defined automatically) non-positional scale to a new column.
     *
     * @receiver [Iterable] that will be added as a column to context dataset.
     * @param DomainType type of the domain.
     * @param scale applying non-positional unspecified scale.
     * @return scaled added column.
     */
    public inline fun  Iterable.scaled(
        scale: NonPositionalUnspecifiedScale
    ): ColumnScaledNonPositionalUnspecified =
        ColumnScaledNonPositionalUnspecified(toColumnPointer(this), scale)

    /**
     * Adds an [Iterable] to context dataset as a column with given name and applies an unspecified
     * (i.e. without specifying the type and parameters;
     * they will be defined automatically) non-positional scale to a new column.
     *
     * @receiver [Pair] of [Iterable] that will be added as a column to context dataset to [String]
     * that will be used as a new column name.
     * @param DomainType type of the domain.
     * @param scale applying non-positional unspecified scale.
     * @return scaled added column.
     */
    public inline fun  Pair, String>.scaled(
        scale: NonPositionalUnspecifiedScale
    ): ColumnScaledNonPositionalUnspecified =
        ColumnScaledNonPositionalUnspecified(toColumnPointer(first, second), scale)

    /**
     * Adds an [Iterable] to context dataset as a column and applies
     * a positional scale to a new column.
     *
     * @receiver [Iterable] that will be added as a column to context dataset.
     * @param DomainType type of the domain.
     * @param scale applying positional scale.
     * @return scaled added column.
     */
    public inline fun  Iterable.scaled(
        scale: PositionalScale
    ): ColumnScaledPositional = ColumnScaledPositional(toColumnPointer(this), scale)

    /**
     * Adds an [Iterable] to context dataset as a column with given name and applies a
     * positional scale to a new column.
     *
     * @receiver [Pair] of [Iterable] that will be added as a column to context dataset to [String]
     * that will be used as a new column name.
     * @param DomainType type of the domain.
     * @param scale applying positional scale.
     * @return scaled added column.
     */
    public inline fun  Pair, String>.scaled(
        scale: PositionalScale
    ): ColumnScaledPositional = ColumnScaledPositional(toColumnPointer(first, second), scale)

    /**
     * Adds an [Iterable] to context dataset as a column and applies
     * a non-positional scale to a new column.
     *
     * @receiver [Iterable] that will be added as a column to context dataset.
     * @param DomainType type of the domain.
     * @param scale applying non-positional scale.
     * @return scaled added column.
     */
    public inline fun  Iterable.scaled(
        scale: NonPositionalScale
    ): ColumnScaledNonPositional =
        ColumnScaledNonPositional(toColumnPointer(this), scale)

    /**
     * Adds an [Iterable] to context dataset as a column with given name and applies a
     * non-positional scale to a new column.
     *
     * @receiver [Pair] of [Iterable] that will be added as a column to context dataset to [String]
     * that will be used as a new column name.
     * @param DomainType type of the domain.
     * @param scale applying non-positional scale.
     * @return scaled added column.
     */
    public inline fun  Pair, String>.scaled(
        scale: NonPositionalScale
    ): ColumnScaledNonPositional =
        ColumnScaledNonPositional(toColumnPointer(first, second), scale)

    /**
     * Adds an [Iterable] to context dataset as a column and maps it
     * to this non-scalable positional ("sub-positional") aesthetic attribute.
     *
     * @param iterable [Iterable] that will be added as a column.
     */
    public inline operator fun  NonScalablePositionalAes.invoke(
        iterable: Iterable
    ) {
        context.bindingCollector.mappings[this.name] =
            NonScalablePositionalMapping(this.name, toColumnPointer(iterable), typeOf())
    }

    /**
     * Adds an [Iterable] to context dataset as a column with a given name and maps it
     * to this non-scalable positional ("sub-positional") aesthetic attribute.
     *
     * @param dataToName [Pair] of [Iterable] that will be added as a column to the name of a new column.
     */
    public inline operator fun  NonScalablePositionalAes.invoke(
        dataToName: Pair, String>
    ) {
        context.bindingCollector.mappings[this.name] =
            NonScalablePositionalMapping(
                this.name, toColumnPointer(dataToName.first, dataToName.second), typeOf()
            )
    }

    /**
     * Adds an [Iterable] to context dataset as a column and maps it
     * to this non-scalable non-positional aesthetic attribute.
     *
     * @param iterable [Iterable] that will be added as a column.
     */
    public inline operator fun 
            NonScalableNonPositionalAes.invoke(
        iterable: Iterable
    ) {
        context.bindingCollector.mappings[this.name] =
            NonScalableNonPositionalMapping(
                this.name, toColumnPointer(iterable), typeOf()
            )
    }

    /**
     * Adds an [Iterable] to context dataset as a column with the given name and maps it
     * to this non-scalable non-positional aesthetic attribute.
     *
     * @param dataToName [Pair] of [Iterable] that will be added as a column to the name of a new column.
     */
    public inline operator fun 
            NonScalableNonPositionalAes.invoke(
        dataToName: Pair, String>
    ) {
        context.bindingCollector.mappings[this.name] =
            NonScalablePositionalMapping(
                this.name, toColumnPointer(dataToName.first, dataToName.second), typeOf()
            )
    }

    /**
     * Adds an [Iterable] to context dataset as a column and maps it
     * to this positional aesthetic attribute with an unspecified
     * (i.e. without specifying the type and parameters; they will be defined automatically) scale.
     *
     * @param iterable [Iterable] that will be added as a column.
     */
    public inline operator fun  ScalablePositionalAes.invoke(
        iterable: Iterable
    ): ScaledUnspecifiedDefaultPositionalMapping {
        val mapping = ScaledUnspecifiedDefaultPositionalMapping(
            this.name,
            toColumnPointer(iterable).scaled(),
            typeOf()
        )
        context.bindingCollector.mappings[this.name] = mapping
        return mapping
    }

    /**
     * Adds an [Iterable] to context dataset as a column with the given name and maps it
     * to this positional aesthetic attribute with an unspecified
     * (i.e. without specifying the type and parameters; they will be defined automatically) scale.
     *
     * @param dataToName [Pair] of [Iterable] that will be added as a column to the name of a new column.
     */
    public inline operator fun  ScalablePositionalAes.invoke(
        dataToName: Pair, String>
    ): ScaledUnspecifiedDefaultPositionalMapping {
        val mapping = ScaledUnspecifiedDefaultPositionalMapping(
            this.name,
            toColumnPointer(dataToName.first, dataToName.second).scaled(),
            typeOf()
        )
        context.bindingCollector.mappings[this.name] = mapping
        return mapping
    }

    /**
     * Adds an [Iterable] to context dataset as a column and maps it
     * to this non-positional aesthetic attribute with an unspecified
     * (i.e. without specifying the type and parameters; they will be defined automatically) scale.
     *
     * @param iterable [Iterable] that will be added as a column.
     */
    public inline operator fun 
            ScalableNonPositionalAes.invoke(
        iterable: Iterable
    ): ScaledUnspecifiedDefaultNonPositionalMapping {
        val mapping = ScaledUnspecifiedDefaultNonPositionalMapping(
            this.name,
            toColumnPointer(iterable).scaled(),
            typeOf()
        )
        context.bindingCollector.mappings[this.name] = mapping
        return mapping
    }

    /**
     * Adds an [Iterable] to context dataset as a column with the given name and maps it
     * to this non-positional aesthetic attribute with an unspecified
     * (i.e. without specifying the type and parameters; they will be defined automatically) scale.
     *
     * @param dataToName [Pair] of [Iterable] that will be added as a column to the name of a new column.
     */
    public inline operator fun 
            ScalableNonPositionalAes.invoke(
        dataToName: Pair, String>
    ): ScaledUnspecifiedDefaultNonPositionalMapping {
        val mapping = ScaledUnspecifiedDefaultNonPositionalMapping(
            this.name,
            toColumnPointer(dataToName.first, dataToName.second).scaled(),
            typeOf()
        )
        context.bindingCollector.mappings[this.name] = mapping
        return mapping
    }
}

/**
 * Base class for nested contexts (that can inherit bindings from parent) with mutable mappings.
 *
 * @constructor Constructor with copying bindings from parent collector.
 * @param parent parental context.
 * @param separatedData whether to create its own data buffer and copy data from the parent dataset
 * or to use the parent dataset.
 * @param copy whether to inherit bindings from parental context.
 * @param copyMappings whether to inherit the mappings.
 * @param copySettings whether to inherit the settings.
 */
public abstract class TableSubContextMutable(
    public val parent: TableBindingContextInterfaceMutable,
    separatedData: Boolean = true,
    copy: Boolean = true,
    copyMappings: Boolean = true,
    copySettings: Boolean = true,
) : TableContextMutableBase() {
    override val dataBuffer: MutableTableData = if (separatedData) {
        MutableNamedData(parent.dataBuffer.map.toMutableMap())
    } else {
        parent.dataBuffer
    }
    override val bindingCollector: BindingCollector = if (copy) {
        BindingCollector(parent.bindingCollector, copyMappings, copySettings)
    } else {
        parent.bindingCollector
    }

    override fun generateID(): String = parent.generateID()
}

/**
 * Context with mutable bindings and layer collecting.
 */
public interface LayerCollectorContextMutable
    : LayerCollectorContextInterface, TableBindingContextInterfaceMutable

/*
public abstract class SubLayerCollectorContextMutable(
    parent: LayerCollectorContextMutable
) : LayerCollectorContextMutable, TableSubContextMutable(parent) {
    override val layers: MutableList = parent.layers
}

 */

/**
 * Layer building context with mutable bindings.
 */
public abstract class LayerContextMutable(parent: LayerCollectorContextMutable) :
    TableSubContextMutable(parent), LayerContextInterface {
    override val features: MutableMap = mutableMapOf()
}

/**
 * Plot context with mutable bindings.
 */
@PlotDslMarker
public class PlotContextMutable : LayerPlotContext, LayerCollectorContextMutable, TableContextMutableBase() {
    override val features: MutableMap = mutableMapOf()
    override val layers: MutableList = mutableListOf()
    override val dataBuffer: MutableNamedData = MutableNamedData(mutableMapOf())
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy