Skip to content

Commit

Permalink
Add board stats, checkbox progress bars
Browse files Browse the repository at this point in the history
Fixes #77
  • Loading branch information
qu1ck committed Jul 5, 2019
1 parent 872cdf4 commit a58b405
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 2 deletions.
48 changes: 47 additions & 1 deletion InteractiveHtmlBom/web/ibom.css
Original file line number Diff line number Diff line change
Expand Up @@ -398,13 +398,59 @@ mark.highlight {

.menubtn {
background-color: white;
font-size: 16px;
border: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36' viewBox='0 0 20 20'%3E%3Cpath fill='none' d='M0 0h20v20H0V0z'/%3E%3Cpath d='M15.95 10.78c.03-.25.05-.51.05-.78s-.02-.53-.06-.78l1.69-1.32c.15-.12.19-.34.1-.51l-1.6-2.77c-.1-.18-.31-.24-.49-.18l-1.99.8c-.42-.32-.86-.58-1.35-.78L12 2.34c-.03-.2-.2-.34-.4-.34H8.4c-.2 0-.36.14-.39.34l-.3 2.12c-.49.2-.94.47-1.35.78l-1.99-.8c-.18-.07-.39 0-.49.18l-1.6 2.77c-.1.18-.06.39.1.51l1.69 1.32c-.04.25-.07.52-.07.78s.02.53.06.78L2.37 12.1c-.15.12-.19.34-.1.51l1.6 2.77c.1.18.31.24.49.18l1.99-.8c.42.32.86.58 1.35.78l.3 2.12c.04.2.2.34.4.34h3.2c.2 0 .37-.14.39-.34l.3-2.12c.49-.2.94-.47 1.35-.78l1.99.8c.18.07.39 0 .49-.18l1.6-2.77c.1-.18.06-.39-.1-.51l-1.67-1.32zM10 13c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z'/%3E%3C/svg%3E%0A");
background-position: center;
background-repeat: no-repeat;
}

.statsbtn {
background-color: white;
border: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 9.52 9.53'%3E%3Cg fill='none' stroke-width='.53'%3E%3Cpath d='M.8.8h7.4v7.67H.8z' stroke='%23666'/%3E%3Cpath d='M8.73 1.06V9H1.06' stroke='%23ccc'/%3E%3Cpath d='M1.85 2.12H3.7M4.5 2.12h1.06M6.09 2.12h1.05M1.85 3.44H3.7M4.5 3.44h1.06M6.09 3.44h1.05M1.85 5.3h1.33M1.85 6.88h1.32M3.97 6.88H6.6M3.97 5.3h3.17' stroke='%23000'/%3E%3C/g%3E%3C/svg%3E");
background-position: center;
background-repeat: no-repeat;
}

.dark .statsbtn {
filter: invert(1);
}

.stats {
border-collapse: collapse;
font-size: 12pt;
table-layout: fixed;
width: 100%;
min-width: 450px;
}

.dark .stats td {
border: 1px solid #bbb;
}

.stats td {
border: 1px solid black;
padding: 5px;
word-wrap: break-word;
text-align: center;
position: relative;
}

#checkbox-stats div {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}

#checkbox-stats .bar {
background-color: rgba(28, 251, 0, 0.6);
}

