Skip to content

Commit

Permalink
New role to add excludes (filtering) for category (#18)
Browse files Browse the repository at this point in the history
* New role for excludes
* Test were added and version was increased
* Version has been increased to 1.3.0
* TSLint fixes
  • Loading branch information
EugeneElkin authored and ignatvilesov committed Aug 17, 2017
1 parent 0ab6593 commit 4d0109f
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 16 deletions.
9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
## 1.3.0
* ADD. Added a new role to set excludes (like filters) for categories. This feature works in addition to StopWords options, however, if option is disabled, excludes will be applied anyway

## 1.2.14
FIX. Fix to use Defered object without jQuery library
* FIX. Fix to use Defered object without jQuery library

## 1.2.13
ADD. Added default color for words
ADD. Added tooltips
* ADD. Added default color for words
* ADD. Added tooltips

## 1.2.12
* FIX. memory leak: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': Out of memory at ImageData creation
Expand Down
26 changes: 23 additions & 3 deletions capabilities.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
"displayNameKey": "Visual_Values",
"kind": "Measure",
"displayName": "Values"
},
{
"name": "Excludes",
"displayNameKey": "Visual_Excludes",
"kind": "Grouping",
"displayName": "Excludes"
}
],
"dataViewMappings": [
Expand All @@ -24,14 +30,28 @@
"Values": {
"min": 0,
"max": 1
},
"Excludes": {
"min": 0,
"max": 1
}
}
],
"categorical": {
"categories": {
"for": {
"in": "Category"
},
"select": [
{
"bind": {
"to": "Category"
}
},
{
"bind": {
"to": "Excludes"
}
}
],

"dataReductionAlgorithm": {
"top": {
"count": 2500
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "powerbi-visuals-wordcloud",
"version": "1.2.14",
"version": "1.3.0",
"description": "Word Cloud is a visual representation of word frequency and value. Use it to get instant insight into the most important terms in a set.",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion pbiviz.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"displayName": "WordCloud",
"guid": "WordCloud1447959067750",
"visualClassName": "WordCloud",
"version": "1.2.14",
"version": "1.3.0",
"description": "Word Cloud is a visual representation of word frequency and value. Use it to get instant insight into the most important terms in a set.",
"supportUrl": "http://community.powerbi.com",
"gitHubUrl": "https://github.com/Microsoft/PowerBI-visuals-WordCloud"
Expand Down
1 change: 1 addition & 0 deletions src/columns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,6 @@ module powerbi.extensibility.visual {
// Data Roles
public Category: T = null;
public Values: T = null;
public Excludes: T = null;
}
}
40 changes: 33 additions & 7 deletions src/visual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ module powerbi.extensibility.visual {
settings: WordCloudSettings,
colorHelper: ColorHelper,
stopWords: string[],
excludedSet: PrimitiveValue[],
texts: WordCloudText[] = [],
reducedTexts: WordCloudText[][],
dataPoints: WordCloudDataPoint[],
Expand Down Expand Up @@ -263,6 +264,10 @@ module powerbi.extensibility.visual {
? stopWords.concat(WordCloud.StopWords)
: stopWords;

excludedSet = !categorical.Excludes || _.isEmpty(categorical.Excludes.values)
? []
: categorical.Excludes.values;

colorHelper = new ColorHelper(
colors,
WordCloud.DataPointFillProperty,
Expand Down Expand Up @@ -308,7 +313,7 @@ module powerbi.extensibility.visual {
});
}

reducedTexts = WordCloud.getReducedText(texts, stopWords, settings);
reducedTexts = WordCloud.getReducedText(texts, stopWords, excludedSet, settings);
dataPoints = WordCloud.getDataPoints(reducedTexts, settings);

return {
Expand Down Expand Up @@ -358,10 +363,11 @@ module powerbi.extensibility.visual {

private static getReducedText(
texts: WordCloudText[],
stopWords: string[],
stopWords: PrimitiveValue[],
excludedSet: PrimitiveValue[],
settings: WordCloudSettings): WordCloudText[][] {

let brokenStrings: WordCloudText[] = WordCloud.processText(texts, stopWords, settings),
let brokenStrings: WordCloudText[] = WordCloud.processText(texts, stopWords, excludedSet, settings),
result: WordCloudText[][] = <WordCloudText[][]>_.values(_.groupBy(
brokenStrings,
(textObject: WordCloudText) => textObject.text.toLocaleLowerCase()));
Expand All @@ -375,21 +381,34 @@ module powerbi.extensibility.visual {

private static processText(
words: WordCloudText[],
stopWords: string[],
stopWords: PrimitiveValue[],
excludedSet: PrimitiveValue[],
settings: WordCloudSettings): WordCloudText[] {
let processedText: WordCloudText[] = [],
partOfProcessedText: WordCloudText[] = [],
whiteSpaceRegExp: RegExp = /\s/,
punctuationRegExp: RegExp = new RegExp(`[${WordCloud.Punctuation.join("\\")}]`, "gim");
punctuationRegExp: RegExp = new RegExp(`[${WordCloud.Punctuation.join("\\")}]`, "gim"),
splittedExcludes: PrimitiveValue[] = [];

excludedSet.forEach((item: PrimitiveValue) => {
if (typeof item === "string" || typeof item === "number") {
let splittedExclude: string[] = item.toString()
.replace(punctuationRegExp, " ")
.split(whiteSpaceRegExp);

splittedExcludes = splittedExcludes.concat(splittedExclude);
}
});

words.forEach((item: WordCloudText) => {
if (typeof item.text === "string") {
let splittedWords: string[] = item.text
.replace(punctuationRegExp, " ")
.split(whiteSpaceRegExp);

const splittedWordsOriginalLength: number = splittedWords.length;

splittedWords = WordCloud.getFilteredWords(splittedWords, stopWords, settings);
splittedWords = WordCloud.getFilteredWords(splittedWords, stopWords, splittedExcludes, settings);
partOfProcessedText = settings.general.isBrokenText
? WordCloud.getBrokenWords(splittedWords, item, whiteSpaceRegExp)
: WordCloud.getFilteredSentences(splittedWords, item, splittedWordsOriginalLength, settings, punctuationRegExp);
Expand Down Expand Up @@ -449,9 +468,16 @@ module powerbi.extensibility.visual {

private static getFilteredWords(
words: string[],
stopWords: string[],
stopWords: PrimitiveValue[],
splittedExcludes: PrimitiveValue[],
settings: WordCloudSettings) {

words = words.filter((value: string) => {
return value.length > 0 && !splittedExcludes.some((removeWord: string) => {
return value.toLocaleLowerCase() === removeWord.toLocaleLowerCase();
});
});

if (!settings.stopWords.show || !stopWords.length) {
return words;
}
Expand Down
3 changes: 2 additions & 1 deletion stringResources/en-US/resources.resjson
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
"Visual_Show": "Show",
"Visual_MinAngle": "Min Angle",
"Visual_MaxAngle": "Max Angle",
"Visual_RotateText": "Rotate Text"
"Visual_RotateText": "Rotate Text",
"Visual_Excludes": "Excludes"
}
9 changes: 9 additions & 0 deletions test/visualData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module powerbi.extensibility.visual.test {
export class WordCloudData extends TestDataViewBuilder {
public static ColumnCategory: string = "Category";
public static ColumnValues: string = "Values";
public static ColumnExcludes: string = "Excludes";

public valuesCategoryValues: any[][] = [
["", null],
Expand Down Expand Up @@ -123,6 +124,14 @@ module powerbi.extensibility.visual.test {
type: ValueType.fromDescriptor({ text: true })
},
values: this.valuesCategoryValues.map((value: any[]) => value[0])
},
{
source: {
displayName: WordCloudData.ColumnExcludes,
roles: { "Excludes": true },
type: ValueType.fromDescriptor({ text: true }),
},
values: ["Afganistan", "Something", "\"Rwanda\", \"Uganda\""]
}
], [
{
Expand Down
20 changes: 20 additions & 0 deletions test/visualTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,26 @@ module powerbi.extensibility.visual.test {
expect(visualBuilder.mainElement[0]).toBeInDOM();
});

it("apply excludes", (done) => {
dataView.categorical.categories[0].values = ["Afganistan", "Angola", "Rwanda", "Uganda", "Fiji", "Papua New Guinea"];

dataView.metadata.objects = {
stopWords: {
show: true,
words: "Papua New Guinea"
}
};

// Should leave Angola and Fiji only
// Afganistan, Rwanda, Uganda must be filtered by Excludes
// Papua New Guinea must be filtered by StopWords option
visualBuilder.updateRenderTimeout(dataView, () => {
let length: number = visualBuilder.words.toArray().length;
expect(length).toEqual(2);
done();
}, 500);
});

it("basic update", (done) => {
visualBuilder.updateRenderTimeout(dataView, () => {
expect(visualBuilder.wordText.length)
Expand Down

0 comments on commit 4d0109f

Please sign in to comment.