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)); }
private void SetupTooltip(ChannelEncoding channelEncoding, Mark markComponent) { if (tooltipInstance != null) { markComponent.SetTooltipObject(ref tooltipInstance); markComponent.SetTooltipField(channelEncoding.field); } }
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); }
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); }
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."); } }
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); }
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); } }
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."); } }
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); } } }
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."); } }
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); } }
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); } } }
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."); } }
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); } } }
//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); }
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); }
// 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); }
// 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); } }
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); }
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); }
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); */ }
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."); } }