Skip to content

Commit

Permalink
Add options for labelling limits, centralise handling of resizing plo…
Browse files Browse the repository at this point in the history
…t on overflow (#356)

* Initial handling for line labels

* Options for location of labels

* Stray changes

* Additional formatting and padding options

* Option to specify prefix for label

* Bump version
  • Loading branch information
andrjohns authored Dec 10, 2024
1 parent 6b29fb3 commit ebeb645
Show file tree
Hide file tree
Showing 11 changed files with 464 additions and 61 deletions.
274 changes: 274 additions & 0 deletions capabilities.json
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,280 @@
"multiplier_specification": {
"displayName": "Apply Multiplier to Specification Limits",
"type" : { "bool" : true }
},
"plot_label_show_99": {
"displayName": "Show Value on Plot",
"type": { "bool": true }
},
"plot_label_show_95": {
"displayName": "Show Value on Plot",
"type": { "bool": true }
},
"plot_label_show_68": {
"displayName": "Show Value on Plot",
"type": { "bool": true }
},
"plot_label_show_main": {
"displayName": "Show Value on Plot",
"type": { "bool": true }
},
"plot_label_show_target": {
"displayName": "Show Value on Plot",
"type": { "bool": true }
},
"plot_label_show_alt_target": {
"displayName": "Show Value on Plot",
"type": { "bool": true }
},
"plot_label_show_specification": {
"displayName": "Show Value on Plot",
"type": { "bool": true }
},
"plot_label_position_99": {
"displayName": "Position of Value on Line(s)",
"type": {
"enumeration" : [
{ "displayName" : "Outside", "value" : "outside" },
{ "displayName" : "Inside", "value" : "inside" },
{ "displayName" : "Above", "value" : "above" },
{ "displayName" : "Below", "value" : "below" },
{ "displayName" : "Beside", "value" : "beside" }
]
}
},
"plot_label_position_95": {
"displayName": "Position of Value on Line(s)",
"type": {
"enumeration" : [
{ "displayName" : "Outside", "value" : "outside" },
{ "displayName" : "Inside", "value" : "inside" },
{ "displayName" : "Above", "value" : "above" },
{ "displayName" : "Below", "value" : "below" },
{ "displayName" : "Beside", "value" : "beside" }
]
}
},
"plot_label_position_68": {
"displayName": "Position of Value on Line(s)",
"type": {
"enumeration" : [
{ "displayName" : "Outside", "value" : "outside" },
{ "displayName" : "Inside", "value" : "inside" },
{ "displayName" : "Above", "value" : "above" },
{ "displayName" : "Below", "value" : "below" },
{ "displayName" : "Beside", "value" : "beside" }
]
}
},
"plot_label_position_main": {
"displayName": "Position of Value on Line(s)",
"type": {
"enumeration" : [
{ "displayName" : "Above", "value" : "above" },
{ "displayName" : "Below", "value" : "below" },
{ "displayName" : "Beside", "value" : "beside" }
]
}
},
"plot_label_position_target": {
"displayName": "Position of Value on Line(s)",
"type": {
"enumeration" : [
{ "displayName" : "Above", "value" : "above" },
{ "displayName" : "Below", "value" : "below" },
{ "displayName" : "Beside", "value" : "beside" }
]
}
},
"plot_label_position_alt_target": {
"displayName": "Position of Value on Line(s)",
"type": {
"enumeration" : [
{ "displayName" : "Above", "value" : "above" },
{ "displayName" : "Below", "value" : "below" },
{ "displayName" : "Beside", "value" : "beside" }
]
}
},
"plot_label_position_specification": {
"displayName": "Position of Value on Line(s)",
"type": {
"enumeration" : [
{ "displayName" : "Outside", "value" : "outside" },
{ "displayName" : "Inside", "value" : "inside" },
{ "displayName" : "Above", "value" : "above" },
{ "displayName" : "Below", "value" : "below" },
{ "displayName" : "Beside", "value" : "beside" }
]
}
},
"plot_label_vpad_99": {
"displayName": "Value Vertical Padding",
"type": { "numeric": true }
},
"plot_label_vpad_95": {
"displayName": "Value Vertical Padding",
"type": { "numeric": true }
},
"plot_label_vpad_68": {
"displayName": "Value Vertical Padding",
"type": { "numeric": true }
},
"plot_label_vpad_main": {
"displayName": "Value Vertical Padding",
"type": { "numeric": true }
},
"plot_label_vpad_target": {
"displayName": "Value Vertical Padding",
"type": { "numeric": true }
},
"plot_label_vpad_alt_target": {
"displayName": "Value Vertical Padding",
"type": { "numeric": true }
},
"plot_label_vpad_specification": {
"displayName": "Value Vertical Padding",
"type": { "numeric": true }
},
"plot_label_hpad_99": {
"displayName": "Value Horizontal Padding",
"type": { "numeric": true }
},
"plot_label_hpad_95": {
"displayName": "Value Horizontal Padding",
"type": { "numeric": true }
},
"plot_label_hpad_68": {
"displayName": "Value Horizontal Padding",
"type": { "numeric": true }
},
"plot_label_hpad_main": {
"displayName": "Value Horizontal Padding",
"type": { "numeric": true }
},
"plot_label_hpad_target": {
"displayName": "Value Horizontal Padding",
"type": { "numeric": true }
},
"plot_label_hpad_alt_target": {
"displayName": "Value Horizontal Padding",
"type": { "numeric": true }
},
"plot_label_hpad_specification": {
"displayName": "Value Horizontal Padding",
"type": { "numeric": true }
},
"plot_label_font_99": {
"displayName": "Value Font",
"type": { "formatting": { "fontFamily": true } }
},
"plot_label_font_95": {
"displayName": "Value Font",
"type": { "formatting": { "fontFamily": true } }
},
"plot_label_font_68": {
"displayName": "Value Font",
"type": { "formatting": { "fontFamily": true } }
},
"plot_label_font_main": {
"displayName": "Value Font",
"type": { "formatting": { "fontFamily": true } }
},
"plot_label_font_target": {
"displayName": "Value Font",
"type": { "formatting": { "fontFamily": true } }
},
"plot_label_font_alt_target": {
"displayName": "Value Font",
"type": { "formatting": { "fontFamily": true } }
},
"plot_label_font_specification": {
"displayName": "Value Font",
"type": { "formatting": { "fontFamily": true } }
},
"plot_label_size_99": {
"displayName": "Value Font Size",
"type": { "formatting": { "fontSize": true } }
},
"plot_label_size_95": {
"displayName": "Value Font Size",
"type": { "formatting": { "fontSize": true } }
},
"plot_label_size_68": {
"displayName": "Value Font Size",
"type": { "formatting": { "fontSize": true } }
},
"plot_label_size_main": {
"displayName": "Value Font Size",
"type": { "formatting": { "fontSize": true } }
},
"plot_label_size_target": {
"displayName": "Value Font Size",
"type": { "formatting": { "fontSize": true } }
},
"plot_label_size_alt_target": {
"displayName": "Value Font Size",
"type": { "formatting": { "fontSize": true } }
},
"plot_label_size_specification": {
"displayName": "Value Font Size",
"type": { "formatting": { "fontSize": true } }
},
"plot_label_colour_99":{
"displayName": "Value Colour",
"type": { "fill": { "solid": { "color": true } } }
},
"plot_label_colour_95":{
"displayName": "Value Colour",
"type": { "fill": { "solid": { "color": true } } }
},
"plot_label_colour_68":{
"displayName": "Value Colour",
"type": { "fill": { "solid": { "color": true } } }
},
"plot_label_colour_main":{
"displayName": "Value Colour",
"type": { "fill": { "solid": { "color": true } } }
},
"plot_label_colour_target":{
"displayName": "Value Colour",
"type": { "fill": { "solid": { "color": true } } }
},
"plot_label_colour_alt_target":{
"displayName": "Value Colour",
"type": { "fill": { "solid": { "color": true } } }
},
"plot_label_colour_specification":{
"displayName": "Value Colour",
"type": { "fill": { "solid": { "color": true } } }
},
"plot_label_prefix_99": {
"displayName": "Value Prefix",
"type": { "text": true }
},
"plot_label_prefix_95": {
"displayName": "Value Prefix",
"type": { "text": true }
},
"plot_label_prefix_68": {
"displayName": "Value Prefix",
"type": { "text": true }
},
"plot_label_prefix_main": {
"displayName": "Value Prefix",
"type": { "text": true }
},
"plot_label_prefix_target": {
"displayName": "Value Prefix",
"type": { "text": true }
},
"plot_label_prefix_alt_target": {
"displayName": "Value Prefix",
"type": { "text": true }
},
"plot_label_prefix_specification": {
"displayName": "Value Prefix",
"type": { "text": true }
}
}
},
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":"SPC Charts",
"guid":"PBISPC",
"visualClassName":"Visual",
"version":"1.4.4.17",
"version":"1.4.4.18",
"description":"A PowerBI custom visual for SPC charts",
"supportUrl":"https://github.com/AUS-DOH-Safety-and-Quality/PowerBI-SPC",
"gitHubUrl":"https://github.com/AUS-DOH-Safety-and-Quality/PowerBI-SPC"
Expand Down
71 changes: 71 additions & 0 deletions src/D3 Plotting Functions/drawLineLabels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import type { svgBaseType, Visual } from "../visual";
import { lineNameMap } from "../Functions/getAesthetic";
import { valueFormatter } from "../Functions";
import * as d3 from "./D3 Modules";

