Skip to content

Commit 4ba5bd5

Browse files
mvgalievignatvilesov
authored andcommitted
added tooltip bucket (#102)
1 parent 701e963 commit 4ba5bd5

File tree

9 files changed

+115
-15
lines changed

9 files changed

+115
-15
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.9.4
2+
* Fixed issue with tooltip duration
3+
* Fixed issue with invisible task line when duration is 1
4+
* Added ability to use custom tooltip rows
15
## 1.9.3
26
* Fixed issue with tooltip duration
37
* Fixed issue with line length with float value and 'second' duration

capabilities.json

+16
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@
6363
"displayName": "Extra information",
6464
"displayNameKey": "Role_ExtraInformation",
6565
"kind": "Grouping"
66+
},
67+
{
68+
"name": "Tooltips",
69+
"displayName": "Tooltips",
70+
"displayNameKey": "Role_Tooltips",
71+
"kind": "Measure"
6672
}
6773
],
6874
"dataViewMappings": [
@@ -198,6 +204,11 @@
198204
"for": {
199205
"in": "ExtraInformation"
200206
}
207+
},
208+
{
209+
"for": {
210+
"in": "Tooltips"
211+
}
201212
}
202213
]
203214
},
@@ -214,6 +225,11 @@
214225
"for": {
215226
"in": "Completion"
216227
}
228+
},
229+
{
230+
"for": {
231+
"in": "Tooltips"
232+
}
217233
}
218234
]
219235
}

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "powerbi-visuals-gantt",
3-
"version": "1.9.3",
3+
"version": "1.9.4",
44
"description": "A Gantt chart is a type of bar chart which illustrates a project timeline or schedule. The Gantt Chart visual shows the Tasks, Start Dates, Durations, % Complete, and Resources for a project. The Gantt Chart visual can be used to show current schedule status using percent-complete shadings and a vertical \"TODAY\" line. The Legend may be used to group or filter tasks based upon data values.",
55
"repository": {
66
"type": "git",

pbiviz.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"displayName": "Gantt",
55
"guid": "Gantt1448688115699",
66
"visualClassName": "Gantt",
7-
"version": "1.9.3",
7+
"version": "1.9.4",
88
"description": "A Gantt chart is a type of bar chart which illustrates a project timeline or schedule. The Gantt Chart visual shows the Tasks, Start Dates, Durations, % Complete, and Resources for a project. The Gantt Chart visual can be used to show current schedule status using percent-complete shadings and a vertical \"TODAY\" line. The Legend may be used to group or filter tasks based upon data values.",
99
"supportUrl": "http://community.powerbi.com",
1010
"gitHubUrl": "https://github.com/Microsoft/powerbi-visuals-gantt"

src/columns.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,12 @@ module powerbi.extensibility.visual {
5555
columns = {};
5656
}
5757
columns[x.source.displayName] = x.values;
58-
} else {
58+
} else if (x.source.roles && x.source.roles["Tooltips"]) {
59+
if (!columns) {
60+
columns = {};
61+
}
62+
columns[x.source.displayName] = x.values;
63+
} else {
5964
columns = x.values;
6065
}
6166
});
@@ -78,5 +83,6 @@ module powerbi.extensibility.visual {
7883
public Completion: T = null;
7984
public Resource: T = null;
8085
public ExtraInformation: T = null;
86+
public Tooltips: T = null;
8187
}
8288
}

src/gantt.ts

+30-11
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ module powerbi.extensibility.visual {
295295
export const Duration: string = "Duration";
296296
export const Completion: string = "Completion";
297297
export const Resource: string = "Resource";
298+
export const Tooltips: string = "Tooltips";
298299
}
299300

