예제 #1
0
        private void InferColorScheme(ChannelEncoding channelEncoding, ref JSONObject scaleSpecsObj)
        {
            string range  = scaleSpecsObj["range"].Value.ToString();
            string scheme = "";

            if (range == "category")
            {
                if (scaleSpecsObj["domain"].AsArray.Count <= 10)
                {
                    scheme = "tableau10";
                }
                else
                {
                    scheme = "tableau20";
                }
            }
            else if (range == "ordinal" || range == "ramp")
            {
                //scheme = "blues";
                scheme = "ramp";
            }
            else if (range == "heatmap")
            {
                scheme = "viridis";
            }
            else
            {
                throw new Exception("Cannot infer color scheme for range " + range);
            }
            scaleSpecsObj.Add("scheme", new JSONString(scheme));
        }
예제 #2
0
 private void SetupTooltip(ChannelEncoding channelEncoding, Mark markComponent)
 {
     if (tooltipInstance != null)
     {
         markComponent.SetTooltipObject(ref tooltipInstance);
         markComponent.SetTooltipField(channelEncoding.field);
     }
 }
예제 #3
0
        private void InferScaleSpecsForChannel(ref ChannelEncoding channelEncoding, ref JSONNode specs, Data data)
        {
            JSONNode   channelSpecs  = specs["encoding"][channelEncoding.channel];
            JSONNode   scaleSpecs    = channelSpecs["scale"];
            JSONObject scaleSpecsObj = (scaleSpecs == null) ? new JSONObject() : scaleSpecs.AsObject;


            if (scaleSpecs["type"] == null)
            {
                InferScaleType(channelEncoding.channel, channelEncoding.fieldDataType, ref scaleSpecsObj);
            }

            if (!(scaleSpecsObj["type"].Value.ToString() == "none"))
            {
                if (scaleSpecs["domain"] == null)
                {
                    InferDomain(channelEncoding, specs, ref scaleSpecsObj, data);
                }

                if (scaleSpecs["padding"] != null)
                {
                    scaleSpecsObj.Add("paddingInner", scaleSpecs["padding"]);
                    scaleSpecsObj.Add("paddingOuter", scaleSpecs["padding"]);
                }
                else
                {
                    /*
                     * if (scaleSpecs["paddingInner"] == null)
                     * {
                     *  scaleSpecsObj.Add("paddingInner", new JSONString(ScaleBand.PADDING_INNER_DEFAULT.ToString()));
                     * }
                     *
                     * if (scaleSpecs["paddingOuter"] == null)
                     * {
                     *  scaleSpecsObj.Add("paddingOuter", new JSONString(ScaleBand.PADDING_OUTER_DEFAULT.ToString()));
                     * }*/
                    scaleSpecsObj.Add("padding", new JSONString(ScalePoint.PADDING_DEFAULT.ToString()));
                }

                if (scaleSpecs["range"] == null)
                {
                    InferRange(channelEncoding, specs, ref scaleSpecsObj);
                }
                else if (scaleSpecs["range"] != null && channelEncoding.channel == "size")
                {
                    maxSizeValue = float.Parse(scaleSpecs["range"].ToString().Split(',')[1].TrimEnd(']')) / 1000f;
                }

                if (channelEncoding.channel == "color" && !scaleSpecsObj["range"].IsArray && scaleSpecsObj["scheme"] == null)
                {
                    InferColorScheme(channelEncoding, ref scaleSpecsObj);
                }
            }

            specs["encoding"][channelEncoding.channel].Add("scale", scaleSpecsObj);
        }
예제 #4
0
        public void Infer(Data data, ref JSONNode sceneSpecs, string sceneSpecsFilename)
        {
            // Go through each channel and infer the missing specs.
            foreach (KeyValuePair <string, JSONNode> kvp in sceneSpecs["encoding"].AsObject)
            {
                ChannelEncoding channelEncoding = new ChannelEncoding();

                // Get minimum required values:
                channelEncoding.channel = kvp.Key;
                JSONNode channelSpecs = kvp.Value;
                if (channelSpecs["value"] == null)
                {
                    if (channelSpecs["field"] == null)
                    {
                        throw new Exception("Missing field in channel " + channelEncoding.channel);
                    }
                    else
                    {
                        channelEncoding.field = channelSpecs["field"];

                        if (channelSpecs["type"] != null)
                        {
                            channelEncoding.fieldDataType = channelSpecs["type"];
                        }
                        else
                        {
                            throw new Exception("Missing field data type in channel " + channelEncoding.channel);
                        }
                    }

                    InferScaleSpecsForChannel(ref channelEncoding, ref sceneSpecs, data);

                    if (channelEncoding.channel == "x" || channelEncoding.channel == "y" ||
                        channelEncoding.channel == "z" || channelEncoding.channel == "width" ||
                        channelEncoding.channel == "height" || channelEncoding.channel == "depth")
                    {
                        InferAxisSpecsForChannel(ref channelEncoding, ref sceneSpecs, data);
                    }

                    if (channelEncoding.channel == "color" || channelEncoding.channel == "size" ||
                        channelEncoding.channel == "shape" || channelEncoding.channel == "opacity")
                    {
                        InferLegendSpecsForChannel(ref channelEncoding, ref sceneSpecs);
                    }
                }
            }

            InferMarkSpecificSpecs(ref sceneSpecs);

            string inferResults = sceneSpecs.ToString();
            string filename     = "Assets/StreamingAssets/" + sceneSpecsFilename.TrimEnd(".json".ToCharArray()) + "_inferred.json";

            WriteStringToFile(inferResults, filename);
        }
