void DrawMinMaxSlider(Rect rect, SerializedProperty minFilterProp, SerializedProperty maxFilterProp, string attributeid, DataSource dataSource)
        {
            bool isUndefined = dataSource == null || attributeid == "Undefined";
            int  idx         = Array.IndexOf(dataSource.Select(m => m.Identifier).ToArray(), attributeid);

            // get the normalized value
            float minValue = !isUndefined ? dataSource[attributeid].MetaData.minValue : 0.0f;
            float maxValue = !isUndefined ? dataSource[attributeid].MetaData.maxValue : 1.0f;

            // [workaround] prevent division by zero
            maxValue = (minValue == maxValue) ? minValue + 1 : maxValue;

            // calculate the real value
            float min = UtilMath.normaliseValue(minFilterProp.floatValue, 0, 1, minValue, maxValue);
            float max = UtilMath.normaliseValue(maxFilterProp.floatValue, 0, 1, minValue, maxValue);

            // get the string representation
            string minLogical = isUndefined ? "" : dataSource.getOriginalValue(minFilterProp.floatValue, idx).ToString();
            string maxLogical = isUndefined ? "" : dataSource.getOriginalValue(maxFilterProp.floatValue, idx).ToString();

            EditorGUI.TextField(new Rect(rect.x, rect.y, 75, rect.height), minLogical);
            EditorGUI.MinMaxSlider(new Rect(rect.x + 75, rect.y, rect.width - 150, rect.height), GUIContent.none, ref min, ref max, minValue, maxValue);
            EditorGUI.TextField(new Rect(rect.x + rect.width - 78, rect.y, 75, rect.height), maxLogical);

            minFilterProp.floatValue = UtilMath.normaliseValue(min, minValue, maxValue, 0, 1);
            maxFilterProp.floatValue = UtilMath.normaliseValue(max, minValue, maxValue, 0, 1);
        }
        public override void UpdateVisualisation(PropertyType propertyType)
        {
            if (viewList.Count == 0)
            {
                CreateVisualisation();
            }

            if (viewList.Count != 0)
            {
                switch (propertyType)
                {
                case AbstractVisualisation.PropertyType.X:
                    if (visualisationReference.xDimension.Attribute.Equals("Undefined"))
                    {
                        viewList[0].ZeroPosition(0);
                    }
                    else
                    {
                        viewList[0].UpdateXPositions(visualisationReference.dataSource[visualisationReference.xDimension.Attribute].Data);
                    }
                    if (creationConfiguration.Axies.ContainsKey(CreationConfiguration.Axis.X))
                    {
                        creationConfiguration.Axies[CreationConfiguration.Axis.X] = visualisationReference.xDimension.Attribute;
                    }
                    else
                    {
                        creationConfiguration.Axies.Add(CreationConfiguration.Axis.X, visualisationReference.xDimension.Attribute);
                    }
                    break;

                case AbstractVisualisation.PropertyType.Y:
                    if (visualisationReference.yDimension.Attribute.Equals("Undefined"))
                    {
                        viewList[0].ZeroPosition(1);
                    }
                    else
                    {
                        viewList[0].UpdateYPositions(visualisationReference.dataSource[visualisationReference.yDimension.Attribute].Data);
                    }
                    if (creationConfiguration.Axies.ContainsKey(CreationConfiguration.Axis.Y))
                    {
                        creationConfiguration.Axies[CreationConfiguration.Axis.Y] = visualisationReference.yDimension.Attribute;
                    }
                    else
                    {
                        creationConfiguration.Axies.Add(CreationConfiguration.Axis.Y, visualisationReference.yDimension.Attribute);
                    }
                    break;

                case AbstractVisualisation.PropertyType.Z:
                    if (visualisationReference.zDimension.Attribute.Equals("Undefined"))
                    {
                        viewList[0].ZeroPosition(2);
                    }
                    else
                    {
                        viewList[0].UpdateZPositions(visualisationReference.dataSource[visualisationReference.zDimension.Attribute].Data);
                    }
                    if (creationConfiguration.Axies.ContainsKey(CreationConfiguration.Axis.Z))
                    {
                        creationConfiguration.Axies[CreationConfiguration.Axis.Z] = visualisationReference.zDimension.Attribute;
                    }
                    else
                    {
                        creationConfiguration.Axies.Add(CreationConfiguration.Axis.Z, visualisationReference.zDimension.Attribute);
                    }
                    break;

                case AbstractVisualisation.PropertyType.Colour:
                    if (visualisationReference.colourDimension != "Undefined")
                    {
                        for (int i = 0; i < viewList.Count; i++)
                        {
                            viewList[i].SetColors(mapColoursContinuous(visualisationReference.dataSource[visualisationReference.colourDimension].Data));
                        }
                    }
                    else if (visualisationReference.colorPaletteDimension != "Undefined")
                    {
                        for (int i = 0; i < viewList.Count; i++)
                        {
                            viewList[i].SetColors(mapColoursPalette(visualisationReference.dataSource[visualisationReference.colorPaletteDimension].Data, visualisationReference.coloursPalette));
                        }
                    }
                    else
                    {
                        for (int i = 0; i < viewList.Count; i++)
                        {
                            Color[] colours = viewList[0].GetColors();
                            for (int j = 0; j < colours.Length; ++j)
                            {
                                colours[j] = visualisationReference.colour;
                            }
                            viewList[i].SetColors(colours);
                        }
                    }

                    creationConfiguration.ColourDimension = visualisationReference.colourDimension;
                    creationConfiguration.colourKeys      = visualisationReference.dimensionColour;
                    creationConfiguration.colour          = visualisationReference.colour;

                    break;

                case AbstractVisualisation.PropertyType.Size:
                {
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        if (visualisationReference.sizeDimension != "Undefined")
                        {
                            viewList[i].SetSizeChannel(visualisationReference.dataSource[visualisationReference.sizeDimension].Data);
                        }
                        else
                        {
                            viewList[i].SetSizeChannel(new float[visualisationReference.dataSource.DataCount]);
                        }
                    }
                    creationConfiguration.SizeDimension = visualisationReference.sizeDimension;
                    break;
                }

                case PropertyType.SizeValues:
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetSize(visualisationReference.size);
                        viewList[i].SetMinSize(visualisationReference.minSize);            // Data is normalised
                        viewList[i].SetMaxSize(visualisationReference.maxSize);
                    }
                    creationConfiguration.Size    = visualisationReference.size;
                    creationConfiguration.MinSize = visualisationReference.minSize;
                    creationConfiguration.MaxSize = visualisationReference.maxSize;

                    break;

                case AbstractVisualisation.PropertyType.LinkingDimension:
                    creationConfiguration.LinkingDimension = visualisationReference.linkingDimension;

                    CreateVisualisation();     // needs to recreate the visualsiation because the mesh properties have changed
                    break;

                case AbstractVisualisation.PropertyType.GeometryType:
                    creationConfiguration.Geometry = visualisationReference.geometry;
                    CreateVisualisation();     // needs to recreate the visualsiation because the mesh properties have changed
                    break;

                case AbstractVisualisation.PropertyType.Scaling:

                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetMinNormX(visualisationReference.xDimension.minScale);
                        viewList[i].SetMaxNormX(visualisationReference.xDimension.maxScale);
                        viewList[i].SetMinNormY(visualisationReference.yDimension.minScale);
                        viewList[i].SetMaxNormY(visualisationReference.yDimension.maxScale);
                        viewList[i].SetMinNormZ(visualisationReference.zDimension.minScale);
                        viewList[i].SetMaxNormZ(visualisationReference.zDimension.maxScale);
                    }
                    break;

                case AbstractVisualisation.PropertyType.DimensionFiltering:
                {
                    float[] isFiltered = new float[visualisationReference.dataSource.DataCount];
                    for (int i = 0; i < visualisationReference.dataSource.DimensionCount; i++)
                    {
                        foreach (DimensionFilter attrFilter in visualisationReference.xScatterplotMatrixDimensions)
                        {
                            if (attrFilter.Attribute == visualisationReference.dataSource[i].Identifier)
                            {
                                float minFilteringValue = UtilMath.normaliseValue(attrFilter.minFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);
                                float maxFilteringValue = UtilMath.normaliseValue(attrFilter.maxFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);

                                for (int j = 0; j < isFiltered.Length; j++)
                                {
                                    isFiltered[j] = (visualisationReference.dataSource[i].Data[j] < minFilteringValue || visualisationReference.dataSource[i].Data[j] > maxFilteringValue) ? 1.0f : isFiltered[j];
                                }
                            }
                        }
                        foreach (DimensionFilter attrFilter in visualisationReference.yScatterplotMatrixDimensions)
                        {
                            if (attrFilter.Attribute == visualisationReference.dataSource[i].Identifier)
                            {
                                float minFilteringValue = UtilMath.normaliseValue(attrFilter.minFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);
                                float maxFilteringValue = UtilMath.normaliseValue(attrFilter.maxFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);

                                for (int j = 0; j < isFiltered.Length; j++)
                                {
                                    isFiltered[j] = (visualisationReference.dataSource[i].Data[j] < minFilteringValue || visualisationReference.dataSource[i].Data[j] > maxFilteringValue) ? 1.0f : isFiltered[j];
                                }
                            }
                        }
                        foreach (DimensionFilter attrFilter in visualisationReference.zScatterplotMatrixDimensions)
                        {
                            if (attrFilter.Attribute == visualisationReference.dataSource[i].Identifier)
                            {
                                float minFilteringValue = UtilMath.normaliseValue(attrFilter.minFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);
                                float maxFilteringValue = UtilMath.normaliseValue(attrFilter.maxFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);

                                for (int j = 0; j < isFiltered.Length; j++)
                                {
                                    isFiltered[j] = (visualisationReference.dataSource[i].Data[j] < minFilteringValue || visualisationReference.dataSource[i].Data[j] > maxFilteringValue) ? 1.0f : isFiltered[j];
                                }
                            }
                        }
                    }
                    // map the filtered attribute into the normal channel of the bigmesh
                    foreach (View v in viewList)
                    {
                        v.SetFilterChannel(isFiltered);
                    }
                    // update axis details
                    for (int i = 0; i < GameObject_Axes_Holders.Count; ++i)
                    {
                        Axis axis = GameObject_Axes_Holders[i].GetComponent <Axis>();
                        BindMinMaxAxisValues(axis, visualisationReference.parallelCoordinatesDimensions[i]);
                    }
                }
                break;

                case AbstractVisualisation.PropertyType.AttributeFiltering:
                {
                    foreach (var viewElement in viewList)
                    {
                        float[] isFiltered = new float[visualisationReference.dataSource.DataCount];
                        for (int i = 0; i < visualisationReference.dataSource.DimensionCount; i++)
                        {
                            foreach (AttributeFilter attrFilter in visualisationReference.attributeFilters)
                            {
                                //print(attrFilter.Attribute + "   " + dataSource[i].Identifier);
                                if (attrFilter.Attribute == visualisationReference.dataSource[i].Identifier)
                                {
                                    float minFilteringValue = UtilMath.normaliseValue(attrFilter.minFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);
                                    float maxFilteringValue = UtilMath.normaliseValue(attrFilter.maxFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);

                                    for (int j = 0; j < isFiltered.Length; j++)
                                    {
                                        isFiltered[j] = (visualisationReference.dataSource[i].Data[j] < minFilteringValue || visualisationReference.dataSource[i].Data[j] > maxFilteringValue) ? 1.0f : isFiltered[j];
                                    }
                                }
                            }
                        }
                        // map the filtered attribute into the normal channel of the bigmesh
                        foreach (View v in viewList)
                        {
                            v.SetFilterChannel(isFiltered);
                        }
                    }
                }
                break;

                case PropertyType.VisualisationType:

                    break;

                default:
                    break;
                }
            }

            if (visualisationReference.geometry != GeometryType.Undefined)// || visualisationType == VisualisationTypes.PARALLEL_COORDINATES)
            {
                SerializeViewConfiguration(creationConfiguration);
            }

            ////Update any label on the corresponding axes
            if (propertyType == AbstractVisualisation.PropertyType.DimensionChange)
            {
                CreateVisualisation();
            }
        }
