'Dynamic position of progress bars based on results for multiple sections
I have a rather interesting question here that I've been stumped on for awhile. We're playing with dynamic results that we'd like to indicate on reports.
We'd like to display a "marker" (darker section) where the end users result ends up in. These are Pathology Results and an example would look like the following:
For the above example, the details are as follows:
- RESULT: 128
- LOW RANGE: 115
- HIGH RANGE: 165
As you can see above in the example graph there are 3 sections:
- Yellow (LOW): indicates a result that is below normal/outside of the lower range.
- Green (GOOD): to indicate a result that is good and within optimal ranges.
- Red (HIGH): indicates a result that is above normal/outside of the upper range.
Another example of what we're trying to achieve would look like the following - however this is all done statically at current:

Notes
- We already now which "section" it'll be in, but we need to create functionality to indicate "where" in that section it would end up, preferably percentage based.
For the Low range we've come up with a simple (pseudo) solution as follows:
$result = 1.15;
$rangeLow = 2.0;
function getLowRangePercentile($result, $rangeLow) {
// number format as we only want the percentile, i.e. 0.1, 0.5, 0.6, etc...
// NOT: 0.45, 0.98, etc...
return number_format($result / $rangeLow, 1);
}
For the High range we've used a similar solution:
$result = 364;
$rangeHigh = 360;
function getHighRangePercentile($result, $rangeHigh) {
return number_format($rangeHigh / $result, 2);
}
There are inherent issues with this as some results and/or ranges could have larger numbers causing the percentiles to be highly specific, i.e. 99% in the above example...
We need to be able to generate HTML (Bootstrap) progress bar's as follows, with the "indicator" being 2% bar of the darker colour for the section it ends up in..
<div class="progress">
<div class="progress-bar bg-light-warning" role="progressbar" style="width: 23%" aria-valuenow="23" aria-valuemin="0" aria-valuemax="100"></div>
<!-- START "INDICATOR" marker -->
<div class="progress-bar bg-warning" role="progressbar" style="width: 2%" aria-valuenow="2" aria-valuemin="0" aria-valuemax="100"></div>
<!-- END "INDICATOR" marker -->
<div class="progress-bar bg-light-success" role="progressbar" style="width: 50%" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div>
<div class="progress-bar bg-light-danger" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</div>
NOTE
The sections are divided up as follows:
-----------------------------------------
| LOW | NORMAL | HIGH |
-----------------------------------------
| 25% | 50% | 25% |
-----------------------------------------
Would love some ideas in terms of sorting this out efficiently for the low/high sections, along with the "good/normal" section (as below).
Which leaves us stumped on how to work on the "good" result section currently. We've currently thought of doing the following:
- Finding out which "range" the result is closer to
- Running a similar calculation to the other sections specified by the ranges
- Generating the progress bars from there...
Thanks.
Solution 1:[1]
Your question is very confusing lol, but I'd try something like this.
Assuming you want a consistent scale e.g. 0-25% is NOT equal to 0-115, I'd do the following:
Don't mess around with trying to balance four progress bars, just use three for the ranges and use an
absolutepositioned div as the marker.Do some maths, let's use your first example (
res: 128,min: 115,max: 165):Since
max-min= 50% of the bar, divide that by 50 to get 1%- 165 - 115 = 50, 50 / 50 = 1
We need to get the lowest value that can fit on the graph so we can adjust the position of the result:
- 115 - 1 * 25 = 90
Now that we know the scaling and the smallest value that can fit on the bar, subtract our smallest value from
res, and divide by the 1% to adjust for scaling:- 128 - 90 = 38, 38 / 1 = 38%
Then just use that as the position of the div e.g. using the left property.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Piotr Płaczek |