예제 #5
0
        private void ConstructLegendObject(JSONNode legendSpecs, ref ChannelEncoding channelEncoding, ref GameObject sceneRoot)
        {
            GameObject legendPrefab = Resources.Load("Legend/Legend", typeof(GameObject)) as GameObject;

            if (legendPrefab != null && markPrefab != null)
            {
                channelEncoding.legend = Instantiate(legendPrefab, sceneRoot.transform);
                channelEncoding.legend.GetComponent <Legend>().UpdateSpecs(legendSpecs, ref channelEncoding, markPrefab);
            }
            else
            {
                throw new Exception("Cannot find legend prefab.");
            }
        }
예제 #6
0
        private void InferScaleSpecsForChannel(ref ChannelEncoding channelEncoding, ref JSONNode sceneSpecs, Data data)
        {
            JSONNode   channelSpecs  = sceneSpecs["encoding"][channelEncoding.channel];
            JSONNode   scaleSpecs    = channelSpecs["scale"];
            JSONObject scaleSpecsObj = (scaleSpecs == null) ? new JSONObject() : scaleSpecs.AsObject;

            if (scaleSpecs["type"] == null)
            {
                InferScaleType(channelEncoding.channel, channelEncoding.fieldDataType, ref scaleSpecsObj);
            }

            if (!(scaleSpecsObj["type"].Value.ToString() == "none" || scaleSpecsObj["type"].Value.ToString() == "custom"))
            {
                if (scaleSpecs["domain"] == null)
                {
                    InferDomain(channelEncoding, sceneSpecs, ref scaleSpecsObj, data);
                }

                if (scaleSpecs["padding"] != null)
                {
                    scaleSpecsObj.Add("paddingInner", scaleSpecs["padding"]);
                    scaleSpecsObj.Add("paddingOuter", scaleSpecs["padding"]);
                }
                else
                {
                    if (scaleSpecs["paddingInner"] == null)
                    {
                        scaleSpecsObj.Add("paddingInner", new JSONString(ScaleBand.PADDING_INNER_DEFAULT.ToString()));
                    }

                    if (scaleSpecs["paddingOuter"] == null)
                    {
                        scaleSpecsObj.Add("paddingOuter", new JSONString(ScaleBand.PADDING_OUTER_DEFAULT.ToString()));
                    }
                }

                if (scaleSpecs["range"] == null)
                {
                    InferRange(channelEncoding, sceneSpecs, ref scaleSpecsObj);
                }

                if (channelEncoding.channel == "color" && !scaleSpecsObj["range"].IsArray && scaleSpecsObj["scheme"] == null)
                {
                    InferColorScheme(channelEncoding, ref scaleSpecsObj);
                }
            }

            sceneSpecs["encoding"][channelEncoding.channel].Add("scale", scaleSpecsObj);
        }
예제 #7
0
        private void CreateChannelEncodingObjects(JSONNode specs)
        {
            channelEncodings = new List <ChannelEncoding>();

            // Go through each channel and create ChannelEncoding for each:
            foreach (KeyValuePair <string, JSONNode> kvp in specs["encoding"].AsObject)
            {
                ChannelEncoding channelEncoding = new ChannelEncoding();

                channelEncoding.channel = kvp.Key;
                JSONNode channelSpecs = kvp.Value;
                if (channelSpecs["value"] != null)
                {
                    channelEncoding.value = channelSpecs["value"].Value.ToString();

                    if (channelSpecs["type"] != null)
                    {
                        channelEncoding.valueDataType = channelSpecs["type"].Value.ToString();
                    }
                }
                else
                {
                    channelEncoding.field = channelSpecs["field"];

                    // Check validity of data field
                    if (!data.fieldNames.Contains(channelEncoding.field))
                    {
                        throw new Exception("Cannot find data field " + channelEncoding.field + " in data. Please check your spelling (case sensitive).");
                    }

                    if (channelSpecs["type"] != null)
                    {
                        channelEncoding.fieldDataType = channelSpecs["type"];
                    }
                    else
                    {
                        throw new Exception("Missing type for field in channel " + channelEncoding.channel);
                    }
                }

                JSONNode scaleSpecs = channelSpecs["scale"];
                if (scaleSpecs != null)
                {
                    CreateScaleObject(scaleSpecs, ref channelEncoding.scale);
                }

                channelEncodings.Add(channelEncoding);
            }
        }
예제 #8
0
파일: Vis.cs 프로젝트: yeidy17/DxR
        private void ConstructAxisObject(JSONNode axisSpecs, ref ChannelEncoding channelEncoding)
        {
            GameObject axisPrefab = Resources.Load("Axis/Axis", typeof(GameObject)) as GameObject;

            if (axisPrefab != null)
            {
                channelEncoding.axis = Instantiate(axisPrefab, guidesParentObject.transform);
                channelEncoding.axis.GetComponent <Axis>().Init(interactionsParentObject.GetComponent <Interactions>(),
                                                                channelEncoding.field);
                channelEncoding.axis.GetComponent <Axis>().UpdateSpecs(axisSpecs, channelEncoding.scale);
            }
            else
            {
                throw new Exception("Cannot find axis prefab.");
            }
        }
예제 #9
0
        private void ConstructLegends(JSONNode specs)
        {
            // Go through each channel and create legend for color, shape, or size channels:
            for (int channelIndex = 0; channelIndex < channelEncodings.Count; channelIndex++)
            {
                ChannelEncoding channelEncoding = channelEncodings[channelIndex];
                JSONNode        legendSpecs     = specs["encoding"][channelEncoding.channel]["legend"];
                if (legendSpecs != null && legendSpecs.Value.ToString() != "none" && channelEncoding.channel == "color")
                {
                    if (verbose)
                    {
                        Debug.Log("Constructing legend for channel " + channelEncoding.channel);
                    }

                    ConstructLegendObject(legendSpecs, ref channelEncoding);
                }
            }
        }