300301
export class Gantt implements IVisual {
@@ -591,6 +592,10 @@ module powerbi.extensibility.visual {
591592
tooltipDataArray.push({ displayName: "Resource", value: task.resource });
592593
}
593594

595+
if (task.tooltipInfo && task.tooltipInfo.length) {
596+
tooltipDataArray.push(...task.tooltipInfo);
597+
}
598+
594599
for (const key of Object.keys(task.extraInformation)) {
595600
tooltipDataArray.push(task.extraInformation[key]);
596601
}
@@ -721,11 +726,9 @@ module powerbi.extensibility.visual {
721726
const colorHelper: ColorHelper = new ColorHelper(colors, Gantt.LegendPropertyIdentifier);
722727
const values: GanttColumns<any> = GanttColumns.getCategoricalValues(dataView);
723728
const groupValues: GanttColumns<DataViewValueColumn>[] = GanttColumns.getGroupedValueColumns(dataView);
724-
725729
if (!values.Task) {
726730
return tasks;
727731
}
728-
729732
let collapsedTasks: string[] = JSON.parse(settings.collapsedTasks.list);
730733
let durationUnit: string = settings.general.durationUnit;
731734
let duration: number = settings.general.durationMin;
@@ -736,6 +739,8 @@ module powerbi.extensibility.visual {
736739
let completion: number = 0;
737740
let taskType: TaskTypeMetadata = null;
738741
let wasDowngradeDurationUnit: boolean = false;
742+
let tooltips: VisualTooltipDataItem[] = [];
743+
let skipTooltipNames: string[] = [];
739744
let stepDurationTransformation: number = 0;
740745

741746
const selectionBuider: ISelectionIdBuilder = host
@@ -753,8 +758,7 @@ module powerbi.extensibility.visual {
753758
color = colorHelper.getColorForMeasure(taskType.columnGroup.objects, taskType.name);
754759
}
755760

756-
duration = group.Duration.values[index] > settings.general.durationMin
757-
&& group.Duration.values[index] as number;
761+
duration = group.Duration.values[index] > settings.general.durationMin ? group.Duration.values[index] as number : settings.general.durationMin;
758762

759763
if (duration && duration % 1 !== 0) {
760764
durationUnit = Gantt.downgradeDurationUnit(durationUnit);
@@ -778,6 +782,14 @@ module powerbi.extensibility.visual {
778782
completion = Gantt.ComplectionMax;
779783
}
780784
}
785+
786+
if (group.Tooltips && group.Tooltips.values[index]) {
787+
tooltips.push({
788+
displayName: group.Tooltips.source.displayName,
789+
value: group.Tooltips.values[index]
790+
} as VisualTooltipDataItem);
791+
skipTooltipNames.push(group.Tooltips.source.displayName);
792+
}
781793
}
782794
});
783795
}
@@ -803,6 +815,17 @@ module powerbi.extensibility.visual {
803815
}
804816
}
805817

