A dynamically adjustable scoring calculator with a lighthouse style data visualization.
Get a score between 0 to 100 from data, with dynamically adjustable target value, a from -5 to +5 adjustable bias , and a self adjusting weighting system.
Optionally the weights can be entered manually to the wished percentages, by clicking on the gear icon in the weighting column.
This Scoring Calculator basically scores a point in time, of which static data points are available, with the option for the front end user to adjust the scoring based on preference and current situation.
Further more every category can be assigned a different scoring method, which allows for even grater accuracy.
The flexibility carries on even when integrating this scoring calculator on the front end with support for all major JavaScript frameworks plus Vanilla Javascript
Including a universal Web Components Version.
The Modules written for Web Components,
React,
Vue or
Angular
may behave different in some cases. But overall the Framework of choice makes no difference, they have all the same end result...
This Demo has the minimum amount of CSS and is written in 100% vanilla JavaScript.
Category | Value | Target Value | Bias | Weighting | Score |
---|
let data = [20, 23, 80, 2];
let
config = {
categoryCount: 4, // number of category
categoryNames: ["Time", "Cost", "Efficiency", "Personell"], //category title to display
categoryUnits: ["s", "€", "%", "P"], // category unit to display
categoryTargets: [10, 20, 100, 0], // target value to which a data Point in the data set should converge
categorySteps: [1, 0.01, 0.01, 1], //how big on step on the slider should be
categoryDirections: [1, 1, -1, 1], // 1: data point > target value; -1: data point < target value
categoryGrains: [1, 1, 1, 1], //(g > 0) && (if categoryValue == targetValue + categoryGrain => categoryScore = 500
categoryEvaluations: ["linear", "linear", "linear", "linear"], // how should the score of a category be calculated
categoryWeightPresets: [25, 25, 25, 25], // presets
categoryColors: ["#ff0000", "#ff7b00", "#ffbb00", "#00dfba", "#127efa", "#8921ff", "#d500e9"], // define the circle colors
};
In this example some imaginary Monitor is being scored. Using The Web Components Method is the easiest way to get this Scoring Calculator onto a Website
For using web components all that needs to be done is shown in the next example. The configuration is directly passed on via the HTML properties. Everything is being handled via attributes applied on the scoring-calc-category html element. Even accessing any value via JavaScript is possible
<script src="DVSC.js" defer></script>
<scoring-calc>
<scoring-calc-category
number="0"
rowName="Resolution"
unit="px"
value="1080"
target="1440"
step="1"
direction="-1"
evaluation="linear"
bias="2"
weight="39.72519332681899"
score="500"
color="#FF1D15"
grain="100"> </scoring-calc-category>
<scoring-calc-category
number="1"
rowName="Size"
unit="in"
value="24"
target="27"
step="0.5"
direction="-1"
evaluation="linear"
bias="-1"
weight="16.693640030592356"
score="500"
color="#0075FF"
grain="1"> </scoring-calc-category>
<scoring-calc-category
number="2"
rowName="Refresh Rate"
unit="Hz"
value="75"
target="90"
step="1"
direction="-1"
evaluation="quad"
bias="1"
weight="13.247233998615995"
score="500"
color="#61E786"
grain="5"> </scoring-calc-category>
<scoring-calc-category
number="3"
rowName="Color Accuracy"
unit="%"
value="96"
target="99"
step="0.1"
direction="-1"
evaluation="linear"
bias="0"
weight="10.1807772250803"
score="500"
color="#FCC217"
grain="1"> </scoring-calc-category>
<scoring-calc-category
number="4"
rowName="Cost"
unit="$"
value="105"
target="90"
step="0.01"
direction="1"
evaluation="cube"
bias="-2"
weight="20.153155418892357"
score="500"
color="#34F6F2"
grain="20"> </scoring-calc-category>
</scoring-calc>
let dvsc = document.querySelector("scoring-calc");
Property | Usage | Example Output | Definition | |
---|---|---|---|---|
categoryBiases | dvsc.categoryBiases |
[0, 0, 1, 0, -2] | Returns an Array of the current bias slider input values | |
categoryColors | dvsc.categoryColors |
['#FF1D15', '#0075FF', '#61E786', '#FCC217', '#34F6F2'] | Returns an array filled with every scoring-calc-category color property | |
categoryCount | dvsc.categoryCount |
5 | Returns an the total number of categories | |
categoryDirections | dvsc.categoryDirections
|
[-1, -1, -1, -1, 1] | Returns an array filled with all scoring-calc-category direction properties | |
categoryEvaluations | dvsc.categoryEvaluations
|
['default', 'linear', 'quadratic', 'cube', 'ERF'] | Returns an array filled with all scoring-calc-category evaluation properties | |
categoryGrains | dvsc.categoryGrains |
[400,3, 7.5, 1, 20] | Returns an array filled with all scoring-calc-category color properties | |
categoryNames | dvsc.categoryNames |
['Resolution','Size', 'Refresh Rate', 'Color Accuracy', 'Cost'] | Returns an array filled with all scoring-calc-category rowname properties | |
categoryNumbers | dvsc.categoryNumbers
|
[0, 1, 2, 3, 4] | Returns an array filled with all scoring-calc-category number properties | |
categoryScores | dvsc.categoryScores |
[500,949.99, 315.5, 31.49, 912.51] | Returns an array filled with all scoring-calc-category score properties | |
categorySteps | dvsc.categorySteps |
[1, 3, 5, 0.1, 0.01] | Returns an array filled with all scoring-calc-category step properties | |
categoryTargets | dvsc.categoryTargets
|
[1440, 27, 90, 99, 90] | Returns an array filled with all current scoring-calc-category target properties | |
categoryUnits | dvsc.categoryUnits |
['px', 'in', 'Hz', '%', '$'] | Returns an array filled with all scoring-calc-category unit properties | |
categoryValues | dvsc.categoryValues |
[1080, 24, 75, 96, 105] | Returns an array filled with all scoring-calc-category value properties | |
categoryWeights | dvsc.categoryWeights
|
[39.725, 16.693, 13.247, 10.180, 20.153] | Returns an array filled with all current scoring-calc-category weight properties | |
elements | dvsc.elements |
[scoring-calc-category, scoring-calc-category, ...] | Returns a HTMLCollection of all children html elements of the parent scoring-calc html element | |
score | dvsc.score |
58.61188808308917 | Returns the total current score | |
Method | Usage | Example Output | Definition | |
dump | dvsc.dump() |
{elements: HTMLCollection(5), categoryCount: 5, categoryNumbers: Array(5), …} | Returns a Object with every property and its values |
In React the configuration is contained by an object and passed to the component via the config property
This is an example on how the implementation in React would look like:*
* This example would only work with an installed npm version of react. The source code of this
demo page uses the CDN version of React and is therefore adjusted
import React from "react";
import DynamicVisualScoringCalculator from "./DynamicVisualScoringCalculator";
function MyComponent() {
let DVSC = {
categoryBias : [0,0,0,0,0],
categoryColors: ["#FF1D15", "#0075FF", "#61E786", "#ffbb00", "#AA3E98", "#AA3E98", "#34F6F2"], // define the circle colors
categoryCount: 5,// number of category
categoryDirections: [-1, 1, 1, -1, -1],// 1: data point > target value; -1: data point < target value
categoryEvaluations: ["lin", "quad", "quad", "linear", "cube"], // how should the score of a category be calculated
categoryGrains: [15, 5, 5, 40,10],// fine tune to the acceptable difference between data point and target value
categoryNames: ["Menu", "Cost", "Waiting Time", "Ambiance", "Taste"],//category title to display
categoryNumbers: [0,1,2,3,4],
categoryScores: [500,500,500,500,500],
categorySteps: [10, 0.01, 1, 10, 1],//how big on step on the slider should be
categoryTargets: [100, 15, 5, 100, 100],// target value to which a data Point in the data set should converge
categoryUnits: ["%", "€", "min", "%","%"],// category unit to display
categoryValues: [70,12,5,60,80],
categoryWeights: [20.00, 20.00, 20.00, 20.00,20.00], // presets
};
return (<DynamicVisualScoringCalculator config={DVSC} />);
}
export default MyComponent;
To calculate a single categoryScore, the main principle is the difference between the categoryTarget and the actual categoryValue. Things to note for the user adjustable properties are as follows:
The categoryValue can not be dynamically adjusted by the front end user, because it is a measured value in open world.
The categoryTarget is adjustable, with the min or max value
automatically being set to the categoryValue.
Should the categoryValue>=
categoryTarget, then the
categoryDirection should be set to 1
.
(E.g. the category goal is it to optimize the measured process for as little time as possible).
If set correctly the categoryTarget cannot be set bigger than the
categoryValue.
The Result is the adjustable categoryTarget will automatically stop at
max =
categoryValue.
Now The other way around: Should the categoryValue <=
categoryTarget, then the categoryDirection should be set to
-1
.
(E.g. the category goal is it to optimize the measured process for the hightest efficiency
possible).
If set correctly the categoryTarget cannot be set smaller than the
categoryValue.
The Result is the adjustable categoryTarget will automatically stop at min
=
categoryValue.
The min and max values for the range sliders are estimated with the
following assumption:
if the categoryUnit is "%":
Depending on the categoryDirection the min is set to "0" or max is set to "100"
if the categoryUnit is not "%":
Lets say our value should always be larger than our categoryTarget, so
therefore the categoryDirection is "1". This also already defines the
max value to categoryValue.
The min value is then "guessed" by calculating
This changes when the categoryValue is lower than the
categoryTarget, so therefore the categoryDirection is "-1". Since
we already know the min value, which is the categoryValue, only
the max value needs to be calculated.
The categoryBias is adjustable, with the categoryBias accepting any
Integer between -5 and 5.
If the categoryBias is grater than 0, the category will experience a favored
rating method and therefore giving it a better score.
If the categoryBias is smaller than 0, the category will experience a
unfavored rating method and therefore giving it a lower score.
Once the categoryBias reaches the upper or lower limit the score tries to be the as
close to the hightest or lowest score possible, this beeing 1000/1000 or
0/1000
The categoryWeight can be adjusted, which affects the overall score, but not the individual categoryScore! When adjusting one categoryWeight all the other Weights will adjust accordingly, so all percentages added up together will always be 100%.
For ease of use the lowest individual categoryWeight is 0.01 %. This ensures, that no
single categoryWeight will be stuck at 0%.
Due to the nature of using linear Algebra (more specific Matrix
calculations) for calculation the weights. Depending on the number of categories, if one
category reaches 0% it will stay at 0% and the other weight will compensate, which is an
unwanted effect
To avoid errors don't leave the categoryWeight value empty, and instead set a
preset.
Things to note for the static properties are as follows:
These are functions, which act as the base for all the evaluation methods.
Default Evaluation:
valid values are "def" or "default"Linear Evaluation:
valid values are "lin" or "linear"Quadratic Evaluation:
valid values are "quad" or "quadratic"Cubic Evaluation:
valid values are "cube" or "cubic"