예제 #10
0
    public void UpdateSpecs(JSONNode legendSpecs, ref DxR.ChannelEncoding channelEncoding, GameObject markPrefab)
    {
        // Create title:
        if (legendSpecs["title"] != null)
        {
            gameObject.GetComponent <Legend>().SetTitle(legendSpecs["title"].Value);
        }

        if (legendSpecs["type"] == "symbol")
        {
            // Create symbols:
            ConstructSymbols(legendSpecs, ref channelEncoding, markPrefab);

#if UNITY_WSA_10_0
            if (legendSpecs["filter"].AsBool && interactionsObject != null)
            {
                interactionsObject.EnableLegendToggleFilter(gameObject);
            }
#endif
        }
        else if (legendSpecs["type"] == "gradient")
        {
            ConstructGradient(legendSpecs, ref channelEncoding);
        }

        // Orient legend:
        if (legendSpecs["orient"] != null && legendSpecs["face"] != null)
        {
            if (legendSpecs["x"] != null && legendSpecs["x"] != null && legendSpecs["x"] != null)
            {
                gameObject.GetComponent <Legend>().SetOrientation(legendSpecs["orient"].Value, legendSpecs["face"].Value,
                                                                  legendSpecs["x"].AsFloat, legendSpecs["y"].AsFloat, legendSpecs["z"].AsFloat);
            }
            else
            {
                gameObject.GetComponent <Legend>().SetOrientation(legendSpecs["orient"].Value, legendSpecs["face"].Value,
                                                                  0, 0, 0);
            }
        }
        else
        {
            throw new Exception("Legend requires both orient and face specs.");
        }
    }
예제 #11
0
        private void CreateChannelEncodingObjects(JSONNode sceneSpecs, out List <ChannelEncoding> channelEncodings)
        {
            channelEncodings = new List <ChannelEncoding>();

            // Go through each channel and create ChannelEncoding for each:
            foreach (KeyValuePair <string, JSONNode> kvp in sceneSpecs["encoding"].AsObject)
            {
                ChannelEncoding channelEncoding = new ChannelEncoding();

                channelEncoding.channel = kvp.Key;
                JSONNode channelSpecs = kvp.Value;
                if (channelSpecs["value"] != null)
                {
                    channelEncoding.value = channelSpecs["value"].Value.ToString();

                    if (channelSpecs["type"] != null)
                    {
                        channelEncoding.valueDataType = channelSpecs["type"].Value.ToString();
                    }
                }
                else
                {
                    channelEncoding.field = channelSpecs["field"];

                    if (channelSpecs["type"] != null)
                    {
                        channelEncoding.fieldDataType = channelSpecs["type"];
                    }
                    else
                    {
                        throw new Exception("Missing type for field in channel " + channelEncoding.channel);
                    }
                }

                JSONNode scaleSpecs = channelSpecs["scale"];
                if (scaleSpecs != null)
                {
                    CreateScaleObject(scaleSpecs, ref channelEncoding.scale);
                }

                channelEncodings.Add(channelEncoding);
            }
        }
예제 #12
0
        private void ConstructAxes(JSONNode specs)
        {
            // Go through each channel and create axis for each spatial / position channel:
            for (int channelIndex = 0; channelIndex < channelEncodings.Count; channelIndex++)
            {
                ChannelEncoding channelEncoding = channelEncodings[channelIndex];
                JSONNode        axisSpecs       = specs["encoding"][channelEncoding.channel]["axis"];
                if (axisSpecs != null && axisSpecs.Value.ToString() != "none" &&
                    (channelEncoding.channel == "x" || channelEncoding.channel == "y" ||
                     channelEncoding.channel == "z"))
                {
                    if (verbose)
                    {
                        Debug.Log("Constructing axis for channel " + channelEncoding.channel);
                    }

                    ConstructAxisObject(axisSpecs, ref channelEncoding);
                }
            }
        }
예제 #13
0
        private void ConstructLegendObject(JSONNode legendSpecs, ref ChannelEncoding channelEncoding)
        {
            GameObject legendPrefab = Resources.Load("Legend/Legend", typeof(GameObject)) as GameObject;

            if (legendPrefab != null && markPrefab != null)
            {
                channelEncoding.legend = Instantiate(legendPrefab, guidesParentObject.transform);

#if UNITY_WSA_10_0
                channelEncoding.legend.GetComponent <Legend>().Init(interactionsParentObject.GetComponent <Interactions>());
#else
                channelEncoding.legend.GetComponent <Legend>().Init();
#endif
                channelEncoding.legend.GetComponent <Legend>().UpdateSpecs(legendSpecs, ref channelEncoding, markPrefab);
            }
            else
            {
                throw new Exception("Cannot find legend prefab.");
            }
        }
예제 #14
0
        private void ApplyChannelEncoding(ChannelEncoding channelEncoding,
                                          ref List <GameObject> markInstances)
        {
            for (int i = 0; i < markInstances.Count; i++)
            {
                Mark markComponent = markInstances[i].GetComponent <Mark>();
                if (markComponent == null)
                {
                    throw new Exception("Mark component not present in mark prefab.");
                }

                if (channelEncoding.value != DxR.Vis.UNDEFINED)
                {
                    markComponent.SetChannelValue(channelEncoding.channel, channelEncoding.value);
                }
                else
                {
                    string channelValue = channelEncoding.scale.ApplyScale(markComponent.datum[channelEncoding.field]);
                    markComponent.SetChannelValue(channelEncoding.channel, channelValue);
                }
            }
        }