818+
if (values.Tooltips) {
819+
const extraTooltipKeys: any[] = Object.keys(values.Tooltips);
820+
for (const key of extraTooltipKeys.filter(k => skipTooltipNames.indexOf(k) < 0)) {
821+
const value: string = values.Tooltips[key][index];
822+
tooltips.push({
823+
displayName: key,
824+
value: value || ""
825+
});
826+
}
827+
}
828+
806829
const task: Task = {
807830
color,
808831
completion,
@@ -817,7 +840,7 @@ module powerbi.extensibility.visual {
817840
duration,
818841
taskType: taskType && taskType.name,
819842
description: categoryValue as string,
820-
tooltipInfo: [],
843+
tooltipInfo: tooltips,
821844
selected: false,
822845
identity: selectionId,
823846
extraInformation,
@@ -1281,10 +1304,8 @@ module powerbi.extensibility.visual {
12811304
* @param options The visual option that contains the dataview and the viewport
12821305
*/
12831306
public update(options: VisualUpdateOptions): void {
1284-
if (!options
1285-
|| !options.dataViews
1286-
|| !options.dataViews[0]
1287-
) { this.clearViewport();
1307+
if (!options || !options.dataViews || !options.dataViews[0]) {
1308+
this.clearViewport();
12881309
return;
12891310
}
12901311

@@ -1299,7 +1320,6 @@ module powerbi.extensibility.visual {
12991320

13001321
this.renderLegend();
13011322
this.updateChartSize();
1302-
13031323
let tasks: Task[] = this.viewModel.tasks
13041324
.filter((task: Task) => task.visibility)
13051325
.map((task: Task, i: number) => {
@@ -1341,7 +1361,6 @@ module powerbi.extensibility.visual {
13411361
this.timeScale = <timeScale<Date, Date>>xAxisProperties.scale;
13421362

13431363
this.collapsedTasks = JSON.parse(settings.collapsedTasks.list);
1344-
13451364
this.renderAxis(xAxisProperties);
13461365
this.renderTasks(groupedTasks);
13471366

stringResources/en-US/resources.resjson

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"Role_Completion": "% Completion",
77
"Role_Resource": "Resource",
88
"Role_ExtraInformation": "Extra information",
9+
"Role_Tooltips": "Tooltips",
910
"Visual_General": "General",
1011
"Visual_GroupTasks": "Group Tasks",
1112
"Visual_ScrollToCurrentTime": "Scroll to current time",

test/visualData.ts

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ module powerbi.extensibility.visual.test {
4343
public static ColumnCompletePrecntege: string = "CompletePrecntege";
4444
public static ColumnExtraInformation: string = "Description";
4545
public static ColumnParent: string = "Parent";
46+
public static ColumnTooltips: string = "Tooltips";
4647

4748
public valuesTaskTypeResource: string[][] = [
4849
["Spec", "MOLAP connectivity", "Mey"],
@@ -82,6 +83,7 @@ module powerbi.extensibility.visual.test {
8283
public valuesDuration = GanttData.getRandomUniqueNumbers(this.valuesTaskTypeResource.length, 3, 40);
8384
public valuesCompletePrecntege = GanttData.getRandomUniqueNumbers(this.valuesTaskTypeResource.length);
8485
public valuesExtraInformation = GanttData.getTexts(this.valuesTaskTypeResource, "Description");
86+
public valuesTooltips = GanttData.getTexts(this.valuesTaskTypeResource, "Description");
8587

8688
public static getTexts(valuesTaskTypeResource: string[][], text: string): string[] {
8789
return valuesTaskTypeResource.map((item) => {

test/visualTest.ts

+53-1
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,34 @@ module powerbi.extensibility.visual.test {
167167
});
168168
});
169169

170+
it("When task duration is 1 or less, it should be set to 1, not false", (done) => {
171+
dataView = defaultDataViewBuilder.getDataView([
172+
GanttData.ColumnType,
173+
GanttData.ColumnTask,
174+
GanttData.ColumnDuration,
175+
GanttData.ColumnStartDate,
176+
GanttData.ColumnResource,
177+
GanttData.ColumnCompletePrecntege]);
178+
179+
dataView
180+
.categorical
181+
.values
182+
.filter(x => x.source.roles.Duration)
183+
.forEach((element, i) => {
184+
element.values = element.values.map((v, i) => i === 0 ? 1 : 1 / v);
185+
});
186+
187+
visualBuilder.updateRenderTimeout(dataView, () => {
188+
let tasks: Task[] = d3.select(visualBuilder.element.get(0)).selectAll(".task").data();
189+
190+
for (let task of tasks) {
191+
expect(task.duration).toEqual(defaultTaskDuration);
192+
}
193+
194+
done();
195+
});
196+
});
197+
170198
it("When task duration is float and duration unit 'second', it should be round", (done) => {
171199
defaultDataViewBuilder.valuesDuration = GanttData.getRandomUniqueNumbers(100, 1, 2, false);
172200
dataView = defaultDataViewBuilder.getDataView([
@@ -280,7 +308,8 @@ module powerbi.extensibility.visual.test {
280308
dataView = defaultDataViewBuilder.getDataView([
281309
GanttData.ColumnTask,
282310
GanttData.ColumnStartDate,
283-
GanttData.ColumnDuration]);
311+
GanttData.ColumnDuration,
312+
GanttData.ColumnTooltips]);
284313

285314
visualBuilder.updateRenderTimeout(dataView, () => {
286315
let taskLabelsInDom = d3.select(visualBuilder.element.get(0)).selectAll(".label title")[0];
@@ -351,6 +380,29 @@ module powerbi.extensibility.visual.test {
351380
});
352381
});
353382

383+
it("Verify tooltips have tooltips", (done) => {
384+
dataView = defaultDataViewBuilder.getDataView([
385+
GanttData.ColumnTask,
386+
GanttData.ColumnStartDate,
387+
GanttData.ColumnDuration,
388+
GanttData.ColumnTooltips]);
389+
390+
visualBuilder.updateRenderTimeout(dataView, () => {
391+
let tasks = d3.select(visualBuilder.element.get(0)).selectAll(".task").data();
392+
let index = 0;
393+
for (let task of tasks) {
394+
for (let tooltipInfo of task.tooltipInfo) {
395+
if (tooltipInfo.displayName === GanttData.ColumnTooltips) {
396+
let value: VisualTooltipDataItem = tooltipInfo.value;
397+
expect(value).toEqual(defaultDataViewBuilder.valuesTooltips[index++]);
398+
}
399+
}
400+
}
401+
402+
done();
403+
});
404+
});
405+
354406
it("Verify sub tasks", (done) => {
355407
dataView = defaultDataViewBuilder.getDataView([
356408
GanttData.ColumnTask,

0 commit comments

Comments
 (0)