Пример #3
0
        public override void UpdateVisualisation(PropertyType propertyType)
        {
            if (viewList.Count != 0)
            {
                switch (propertyType)
                {
                case AbstractVisualisation.PropertyType.Colour:
                    if (visualisationReference.colourDimension != "Undefined")
                    {
                        for (int i = 0; i < viewList.Count; i++)
                        {
                            viewList[i].SetColors(mapColoursContinuous(visualisationReference.dataSource[visualisationReference.colourDimension].Data));
                        }
                    }
                    else if (visualisationReference.colorPaletteDimension != "Undefined")
                    {
                        for (int i = 0; i < viewList.Count; i++)
                        {
                            viewList[i].SetColors(mapColoursPalette(visualisationReference.dataSource[visualisationReference.colorPaletteDimension].Data, visualisationReference.coloursPalette));
                        }
                    }
                    else
                    {
                        for (int i = 0; i < viewList.Count; i++)
                        {
                            Color[] colours = viewList[0].GetColors();
                            for (int j = 0; j < colours.Length; ++j)
                            {
                                colours[j] = visualisationReference.colour;
                            }
                            viewList[i].SetColors(colours);
                        }
                    }

                    creationConfiguration.ColourDimension = visualisationReference.colourDimension;
                    creationConfiguration.colourKeys      = visualisationReference.dimensionColour;
                    creationConfiguration.colour          = visualisationReference.colour;

                    break;

                case AbstractVisualisation.PropertyType.Size:
                {
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        if (visualisationReference.sizeDimension != "Undefined")
                        {
                            viewList[i].SetSizeChannel(visualisationReference.dataSource[visualisationReference.sizeDimension].Data);
                        }
                        else
                        {
                            viewList[i].SetSizeChannel(Enumerable.Repeat(1f, visualisationReference.dataSource[0].Data.Length).ToArray());
                        }
                    }
                    creationConfiguration.SizeDimension = visualisationReference.sizeDimension;
                    break;
                }

                case PropertyType.SizeValues:
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetSize(visualisationReference.size);
                        viewList[i].SetMinSize(visualisationReference.minSize);     // Data is normalised
                        viewList[i].SetMaxSize(visualisationReference.maxSize);
                    }
                    creationConfiguration.Size    = visualisationReference.size;
                    creationConfiguration.MinSize = visualisationReference.minSize;
                    creationConfiguration.MaxSize = visualisationReference.maxSize;

                    break;

                case AbstractVisualisation.PropertyType.LinkingDimension:
                    creationConfiguration.LinkingDimension = visualisationReference.linkingDimension;
                    CreateVisualisation();     // needs to recreate the visualsiation because the mesh properties have changed
                    break;

                case AbstractVisualisation.PropertyType.GeometryType:
                    creationConfiguration.Geometry = visualisationReference.geometry;
                    CreateVisualisation();     // needs to recreate the visualsiation because the mesh properties have changed
                    break;

                case AbstractVisualisation.PropertyType.Scaling:

                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetMinNormX(visualisationReference.xDimension.minScale);
                        viewList[i].SetMaxNormX(visualisationReference.xDimension.maxScale);
                        viewList[i].SetMinNormY(visualisationReference.yDimension.minScale);
                        viewList[i].SetMaxNormY(visualisationReference.yDimension.maxScale);
                        viewList[i].SetMinNormZ(visualisationReference.zDimension.minScale);
                        viewList[i].SetMaxNormZ(visualisationReference.zDimension.maxScale);
                    }
                    for (int i = 0; i < GameObject_Axes_Holders.Count; ++i)
                    {
                        Axis axis = GameObject_Axes_Holders[i].GetComponent <Axis>();

                        // [Experimental] Update padding space by width property
                        axis.transform.localPosition = Vector3.right * i * visualisationReference.width;
                        axis.Length = visualisationReference.height;
                        axis.UpdateLength();

                        if (i < visualisationReference.parallelCoordinatesDimensions.Length)
                        {
                            BindMinMaxAxisValues(axis, visualisationReference.parallelCoordinatesDimensions[i]);
                        }
                    }
                    // [Experimental] Update mesh's scale by width & height properties
                    foreach (View view in viewList)
                    {
                        view.transform.localScale = new Vector3(visualisationReference.width, visualisationReference.height, 1);
                    }

                    break;

                case AbstractVisualisation.PropertyType.DimensionFiltering:
                {
                    float[] isFiltered = new float[visualisationReference.dataSource.DataCount];
                    for (int i = 0; i < visualisationReference.dataSource.DimensionCount; i++)
                    {
                        foreach (DimensionFilter attrFilter in visualisationReference.parallelCoordinatesDimensions)
                        {
                            if (attrFilter.Attribute == visualisationReference.dataSource[i].Identifier)
                            {
                                float minFilteringValue = UtilMath.normaliseValue(attrFilter.minFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);
                                float maxFilteringValue = UtilMath.normaliseValue(attrFilter.maxFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);

                                for (int j = 0; j < isFiltered.Length; j++)
                                {
                                    isFiltered[j] = (visualisationReference.dataSource[i].Data[j] < minFilteringValue || visualisationReference.dataSource[i].Data[j] > maxFilteringValue) ? 1.0f : isFiltered[j];
                                }
                            }
                        }
                    }
                    // map the filtered attribute into the normal channel of the bigmesh
                    foreach (View v in viewList)
                    {
                        v.SetFilterChannel(isFiltered);
                    }
                    // update axis details
                    for (int i = 0; i < GameObject_Axes_Holders.Count; ++i)
                    {
                        Axis axis = GameObject_Axes_Holders[i].GetComponent <Axis>();
                        BindMinMaxAxisValues(axis, visualisationReference.parallelCoordinatesDimensions[i]);
                    }
                }
                break;

                case AbstractVisualisation.PropertyType.AttributeFiltering:
                    foreach (var viewElement in viewList)
                    {
                        float[] isFiltered = new float[visualisationReference.dataSource.DataCount];
                        for (int i = 0; i < visualisationReference.dataSource.DimensionCount; i++)
                        {
                            foreach (AttributeFilter attrFilter in visualisationReference.attributeFilters)
                            {
                                //print(attrFilter.Attribute + "   " + dataSource[i].Identifier);
                                if (attrFilter.Attribute == visualisationReference.dataSource[i].Identifier)
                                {
                                    float minFilteringValue = UtilMath.normaliseValue(attrFilter.minFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);
                                    float maxFilteringValue = UtilMath.normaliseValue(attrFilter.maxFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);

                                    for (int j = 0; j < isFiltered.Length; j++)
                                    {
                                        isFiltered[j] = (visualisationReference.dataSource[i].Data[j] < minFilteringValue || visualisationReference.dataSource[i].Data[j] > maxFilteringValue) ? 1.0f : isFiltered[j];
                                    }
                                }
                            }
                        }
                        // map the filtered attribute into the normal channel of the bigmesh
                        foreach (View v in viewList)
                        {
                            v.SetFilterChannel(isFiltered);
                        }
                    }
                    break;

                case PropertyType.VisualisationType:

                    break;

                case PropertyType.BlendDestinationMode:
                    float bmds = (int)(System.Enum.Parse(typeof(UnityEngine.Rendering.BlendMode), visualisationReference.blendingModeDestination));
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetBlendindDestinationMode(bmds);
                    }

                    break;

                case PropertyType.BlendSourceMode:
                    float bmd = (int)(System.Enum.Parse(typeof(UnityEngine.Rendering.BlendMode), visualisationReference.blendingModeSource));
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetBlendingSourceMode(bmd);
                    }

                    break;

                case PropertyType.DimensionChangeFiltering:
                    //foreach (var viewElement in viewList)

                    break;

                default:
                    break;
                }
            }

            // if (visualisationReference.geometry != GeometryType.Undefined)// || visualisationType == VisualisationTypes.PARALLEL_COORDINATES)
            if (creationConfiguration != null)
            {
                SerializeViewConfiguration(creationConfiguration);
            }

            //Update any label on the corresponding axes
            if (propertyType == PropertyType.DimensionChange)
            {
                RebuildAxis();
            }
        }