예제 #15
0
        //public void Infer(Data data, ref JSONNode specs, string specsFilename) { }

        /*
         * public void Infer(Data data, ref JSONNode specs, string specsFilename)
         * {
         *  // Go through each channel and infer the missing specs.
         *  foreach (KeyValuePair<string, JSONNode> kvp in specs["encoding"].AsObject)
         *  {
         *      ChannelEncoding channelEncoding = new ChannelEncoding();
         *
         *      // Get minimum required values:
         *      channelEncoding.channel = kvp.Key;
         *      JSONNode channelSpecs = kvp.Value;
         *      if (channelSpecs["value"] == null)
         *      {
         *          if (channelSpecs["field"] == null)
         *          {
         *              throw new Exception("Missing field in channel " + channelEncoding.channel);
         *          }
         *          else
         *          {
         *              channelEncoding.field = channelSpecs["field"];
         *
         *              if (channelSpecs["type"] != null)
         *              {
         *                  channelEncoding.fieldDataType = channelSpecs["type"];
         *              }
         *              else
         *              {
         *                  throw new Exception("Missing field data type in channel " + channelEncoding.channel);
         *              }
         *          }
         *
         *          InferScaleSpecsForChannel(ref channelEncoding, ref specs, data);
         *
         *          if (channelEncoding.channel == "x" || channelEncoding.channel == "y" ||
         *              channelEncoding.channel == "z" || channelEncoding.channel == "width" ||
         *              channelEncoding.channel == "height" || channelEncoding.channel == "depth")
         *          {
         *              InferAxisSpecsForChannel(ref channelEncoding, ref specs, data);
         *          }
         *
         *          if(channelEncoding.channel == "color" || channelEncoding.channel == "size" ||
         *              channelEncoding.channel == "shape" || channelEncoding.channel == "opacity")
         *          {
         *              InferLegendSpecsForChannel(ref channelEncoding, ref specs);
         *          }
         *      }
         *  }
         *
         *  InferMarkSpecificSpecs(ref specs);
         *
         *  string inferResults = specs.ToString();
         *  string filename = "Assets/StreamingAssets/" + specsFilename.TrimEnd(".json".ToCharArray()) + "_inferred.json";
         *  WriteStringToFile(inferResults, filename);
         * }
         */

        private void InferLegendSpecsForChannel(ref ChannelEncoding channelEncoding, ref JSONNode specs)
        {
            string   channel      = channelEncoding.channel;
            JSONNode channelSpecs = specs["encoding"][channel];
            JSONNode legendSpecs  = channelSpecs["legend"];

            if (legendSpecs != null && legendSpecs.Value.ToString() == "none")
            {
                return;
            }

            JSONObject legendSpecsObj = (legendSpecs == null) ? new JSONObject() : legendSpecs.AsObject;

            if (legendSpecsObj["type"] == null)
            {
                string fieldDataType = channelSpecs["type"].Value.ToString();
                if (fieldDataType == "quantitative" || fieldDataType == "temporal")
                {
                    legendSpecsObj.Add("type", new JSONString("gradient"));
                }
                else
                {
                    legendSpecsObj.Add("type", new JSONString("symbol"));
                }
            }

            if (legendSpecsObj["filter"] == null)
            {
                legendSpecsObj.Add("filter", new JSONBool(false));
            }

            // TODO: Add proper inference.
            // HACK: For now, always use hard coded options.
            if (legendSpecsObj["gradientWidth"] == null)
            {
                legendSpecsObj.Add("gradientWidth", new JSONNumber(200));
            }

            if (legendSpecsObj["gradientHeight"] == null)
            {
                legendSpecsObj.Add("gradientHeight", new JSONNumber(50));
            }

            if (legendSpecsObj["face"] == null)
            {
                legendSpecsObj.Add("face", new JSONString("front"));
            }

            if (legendSpecsObj["orient"] == null)
            {
                legendSpecsObj.Add("orient", new JSONString("right"));
            }

            if (legendSpecsObj["face"] == null)
            {
                legendSpecsObj.Add("face", new JSONString("front"));
            }

            if (legendSpecsObj["x"] == null)
            {
                legendSpecsObj.Add("x", new JSONNumber(float.Parse(specs["width"].Value.ToString())));
            }

            if (legendSpecsObj["y"] == null)
            {
                legendSpecsObj.Add("y", new JSONNumber(float.Parse(specs["height"].Value.ToString())));
            }

            if (legendSpecsObj["z"] == null)
            {
                legendSpecsObj.Add("z", new JSONNumber(0));
            }

            if (legendSpecsObj["title"] == null)
            {
                legendSpecsObj.Add("title", new JSONString("Legend: " + channelSpecs["field"]));
            }

            specs["encoding"][channelEncoding.channel].Add("legend", legendSpecsObj);
        }
