/// <summary>
        /// returns a View with the specific geometry configuration
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="builder"></param>
        /// <returns></returns>
        protected View ApplyGeometryAndRendering(CreationConfiguration configuration, ref ViewBuilder builder)
        {
            Material mt = null;

            switch (configuration.Geometry)
            {
            case AbstractVisualisation.GeometryType.Undefined:
                return(null);

            case AbstractVisualisation.GeometryType.Points:
                builder.createIndicesPointTopology();
                mt                  = new Material(Shader.Find("IATK/OutlineDots"));
                mt.mainTexture      = Resources.Load("circle-outline-basic") as Texture2D;
                mt.renderQueue      = 3000;
                mt.enableInstancing = true;
                return(builder.updateView().
                       apply(gameObject, mt));

            case AbstractVisualisation.GeometryType.Lines:
                if (visualisationReference.graphDimension != "Undefined")
                {
                    CSVDataSource csvds = (CSVDataSource)(visualisationReference.dataSource);
                    builder.createIndicesGraphTopology(csvds.GraphEdges);
                    mt                  = new Material(Shader.Find("IATK/LinesShader"));
                    mt.renderQueue      = 3000;
                    mt.enableInstancing = true;
                    return(builder.updateView().
                           apply(gameObject, mt));
                }
                else
                if (visualisationReference.linkingDimension != "Undefined")
                {
                    builder.createIndicesConnectedLineTopology(visualisationReference.dataSource[visualisationReference.linkingDimension].Data);
                    mt                  = new Material(Shader.Find("IATK/LinesShader"));
                    mt.renderQueue      = 3000;
                    mt.enableInstancing = true;
                    return(builder.updateView().
                           apply(gameObject, mt));
                }
                else
                {
                    throw new UnityException("'Linkinfield' or 'GraphDimension' is undefined. Please select a linking field or a graph dimension");
                }
                break;

            case AbstractVisualisation.GeometryType.Quads:
                builder.createIndicesPointTopology();
                mt                  = new Material(Shader.Find("IATK/Quads"));
                mt.renderQueue      = 3000;
                mt.enableInstancing = true;
                return(builder.updateView().
                       apply(gameObject, mt));

            case AbstractVisualisation.GeometryType.LinesAndDots:
                if (visualisationReference.graphDimension != "Undefined")
                {
                    CSVDataSource csvds = (CSVDataSource)(visualisationReference.dataSource);
                    builder.createIndicesGraphTopology(csvds.GraphEdges);
                    mt                  = new Material(Shader.Find("IATK/LineAndDotsShader"));
                    mt.renderQueue      = 3000;
                    mt.enableInstancing = true;
                    return(builder.updateView().
                           apply(gameObject, mt));
                }
                if (visualisationReference.linkingDimension != "Undefined")
                {
                    builder.createIndicesConnectedLineTopology(visualisationReference.dataSource[visualisationReference.linkingDimension].Data);
                    mt                  = new Material(Shader.Find("IATK/LineAndDotsShader"));
                    mt.renderQueue      = 3000;
                    mt.enableInstancing = true;
                    return(builder.updateView().
                           apply(gameObject, mt));
                }
                else
                {
                    throw new UnityException("'Linkinfield' or 'GraphDimension' is undefined. Please select a linking field or a graph dimension");
                }


            case AbstractVisualisation.GeometryType.Cubes:
                builder.createIndicesPointTopology();     // createIndicesLinkedTopology(dataSource[linkingDimension].Data);
                mt                  = new Material(Shader.Find("IATK/CubeShader"));
                mt.renderQueue      = 3000;
                mt.enableInstancing = true;
                return(builder.updateView().
                       apply(gameObject, mt));

            case AbstractVisualisation.GeometryType.Bars:
                builder.createIndicesPointTopology();     // createIndicesLinkedTopology(dataSource[linkingDimension].Data);
                mt                  = new Material(Shader.Find("IATK/BarShader"));
                mt.renderQueue      = 3000;
                mt.enableInstancing = true;
                return(builder.updateView().
                       apply(gameObject, mt));

            case AbstractVisualisation.GeometryType.Spheres:
                builder.createIndicesPointTopology();     // createIndicesLinkedTopology(dataSource[linkingDimension].Data);
                mt                  = new Material(Shader.Find("IATK/SphereShader"));
                mt.mainTexture      = Resources.Load("sphere-texture") as Texture2D;
                mt.renderQueue      = 3000;
                mt.enableInstancing = true;
                return(builder.updateView().
                       apply(gameObject, mt));

            default:
                return(null);
            }
        }
        /// <summary>
        /// returns a View with the specific geometry configuration
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="builder"></param>
        /// <returns></returns>
        protected View ApplyGeometryAndRendering(CreationConfiguration configuration, ref ViewBuilder builder)
        {
            Material mt = null;

            switch (configuration.Geometry)
            {
            case AbstractVisualisation.GeometryType.Undefined:
                return(null);

            case AbstractVisualisation.GeometryType.Points:
                builder.createIndicesPointTopology();
                mt             = new Material(Shader.Find("IATK/OutlineDots"));
                mt.mainTexture = Resources.Load("circle-outline-basic") as Texture2D;
                mt.renderQueue = 3000;
                return(builder.updateView().
                       apply(gameObject, mt));

            case AbstractVisualisation.GeometryType.Lines:
                if (visualisationReference.linkingDimension == "Undefined")
                {
                    throw new UnityException("The linking field 'Linkinfield' is undefined. Please select a linking field");
                }
                builder.createIndicesLinkedTopology(visualisationReference.dataSource[visualisationReference.linkingDimension].Data, visualisationReference.dataSource[visualisationReference.xDimension.Attribute].Data);
                mt             = new Material(Shader.Find("IATK/LinesShader"));
                mt.renderQueue = 3000;
                return(builder.updateView().
                       apply(gameObject, mt));

            case AbstractVisualisation.GeometryType.Quads:
                builder.createIndicesPointTopology();
                mt             = new Material(Shader.Find("IATK/Quads"));
                mt.renderQueue = 3000;
                return(builder.updateView().
                       apply(gameObject, mt));

            case AbstractVisualisation.GeometryType.LinesAndDots:

                if (visualisationReference.linkingDimension == "Undefined")
                {
                    throw new UnityException("The linking field 'Linkinfield' is undefined. Please select a linking field");
                }
                builder.createIndicesLinkedTopology(visualisationReference.dataSource[visualisationReference.linkingDimension].Data, visualisationReference.dataSource[visualisationReference.xDimension.Attribute].Data);
                mt             = new Material(Shader.Find("IATK/LineAndDotsShader"));
                mt.renderQueue = 3000;
                return(builder.updateView().
                       apply(gameObject, mt));

            case AbstractVisualisation.GeometryType.Cubes:
                builder.createIndicesPointTopology();     // createIndicesLinkedTopology(dataSource[linkingDimension].Data);
                mt             = new Material(Shader.Find("IATK/CubeShader"));
                mt.renderQueue = 3000;
                return(builder.updateView().
                       apply(gameObject, mt));

            case AbstractVisualisation.GeometryType.Bars:
                builder.createIndicesPointTopology();     // createIndicesLinkedTopology(dataSource[linkingDimension].Data);
                mt             = new Material(Shader.Find("IATK/BarShader"));
                mt.renderQueue = 3000;

                return(builder.updateView().
                       apply(gameObject, mt));

            case AbstractVisualisation.GeometryType.Spheres:
                builder.createIndicesPointTopology();     // createIndicesLinkedTopology(dataSource[linkingDimension].Data);
                mt             = new Material(Shader.Find("IATK/SphereShader"));
                mt.mainTexture = Resources.Load("sphere-texture") as Texture2D;
                mt.renderQueue = 3000;
                return(builder.updateView().
                       apply(gameObject, mt));

            default:
                return(null);
            }
        }
        public override void CreateVisualisation()
        {
            if (visualisationReference.parallelCoordinatesDimensions.Length > 1 && visualisationReference.parallelCoordinatesDimensions.None(x => x == null || x.Attribute == "Undefined"))
            {
                viewList.Clear();
                destroyView();

                ViewBuilder viewParallel;

                List <float> positionsLocalX = new List <float>();
                List <float> positionsLocalY = new List <float>();
                List <float> positionsLocalZ = new List <float>();
                List <int>   indices         = new List <int>();

                for (int i = 0; i < visualisationReference.parallelCoordinatesDimensions.Length; i++)
                {
                    if (visualisationReference.parallelCoordinatesDimensions[i] != null && visualisationReference.parallelCoordinatesDimensions[i].Attribute != "Undefined")
                    {
                        float[] positions = visualisationReference.dataSource[visualisationReference.parallelCoordinatesDimensions[i].Attribute].Data;
                        for (int k = 0; k < positions.Length; k++)
                        {
                            positionsLocalX.Add((float)GameObject_Axes_Holders[i].transform.localPosition.x);
                            positionsLocalY.Add(positions[k] + (float)GameObject_Axes_Holders[i].transform.localPosition.y);
                            positionsLocalZ.Add((float)GameObject_Axes_Holders[i].transform.localPosition.z);
                        }
                    }
                }

                List <float> parallelCoordinatesIndices = new List <float>();
                List <float> repeatPattern = Enumerable.Range(0, visualisationReference.dataSource.DataCount).Select(x => x * 1f).ToList();

                for (int i = 0; i < visualisationReference.parallelCoordinatesDimensions.Length; i++)
                {
                    parallelCoordinatesIndices.AddRange(repeatPattern);
                }

                //build indices
                for (int i = 0; i < visualisationReference.dataSource.DataCount; i++)
                {
                    for (int j = 0; j < visualisationReference.parallelCoordinatesDimensions.Length - 1; j++)
                    {
                        indices.Add(j * visualisationReference.dataSource.DataCount + i);
                        indices.Add((j + 1) * visualisationReference.dataSource.DataCount + i);
                    }
                }

                int[] lineLength = new int[visualisationReference.dataSource.DataCount];
                for (int i = 0; i < visualisationReference.dataSource.DataCount; i++)
                {
                    lineLength[i] = visualisationReference.parallelCoordinatesDimensions.Length;
                }

                viewParallel = new ViewBuilder(MeshTopology.Lines, "[IATK] Parallel Coordinates");
                viewParallel.initialiseDataView(positionsLocalX.Count);
                viewParallel.setDataDimension(positionsLocalX.ToArray(), ViewBuilder.VIEW_DIMENSION.X);
                viewParallel.setDataDimension(positionsLocalY.ToArray(), ViewBuilder.VIEW_DIMENSION.Y);
                viewParallel.setDataDimension(positionsLocalZ.ToArray(), ViewBuilder.VIEW_DIMENSION.Z);
                viewParallel.Indices    = indices;
                viewParallel.LineLength = lineLength.ToList();
                //viewParallel.;

                Material mt = new Material(Shader.Find("IATK/PCPShader"));
                mt.renderQueue      = 3000;
                mt.enableInstancing = true;
                View v = viewParallel.
                         createIndicesPointTopology(parallelCoordinatesIndices.ToArray()).
                         updateView().apply(gameObject, mt);

                //v.SetVertexIdChannel(parallelCoordinatesIndices.ToArray());

                viewList.Add(v);

                //Creation configuration management
                if (creationConfiguration == null)
                {
                    creationConfiguration = new CreationConfiguration();
                }

                creationConfiguration.VisualisationType             = AbstractVisualisation.VisualisationTypes.PARALLEL_COORDINATES;
                creationConfiguration.parallelCoordinatesDimensions = visualisationReference.parallelCoordinatesDimensions;
                creationConfiguration.colour           = visualisationReference.colour;
                creationConfiguration.ColourDimension  = visualisationReference.colourDimension;
                creationConfiguration.colourKeys       = visualisationReference.dimensionColour;
                creationConfiguration.Geometry         = visualisationReference.geometry;
                creationConfiguration.LinkingDimension = visualisationReference.linkingDimension;
                creationConfiguration.SizeDimension    = visualisationReference.sizeDimension;
                creationConfiguration.Axies            = new Dictionary <CreationConfiguration.Axis, string>();

                //restore properties
                UpdateVisualisation(AbstractVisualisation.PropertyType.Colour);
                UpdateVisualisation(AbstractVisualisation.PropertyType.Size);
                UpdateVisualisation(AbstractVisualisation.PropertyType.SizeValues);
            }
        }