const positionOffsetMap: Record<string, number> = {
"above": -1,
"below": 1,
"beside": -1
}

const outsideMap: Record<string, string> = {
"ll99" : "below",
"ll95" : "below",
"ll68" : "below",
"ul68" : "above",
"ul95" : "above",
"ul99" : "above",
"speclimits_lower" : "below",
"speclimits_upper" : "above"
}

const insideMap: Record<string, string> = {
"ll99" : "above",
"ll95" : "above",
"ll68" : "above",
"ul68" : "below",
"ul95" : "below",
"ul99" : "below",
"speclimits_lower" : "above",
"speclimits_upper" : "below"
}

export default function drawLineLabels(selection: svgBaseType, visualObj: Visual) {
const lineSettings = visualObj.viewModel.inputSettings.settings.lines;
const formatValue = valueFormatter(visualObj.viewModel.inputSettings.settings, visualObj.viewModel.inputSettings.derivedSettings);
selection
.select(".linesgroup")
.selectAll("text")
.data(visualObj.viewModel.groupedLines)
.join("text")
.text(d => {
return lineSettings[`plot_label_show_${lineNameMap[d[0]]}`]
? lineSettings[`plot_label_prefix_${lineNameMap[d[0]]}`] + formatValue(d[1][d[1].length - 1].line_value, "value")
: "";
})
.attr("x", d => visualObj.viewModel.plotProperties.xScale(d[1][d[1].length - 1].x))
.attr("y", d => visualObj.viewModel.plotProperties.yScale(d[1][d[1].length - 1].line_value))
.attr("fill", d => lineSettings[`plot_label_colour_${lineNameMap[d[0]]}`])
.attr("font-size", d => `${lineSettings[`plot_label_size_${lineNameMap[d[0]]}`]}px`)
.attr("font-family", d => lineSettings[`plot_label_font_${lineNameMap[d[0]]}`])
.attr("text-anchor", d => lineSettings[`plot_label_position_${lineNameMap[d[0]]}`] === "beside" ? "start" : "end")
.attr("dx", d => {
const offset = (lineSettings[`plot_label_position_${lineNameMap[d[0]]}`] === "beside" ? 1 : -1) * lineSettings[`plot_label_hpad_${lineNameMap[d[0]]}`];
return `${offset}px`;
})
.attr("dy", function(d) {
const bounds = (d3.select(this).node() as SVGGraphicsElement).getBoundingClientRect() as DOMRect;
let position: string = lineSettings[`plot_label_position_${lineNameMap[d[0]]}`];
let vpadding: number = lineSettings[`plot_label_vpad_${lineNameMap[d[0]]}`];
if (["outside", "inside"].includes(position)) {
position = position === "outside" ? outsideMap[d[0]] : insideMap[d[0]];
}
const heightMap: Record<string, number> = {
"above": -lineSettings[`width_${lineNameMap[d[0]]}`],
"below": lineSettings[`plot_label_size_${lineNameMap[d[0]]}`],
"beside": bounds.height / 4
}
return `${positionOffsetMap[position] * vpadding + heightMap[position]}px`;
});
}
File renamed without changes.
Loading

0 comments on commit ebeb645

Please sign in to comment.