예제 #16
0
        private void InferDomain(ChannelEncoding channelEncoding, JSONNode specs, ref JSONObject scaleSpecsObj, Data data)
        {
            string sortType = "ascending";

            if (specs != null && specs["encoding"][channelEncoding.channel]["sort"] != null)
            {
                sortType = specs["encoding"][channelEncoding.channel]["sort"].Value.ToString();
            }

            string    channel = channelEncoding.channel;
            JSONArray domain  = new JSONArray();

            if (channelEncoding.fieldDataType == "quantitative" &&
                (channel == "x" || channel == "y" || channel == "z" ||
                 channel == "width" || channel == "height" || channel == "depth" || channel == "length" ||
                 channel == "color" || channel == "xrotation" || channel == "yrotation" ||
                 channel == "zrotation" || channel == "size" || channel == "xdirection") ||
                channel == "ydirection" || channel == "zdirection" || channel == "opacity")
            {
                List <float> minMax = new List <float>();
                GetExtent(data, channelEncoding.field, ref minMax);

                /*
                 * // For positive minimum values, set the baseline to zero.
                 * // TODO: Handle logarithmic scale with undefined 0 value.
                 * if(minMax[0] >= 0)
                 * {
                 *  minMax[0] = 0;
                 * }
                 *
                 * float roundedMaxDomain = RoundNice(minMax[1] - minMax[0]);
                 */

                if (sortType == "none" || sortType == "ascending")
                {
                    //domain.Add(new JSONString(minMax[0].ToString()));
                    domain.Add(new JSONString("0"));
                    domain.Add(new JSONString(minMax[1].ToString()));
                }
                else
                {
                    domain.Add(new JSONString(minMax[1].ToString()));
                    domain.Add(new JSONString("0"));
                    //domain.Add(new JSONString(minMax[0].ToString()));
                }
            }
            else
            {
                List <string> uniqueValues = new List <string>();
                GetUniqueValues(data, channelEncoding.field, ref uniqueValues);

                if (sortType == "ascending")
                {
                    uniqueValues.Sort();
                }
                else if (sortType == "descending")
                {
                    uniqueValues.Sort();
                    uniqueValues.Reverse();
                }

                foreach (string val in uniqueValues)
                {
                    domain.Add(val);
                }
            }

            scaleSpecsObj.Add("domain", domain);
        }
예제 #17
0
        // TODO: Fix range computation to consider paddingOUter!!!
        // TODO: Fix range size.
        private void InferRange(ChannelEncoding channelEncoding, JSONNode specs, ref JSONObject scaleSpecsObj)
        {
            JSONArray range = new JSONArray();

            string channel = channelEncoding.channel;

            if (channel == "x" || channel == "width")
            {
                range.Add(new JSONString("0"));

                if (scaleSpecsObj["rangeStep"] == null)
                {
                    range.Add(new JSONString(specs["width"]));
                }
                else
                {
                    float rangeSize = float.Parse(scaleSpecsObj["rangeStep"]) * (float)scaleSpecsObj["domain"].Count;
                    range.Add(new JSONString(rangeSize.ToString()));
                    specs["width"] = rangeSize;
                }
            }
            else if (channel == "y" || channel == "height")
            {
                range.Add(new JSONString("0"));
                if (scaleSpecsObj["rangeStep"] == null)
                {
                    range.Add(new JSONString(specs["height"]));
                }
                else
                {
                    float rangeSize = float.Parse(scaleSpecsObj["rangeStep"]) * (float)scaleSpecsObj["domain"].Count;
                    range.Add(new JSONString(rangeSize.ToString()));
                    specs["height"] = rangeSize;
                }
            }
            else if (channel == "z" || channel == "depth")
            {
                range.Add(new JSONString("0"));
                if (scaleSpecsObj["rangeStep"] == null)
                {
                    range.Add(new JSONString(specs["depth"]));
                }
                else
                {
                    float rangeSize = float.Parse(scaleSpecsObj["rangeStep"]) * (float)scaleSpecsObj["domain"].Count;
                    range.Add(new JSONString(rangeSize.ToString()));
                    specs["depth"] = rangeSize;
                }
            }
            else if (channel == "opacity")
            {
                range.Add(new JSONString("0"));
                range.Add(new JSONString("1"));
            }
            else if (channel == "size" || channel == "length")
            {
                range.Add(new JSONString("0"));
                string maxDimSize = Math.Max(Math.Max(specs["width"].AsFloat, specs["height"].AsFloat),
                                             specs["depth"].AsFloat).ToString();

                range.Add(new JSONString(maxDimSize));
            }
            else if (channel == "color")
            {
                if (channelEncoding.fieldDataType == "nominal")
                {
                    scaleSpecsObj.Add("range", new JSONString("category"));
                }
                else if (channelEncoding.fieldDataType == "ordinal")
                {
                    scaleSpecsObj.Add("range", new JSONString("ordinal"));
                }
                else if (channelEncoding.fieldDataType == "quantitative" ||
                         channelEncoding.fieldDataType == "temporal")
                {
                    scaleSpecsObj.Add("range", new JSONString("ramp"));
                }
            }
            else if (channel == "shape")
            {
                range.Add(new JSONString("symbol"));
                throw new Exception("Not implemented yet.");
            }
            else if (channel == "xrotation" || channel == "yrotation" || channel == "zrotation")
            {
                range.Add(new JSONString("0"));
                range.Add(new JSONString("360"));
            }
            else if (channel == "xdirection" || channel == "ydirection" || channel == "zdirection")
            {
                range.Add(new JSONString("0"));
                range.Add(new JSONString("1"));
            }

            if (range.Count > 0)
            {
                scaleSpecsObj.Add("range", range);
            }
            // Debug.Log(scaleSpecsObj);
        }