.dark .menubtn {
filter: invert(1);
}
Expand Down
45 changes: 45 additions & 0 deletions InteractiveHtmlBom/web/ibom.html
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,51 @@
<button id="tb-btn" class="right-most-button" onclick="changeBomLayout('top-bottom')"
title="BOM top, drawings bot"></button>
</div>
<div class="hideonprint menu" style="float: right; margin: 10px; top: 8px;">
<button class="statsbtn"></button>
<div class="menu-content">
<table class="stats">
<tbody>
<tr>
<td width="40%">Board stats</td>
<td>Front</td>
<td>Back</td>
<td>Total</td>
</tr>
<tr>
<td>Components</td>
<td id="stats-components-front">~</td>
<td id="stats-components-back">~</td>
<td id="stats-components-total">~</td>
</tr>
<tr>
<td>Groups</td>
<td id="stats-groups-front">~</td>
<td id="stats-groups-back">~</td>
<td id="stats-groups-total">~</td>
</tr>
<tr>
<td>SMD pads</td>
<td id="stats-smd-pads-front">~</td>
<td id="stats-smd-pads-back">~</td>
<td id="stats-smd-pads-total">~</td>
</tr>
<tr>
<td>TH pads</td>
<td colspan=3 id="stats-th-pads">~</td>
</tr>
</tbody>
</table>
<table class="stats">
<col width="40%"/><col />
<tbody id="checkbox-stats">
<tr>
<td colspan=2 style="border-top: 0">Checkboxes</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="fileinfodiv" style="overflow: auto;">
<table class="fileinfo">
Expand Down
75 changes: 74 additions & 1 deletion InteractiveHtmlBom/web/ibom.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ function createCheckboxChangeHandler(checkbox, references) {
}
}
writeStorage("checkbox_" + checkbox, [...refsSet].join(","));
updateCheckboxStats(checkbox);
}
}

