Skip to content

Commit 91297dd

Browse files
committed
Add smart sort for value column
Fixes #60
1 parent 6322900 commit 91297dd

File tree

2 files changed

+126
-2
lines changed

2 files changed

+126
-2
lines changed

InteractiveHtmlBom/ibom.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,7 @@ function populateBomHeader() {
289289
}
290290
}
291291
tr.appendChild(createColumnHeader("Value", "Value", (a, b) => {
292-
if (a[1] != b[1]) return a[1] > b[1] ? 1 : -1;
293-
else return 0;
292+
return valueCompare(a[5], b[5], a[1], b[1]);
294293
}));
295294
tr.appendChild(createColumnHeader("Footprint", "Footprint", (a, b) => {
296295
if (a[2] != b[2]) return a[2] > b[2] ? 1 : -1;
@@ -747,6 +746,7 @@ function initDefaults() {
747746
}
748747

749748
window.onload = function(e) {
749+
initUtils();
750750
initRender();
751751
initStorage();
752752
initDefaults();

InteractiveHtmlBom/util.js

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,127 @@ function cleanGutters() {
129129
removeGutterNode(document.getElementById("bot"));
130130
removeGutterNode(document.getElementById("canvasdiv"));
131131
}
132+
133+
var units = {
134+
prefixes: {
135+
giga: ["G", "g", "giga", "Giga", "GIGA"],
136+
mega: ["M", "mega", "Mega", "MEGA"],
137+
kilo: ["K", "k", "kilo", "Kilo", "KILO"],
138+
milli: ["m", "milli", "Milli", "MILLI"],
139+
micro: ["U", "u", "micro", "Micro", "MICRO", "μ", "µ"], // different utf8 μ
140+
nano: ["N", "n", "nano", "Nano", "NANO"],
141+
pico: ["P", "p", "pico", "Pico", "PICO"],
142+
},
143+
unitsShort: ["R", "r", "Ω", "F", "f", "H", "h"],
144+
unitsLong: [
145+
"OHM", "Ohm", "ohm", "ohms",
146+
"FARAD", "Farad", "farad",
147+
"HENRY", "Henry", "henry"
148+
],
149+
getMultiplier: function(s) {
150+
if (this.prefixes.giga.includes(s)) return 1e9;
151+
if (this.prefixes.mega.includes(s)) return 1e6;
152+
if (this.prefixes.kilo.includes(s)) return 1e3;
153+
if (this.prefixes.milli.includes(s)) return 1e-3;
154+
if (this.prefixes.micro.includes(s)) return 1e-6;
155+
if (this.prefixes.nano.includes(s)) return 1e-9;
156+
if (this.prefixes.pico.includes(s)) return 1e-12;
157+
return 1;
158+
},
159+
valueRegex: null,
160+
}
161+
162+
function initUtils() {
163+
var allPrefixes = units.prefixes.giga
164+
.concat(units.prefixes.mega)
165+
.concat(units.prefixes.kilo)
166+
.concat(units.prefixes.milli)
167+
.concat(units.prefixes.micro)
168+
.concat(units.prefixes.nano)
169+
.concat(units.prefixes.pico);
170+
var allUnits = units.unitsShort.concat(units.unitsLong);
171+
units.valueRegex = new RegExp("^([0-9\.]+)" +
172+
"\\s*(" + allPrefixes.join("|") + ")?" +
173+
"(" + allUnits.join("|") + ")?" +
174+
"(\\b.*)?$", "");
175+
units.valueAltRegex = new RegExp("^([0-9]*)" +
176+
"(" + units.unitsShort.join("|") + ")?" +
177+
"([GgMmKkUuNnPp])?" +
178+
"([0-9]*)" +
179+
"(\\b.*)?$", "");
180+
for (var bomtable of Object.values(pcbdata.bom)) {
181+
for (var row of bomtable) {
182+
row.push(parseValue(row[1], row[3][0][0]));
183+
}
184+
}
185+
}
186+
187+
function parseValue(val, ref) {
188+
var inferUnit = (unit, ref) => {
189+
if (unit) {
190+
unit = unit.toLowerCase();
191+
if (unit == 'Ω' || unit == "ohm" || unit == "ohms") {
192+
unit = 'r';
193+
}
194+
unit = unit[0];
195+
} else {
196+
ref = /^([a-z]+)\d+$/i.exec(ref);
197+
if (ref) {
198+
ref = ref[1].toLowerCase();
199+
if (ref == "c") unit = 'f';
200+
else if (ref == "l") unit = 'h';
201+
else if (ref == "r" || ref == "rv") unit = 'r';
202+
else unit = null;
203+
}
204+
}
205+
return unit;
206+
};
207+
val = val.replace(/,/g, "");
208+
var match = units.valueRegex.exec(val);
209+
var unit;
210+
if (match) {
211+
val = parseFloat(match[1]);
212+
if (match[2]) {
213+
val = val * units.getMultiplier(match[2]);
214+
}
215+
unit = inferUnit(match[3], ref);
216+
if (!unit) return null;
217+
else return {
218+
val: val,
219+
unit: unit,
220+
extra: match[4],
221+
}
222+
}
223+
match = units.valueAltRegex.exec(val);
224+
if (match && (match[1] || match[4])) {
225+
val = parseFloat(match[1] + "." + match[4]);
226+
if (match[3]) {
227+
val = val * units.getMultiplier(match[3]);
228+
}
229+
unit = inferUnit(match[2], ref);
230+
if (!unit) return null;
231+
else return {
232+
val: val,
233+
unit: unit,
234+
extra: match[5],
235+
}
236+
}
237+
return null;
238+
}
239+
240+
function valueCompare(a, b, stra, strb) {
241+
if (a === null && b === null) {
242+
// Failed to parse both values, compare them as strings.
243+
if (stra != strb) return stra > strb ? 1 : -1;
244+
else return 0;
245+
} else if (a === null) {
246+
return 1;
247+
} else if (b === null) {
248+
return -1;
249+
} else {
250+
if (a.unit != b.unit) return a.unit > b.unit ? 1 : -1;
251+
else if (a.val != b.val) return a.val > b.val ? 1 : -1;
252+
else if (a.extra != b.extra) return a.extra > b.extra ? 1 : -1;
253+
else return 0;
254+
}
255+
}

0 commit comments

Comments
 (0)