예제 #18
0
        // TODO: Fix range computation to consider paddingOUter!!!
        private void InferRange(ChannelEncoding channelEncoding, JSONNode sceneSpecs, ref JSONObject scaleSpecsObj)
        {
            JSONArray range = new JSONArray();

            string channel = channelEncoding.channel;

            if (channel == "x" || channel == "width")
            {
                range.Add(new JSONString("0"));

                if (scaleSpecsObj["rangeStep"] == null)
                {
                    range.Add(new JSONString(sceneSpecs["width"]));
                }
                else
                {
                    float rangeSize = float.Parse(scaleSpecsObj["rangeStep"]) * (float)scaleSpecsObj["domain"].Count;
                    range.Add(new JSONString(rangeSize.ToString()));
                    sceneSpecs["width"] = rangeSize;
                }
            }
            else if (channel == "y" || channel == "height")
            {
                range.Add(new JSONString("0"));
                if (scaleSpecsObj["rangeStep"] == null)
                {
                    range.Add(new JSONString(sceneSpecs["height"]));
                }
                else
                {
                    float rangeSize = float.Parse(scaleSpecsObj["rangeStep"]) * (float)scaleSpecsObj["domain"].Count;
                    range.Add(new JSONString(rangeSize.ToString()));
                    sceneSpecs["height"] = rangeSize;
                }
            }
            else if (channel == "z" || channel == "depth")
            {
                range.Add(new JSONString("0"));
                if (scaleSpecsObj["rangeStep"] == null)
                {
                    range.Add(new JSONString(sceneSpecs["depth"]));
                }
                else
                {
                    float rangeSize = float.Parse(scaleSpecsObj["rangeStep"]) * (float)scaleSpecsObj["domain"].Count;
                    range.Add(new JSONString(rangeSize.ToString()));
                    sceneSpecs["depth"] = rangeSize;
                }
            }
            else if (channel == "opacity")
            {
                range.Add(new JSONString("0"));
                range.Add(new JSONString("1"));
            }
            else if (channel == "size")
            {
                // TODO: Get min and max size of mark.

                // HACK: Hard code range
                range.Add(new JSONString("0"));
                range.Add(new JSONString("200"));
            }
            else if (channel == "color")
            {
                if (channelEncoding.fieldDataType == "nominal")
                {
                    scaleSpecsObj.Add("range", new JSONString("category"));
                }
                else if (channelEncoding.fieldDataType == "ordinal")
                {
                    scaleSpecsObj.Add("range", new JSONString("ordinal"));
                }
                else if (channelEncoding.fieldDataType == "quantitative" ||
                         channelEncoding.fieldDataType == "temporal")
                {
                    if (markName == "rect")
                    {
                        scaleSpecsObj.Add("range", new JSONString("heatmap"));
                    }
                    else
                    {
                        scaleSpecsObj.Add("range", new JSONString("ramp"));
                    }
                }
            }
            else if (channel == "shape")
            {
                range.Add(new JSONString("symbol"));
                throw new Exception("Not implemented yet.");
            }

            if (range.Count > 0)
            {
                scaleSpecsObj.Add("range", range);
            }
        }
예제 #19
0
        private void InferAxisSpecsForChannel(ref ChannelEncoding channelEncoding, ref JSONNode specs, Data data)
        {
            string   channel      = channelEncoding.channel;
            JSONNode channelSpecs = specs["encoding"][channel];
            JSONNode axisSpecs    = channelSpecs["axis"];

            if (axisSpecs != null && axisSpecs.Value.ToString() == "none")
            {
                return;
            }

            JSONObject axisSpecsObj = (axisSpecs == null) ? new JSONObject() : axisSpecs.AsObject;

            if (axisSpecsObj["filter"] == null)
            {
                axisSpecsObj.Add("filter", new JSONBool(false));
            }

            if (axisSpecsObj["face"] == null)
            {
                if (channel == "x" || channel == "y")
                {
                    axisSpecsObj.Add("face", new JSONString("front"));
                }
                else if (channel == "z")
                {
                    axisSpecsObj.Add("face", new JSONString("left"));
                }
            }

            if (axisSpecsObj["orient"] == null)
            {
                if (channel == "x" || channel == "z")
                {
                    axisSpecsObj.Add("orient", new JSONString("bottom"));
                }
                else if (channel == "y")
                {
                    axisSpecsObj.Add("orient", new JSONString("left"));
                }
            }

            if (axisSpecsObj["title"] == null)
            {
                axisSpecsObj.Add("title", new JSONString(channelEncoding.field));
            }

            if (axisSpecsObj["length"] == null)
            {
                float axisLength = 0.0f;
                switch (channelEncoding.channel)
                {
                case "x":
                    //case "width":
                    axisLength = specs["width"].AsFloat;
                    break;

                case "y":
                    //case "height":
                    axisLength = specs["height"].AsFloat;
                    break;

                case "z":
                    //case "depth":
                    axisLength = specs["depth"].AsFloat;
                    break;

                default:
                    axisLength = 0.0f;
                    break;
                }

                axisSpecsObj.Add("length", new JSONNumber(axisLength));
            }

            if (axisSpecs["color"] == null)
            {
                axisSpecsObj.Add("color", new JSONString("#bebebe"));
            }

            /*
             * if(axisSpecs["color"] == null)
             * {
             *  string color = "";
             *  switch (channelEncoding.channel)
             *  {
             *      case "x":
             *          color = "#ff0000";
             *          break;
             *      case "y":
             *          color = "#00ff00";
             *          break;
             *      case "z":
             *          color = "#0000ff";
             *          break;
             *      default:
             *          break;
             *  }
             *
             *  axisSpecsObj.Add("color", new JSONString(color));
             * }
             */

            if (axisSpecsObj["grid"] == null)
            {
                axisSpecsObj.Add("grid", new JSONBool(false));
            }

            if (axisSpecs["ticks"] == null)
            {
                axisSpecsObj.Add("ticks", new JSONBool(true));
            }

            if (axisSpecsObj["values"] == null)
            {
                JSONArray tickValues = new JSONArray();
                JSONNode  domain     = specs["encoding"][channelEncoding.channel]["scale"]["domain"];
                JSONNode  values     = channelEncoding.fieldDataType == "quantitative" ? new JSONArray() : domain;

                if (channelEncoding.fieldDataType == "quantitative" &&
                    (channel == "x" || channel == "y" || channel == "z"))
                {
                    // Round domain into a nice number.
                    //float maxDomain = RoundNice(domain.AsArray[1].AsFloat - domain.AsArray[0].AsFloat);

                    int numDecimals = Math.Max(GetNumDecimalPlaces(domain.AsArray[0].AsFloat), GetNumDecimalPlaces(domain.AsArray[1].AsFloat));
                    //Debug.Log("NUM DEC " + numDecimals);
                    // Add number of ticks.
                    int   defaultNumTicks = 6;
                    int   numTicks        = axisSpecsObj["tickCount"] == null ? defaultNumTicks : axisSpecsObj["tickCount"].AsInt;
                    float intervals       = Math.Abs(domain.AsArray[1].AsFloat - domain.AsArray[0].AsFloat) / (numTicks - 1.0f);


                    for (int i = 0; i < numTicks; i++)
                    {
                        float tickVal = (float)Math.Round(domain.AsArray[0].AsFloat + (intervals * (float)(i)), numDecimals);
                        //Debug.Log(tickVal);
                        values.Add(new JSONString(tickVal.ToString()));
                    }
                }

                axisSpecsObj.Add("values", values.AsArray);
            }

            if (axisSpecsObj["tickCount"] == null)
            {
                axisSpecsObj.Add("tickCount", new JSONNumber(axisSpecsObj["values"].Count));
            }

            if (axisSpecsObj["labels"] == null)
            {
                axisSpecsObj.Add("labels", new JSONBool(true));
            }

            specs["encoding"][channelEncoding.channel].Add("axis", axisSpecsObj);
        }