Expand Down Expand Up @@ -300,7 +301,6 @@ function populateBomHeader() {
var th = document.createElement("TH");
th.classList.add("numCol");
tr.appendChild(th);
checkboxes = bomCheckboxes.split(",").filter((e) => e);
var checkboxCompareClosure = function(checkbox) {
return (a, b) => {
var stateA = getCheckboxState(checkbox, a[3]);
Expand Down Expand Up @@ -548,6 +548,38 @@ function populateMetadata() {
if (pcbdata.metadata.title != "") {
document.title = pcbdata.metadata.title + " BOM";
}
var fp_f = 0, fp_b = 0, pads_f = 0, pads_b = 0, pads_th = 0;
for (var i = 0; i < pcbdata.modules.length; i++) {
if (pcbdata.bom.skipped.includes(i)) continue;
var mod = pcbdata.modules[i];
if (mod.layer == "F") {
fp_f++;
} else {
fp_b++;
}
for (var pad of mod.pads) {
if (pad.type == "th") {
pads_th++;
} else {
if (pad.layers.includes("F")) {
pads_f++;
}
if (pad.layers.includes("B")) {
pads_b++;
}
}
}
}
document.getElementById("stats-components-front").innerHTML = fp_f;
document.getElementById("stats-components-back").innerHTML = fp_b;
document.getElementById("stats-components-total").innerHTML = fp_f + fp_b;
document.getElementById("stats-groups-front").innerHTML = pcbdata.bom.F.length;
document.getElementById("stats-groups-back").innerHTML = pcbdata.bom.B.length;
document.getElementById("stats-groups-total").innerHTML = pcbdata.bom.both.length;
document.getElementById("stats-smd-pads-front").innerHTML = pads_f;
document.getElementById("stats-smd-pads-back").innerHTML = pads_b;
document.getElementById("stats-smd-pads-total").innerHTML = pads_f + pads_b;
document.getElementById("stats-th-pads").innerHTML = pads_th;
}

function changeBomLayout(layout) {
Expand Down Expand Up @@ -664,9 +696,49 @@ function checkBomCheckbox(bomrowid, checkboxname) {
function setBomCheckboxes(value) {
bomCheckboxes = value;
writeStorage("bomCheckboxes", value);
prepCheckboxes();
populateBomTable();
}

function prepCheckboxes() {
checkboxes = bomCheckboxes.split(",").filter((e) => e);
var table = document.getElementById("checkbox-stats");
while (table.childElementCount > 1) {
table.removeChild(table.lastChild);
}
if (checkboxes.length) {
table.style.display = "";
} else {
table.style.display = "none";
}
for (var checkbox of checkboxes) {
var tr = document.createElement("TR");
var td = document.createElement("TD");
td.innerHTML = checkbox;
tr.appendChild(td);
td = document.createElement("TD");
td.id = "checkbox-stats-" + checkbox;
var progressbar = document.createElement("div");
progressbar.classList.add("bar");
td.appendChild(progressbar);
var text = document.createElement("div");
text.classList.add("text");
td.appendChild(text);
tr.appendChild(td);
table.appendChild(tr);
updateCheckboxStats(checkbox);
}
}

function updateCheckboxStats(checkbox) {
var checked = getStoredCheckboxRefs(checkbox).size;
var total = pcbdata.modules.length - pcbdata.bom.skipped.length;
var percent = checked * 100.0 / total;
var td = document.getElementById("checkbox-stats-" + checkbox);
td.firstChild.style.width = percent + "%";
td.lastChild.innerHTML = checked + "/" + total + " (" + Math.round(percent) + "%)";
}

document.onkeydown = function(e) {
switch (e.key) {
case "n":
Expand Down Expand Up @@ -820,6 +892,7 @@ window.onload = function(e) {
filter = "";
reflookup = "";
initDone = true;
prepCheckboxes();
// Triggers render
changeBomLayout(bomlayout);
}
Expand Down
7 changes: 7 additions & 0 deletions icons/stats-36px.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

9 comments on commit a58b405

@Gasman2014
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to break the component list output on my machine. The previous committed version works perfectly but this version produces an empty bom. Safari/macOS

a58b405 CURRENT
Screen Shot 2019-07-06 at 11 51 41

872cdf4 PREVIOUS
Screen Shot 2019-07-06 at 11 47 52

@qu1ck
Copy link
Member Author

@qu1ck qu1ck commented on a58b405 Jul 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you copy any errors from JS console? Or share your project?

@Gasman2014
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TypeError: undefined is not an object (evaluating 'pcbdata.bom.skipped.includes')

2271 if (pcbdata.bom.skipped.includes(i)) continue;

@qu1ck
Copy link
Member Author

@qu1ck qu1ck commented on a58b405 Jul 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, that's strange. I will have to see the generated html or the pcb to debug.

@Gasman2014
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Project archive (zipped) and generated html (zipped) fyi. I don't think that the project is anything particularly odd - it is just a WeMos shield. The footprints are standard - the only difference is that there are some extra fields
Description
Characteristics
Package_ID
Placement
Part#
I have simply achieved the whole project from within Kicad - so there are quite a lot of extra directories etc.

PostBox BOM.zip
PostBox.zip

@qu1ck
Copy link
Member Author

@qu1ck qu1ck commented on a58b405 Jul 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot repro with your project, I get working output. Btw there is only one extra field Part#, did you attach wrong version of your project?

Looking at bom from your zip it is very weird. It's like the pcbdata portion was generated with older version while the rest of the page (code, html, etc) is from new one. Like I said, I can't get the same result.
If this reproduces for you can you tell me exact settings you use to generate the bom?

@qu1ck
Copy link
Member Author

@qu1ck qu1ck commented on a58b405 Jul 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One potential reason for this issue could be a unclean update to new version of the plugin. Some files were moved around since v2.1, if you just overwrote the folder old files could stay in place and mess up plugin logic. Make sure you delete everything (except config.ini if you want to preserve settings) before dropping in v2.2.

@Gasman2014
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just rechecked and the other fields are added to eeschema but only the Part# field has any content so the others are suppressed.

I think I must have failed to purge the .pyc file from the plugin directory. When I checked out the new version I think I must have left the .pyc in place. I have symlinked the working directory to the plugin directory to make it easier to update.

I have recloned the repo and it now works. Since I could see the newly added table stuff in the generated webpage, I thought I must have updated correctly but there was an issue with the code. Sorry for the noise.

I must have a look at git clean options to see if I can automate .pyc purging.

@qu1ck
Copy link
Member Author

@qu1ck qu1ck commented on a58b405 Jul 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git clean -fdx will remove ignored .pyc files and anything else untracked. But it will remove config.ini too. If you want to preserve that it might be easier to just find . -name '*.pyc' -exec rm {} +

Please sign in to comment.