+ return element;
+}
+
+function add_3cell_ci(tr, ci) {
+ console.log(ci);
+ if (isNaN(ci.val)) {
+ add_3cell(tr, 'N/A');
+ return; // FIXME: some SVG padding needed
+ }
+ let element = add_3cell(tr, ci.val.toFixed(2));
+ let to_x = (val) => { return width * (val - ci.min) / (ci.max - ci.min); };
+
+ // Container.
+ const width = 100;
+ const height = 20;
+ let svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+ svg.classList.add('ci');
+ svg.setAttribute('width', width);
+ svg.setAttribute('height', height);
+
+ // The good (green) and red (bad) ranges.
+ let s0 = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+ s0.classList.add('range');
+ s0.classList.add('s0');
+ s0.setAttribute('width', to_x(ci.desired));
+ s0.setAttribute('height', height);
+ s0.setAttribute('x', '0');
+
+ let s1 = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+ s1.classList.add('range');
+ s1.classList.add('s1');
+ s1.setAttribute('width', width - to_x(ci.desired));
+ s1.setAttribute('height', height);
+ s1.setAttribute('x', to_x(ci.desired));
+
+ // Confidence bar.
+ let bar = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+ bar.classList.add('bar');
+ bar.setAttribute('width', to_x(ci.upper_ci) - to_x(ci.lower_ci));
+ bar.setAttribute('height', height / 3);
+ bar.setAttribute('x', to_x(ci.lower_ci));
+ bar.setAttribute('y', height / 3);
+
+ // Marker line for average.
+ let marker = document.createElementNS('http://www.w3.org/2000/svg', 'line');
+ marker.classList.add('marker');
+ marker.setAttribute('x1', to_x(ci.val));
+ marker.setAttribute('x2', to_x(ci.val));
+ marker.setAttribute('y1', height / 6);
+ marker.setAttribute('y2', height * 5 / 6);
+
+ svg.appendChild(s0);
+ svg.appendChild(s1);
+ svg.appendChild(bar);
+ svg.appendChild(marker);
+
+ element.appendChild(svg);