예제 #20
0
        private void InferAxisSpecsForChannel(ref ChannelEncoding channelEncoding, ref JSONNode sceneSpecs, Data data)
        {
            string   channel      = channelEncoding.channel;
            JSONNode channelSpecs = sceneSpecs["encoding"][channel];
            JSONNode axisSpecs    = channelSpecs["axis"];

            if (axisSpecs != null && axisSpecs.Value.ToString() == "none")
            {
                return;
            }

            JSONObject axisSpecsObj = (axisSpecs == null) ? new JSONObject() : axisSpecs.AsObject;

            if (axisSpecsObj["face"] == null)
            {
                if (channel == "x" || channel == "y" || channel == "width" || channel == "height")
                {
                    axisSpecsObj.Add("face", new JSONString("front"));
                }
                else if (channel == "z" || channel == "depth")
                {
                    axisSpecsObj.Add("face", new JSONString("left"));
                }
            }

            if (axisSpecsObj["orient"] == null)
            {
                if (channel == "x" || channel == "z" || channel == "width" || channel == "depth")
                {
                    axisSpecsObj.Add("orient", new JSONString("bottom"));
                }
                else if (channel == "y" || channel == "height")
                {
                    axisSpecsObj.Add("orient", new JSONString("left"));
                }
            }

            if (axisSpecsObj["title"] == null)
            {
                axisSpecsObj.Add("title", new JSONString(channelEncoding.field));
            }

            if (axisSpecsObj["grid"] == null)
            {
                axisSpecsObj.Add("grid", new JSONBool(false));
            }

            if (axisSpecs["ticks"] == null)
            {
                axisSpecsObj.Add("ticks", new JSONBool(true));
            }

            if (axisSpecsObj["values"] == null)
            {
                JSONArray tickValues = new JSONArray();
                JSONNode  domain     = sceneSpecs["encoding"][channelEncoding.channel]["scale"]["domain"];
                JSONNode  values     = channelEncoding.fieldDataType == "quantitative" ? new JSONArray() : domain;

                if (channelEncoding.fieldDataType == "quantitative" &&
                    (channel == "x" || channel == "y" || channel == "z" ||
                     channel == "width" || channel == "height" || channel == "depth"))
                {
                    // Round domain into a nice number.
                    // TODO: make robust rounding.
                    // HACK:
                    float maxDomain = RoundNice(domain.AsArray[1].AsFloat - domain.AsArray[0].AsFloat);

                    // Add number of ticks.
                    int   defaultNumTicks = 6;
                    int   numTicks        = axisSpecsObj["tickCount"] == null ? defaultNumTicks : axisSpecsObj["tickCount"].AsInt;
                    float intervals       = maxDomain / (numTicks - 1.0f);


                    for (int i = 0; i < numTicks; i++)
                    {
                        float tickVal = domain.AsArray[0].AsFloat + (intervals * (float)(i));
                        values.Add(new JSONNumber(tickVal));
                    }
                }

                axisSpecsObj.Add("values", values.AsArray);
            }

            if (axisSpecsObj["tickCount"] == null)
            {
                axisSpecsObj.Add("tickCount", new JSONNumber(axisSpecsObj["values"].Count));
            }

            if (axisSpecsObj["labels"] == null)
            {
                axisSpecsObj.Add("labels", new JSONBool(true));
            }

            sceneSpecs["encoding"][channelEncoding.channel].Add("axis", axisSpecsObj);
        }
