Compare commits
2 Commits
dev
...
offline-loading
| Author | SHA1 | Date | |
|---|---|---|---|
| ff7db38b8d | |||
| 1702c95e50 |
@@ -16,7 +16,7 @@
|
|||||||
"settings": {
|
"settings": {
|
||||||
"powerquery.general.mode": "SDK",
|
"powerquery.general.mode": "SDK",
|
||||||
"powerquery.sdk.defaultQueryFile": "${workspaceFolder}\\src\\powerbi-data-connector\\Speckle.query.pq",
|
"powerquery.sdk.defaultQueryFile": "${workspaceFolder}\\src\\powerbi-data-connector\\Speckle.query.pq",
|
||||||
"powerquery.sdk.defaultExtension": "${workspaceFolder}\\bin\\${workspaceFolderBasename}.mez",
|
"powerquery.sdk.defaultExtension": "${workspaceFolder}\\src\\powerbi-data-connector\\bin\\Speckle.mez",
|
||||||
"files.eol": "\n",
|
"files.eol": "\n",
|
||||||
"files.watcherExclude": {
|
"files.watcherExclude": {
|
||||||
"**/.git/objects/**": true,
|
"**/.git/objects/**": true,
|
||||||
|
|||||||
@@ -1,7 +1,2 @@
|
|||||||
// Use this file to write queries to test your data connector
|
// Use this file to write queries to test your data connector
|
||||||
let
|
let result = Speckle.GetByUrl("https://app.speckle.systems/projects/e2988234fb/models/60b2300470@b1f31a351a") in result
|
||||||
result = Speckle.GetByUrl(
|
|
||||||
"https://app.speckle.systems/projects/e2988234fb/models/60b2300470@b1f31a351a,60b2300470"
|
|
||||||
)
|
|
||||||
in
|
|
||||||
result
|
|
||||||
|
|||||||
@@ -44,15 +44,13 @@ in
|
|||||||
addSpeckleTypeCol = Table.AddColumn(
|
addSpeckleTypeCol = Table.AddColumn(
|
||||||
addObjectIdCol, "speckle_type", each try[data][speckle_type] otherwise null
|
addObjectIdCol, "speckle_type", each try[data][speckle_type] otherwise null
|
||||||
),
|
),
|
||||||
|
// TODO: JSON Column must be added here so that any detached objects can be re-attached before doing the json thing. If we just pick the raw result from the API, it will only work in the simplest of objects.
|
||||||
|
addJsonCol = Table.AddColumn(
|
||||||
|
addSpeckleTypeCol, "json", each try Text.FromBinary(Json.FromValue([data])) otherwise null
|
||||||
|
),
|
||||||
final = Table.ReorderColumns(
|
final = Table.ReorderColumns(
|
||||||
addSpeckleTypeCol, {
|
addJsonCol,
|
||||||
"Model URL",
|
{"Model URL", "URL Type", "Version Object ID", "Object ID", "speckle_type", "data", "json"}
|
||||||
"URL Type",
|
|
||||||
"Version Object ID",
|
|
||||||
"Object ID",
|
|
||||||
"speckle_type",
|
|
||||||
"data"
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
in
|
in
|
||||||
final
|
final
|
||||||
|
|||||||
@@ -20,6 +20,11 @@
|
|||||||
"kind": "Grouping",
|
"kind": "Grouping",
|
||||||
"name": "objectColorBy"
|
"name": "objectColorBy"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"displayName": "JSON Data",
|
||||||
|
"kind": "Measure",
|
||||||
|
"name": "json"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"displayName": "Tooltip Data",
|
"displayName": "Tooltip Data",
|
||||||
"kind": "Measure",
|
"kind": "Measure",
|
||||||
@@ -36,16 +41,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"select": [
|
"select": [
|
||||||
{
|
|
||||||
"bind": {
|
|
||||||
"to": "stream"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"bind": {
|
|
||||||
"to": "parentObject"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"bind": {
|
"bind": {
|
||||||
"to": "objectColorBy"
|
"to": "objectColorBy"
|
||||||
@@ -60,6 +55,11 @@
|
|||||||
},
|
},
|
||||||
"values": {
|
"values": {
|
||||||
"select": [
|
"select": [
|
||||||
|
{
|
||||||
|
"bind": {
|
||||||
|
"to": "json"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"bind": {
|
"bind": {
|
||||||
"to": "objectData"
|
"to": "objectData"
|
||||||
@@ -206,6 +206,7 @@
|
|||||||
"essential": true,
|
"essential": true,
|
||||||
"name": "WebAccess",
|
"name": "WebAccess",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
|
"https://*.speckle.systems",
|
||||||
"https://speckle.xyz",
|
"https://speckle.xyz",
|
||||||
"https://*.speckle.xyz",
|
"https://*.speckle.xyz",
|
||||||
"https://latest.speckle.dev",
|
"https://latest.speckle.dev",
|
||||||
|
|||||||
Generated
+2
-2
@@ -6,6 +6,7 @@
|
|||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@specklesystems/powerbi-visual",
|
"name": "@specklesystems/powerbi-visual",
|
||||||
|
"version": "2.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.21.5",
|
"@babel/runtime": "^7.21.5",
|
||||||
@@ -70,8 +71,7 @@
|
|||||||
"webpack-bundle-analyzer": "^4.8.0",
|
"webpack-bundle-analyzer": "^4.8.0",
|
||||||
"webpack-cli": "^5.1.1",
|
"webpack-cli": "^5.1.1",
|
||||||
"webpack-dev-server": "^4.15.0"
|
"webpack-dev-server": "^4.15.0"
|
||||||
},
|
}
|
||||||
"version": "2.0.0"
|
|
||||||
},
|
},
|
||||||
"node_modules/@alloc/quick-lru": {
|
"node_modules/@alloc/quick-lru": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
|
|||||||
@@ -90,62 +90,74 @@ export default class ViewerHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async unloadObjects(
|
public async unloadObjects(
|
||||||
objects: string[],
|
objectIds: string[],
|
||||||
signal?: AbortSignal,
|
signal?: AbortSignal,
|
||||||
onObjectUnloaded?: (url: string) => void
|
onObjectUnloaded?: (url: string) => void
|
||||||
) {
|
) {
|
||||||
for (const url of objects) {
|
console.log('Unloading objects', objectIds)
|
||||||
|
for (const speckleObjectId of objectIds) {
|
||||||
if (signal?.aborted) return
|
if (signal?.aborted) return
|
||||||
await this.viewer
|
// TODO: Here's where the viewer unloads any objects that have been removed. It first ensures any loading is cancelled.
|
||||||
.cancelLoad(url, true)
|
// await this.viewer
|
||||||
.catch((e) => console.warn('Viewer Unload error', url, e))
|
// .cancelLoad(url, true)
|
||||||
.finally(() => {
|
// .catch((e) => console.warn('Viewer error while cancelling load', url, e))
|
||||||
if (this.loadedObjectsCache.has(url)) this.loadedObjectsCache.delete(url)
|
|
||||||
if (onObjectUnloaded) onObjectUnloaded(url)
|
if (this.loadedObjectsCache.has(speckleObjectId))
|
||||||
})
|
this.loadedObjectsCache.delete(speckleObjectId)
|
||||||
|
if (onObjectUnloaded) onObjectUnloaded(speckleObjectId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async loadObjectsWithAutoUnload(
|
public async loadObjectsWithAutoUnload(
|
||||||
objectUrls: string[],
|
objects: any[],
|
||||||
onLoad: (url: string, index: number) => void,
|
onLoad: (url: string, index: number) => void,
|
||||||
onError: (url: string, error: Error) => void,
|
onError: (url: string, error: Error) => void,
|
||||||
signal: AbortSignal
|
signal: AbortSignal
|
||||||
) {
|
) {
|
||||||
var objectsToUnload = _.difference([...this.loadedObjectsCache], objectUrls)
|
var objectsToUnload = _.difference(
|
||||||
|
[...this.loadedObjectsCache],
|
||||||
|
objects.map((o) => o.id as string)
|
||||||
|
)
|
||||||
await this.unloadObjects(objectsToUnload, signal)
|
await this.unloadObjects(objectsToUnload, signal)
|
||||||
await this.loadObjects(objectUrls, onLoad, onError, signal)
|
await this.loadObjects(objects, onLoad, onError, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async loadObjects(
|
public async loadObjects(
|
||||||
objectUrls: string[],
|
objectsToLoad: any[],
|
||||||
onLoad: (url: string, index: number) => void,
|
onLoad: (url: string, index: number) => void,
|
||||||
onError: (url: string, error: Error) => void,
|
onError: (url: string, error: Error) => void,
|
||||||
signal: AbortSignal
|
signal: AbortSignal
|
||||||
) {
|
) {
|
||||||
|
console.log('Loading objects', objectsToLoad)
|
||||||
try {
|
try {
|
||||||
let index = 0
|
//let index = 0
|
||||||
let promises = []
|
let promises = []
|
||||||
for (const url of objectUrls) {
|
for (const speckleObject of objectsToLoad) {
|
||||||
signal.throwIfAborted()
|
signal.throwIfAborted()
|
||||||
console.log('Attempting to load', url)
|
console.log('Attempting to load', speckleObject.id, speckleObject)
|
||||||
if (!this.loadedObjectsCache.has(url)) {
|
|
||||||
|
if (!this.loadedObjectsCache.has(speckleObject.id)) {
|
||||||
console.log('Object is not in cache')
|
console.log('Object is not in cache')
|
||||||
const promise = this.viewer
|
|
||||||
.loadObjectAsync(url, this.config.authToken, false)
|
// TODO: Here's were the viewer loads each object, this used to be done via URL but is now changed to use JSON objects instead (already deserialized)
|
||||||
.then(() => onLoad(url, index++))
|
|
||||||
.catch((e: Error) => onError(url, e))
|
// const promise = this.viewer
|
||||||
.finally(() => {
|
// .loadObjectAsync(speckleObject, this.config.authToken, false)
|
||||||
if (!this.loadedObjectsCache.has(url)) this.loadedObjectsCache.add(url)
|
// .then(() => onLoad(speckleObject.id, index++))
|
||||||
})
|
// .catch((e: Error) => onError(speckleObject, e))
|
||||||
promises.push(promise)
|
|
||||||
|
// promises.push(promise)
|
||||||
|
|
||||||
|
// If batchSize has been reached, wait till all promises resolve before continuing
|
||||||
if (promises.length == this.config.batchSize) {
|
if (promises.length == this.config.batchSize) {
|
||||||
//this.promises.push(Promise.resolve(this.later(1000)))
|
|
||||||
await Promise.all(promises)
|
await Promise.all(promises)
|
||||||
promises = []
|
promises = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.loadedObjectsCache.has(speckleObject.id))
|
||||||
|
this.loadedObjectsCache.add(speckleObject.id)
|
||||||
} else {
|
} else {
|
||||||
console.log('Object was already in cache')
|
console.log('Object was already in cache/already loaded')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await Promise.all(promises)
|
await Promise.all(promises)
|
||||||
@@ -174,6 +186,7 @@ export default class ViewerHandler {
|
|||||||
objects: res.objects
|
objects: res.objects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public zoom(objectIds?: string[]) {
|
public zoom(objectIds?: string[]) {
|
||||||
this.viewer.zoom(objectIds)
|
this.viewer.zoom(objectIds)
|
||||||
}
|
}
|
||||||
@@ -181,6 +194,7 @@ export default class ViewerHandler {
|
|||||||
public zoomExtents() {
|
public zoomExtents() {
|
||||||
this.viewer.zoom()
|
this.viewer.zoom()
|
||||||
}
|
}
|
||||||
|
|
||||||
public async unIsolateObjects() {
|
public async unIsolateObjects() {
|
||||||
if (this.state.isolatedObjects)
|
if (this.state.isolatedObjects)
|
||||||
this.state = await this.viewer.unIsolateObjects(this.state.isolatedObjects, 'powerbi', true)
|
this.state = await this.viewer.unIsolateObjects(this.state.isolatedObjects, 'powerbi', true)
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
import powerbi from 'powerbi-visuals-api'
|
import powerbi from 'powerbi-visuals-api'
|
||||||
import { IViewerTooltip, IViewerTooltipData, SpeckleDataInput } from '../types'
|
import { IViewerTooltip, IViewerTooltipData, SpeckleDataInput } from '../types'
|
||||||
import { formattingSettings as fs } from 'powerbi-visuals-utils-formattingmodel'
|
import { formattingSettings as fs } from 'powerbi-visuals-utils-formattingmodel'
|
||||||
import {
|
|
||||||
createDataViewWildcardSelector,
|
|
||||||
DataViewWildcardMatchingOption
|
|
||||||
} from 'powerbi-visuals-utils-dataviewutils/lib/dataViewWildcard'
|
|
||||||
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions
|
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions
|
||||||
import { SpeckleVisualSettingsModel } from 'src/settings/visualSettingsModel'
|
import { SpeckleVisualSettingsModel } from 'src/settings/visualSettingsModel'
|
||||||
|
|
||||||
@@ -15,23 +11,18 @@ export function validateMatrixView(options: VisualUpdateOptions): {
|
|||||||
const matrixVew = options.dataViews[0].matrix
|
const matrixVew = options.dataViews[0].matrix
|
||||||
if (!matrixVew) throw new Error('Data does not contain a matrix data view')
|
if (!matrixVew) throw new Error('Data does not contain a matrix data view')
|
||||||
|
|
||||||
let hasStream = false,
|
let hasObject = false,
|
||||||
hasParentObject = false,
|
|
||||||
hasObject = false,
|
|
||||||
hasColorFilter = false
|
hasColorFilter = false
|
||||||
|
|
||||||
matrixVew.rows.levels.forEach((level) => {
|
matrixVew.rows.levels.forEach((level) => {
|
||||||
level.sources.forEach((source) => {
|
level.sources.forEach((source) => {
|
||||||
if (!hasStream) hasStream = source.roles['stream'] != undefined
|
|
||||||
if (!hasParentObject) hasParentObject = source.roles['parentObject'] != undefined
|
|
||||||
if (!hasObject) hasObject = source.roles['object'] != undefined
|
if (!hasObject) hasObject = source.roles['object'] != undefined
|
||||||
if (!hasColorFilter) hasColorFilter = source.roles['objectColorBy'] != undefined
|
if (!hasColorFilter) hasColorFilter = source.roles['objectColorBy'] != undefined
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!hasStream) throw new Error('Missing Stream ID input')
|
|
||||||
if (!hasParentObject) throw new Error('Missing Commit Object ID input')
|
|
||||||
if (!hasObject) throw new Error('Missing Object Id input')
|
if (!hasObject) throw new Error('Missing Object Id input')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hasColorFilter,
|
hasColorFilter,
|
||||||
view: matrixVew
|
view: matrixVew
|
||||||
@@ -65,7 +56,7 @@ function processObjectValues(
|
|||||||
displayName: colInfo.displayName,
|
displayName: colInfo.displayName,
|
||||||
value: value.value.toString()
|
value: value.value.toString()
|
||||||
}
|
}
|
||||||
objectData.push(propData)
|
if (value.valueSourceIndex) objectData.push(propData)
|
||||||
})
|
})
|
||||||
return { data: objectData, shouldColor, shouldSelect }
|
return { data: objectData, shouldColor, shouldSelect }
|
||||||
}
|
}
|
||||||
@@ -126,94 +117,50 @@ export function processMatrixView(
|
|||||||
settings: SpeckleVisualSettingsModel,
|
settings: SpeckleVisualSettingsModel,
|
||||||
onSelectionPair: (objId: string, selectionId: powerbi.extensibility.ISelectionId) => void
|
onSelectionPair: (objId: string, selectionId: powerbi.extensibility.ISelectionId) => void
|
||||||
): SpeckleDataInput {
|
): SpeckleDataInput {
|
||||||
const objectUrlsToLoad = [],
|
const objectJsonToLoad = [],
|
||||||
objectIds = [],
|
objectIds = [],
|
||||||
selectedIds = [],
|
selectedIds = [],
|
||||||
colorByIds = [],
|
colorByIds = [],
|
||||||
objectTooltipData = new Map<string, IViewerTooltip>()
|
objectTooltipData = new Map<string, IViewerTooltip>()
|
||||||
|
|
||||||
matrixView.rows.root.children.forEach((streamUrlChild) => {
|
// Assume this has color filter
|
||||||
const url = streamUrlChild.value
|
matrixView.rows.root?.children?.forEach((colorByGroup) => {
|
||||||
|
const colorByValue = colorByGroup.value
|
||||||
|
console.log('Color by group', colorByValue, colorByGroup)
|
||||||
|
|
||||||
streamUrlChild.children?.forEach((parentObjectIdChild) => {
|
const colorGroup = createColorGroup(host, colorByGroup, matrixView)
|
||||||
const parentId = parentObjectIdChild.value
|
|
||||||
objectUrlsToLoad.push(`${url}/objects/${parentId}`)
|
|
||||||
|
|
||||||
if (!hasColorFilter) {
|
colorByGroup.children.forEach((objectIdGroup) => {
|
||||||
processObjectIdLevel(parentObjectIdChild, host, matrixView).forEach((objRes) => {
|
const uniqueId = objectIdGroup.value
|
||||||
objectIds.push(objRes.id)
|
const jsonValue = objectIdGroup.values[0] // TODO: Json value is set as first value in capabilities.json
|
||||||
onSelectionPair(objRes.id, objRes.selectionId)
|
|
||||||
if (objRes.shouldSelect) selectedIds.push(objRes.id)
|
|
||||||
if (objRes.color) {
|
|
||||||
let group = colorByIds.find((g) => g.color === objRes.color)
|
|
||||||
if (!group) {
|
|
||||||
group = {
|
|
||||||
color: objRes.color,
|
|
||||||
objectIds: []
|
|
||||||
}
|
|
||||||
colorByIds.push(group)
|
|
||||||
}
|
|
||||||
group.objectIds.push(objRes.id)
|
|
||||||
}
|
|
||||||
objectTooltipData.set(objRes.id, {
|
|
||||||
selectionId: objRes.selectionId,
|
|
||||||
data: objRes.data
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
if (previousPalette) host.colorPalette['colorPalette'] = previousPalette
|
|
||||||
parentObjectIdChild.children?.forEach((colorByChild) => {
|
|
||||||
const colorSelectionId = host
|
|
||||||
.createSelectionIdBuilder()
|
|
||||||
.withMatrixNode(colorByChild, matrixView.rows.levels)
|
|
||||||
.createSelectionId()
|
|
||||||
|
|
||||||
const color = host.colorPalette.getColor(colorByChild.value as string)
|
objectJsonToLoad.push(JSON.parse(jsonValue.value.toString()))
|
||||||
if (colorByChild.objects) {
|
colorGroup.objectIds.push(uniqueId)
|
||||||
console.log(
|
|
||||||
'⚠️COLOR NODE HAS objects',
|
|
||||||
colorByChild.objects,
|
|
||||||
colorByChild.objects.color?.fill
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const colorSlice = new fs.ColorPicker({
|
if (jsonValue.highlight) console.log(uniqueId, jsonValue)
|
||||||
name: 'selectorFill',
|
var processedObject = processObjectNode(objectIdGroup, host, matrixView)
|
||||||
displayName: colorByChild.value.toString(),
|
console.log(processedObject)
|
||||||
value: {
|
|
||||||
value: color.value
|
|
||||||
},
|
|
||||||
selector: colorSelectionId.getSelector()
|
|
||||||
})
|
|
||||||
|
|
||||||
const colorGroup = {
|
onSelectionPair(uniqueId.toString(), processedObject.selectionId)
|
||||||
color: color.value,
|
|
||||||
slice: colorSlice,
|
|
||||||
objectIds: []
|
|
||||||
}
|
|
||||||
|
|
||||||
processObjectIdLevel(colorByChild, host, matrixView).forEach((objRes) => {
|
if (processedObject.shouldSelect) selectedIds.push(processedObject.id)
|
||||||
objectIds.push(objRes.id)
|
if (processedObject.shouldColor) colorGroup.objectIds.push(processedObject.id)
|
||||||
onSelectionPair(objRes.id, objRes.selectionId)
|
|
||||||
if (objRes.shouldSelect) selectedIds.push(objRes.id)
|
objectTooltipData.set(processedObject.id, {
|
||||||
if (objRes.shouldColor) {
|
selectionId: processedObject.selectionId,
|
||||||
colorGroup.objectIds.push(objRes.id)
|
data: processedObject.data
|
||||||
}
|
})
|
||||||
objectTooltipData.set(objRes.id, {
|
|
||||||
selectionId: objRes.selectionId,
|
|
||||||
data: objRes.data
|
|
||||||
})
|
|
||||||
})
|
|
||||||
if (colorGroup.objectIds.length > 0) colorByIds.push(colorGroup)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (colorGroup.objectIds.length > 0) colorByIds.push(colorGroup)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// TODO: Code behavior without color filter
|
||||||
|
|
||||||
previousPalette = host.colorPalette['colorPalette']
|
previousPalette = host.colorPalette['colorPalette']
|
||||||
|
|
||||||
return {
|
return {
|
||||||
objectsToLoad: objectUrlsToLoad,
|
objectsToLoad: objectJsonToLoad,
|
||||||
objectIds,
|
objectIds,
|
||||||
selectedIds,
|
selectedIds,
|
||||||
colorByIds: colorByIds.length > 0 ? colorByIds : null,
|
colorByIds: colorByIds.length > 0 ? colorByIds : null,
|
||||||
@@ -221,3 +168,34 @@ export function processMatrixView(
|
|||||||
view: matrixView
|
view: matrixView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function createColorGroup(
|
||||||
|
host: powerbi.extensibility.visual.IVisualHost,
|
||||||
|
colorByGroup: powerbi.DataViewMatrixNode,
|
||||||
|
matrixView: powerbi.DataViewMatrix
|
||||||
|
) {
|
||||||
|
const colorSelectionId = host
|
||||||
|
.createSelectionIdBuilder()
|
||||||
|
.withMatrixNode(colorByGroup, matrixView.rows.levels)
|
||||||
|
.createSelectionId()
|
||||||
|
|
||||||
|
const color = host.colorPalette.getColor(colorByGroup.value as string)
|
||||||
|
if (colorByGroup.objects) {
|
||||||
|
console.log('⚠️COLOR NODE HAS objects', colorByGroup.objects, colorByGroup.objects.color?.fill)
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorSlice = new fs.ColorPicker({
|
||||||
|
name: 'selectorFill',
|
||||||
|
displayName: colorByGroup.value.toString(),
|
||||||
|
value: {
|
||||||
|
value: color.value
|
||||||
|
},
|
||||||
|
selector: colorSelectionId.getSelector()
|
||||||
|
})
|
||||||
|
|
||||||
|
const colorGroup = {
|
||||||
|
color: color.value,
|
||||||
|
slice: colorSlice,
|
||||||
|
objectIds: []
|
||||||
|
}
|
||||||
|
return colorGroup
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,11 +20,6 @@ import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructor
|
|||||||
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions
|
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions
|
||||||
import IVisual = powerbi.extensibility.visual.IVisual
|
import IVisual = powerbi.extensibility.visual.IVisual
|
||||||
import ITooltipService = powerbi.extensibility.ITooltipService
|
import ITooltipService = powerbi.extensibility.ITooltipService
|
||||||
import {
|
|
||||||
createDataViewWildcardSelector,
|
|
||||||
DataViewWildcardMatchingOption
|
|
||||||
} from 'powerbi-visuals-utils-dataviewutils/lib/dataViewWildcard'
|
|
||||||
import { ColorSelectorSettings } from 'src/settings/colorSettings'
|
|
||||||
|
|
||||||
// noinspection JSUnusedGlobalSymbols
|
// noinspection JSUnusedGlobalSymbols
|
||||||
export class Visual implements IVisual {
|
export class Visual implements IVisual {
|
||||||
|
|||||||
Reference in New Issue
Block a user