Skip to content

Commit

Permalink
add static object property that toggles an axis
Browse files Browse the repository at this point in the history
  • Loading branch information
wesyao authored and Wes committed Jul 30, 2016
1 parent b765940 commit 7602bb5
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 4 deletions.
13 changes: 12 additions & 1 deletion capabilities.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,16 @@
}
}
}
]
],
"objects": {
"enableAxis": {
"displayName": "Enable Axis",
"properties": {
"show": {
"displayName": "Enable Axis",
"type": { "bool": true }
}
}
}
}
}
86 changes: 83 additions & 3 deletions src/barChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module powerbi.extensibility.visual {
interface BarChartViewModel {
dataPoints: BarChartDataPoint[];
dataMax: number;
settings: BarChartSettings;
};

/**
Expand All @@ -28,6 +29,18 @@ module powerbi.extensibility.visual {
selectionId: ISelectionId;
};

/**
* Interface for BarChart settings.
*
* @interface
* @property {{show:boolean}} enableAxis - Object property that allows axis to be enabled.
*/
interface BarChartSettings {
enableAxis: {
show: boolean;
};
}

/**
* Function that converts queried data into a view model that will be used by the visual.
*
Expand All @@ -39,9 +52,15 @@ module powerbi.extensibility.visual {
*/
function visualTransform(options: VisualUpdateOptions, host: IVisualHost): BarChartViewModel {
let dataViews = options.dataViews;
let defaultSettings: BarChartSettings = {
enableAxis: {
show: false,
}
};
let viewModel: BarChartViewModel = {
dataPoints: [],
dataMax: 0
dataMax: 0,
settings: defaultSettings
};

if (!dataViews
Expand All @@ -60,6 +79,12 @@ module powerbi.extensibility.visual {
let dataMax: number;

let colorPalette: IColorPalette = createColorPalette(host.colors).reset();
let objects = dataViews[0].metadata.objects;
let barChartSettings: BarChartSettings = {
enableAxis: {
show: getValue<boolean>(objects, 'enableAxis', 'show', defaultSettings.enableAxis.show),
}
}
for (let i = 0, len = Math.max(category.values.length, dataValue.values.length); i < len; i++) {
barChartDataPoints.push({
category: category.values[i],
Expand All @@ -74,7 +99,8 @@ module powerbi.extensibility.visual {

return {
dataPoints: barChartDataPoints,
dataMax: dataMax
dataMax: dataMax,
settings: barChartSettings,
};
}

Expand All @@ -84,12 +110,21 @@ module powerbi.extensibility.visual {
private selectionManager: ISelectionManager;
private barChartContainer: d3.Selection<SVGElement>;
private barContainer: d3.Selection<SVGElement>;
private xAxis: d3.Selection<SVGElement>;
private bars: d3.Selection<SVGElement>;
private barChartSettings: BarChartSettings;

static Config = {
xScalePadding: 0.1,
solidOpacity: 1,
transparentOpacity: 0.5,
margins: {
top: 0,
right: 0,
bottom: 25,
left: 30,
},
xAxisFontMultiplier: 0.04,
};

/**
Expand All @@ -109,6 +144,9 @@ module powerbi.extensibility.visual {

this.barContainer = svg.append('g')
.classed('barContainer', true);

this.xAxis = svg.append('g')
.classed('xAxis', true);
}

/**
Expand All @@ -121,6 +159,8 @@ module powerbi.extensibility.visual {
*/
public update(options: VisualUpdateOptions) {
let viewModel: BarChartViewModel = visualTransform(options, this.host);
let settings = this.barChartSettings = viewModel.settings;

let width = options.viewport.width;
let height = options.viewport.height;

Expand All @@ -129,13 +169,29 @@ module powerbi.extensibility.visual {
height: height
});

if(settings.enableAxis.show) {
let margins = BarChart.Config.margins;
height -= margins.bottom;
}

this.xAxis.style({
'font-size': d3.min([height, width]) * BarChart.Config.xAxisFontMultiplier,
});

let yScale = d3.scale.linear()
.domain([0, viewModel.dataMax])
.range([height, 0]);

let xScale = d3.scale.ordinal()
.domain(viewModel.dataPoints.map(d => d.category))
.rangeRoundBands([0, width], BarChart.Config.xScalePadding);
.rangeRoundBands([0, width], BarChart.Config.xScalePadding, 0.2);

let xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom');

this.xAxis.attr('transform', 'translate(0, ' + height + ')')
.call(xAxis);

let bars = this.barContainer.selectAll('.bar').data(viewModel.dataPoints);
bars.enter()
Expand Down Expand Up @@ -173,6 +229,30 @@ module powerbi.extensibility.visual {
.remove();
}

/**
* Enumerates through the objects defined in the capabilities and adds the properties to the format pane
*
* @function
* @param {EnumerateVisualObjectInstancesOptions} options - Map of defined objects
*/
public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstanceEnumeration {
let objectName = options.objectName;
let objectEnumeration: VisualObjectInstance[] = [];

switch(objectName) {
case 'enableAxis':
objectEnumeration.push({
objectName: objectName,
properties: {
show: this.barChartSettings.enableAxis.show,
},
selector: null
});
};

return objectEnumeration;
}

/**
* Destroy runs when the visual is removed. Any cleanup that the visual needs to
* do should be done here.
Expand Down
23 changes: 23 additions & 0 deletions src/objectEnumerationUtility.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module powerbi.extensibility.visual {
/**
* Gets property value for a particular object.
*
* @function
* @param {DataViewObjects} objects - Map of defined objects.
* @param {string} objectName - Name of desired object.
* @param {string} propertyName - Name of desired property.
* @param {T} defaultValue - Default value of desired property.
*/
export function getValue<T>(objects: DataViewObjects, objectName: string, propertyName: string, defaultValue: T ): T {
if(objects) {
let object = objects[objectName];
if(object) {
let property: T = object[propertyName];

This comment has been minimized.

Copy link
@Marnnn

Marnnn Nov 28, 2017

I'm using API 1.9.0 and getting an error at this point when I try to build. It comes from the objectEnumerationUtility.ts file.

TYPESCRIPT /src/objectEnumerationUtility.ts : (15,21) Type 'DataViewPropertyValue' is not assignable to type 'T'. Type 'string' is not assignable to type 'T'.

I can see what it's trying to do (I think) by taking the type from the object property default rather than being explicit as there'll be different types of properties on the object (line 15). Sorry I'm new to Typescript and have tried to find a solution but think it's strange this isn't working. Maybe there could be something else wrong?

This comment has been minimized.

Copy link
@Jemdo

Jemdo Feb 13, 2018

it seems object[propertyName] is now of type DataViewPropertyValue so you could replace generic T to DataViewPropertyValue and then whenever you use getValue function you could cast it to proper type

This comment has been minimized.

Copy link
@ujessen

ujessen Feb 21, 2018

I am using API 1.10.1 and I get an error that DataViewObjects is not found:

[ts] Der Name "DataViewObjects" wurde nicht gefunden.
I changed it to any and it seems to work now.

if(property !== undefined) {
return property;
}
}
}
return defaultValue;
}
}
4 changes: 4 additions & 0 deletions style/visual.less
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ p {
padding: 5px;

}
}

.xAxis path {
display: none;
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
".api/v1.1.0/PowerBI-visuals.d.ts",
"src/colorPalette.ts",
"src/barChart.ts",
"src/objectEnumerationUtility.ts",
"typings/index.d.ts"
]
}

2 comments on commit 7602bb5

@vichus1995
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this going to change in API 1.7.0, with parseSettings() ?

@jt6414
Copy link

@jt6414 jt6414 commented on 7602bb5 Feb 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current template for new custom visuals have a settings.ts file to help retrieve object values from the dataView. The visual.ts already has a method called enumerateObjectInstances() and parseSettings()
There is no need to create an objectEnumerationUtility.ts file with helper methods anymore. In the settings.ts file:

    export class VisualSettings extends DataViewObjectsParser {
        public dataPoint: dataPointSettings = new dataPointSettings();
        public enableAxis: barChartXAxisSettings = new barChartXAxisSettings();
    }

...

    export class barChartXAxisSettings {
        public show: boolean = true;
    }

In your visual update() method near the top add:

this.settings = BarChart.parseSettings(options && options.dataViews && options.dataViews[0]);

...

if (this.settings.enableAxis.show) {
    let margins = BarChart.Config.margins;
    height -= margins.bottom;
}

Disregard the changes for BarChartSettings as you'll be using VisualSettings

Please sign in to comment.