Пример #4
0
        public override void UpdateVisualisation(PropertyType propertyType)
        {
            if (viewList.Count == 0)
            {
                CreateVisualisation();
            }

            if (viewList.Count != 0)
            {
                switch (propertyType)
                {
                case AbstractVisualisation.PropertyType.X:
                    if (visualisationReference.xDimension.Attribute.Equals("Undefined"))
                    {
                        viewList[0].ZeroPosition(0);
                        viewList[0].TweenPosition();
                    }
                    else
                    {
                        viewList[0].UpdateXPositions(visualisationReference.dataSource[visualisationReference.xDimension.Attribute].Data);
                        viewList[0].TweenPosition();
                    }
                    if (creationConfiguration.Axies.ContainsKey(CreationConfiguration.Axis.X))
                    {
                        creationConfiguration.Axies[CreationConfiguration.Axis.X] = visualisationReference.xDimension.Attribute;
                    }
                    else
                    {
                        creationConfiguration.Axies.Add(CreationConfiguration.Axis.X, visualisationReference.xDimension.Attribute);
                    }
                    break;

                case AbstractVisualisation.PropertyType.Y:
                    if (visualisationReference.yDimension.Attribute.Equals("Undefined"))
                    {
                        viewList[0].ZeroPosition(1);
                        viewList[0].TweenPosition();
                    }
                    else
                    {
                        viewList[0].UpdateYPositions(visualisationReference.dataSource[visualisationReference.yDimension.Attribute].Data);
                        viewList[0].TweenPosition();
                    }
                    if (creationConfiguration.Axies.ContainsKey(CreationConfiguration.Axis.Y))
                    {
                        creationConfiguration.Axies[CreationConfiguration.Axis.Y] = visualisationReference.yDimension.Attribute;
                    }
                    else
                    {
                        creationConfiguration.Axies.Add(CreationConfiguration.Axis.Y, visualisationReference.yDimension.Attribute);
                    }
                    break;

                case AbstractVisualisation.PropertyType.Z:
                    if (visualisationReference.zDimension.Attribute.Equals("Undefined"))
                    {
                        viewList[0].ZeroPosition(2);
                        viewList[0].TweenPosition();
                    }
                    else
                    {
                        viewList[0].UpdateZPositions(visualisationReference.dataSource[visualisationReference.zDimension.Attribute].Data);
                        viewList[0].TweenPosition();
                    }
                    if (creationConfiguration.Axies.ContainsKey(CreationConfiguration.Axis.Z))
                    {
                        creationConfiguration.Axies[CreationConfiguration.Axis.Z] = visualisationReference.zDimension.Attribute;
                    }
                    else
                    {
                        creationConfiguration.Axies.Add(CreationConfiguration.Axis.Z, visualisationReference.zDimension.Attribute);
                    }
                    break;

                case AbstractVisualisation.PropertyType.Colour:
                    if (visualisationReference.colourDimension != "Undefined")
                    {
                        for (int i = 0; i < viewList.Count; i++)
                        {
                            viewList[i].SetColors(mapColoursContinuous(visualisationReference.dataSource[visualisationReference.colourDimension].Data));
                        }
                    }
                    else if (visualisationReference.colorPaletteDimension != "Undefined")
                    {
                        for (int i = 0; i < viewList.Count; i++)
                        {
                            viewList[i].SetColors(mapColoursPalette(visualisationReference.dataSource[visualisationReference.colorPaletteDimension].Data, visualisationReference.coloursPalette));
                        }
                    }
                    else
                    {
                        for (int i = 0; i < viewList.Count; i++)
                        {
                            Color[] colours = viewList[0].GetColors();
                            for (int j = 0; j < colours.Length; ++j)
                            {
                                colours[j] = visualisationReference.colour;
                            }
                            viewList[i].SetColors(colours);
                        }
                    }

                    creationConfiguration.ColourDimension = visualisationReference.colourDimension;
                    creationConfiguration.colourKeys      = visualisationReference.dimensionColour;
                    creationConfiguration.colour          = visualisationReference.colour;

                    break;

                case AbstractVisualisation.PropertyType.Size:
                {
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        if (visualisationReference.sizeDimension != "Undefined")
                        {
                            viewList[i].SetSizeChannel(visualisationReference.dataSource[visualisationReference.sizeDimension].Data);
                        }
                        else
                        {
                            viewList[i].SetSizeChannel(new float[visualisationReference.dataSource.DataCount]);
                        }
                    }
                    creationConfiguration.SizeDimension = visualisationReference.sizeDimension;
                    viewList[0].TweenSize();

                    break;
                }

                case PropertyType.SizeValues:
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetSize(visualisationReference.size);
                        viewList[i].SetMinSize(visualisationReference.minSize);            // Data is normalised
                        viewList[i].SetMaxSize(visualisationReference.maxSize);
                    }
                    creationConfiguration.Size    = visualisationReference.size;
                    creationConfiguration.MinSize = visualisationReference.minSize;
                    creationConfiguration.MaxSize = visualisationReference.maxSize;

                    break;

                case AbstractVisualisation.PropertyType.LinkingDimension:
                    creationConfiguration.LinkingDimension = visualisationReference.linkingDimension;

                    CreateVisualisation();     // needs to recreate the visualsiation because the mesh properties have changed
                    rescaleViews();
                    break;

                case AbstractVisualisation.PropertyType.GeometryType:
                    creationConfiguration.Geometry = visualisationReference.geometry;
                    CreateVisualisation();     // needs to recreate the visualsiation because the mesh properties have changed
                    rescaleViews();
                    break;

                case AbstractVisualisation.PropertyType.Scaling:

                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetMinNormX(visualisationReference.xDimension.minScale);
                        viewList[i].SetMaxNormX(visualisationReference.xDimension.maxScale);
                        viewList[i].SetMinNormY(visualisationReference.yDimension.minScale);
                        viewList[i].SetMaxNormY(visualisationReference.yDimension.maxScale);
                        viewList[i].SetMinNormZ(visualisationReference.zDimension.minScale);
                        viewList[i].SetMaxNormZ(visualisationReference.zDimension.maxScale);
                    }

                    // TODO: Move visualsiation size from Scaling to its own PropertyType
                    creationConfiguration.VisualisationWidth  = visualisationReference.width;
                    creationConfiguration.VisualisationHeight = visualisationReference.height;
                    creationConfiguration.VisualisationDepth  = visualisationReference.depth;
                    break;

                case AbstractVisualisation.PropertyType.DimensionFiltering:
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetMinX(visualisationReference.xDimension.minFilter);
                        viewList[i].SetMaxX(visualisationReference.xDimension.maxFilter);
                        viewList[i].SetMinY(visualisationReference.yDimension.minFilter);
                        viewList[i].SetMaxY(visualisationReference.yDimension.maxFilter);
                        viewList[i].SetMinZ(visualisationReference.zDimension.minFilter);
                        viewList[i].SetMaxZ(visualisationReference.zDimension.maxFilter);
                    }
                    break;

                case AbstractVisualisation.PropertyType.AttributeFiltering:
                    if (visualisationReference.attributeFilters != null)
                    {
                        foreach (var viewElement in viewList)
                        {
                            float[] isFiltered = new float[visualisationReference.dataSource.DataCount];
                            for (int i = 0; i < visualisationReference.dataSource.DimensionCount; i++)
                            {
                                foreach (AttributeFilter attrFilter in visualisationReference.attributeFilters)
                                {
                                    if (attrFilter.Attribute == visualisationReference.dataSource[i].Identifier)
                                    {
                                        float minFilteringValue = UtilMath.normaliseValue(attrFilter.minFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);
                                        float maxFilteringValue = UtilMath.normaliseValue(attrFilter.maxFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);

                                        for (int j = 0; j < isFiltered.Length; j++)
                                        {
                                            isFiltered[j] = (visualisationReference.dataSource[i].Data[j] < minFilteringValue || visualisationReference.dataSource[i].Data[j] > maxFilteringValue) ? 1.0f : isFiltered[j];
                                        }
                                    }
                                }
                            }
                            // map the filtered attribute into the normal channel of the bigmesh
                            foreach (View v in viewList)
                            {
                                v.SetFilterChannel(isFiltered);
                            }
                        }
                    }
                    break;

                case PropertyType.VisualisationType:
                    break;

                case PropertyType.BlendDestinationMode:
                    float bmds = (int)(System.Enum.Parse(typeof(UnityEngine.Rendering.BlendMode), visualisationReference.blendingModeDestination));
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetBlendindDestinationMode(bmds);
                    }

                    break;

                case PropertyType.BlendSourceMode:
                    float bmd = (int)(System.Enum.Parse(typeof(UnityEngine.Rendering.BlendMode), visualisationReference.blendingModeSource));
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetBlendingSourceMode(bmd);
                    }

                    break;

                default:
                    break;
                }
            }

            if (visualisationReference.geometry != GeometryType.Undefined)// || visualisationType == VisualisationTypes.PARALLEL_COORDINATES)
            {
                SerializeViewConfiguration(creationConfiguration);
            }

            //Update any label on the corresponding axes
            UpdateVisualisationAxes(propertyType);
        }
        public override void UpdateVisualisation(PropertyType propertyType)
        {
            if (viewList.Count == 0)
            {
                CreateVisualisation();
            }

            if (viewList.Count != 0)
            {
                switch (propertyType)
                {
                case AbstractVisualisation.PropertyType.X:
                    if (visualisationReference.xDimension.Attribute.Equals("Undefined"))
                    {
                        viewList[0].ZeroPosition(0);
                        viewList[0].TweenPosition();
                    }
                    else
                    {
                        viewList[0].UpdateXPositions(visualisationReference.dataSource[visualisationReference.xDimension.Attribute].Data);
                        viewList[0].TweenPosition();
                    }
                    if (creationConfiguration.Axies.ContainsKey(CreationConfiguration.Axis.X))
                    {
                        creationConfiguration.Axies[CreationConfiguration.Axis.X] = visualisationReference.xDimension.Attribute;
                    }
                    else
                    {
                        creationConfiguration.Axies.Add(CreationConfiguration.Axis.X, visualisationReference.xDimension.Attribute);
                    }
                    break;

                case AbstractVisualisation.PropertyType.Y:
                    if (visualisationReference.yDimension.Attribute.Equals("Undefined"))
                    {
                        viewList[0].ZeroPosition(1);
                        viewList[0].TweenPosition();
                    }
                    else
                    {
                        viewList[0].UpdateYPositions(visualisationReference.dataSource[visualisationReference.yDimension.Attribute].Data);
                        viewList[0].TweenPosition();
                    }
                    if (creationConfiguration.Axies.ContainsKey(CreationConfiguration.Axis.Y))
                    {
                        creationConfiguration.Axies[CreationConfiguration.Axis.Y] = visualisationReference.yDimension.Attribute;
                    }
                    else
                    {
                        creationConfiguration.Axies.Add(CreationConfiguration.Axis.Y, visualisationReference.yDimension.Attribute);
                    }
                    break;

                case AbstractVisualisation.PropertyType.Z:
                    if (visualisationReference.zDimension.Attribute.Equals("Undefined"))
                    {
                        viewList[0].ZeroPosition(2);
                        viewList[0].TweenPosition();
                    }
                    else
                    {
                        viewList[0].UpdateZPositions(visualisationReference.dataSource[visualisationReference.zDimension.Attribute].Data);
                        viewList[0].TweenPosition();
                    }
                    if (creationConfiguration.Axies.ContainsKey(CreationConfiguration.Axis.Z))
                    {
                        creationConfiguration.Axies[CreationConfiguration.Axis.Z] = visualisationReference.zDimension.Attribute;
                    }
                    else
                    {
                        creationConfiguration.Axies.Add(CreationConfiguration.Axis.Z, visualisationReference.zDimension.Attribute);
                    }
                    break;

                case AbstractVisualisation.PropertyType.Colour:
                    if (visualisationReference.colourDimension != "Undefined")
                    {
                        for (int i = 0; i < viewList.Count; i++)
                        {
                            viewList[i].SetColors(mapColoursContinuous(visualisationReference.dataSource[visualisationReference.colourDimension].Data));
                        }
                    }
                    else if (visualisationReference.colorPaletteDimension != "Undefined")
                    {
                        for (int i = 0; i < viewList.Count; i++)
                        {
                            viewList[i].SetColors(mapColoursPalette(visualisationReference.dataSource[visualisationReference.colorPaletteDimension].Data, visualisationReference.coloursPalette));
                        }
                    }
                    else
                    {
                        for (int i = 0; i < viewList.Count; i++)
                        {
                            Color[] colours = viewList[0].GetColors();
                            for (int j = 0; j < colours.Length; ++j)
                            {
                                colours[j] = visualisationReference.colour;
                            }
                            viewList[i].SetColors(colours);
                        }
                    }

                    creationConfiguration.ColourDimension = visualisationReference.colourDimension;
                    creationConfiguration.colourKeys      = visualisationReference.dimensionColour;
                    creationConfiguration.colour          = visualisationReference.colour;

                    break;

                case AbstractVisualisation.PropertyType.Size:
                {
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        if (visualisationReference.sizeDimension != "Undefined")
                        {
                            viewList[i].SetSizeChannel(visualisationReference.dataSource[visualisationReference.sizeDimension].Data);
                        }
                        else
                        {
                            viewList[i].SetSizeChannel(Enumerable.Repeat(0f, visualisationReference.dataSource[0].Data.Length).ToArray());
                        }
                    }
                    creationConfiguration.SizeDimension = visualisationReference.sizeDimension;
                    viewList[0].TweenSize();

                    break;
                }

                case PropertyType.SizeValues:
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetSize(visualisationReference.size);
                        viewList[i].SetMinSize(visualisationReference.minSize);            // Data is normalised
                        viewList[i].SetMaxSize(visualisationReference.maxSize);
                    }
                    creationConfiguration.Size    = visualisationReference.size;
                    creationConfiguration.MinSize = visualisationReference.minSize;
                    creationConfiguration.MaxSize = visualisationReference.maxSize;

                    break;

                case AbstractVisualisation.PropertyType.LinkingDimension:
                    creationConfiguration.LinkingDimension = visualisationReference.linkingDimension;

                    string  xDimension           = visualisationReference.xDimension.Attribute;
                    string  yDimension           = visualisationReference.yDimension.Attribute;
                    string  linkingDimension     = visualisationReference.linkingDimension;
                    float[] newAggregatedYValues = new float[0];

                    if (xDimension != "Undefined" && yDimension != "Undefined" && linkingDimension != "Undefined")
                    {
                        float[] xData       = visualisationReference.dataSource[xDimension].Data;
                        float[] yData       = visualisationReference.dataSource[yDimension].Data;
                        float[] linkingData = visualisationReference.dataSource[linkingDimension].Data;

                        // Create new list of pairs where Item1 is the x dimension, Item2 is the linking dimension
                        List <Tuple <float, float> > pairs = new List <Tuple <float, float> >();
                        for (int i = 0; i < visualisationReference.dataSource.DataCount; i++)
                        {
                            pairs.Add(new Tuple <float, float>(xData[i], linkingData[i]));
                        }

                        // Sort by x dimension values, then by linking values
                        var sort = pairs.Select((value, index) => new { value, index }).OrderBy(x => x.value.Item1).ThenBy(x => x.value.Item2).ToList();
                        //List<float> sortedXValues = sort.Select(x => x.value.Item1).ToList();
                        //List<float> sortedLinkingValues = sort.Select(x => x.value.Item2).ToList();
                        //List<int> sortedIndices = sort.Select(x => x.index).ToList();

                        List <int> associatedIndices = new List <int>();

                        newAggregatedYValues = new float[visualisationReference.dataSource.DataCount];

                        int    count           = 0;
                        double total           = 0;
                        float  previousX       = Mathf.Infinity;
                        float  previousLinking = Mathf.Infinity;
                        float  avg;

                        for (int i = 0; i < sort.Count; i++)
                        {
                            float currentX       = sort[i].value.Item1;
                            float currentLinking = sort[i].value.Item2;

                            // If now looking at a new x, linking group
                            if (previousLinking != currentLinking || previousX != currentX)
                            {
                                // Calculate average
                                avg = (float)(total / count);

                                // Back-fill the values of the averages to the associated indices
                                foreach (int idx in associatedIndices)
                                {
                                    newAggregatedYValues[idx] = avg;
                                }

                                associatedIndices.Clear();
                                count = 0;
                                total = 0;
                            }

                            previousX       = currentX;
                            previousLinking = currentLinking;

                            int actualIndex = sort[i].index;

                            total += yData[actualIndex];
                            count++;

                            associatedIndices.Add(actualIndex);
                        }

                        // Do one last final check
                        avg = (float)(total / count);

                        // Back-fill the values of the averages to the associated indices
                        foreach (int idx in associatedIndices)
                        {
                            newAggregatedYValues[idx] = avg;
                        }
                    }

                    CreateVisualisation();     // needs to recreate the visualsiation because the mesh properties have changed

                    if (newAggregatedYValues.Length > 0)
                    {
                        viewList[0].UpdateYPositions(newAggregatedYValues);
                    }
                    break;

                case AbstractVisualisation.PropertyType.GeometryType:
                    creationConfiguration.Geometry = visualisationReference.geometry;
                    CreateVisualisation();     // needs to recreate the visualsiation because the mesh properties have changed
                    break;

                case AbstractVisualisation.PropertyType.Scaling:

                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetMinNormX(visualisationReference.xDimension.minScale);
                        viewList[i].SetMaxNormX(visualisationReference.xDimension.maxScale);
                        viewList[i].SetMinNormY(visualisationReference.yDimension.minScale);
                        viewList[i].SetMaxNormY(visualisationReference.yDimension.maxScale);
                        viewList[i].SetMinNormZ(visualisationReference.zDimension.minScale);
                        viewList[i].SetMaxNormZ(visualisationReference.zDimension.maxScale);
                    }
                    break;

                case AbstractVisualisation.PropertyType.DimensionFiltering:
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetMinX(visualisationReference.xDimension.minFilter);
                        viewList[i].SetMaxX(visualisationReference.xDimension.maxFilter);
                        viewList[i].SetMinY(visualisationReference.yDimension.minFilter);
                        viewList[i].SetMaxY(visualisationReference.yDimension.maxFilter);
                        viewList[i].SetMinZ(visualisationReference.zDimension.minFilter);
                        viewList[i].SetMaxZ(visualisationReference.zDimension.maxFilter);
                    }
                    break;

                case AbstractVisualisation.PropertyType.AttributeFiltering:
                    if (visualisationReference.attributeFilters != null)
                    {
                        foreach (var viewElement in viewList)
                        {
                            float[] isFiltered = new float[visualisationReference.dataSource.DataCount];
                            for (int i = 0; i < visualisationReference.dataSource.DimensionCount; i++)
                            {
                                foreach (AttributeFilter attrFilter in visualisationReference.attributeFilters)
                                {
                                    if (attrFilter.Attribute == visualisationReference.dataSource[i].Identifier)
                                    {
                                        float minFilteringValue = UtilMath.normaliseValue(attrFilter.minFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);
                                        float maxFilteringValue = UtilMath.normaliseValue(attrFilter.maxFilter, 0f, 1f, attrFilter.minScale, attrFilter.maxScale);

                                        for (int j = 0; j < isFiltered.Length; j++)
                                        {
                                            isFiltered[j] = (visualisationReference.dataSource[i].Data[j] < minFilteringValue || visualisationReference.dataSource[i].Data[j] > maxFilteringValue) ? 1.0f : isFiltered[j];
                                        }
                                    }
                                }
                            }
                            // map the filtered attribute into the normal channel of the bigmesh
                            foreach (View v in viewList)
                            {
                                v.SetFilterChannel(isFiltered);
                            }
                        }
                    }
                    break;

                case PropertyType.VisualisationType:
                    break;

                case PropertyType.BlendDestinationMode:
                    float bmds = (int)(System.Enum.Parse(typeof(UnityEngine.Rendering.BlendMode), visualisationReference.blendingModeDestination));
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetBlendindDestinationMode(bmds);
                    }

                    break;

                case PropertyType.BlendSourceMode:
                    float bmd = (int)(System.Enum.Parse(typeof(UnityEngine.Rendering.BlendMode), visualisationReference.blendingModeSource));
                    for (int i = 0; i < viewList.Count; i++)
                    {
                        viewList[i].SetBlendingSourceMode(bmd);
                    }

                    break;

                default:
                    break;
                }
            }

            //if (visualisationReference.geometry != GeometryType.Undefined)// || visualisationType == VisualisationTypes.PARALLEL_COORDINATES)
            //    SerializeViewConfiguration(creationConfiguration);

            //Update any label on the corresponding axes
            UpdateVisualisationAxes(propertyType);
        }