Example #1
0
        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}");

								}

							}

						}

					}

				}

			}

		}
Example #10
0
		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) {



		}