예제 #21
0
        public void Infer(Data data, JSONNode specsOrig, out JSONNode specs,
                          string specsFilename)
        {
            specs = null;
            string origSpecsString = specsOrig.ToString();

            specs = JSON.Parse(origSpecsString);

            // Go through each channel and infer the missing specs.
            foreach (KeyValuePair <string, JSONNode> kvp in specs["encoding"].AsObject)
            {
                ChannelEncoding channelEncoding = new ChannelEncoding();

                // Get minimum required values:
                channelEncoding.channel = kvp.Key;

                // Check validity of channel
                // TODO:

                JSONNode channelSpecs = kvp.Value;
                if (channelSpecs["value"] == null)
                {
                    if (channelSpecs["field"] == null)
                    {
                        throw new Exception("Missing field in channel " + channelEncoding.channel);
                    }
                    else
                    {
                        channelEncoding.field = channelSpecs["field"];

                        // Check validity of data field
                        if (!data.fieldNames.Contains(channelEncoding.field))
                        {
                            throw new Exception("Cannot find data field " + channelEncoding.field + " in data. Please check your spelling (case sensitive).");
                        }

                        if (channelSpecs["type"] != null)
                        {
                            channelEncoding.fieldDataType = channelSpecs["type"];
                        }
                        else
                        {
                            throw new Exception("Missing field data type in channel " + channelEncoding.channel);
                        }
                    }

                    InferScaleSpecsForChannel(ref channelEncoding, ref specs, data);

                    if (channelEncoding.channel == "x" || channelEncoding.channel == "y" ||
                        channelEncoding.channel == "z")
                    {
                        InferAxisSpecsForChannel(ref channelEncoding, ref specs, data);
                    }

                    if (channelEncoding.channel == "color" || channelEncoding.channel == "size")
                    {
                        InferLegendSpecsForChannel(ref channelEncoding, ref specs);
                    }
                }
            }

            for (int n = 0; n < specs["interaction"].AsArray.Count; n++)
            {
                JSONObject node = specs["interaction"].AsArray[n].AsObject;
                if (node["type"] == null || node["field"] == null)
                {
                    continue;
                    //throw new Exception("Missing type and/or field for interaction specs.");
                }
                else
                {
                    if (node["domain"] == null)
                    {
                        ChannelEncoding ch = new ChannelEncoding();
                        ch.field = node["field"].Value;

                        // Check validity of data field
                        if (!data.fieldNames.Contains(ch.field))
                        {
                            throw new Exception("Cannot find data field " + ch.field + " in data (check your interaction specs). Please check your spelling (case sensitive).");
                        }

                        ch.channel = "color";

                        switch (node["type"].Value)
                        {
                        case "toggleFilter":
                            ch.fieldDataType = "nominal";
                            break;

                        case "thresholdFilter":
                        case "rangeFilter":
                            ch.fieldDataType = "quantitative";
                            break;

                        default:
                            break;
                        }

                        JSONNode temp = null;
                        InferDomain(ch, temp, ref node, data);
                    }
                }
            }

            /*
             * string inferResults = specs.ToString(2);
             * string filename = "Assets/StreamingAssets/" + specsFilename.TrimEnd(".json".ToCharArray()) + "_inferred.json";
             * WriteStringToFile(inferResults, filename);
             *
             * Debug.Log("inferred mark:" + specs["mark"].Value);
             *
             * string origSpecsStringPrint = specsOrig.ToString(2);
             * string filenameOrig = "Assets/StreamingAssets/" + specsFilename.TrimEnd(".json".ToCharArray()) + "_orig.json";
             * WriteStringToFile(origSpecsStringPrint, filenameOrig);
             * Debug.Log("orig mark:" + specsOrig["mark"].Value);
             */
        }
예제 #22
0
        private void ConstructAxisObject(JSONNode axisSpecs, ref ChannelEncoding channelEncoding, ref GameObject sceneRoot)
        {
            GameObject axisPrefab = Resources.Load("Axis/Axis", typeof(GameObject)) as GameObject;

            if (axisPrefab != null)
            {
                channelEncoding.axis = Instantiate(axisPrefab, sceneRoot.transform);

                // TODO: Move all the following update code to the Axis object class.

                if (axisSpecs["title"] != null)
                {
                    channelEncoding.axis.GetComponent <Axis>().SetTitle(axisSpecs["title"].Value);
                }

                float axisLength = 0.0f;
                if (axisSpecs["length"] != null)
                {
                    axisLength = axisSpecs["length"].AsFloat;
                }
                else
                {
                    switch (channelEncoding.channel)
                    {
                    case "x":
                        axisLength = width;
                        break;

                    case "y":
                        axisLength = height;
                        break;

                    case "z":
                        axisLength = depth;
                        break;

                    default:
                        axisLength = 0.0f;
                        break;
                    }
                    channelEncoding.axis.GetComponent <Axis>().SetLength(axisLength);
                }

                if (axisSpecs["orient"] != null && axisSpecs["face"] != null)
                {
                    channelEncoding.axis.GetComponent <Axis>().SetOrientation(axisSpecs["orient"].Value, axisSpecs["face"].Value);
                }
                else
                {
                    throw new Exception("Axis of channel " + channelEncoding.channel + " requires both orient and face specs.");
                }

                // TODO: Do the axis color coding more elegantly.
                // Experimental: Set color of axis based on channel type.
                channelEncoding.axis.GetComponent <Axis>().EnableAxisColorCoding(channelEncoding.channel);
            }
            else
            {
                throw new Exception("Cannot find axis prefab.");
            }
        }