public static void Send(LayoutTag tag, WindowBase window, WindowComponent component, Vector2 localNormalizedPoint) { var flowWindow = Flow.FlowSystem.GetWindow(window); if (flowWindow == null) { Debug.LogWarningFormat("[ Heatmap ] FlowWindow not found. Source {0} used ({1}).", window, tag); return; } // Offline #if UNITY_EDITOR var modulesPath = FlowSystem.GetData().GetModulesPath(); var settings = ME.EditorUtilities.GetAssetsOfType <HeatmapSettings>(modulesPath, useCache: false).FirstOrDefault(); #else HeatmapSettings settings = null; #endif if (settings == null) { return; } var data = settings.data.Get(flowWindow); data.AddPoint(localNormalizedPoint, new Vector2Int(Screen.width, Screen.height), flowWindow.id, tag, component); }
public override void OnFlowWindowLayoutGUI(Rect rect, FD.FlowWindow window) { if (Heatmap.settings == null) Heatmap.settings = this.GetSettingsFile(); var settings = Heatmap.settings; if (settings != null) { if (settings.show == true) { var data = settings.data.Get(window); data.UpdateMap(); if (data != null && data.texture != null && data.status == HeatmapSettings.WindowsData.Window.Status.Loaded) { GUI.DrawTexture(rect, data.texture, ScaleMode.StretchToFill, alphaBlend: true); } else { if (this.noDataTexture != null) GUI.DrawTexture(rect, this.noDataTexture, ScaleMode.StretchToFill, alphaBlend: true); } } } }
public override void OnFlowSettingsGUI() { if (Heatmap.settings == null) { Heatmap.settings = this.GetSettingsFile(); //if (Heatmap.settings == null) Heatmap.settings = ME.EditorUtilities.GetAssetsOfType<HeatmapSettings>(useCache: false).FirstOrDefault(); } if (this.noDataTexture == null) this.noDataTexture = Resources.Load("UI.Windows/Heatmap/NoData") as Texture; var settings = Heatmap.settings; if (settings == null) { EditorGUILayout.HelpBox(string.Format(FlowAddon.MODULE_HAS_ERRORS, "Settings file not found (HeatmapSettings)."), MessageType.Error); } else { GUILayout.Label(FlowAddon.MODULE_INSTALLED, EditorStyles.centeredGreyMiniLabel); if (this.editor == null) this.editor = Editor.CreateEditor(settings); if (this.editor != null) { this.editor.OnInspectorGUI(); } } }
public override void OnFlowWindowLayoutGUI(Rect rect, FD.FlowWindow window) { if (Heatmap.settings == null) Heatmap.settings = Heatmap.GetSettingsFile(); var settings = Heatmap.settings; if (settings != null) { if (settings.show == true) { var data = settings.data.Get(window); //data.UpdateMap(); if (data != null && data.texture != null && data.status == HeatmapSettings.WindowsData.Window.Status.Loaded) { LayoutWindowType screen; var layout = HeatmapSystem.GetLayout(window.id, out screen); if (layout == null) return; var scaleFactor = HeatmapSystem.GetFactor(new Vector2(layout.root.editorRect.width, layout.root.editorRect.height), rect.size); //var scaleFactorCanvas = layout.editorScale > 0f ? 1f / layout.editorScale : 1f; //scaleFactor *= scaleFactorCanvas; var r = layout.root.editorRect; r.x *= scaleFactor; r.y *= scaleFactor; r.x += rect.x + rect.width * 0.5f; r.y += rect.y + rect.height * 0.5f; r.width *= scaleFactor; r.height *= scaleFactor; var c = Color.white; c.a = 0.5f; GUI.color = c; GUI.DrawTexture(r, data.texture, ScaleMode.StretchToFill, alphaBlend: false); GUI.color = Color.white; } else { if (this.noDataTexture != null) GUI.DrawTexture(rect, this.noDataTexture, ScaleMode.ScaleToFit, alphaBlend: true); } } } }
public static void Send(LayoutTag tag, WindowBase window, WindowComponent component, Vector2 localNormalizedPoint) { var flowWindow = Flow.FlowSystem.GetWindow(window); if (flowWindow == null) { Debug.LogWarningFormat("[ Heatmap ] FlowWindow not found. Source {0} used ({1}).", window, tag); return; } // TODO: Send to server // Request the new map from server. // Use tag, window and component as a keys. // Offline #if UNITY_EDITOR var settings = ME.EditorUtilities.GetAssetsOfType <HeatmapSettings>(useCache: false).FirstOrDefault(); #else HeatmapSettings settings = null; #endif if (settings == null) { return; } var data = settings.data.Get(flowWindow); data.status = HeatmapSettings.WindowsData.Window.Status.Loading; data.size = (window as LayoutWindowType).layout.GetLayoutInstance().GetSize(); data.AddPoint(localNormalizedPoint, tag, component); #if UNITY_EDITOR UnityEditor.EditorUtility.SetDirty(settings); #endif data.status = HeatmapSettings.WindowsData.Window.Status.Loaded; }
public override void OnFlowWindowLayoutGUI(Rect rect, FD.FlowWindow window) { if (window.isVisibleState == false) return; if (window.IsContainer() == true) return; if (window.IsSmall() == true && window.IsFunction() == true) return; if (window.IsShowDefault() == true) return; if (Heatmap.settings == null) Heatmap.settings = Heatmap.GetSettingsFile(); var settings = Heatmap.settings; if (settings != null) { var data = settings.data.Get(window); if (data == null) return; LayoutWindowType screen; var layout = HeatmapSystem.GetLayout(window.id, out screen); if (layout == null) return; var targetScreenSize = new Vector2(layout.root.editorRect.width, layout.root.editorRect.height); foreach (var item in settings.items) { if (item.show == true && item.enabled == true) { foreach (var serviceBase in this.editor.services) { var service = serviceBase as IAnalyticsService; if (service.GetServiceName() == item.serviceName) { var key = string.Format("{0}_{1}", item.serviceName, window.id); HeatmapResult result; if (this.heatmapResultsCache.TryGetValue(key, out result) == true) { if (result != null) { var texture = this.heatmapTexturesCache[key]; if (texture != null) { var scaleFactor = HeatmapSystem.GetFactor(targetScreenSize, rect.size); //var scaleFactorCanvas = layout.editorScale > 0f ? 1f / layout.editorScale : 1f; //scaleFactor *= scaleFactorCanvas; var r = layout.root.editorRect; r.x *= scaleFactor; r.y *= scaleFactor; r.x += rect.x + rect.width * 0.5f; r.y += rect.y + rect.height * 0.5f; r.width *= scaleFactor; r.height *= scaleFactor; var c = Color.white; GUI.color = c; GUI.DrawTexture(r, texture, ScaleMode.StretchToFill, alphaBlend: true); GUI.color = Color.white; } else { if (this.noDataTexture != null) GUI.DrawTexture(rect, this.noDataTexture, ScaleMode.ScaleToFit, alphaBlend: true); } } else { // still loading... } } else { if (Event.current.type == EventType.Repaint) { var rectSize = targetScreenSize;//rect.size; var rootRect = layout.root.editorRect; this.heatmapResultsCache.Add(key, null); this.heatmapTexturesCache.Add(key, null); service.GetHeatmapData(window.id, (int)targetScreenSize.x, (int)targetScreenSize.y, item.userFilter, (_result) => { var heatmapResult = _result as HeatmapResult; // Convert normalized points to real points for (int i = 0; i < heatmapResult.points.Length; ++i) { var root = layout.GetRootByTag((LayoutTag)heatmapResult.points[i].tag); if (root != null) { var xn = heatmapResult.points[i].x; var yn = heatmapResult.points[i].y; var sourceRect = root.editorRect; var radius = (float)HeatmapVisualizer.GetRadius(); sourceRect.x += radius; sourceRect.y += radius; sourceRect.width -= radius * 2f; sourceRect.height -= radius * 2f; var scaleFactor = HeatmapSystem.GetFactor(targetScreenSize, rectSize); var r = sourceRect; r.x *= scaleFactor; r.y *= scaleFactor; r.x += rootRect.width * 0.5f; r.y = rootRect.height * 0.5f - r.y; r.width *= scaleFactor; r.height *= scaleFactor; heatmapResult.points[i].realPoint = new Vector2(r.x + xn * r.width, r.y - yn * r.height); } } this.heatmapResultsCache[key] = heatmapResult; HeatmapSystem.GenerateTextureFromData((int)targetScreenSize.x, (int)targetScreenSize.y, this.heatmapResultsCache[key], (texture) => { this.heatmapTexturesCache[key] = texture; }); }); } } } } } } } }
public override void OnFlowWindowScreenMenuGUI(FD.FlowWindow window, GenericMenu menu) { if (window.isVisibleState == false) return; if (window.IsContainer() == true) return; if (window.IsSmall() == true && window.IsFunction() == true) return; if (window.IsShowDefault() == true) return; if (Heatmap.settings == null) Heatmap.settings = Heatmap.GetSettingsFile(); var settings = Heatmap.settings; if (settings != null) { var data = settings.data.Get(window); if (data == null) return; foreach (var item in settings.items) { if (item.show == true && item.enabled == true) { foreach (var serviceBase in this.editor.services) { var service = serviceBase as IAnalyticsService; if (service.GetServiceName() == item.serviceName) { var key = string.Format("{0}_{1}", item.serviceName, window.id); var windowId = window.id; menu.AddItem(new GUIContent("Open Heatmap..."), false, () => { //this.fullScreenData = this.heatmapResultsCache[key]; this.fullScreenTexture = this.heatmapTexturesCache[key]; this.fullScreenWindowId = windowId; this.fullScreenEditor = null; this.openFullScreen = true; this.flowEditor.SetDisabled(); }); } } } } } }
public override void OnFlowSettingsGUI() { if (Heatmap.settings == null) Heatmap.settings = Heatmap.GetSettingsFile(); if (this.noDataTexture == null) this.noDataTexture = Resources.Load<Texture>("UI.Windows/Heatmap/NoData"); var settings = Heatmap.settings; if (settings == null) { EditorGUILayout.HelpBox(string.Format(FlowAddon.MODULE_HAS_ERRORS, "Settings file not found (HeatmapSettings)."), MessageType.Error); } else { GUILayout.Label(FlowAddon.MODULE_INSTALLED, EditorStyles.centeredGreyMiniLabel); if (this.editor == null) { this.editor = Editor.CreateEditor(settings) as HeatmapSettingsEditor; this.editor.SetResetCallback(this.ResetCache); } if (this.editor != null) { this.editor.OnInspectorGUI(); } } }
public override void OnFlowWindow(FD.FlowWindow window) { if (window.isVisibleState == false) return; if (window.IsContainer() == true) return; if (window.IsSmall() == true && window.IsFunction() == true) return; if (window.IsShowDefault() == true) return; if (Heatmap.settings == null) Heatmap.settings = Heatmap.GetSettingsFile(); var settings = Heatmap.settings; if (settings != null) { var result = new ScreenResult(); foreach (var item in settings.items) { if (item.show == true && item.enabled == true) { foreach (var serviceBase in this.editor.services) { var service = serviceBase as IAnalyticsService; if (service.GetServiceName() == item.serviceName) { var rect = window.rect; this.DrawBubble(new Rect(new Vector2(rect.x + rect.width * 0.5f, rect.y), Vector2.zero), 0, window.id, -1, Vector2.zero, "LabelGreen"); int value; var keyTransition = string.Format("{0}_{1}", item.serviceName, window.id); if (this.resultsTransitionCache.TryGetValue(keyTransition, out value) == true) { result.uniqueCount = value; } if (result.uniqueCount > 0 && result.popup == false) { // Draw exit bubble this.DrawBubble(new Vector2(rect.x + rect.width * 0.5f, rect.y + rect.height), result, Vector2.zero, "LabelRed", "{1}"); } } } } } } }
public void DrawBubble(Rect rect, int index, int fromScreenId, int toScreenId, Vector2 offset, string styleName = "LabelYellow", string format = "<b>All:</b> {0}\n<b>Unique:</b> {1}") { if (Heatmap.settings == null) Heatmap.settings = Heatmap.GetSettingsFile(); if (this.editor == null) return; var settings = Heatmap.settings; foreach (var item in settings.items) { if (item.show == true && item.enabled == true && item.processing == false) { foreach (var serviceBase in this.editor.services) { var service = serviceBase as IAnalyticsService; if (service.GetServiceName() == item.serviceName) { var key = string.Format("{0}_{1}_{2}_{3}", item.serviceName, index, fromScreenId, toScreenId); var keyTransition = string.Format("{0}_{1}", item.serviceName, fromScreenId); ScreenResult result; if (this.resultsCache.TryGetValue(key, out result) == true) { if (result != null) { this.DrawBubble(rect.center, result, offset, styleName, format); } else { // still loading this.DrawBubble(rect.center, "Loading...", "LabelYellow", Vector2.zero); } } else { this.resultsCache.Add(key, null); if (this.resultsTransitionCache.ContainsKey(keyTransition) == false) this.resultsTransitionCache.Add(keyTransition, 0); var filter = item.userFilter; if (toScreenId == -1) { /* Debug.Log("Screen Request"); */ service.GetScreen(fromScreenId, filter, (_result) => { this.resultsCache[key] = _result; this.resultsTransitionCache[keyTransition] += _result.uniqueCount; }); } else { /* Debug.Log("Screen Transition Request"); */ service.GetScreenTransition(index, fromScreenId, toScreenId, filter, (_result) => { this.resultsCache[key] = _result; this.resultsTransitionCache[keyTransition] -= _result.uniqueCount; }); } } } } } } }
public static int MINIMUM_THRESHOLD = 100; //!< Minimum threshold. /// Minimum alpha a point must have to be rendered at all. public static Texture2D Create(Texture2D map, HeatmapSettings.WindowsData.Window window, List<UnityEngine.UI.Windows.Plugins.Heatmap.Core.HeatmapSettings.Point> normalizedPoints, Vector2 size, int radius = 10) { if (size == Vector2.zero) { return null; } // Create new texture // Texture2D map = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false); if (map == null) { map = new Texture2D((int)size.x, (int)size.y, TextureFormat.ARGB32, false); } // Set texture to alpha-fied state map.SetPixels(HeatmapVisualizer.ColorArray(new Color(1f, 1f, 1f, 0f), map.width * map.height), 0); /*** Generate Grayscale Values ***/ { int x2; // the offset x val in img coordinates int y2; // the offset y val in img coordinates (0,0) - (maxX, maxY) float pointAlpha = .9f; // The alpha that the darkest pixel will be in a point. Color color = new Color(1f, 1f, 1f, pointAlpha); int lineWidth = 1;//(int)(radius * .05f); Dictionary<Vector2, Color> pixelAlpha = new Dictionary<Vector2, Color>(); for (int i = 0; i < normalizedPoints.Count; ++i) { // generate alpha add for each point and a specified circumference pixelAlpha.Clear(); for (int r = 0; r < radius; r+=lineWidth) { // draw and fill them circles for (int angle = 0; angle < 360; ++angle) { x2 = (int)(r * Mathf.Cos(angle)) + (int)(normalizedPoints[i].GetAbsoluteX(window, size.x)); y2 = (int)(r * Mathf.Sin(angle)) + (int)(normalizedPoints[i].GetAbsoluteY(window, size.y)); // This could be sped up for (int y = y2; y > y2 - lineWidth; --y) { for (int x = x2; x < x2 + lineWidth; ++x) { Vector2 coord = new Vector2(x, y); if (pixelAlpha.ContainsKey(coord) == true) { pixelAlpha[coord] = color; } else { pixelAlpha.Add(new Vector2(x, y), color); } } } } color = new Color(color.r, color.g, color.b, color.a - (pointAlpha / ((float)radius / lineWidth))); } // Since the radial fill code overwrites it's own pixels, make sure to only add finalized alpha to // old values. foreach (KeyValuePair<Vector2, Color> keyval in pixelAlpha) { Vector2 coord = keyval.Key; Color previousColor = map.GetPixel((int)coord.x, (int)coord.y); Color newColor = keyval.Value; map.SetPixel((int)coord.x, (int)coord.y, new Color(newColor.r, newColor.b, newColor.g, newColor.a + previousColor.a)); } // Reset color for next point color = new Color(color.r, color.g, color.b, pointAlpha); } } map.Apply(); map.SetPixels32(Colorize(map.GetPixels32(0)), 0); map.Apply(); return map; }
protected virtual void OnInspectorGUI(HeatmapSettings settings, AnalyticsServiceItem item, System.Action onReset, GUISkin skin) { }