* Configures the Megaplot Selections for each facet in `this.groupedExamples` * using the grouped facets method, which produces a 2D matrix of dot groups, * similar to small multiples visualizations. * * The GroupService returns groups of examples at the intersections of facet * param
()
| 260 | * size and the cell's size. |
| 261 | */ |
| 262 | private configure() { |
| 263 | const colFeature = this.groupService.denseFeatureNames[this.colsFeatureIdx]; |
| 264 | const rowFeature = this.groupService.denseFeatureNames[this.rowsFeatureIdx]; |
| 265 | if (colFeature == null || rowFeature == null) return; |
| 266 | |
| 267 | const bindDot = (sprite: SpriteView, dot: Dot) => { |
| 268 | const isHovered = |
| 269 | this.focusService.focusData?.datapointId === dot.id; |
| 270 | const isPinned = |
| 271 | this.pinnedSelectionService.primarySelectedId === dot.id; |
| 272 | const isPrimary = |
| 273 | this.selectionService.primarySelectedId === dot.id; |
| 274 | const isSelected = |
| 275 | this.selectionService.selectedIds.includes(dot.id) && |
| 276 | !(isHovered || isPinned || isPrimary); |
| 277 | const isSpecial = isHovered || isPinned || isPrimary || isSelected; |
| 278 | const noSelections = this.selectionService.selectedIds.length === 0; |
| 279 | |
| 280 | const input = this.appState.getCurrentInputDataById(dot.id); |
| 281 | const colorString = this.colorService.getDatapointColor(input); |
| 282 | const color = colorToRGB(colorString); |
| 283 | |
| 284 | sprite.BorderColor = isPinned ? COLOR_PINNED_BORDER : |
| 285 | isPrimary ? COLOR_PRIMARY_BORDER : color; |
| 286 | sprite.BorderColorOpacity = isSpecial ? 1 : 0.25; |
| 287 | sprite.BorderRadiusPixel = (isPinned || isPrimary) ? 2 : 0; |
| 288 | sprite.BorderPlacement = 1; |
| 289 | sprite.FillColor = (isHovered || isPinned) ? COLOR_HOVER_FILL : color; |
| 290 | sprite.FillColorOpacity = (noSelections || isSpecial) ? 1 : 0.25; |
| 291 | sprite.PositionWorld = dot.world; |
| 292 | sprite.PositionPixel = dot.pixel; |
| 293 | sprite.Sides = 2; |
| 294 | sprite.SizeWorld = stepSize * .9; |
| 295 | sprite.SizePixel = 0; |
| 296 | }; |
| 297 | |
| 298 | // TODO(b/202181874): Explore alternative sorting based on bucketing. |
| 299 | const sortInputs = (a: IndexedInput, b: IndexedInput): number => { |
| 300 | const aVal = this.colorValueMap.get(a.id)!; |
| 301 | const bVal = this.colorValueMap.get(b.id)!; |
| 302 | if (aVal > bVal) { |
| 303 | return 1; |
| 304 | } else if (aVal < bVal) { |
| 305 | return -1; |
| 306 | } else { |
| 307 | return 0; |
| 308 | } |
| 309 | }; |
| 310 | |
| 311 | const groupedExamples = this.groupExamples([rowFeature, colFeature]); |
| 312 | const sizes = this.matrixSizes(groupedExamples, colFeature, rowFeature); |
| 313 | const colSizes = sizes.columns; |
| 314 | const colFeatureVals = Object.keys(colSizes).sort(keySorter); |
| 315 | const rowSizes = sizes.rows; |
| 316 | const rowFeatureVals = Object.keys(rowSizes).sort(keySorter); |
| 317 | /** |
| 318 | * The step size used to position dots in the grid. |
| 319 | * |
no test coverage detected