improve questionnaire rendering

This commit is contained in:
Grahame Grieve 2021-06-16 12:15:03 +10:00
parent a777ab53a8
commit 45801c1918
3 changed files with 97 additions and 3 deletions

View File

@ -0,0 +1,14 @@
Validator:
* Add support for $index on aggregators in FHIRPath
* don't fail with an exception if an unknown resource type appears in contained resource
* improved validation for some value sets that are based on unknown code systems
* add the -verbose parameter, and add additional verbose messages
Other code changes:
* Fix rendering of slices so type on slicer is not hidden
* Fix rendering for most resources - remove empty tables (e.g. text element, that shouldn't render)
* Fix NPE rendering code systems with some kinds of properties
* Improve rendering of questionnaires (icons, option sets)

View File

@ -14,6 +14,7 @@ import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Expression;
import org.hl7.fhir.r5.model.Extension;
import org.hl7.fhir.r5.model.PrimitiveType;
import org.hl7.fhir.r5.model.Questionnaire;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
@ -60,7 +61,11 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
public boolean renderTree(XhtmlNode x, Questionnaire q) throws UnsupportedEncodingException, IOException {
boolean hasFlags = checkForFlags(q.getItem());
boolean doOpts = context.getDefinitionsTarget() == null && hasAnyOptions(q.getItem());
if (doOpts) {
x.b().tx("Structure");
}
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(context.getDestDir(), context.isInlineGraphics(), true);
TableModel model = gen.new TableModel("qtree="+q.getId(), !forResource);
model.setAlternating(true);
@ -83,9 +88,79 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
}
XhtmlNode xn = gen.generate(model, context.getLocalPrefix(), 1, null);
x.getChildNodes().add(xn);
if (doOpts) {
renderOptions(q, x);
}
return hasExt;
}
private void renderOptions(Questionnaire q, XhtmlNode x) {
if (hasAnyOptions(q.getItem())) {
x.hr();
x.para().b().tx("Option Sets");
renderOptions(q.getItem(), x);
}
}
private void renderOptions(List<QuestionnaireItemComponent> items, XhtmlNode x) {
for (QuestionnaireItemComponent i : items) {
renderItemOptions(x, i);
renderOptions(i.getItem(), x);
}
}
public void renderItemOptions(XhtmlNode x, QuestionnaireItemComponent i) {
if (i.hasAnswerOption()) {
boolean useSelect = false;
for (QuestionnaireItemAnswerOptionComponent opt : i.getAnswerOption()) {
useSelect = useSelect || opt.getInitialSelected();
}
x.an("opt-item."+i.getLinkId());
x.para().b().tx("Answer options for "+i.getLinkId());
XhtmlNode ul = x.ul();
for (QuestionnaireItemAnswerOptionComponent opt : i.getAnswerOption()) {
XhtmlNode li = ul.li();
li.style("font-size: 11px");
if (useSelect) {
if (opt.getInitialSelected()) {
li.img("icon-selected.png");
} else {
li.img("icon-not-selected.png");
}
}
if (opt.getValue().isPrimitive()) {
li.tx(opt.getValue().primitiveValue());
} else if (opt.getValue() instanceof Coding) {
Coding c = (Coding) opt.getValue();
String link = context.getWorker().getLinkForUrl(context.getSpecificationLink(), c.getSystem());
if (link == null) {
li.tx(c.getSystem()+"#"+c.getCode());
} else {
li.ah(link).tx(describeSystem(c.getSystem()));
li.tx(": "+c.getCode());
}
if (c.hasDisplay()) {
li.tx(" (\""+c.getDisplay()+"\")");
}
} else {
li.tx("??");
}
}
}
}
private boolean hasAnyOptions(List<QuestionnaireItemComponent> items) {
for (QuestionnaireItemComponent i : items) {
if (i.hasAnswerOption()) {
return true;
}
if (hasAnyOptions(i.getItem())) {
return true;
}
}
return false;
}
private boolean checkForFlags(List<QuestionnaireItemComponent> items) {
for (QuestionnaireItemComponent i : items) {
if (checkForFlags(i)) {
@ -228,7 +303,12 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
if (i.hasAnswerOption()) {
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
defn.getPieces().add(gen.new Piece(null, "Options: ", null));
defn.getPieces().add(gen.new Piece(context.getDefinitionsTarget()+"#item."+i.getLinkId(), Integer.toString(i.getAnswerOption().size())+" "+Utilities.pluralize("option", i.getAnswerOption().size()), null));
if (context.getDefinitionsTarget() == null) {
// if we don't have a definitions target, we'll add them below.
defn.getPieces().add(gen.new Piece("#opt-item."+i.getLinkId(), Integer.toString(i.getAnswerOption().size())+" "+Utilities.pluralize("option", i.getAnswerOption().size()), null));
} else {
defn.getPieces().add(gen.new Piece(context.getDefinitionsTarget()+"#item."+i.getLinkId(), Integer.toString(i.getAnswerOption().size())+" "+Utilities.pluralize("option", i.getAnswerOption().size()), null));
}
}
if (i.hasInitial()) {
for (QuestionnaireItemInitialComponent v : i.getInitial()) {
@ -725,7 +805,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
}
}
} else if (i.hasAnswerOption()) {
renderItemOptions(select, i);
}
select.option("a", "??", false);
}

View File

@ -19,7 +19,7 @@
<properties>
<hapi_fhir_version>5.1.0</hapi_fhir_version>
<validator_test_case_version>1.1.64</validator_test_case_version>
<validator_test_case_version>1.1.65-SNAPSHOT</validator_test_case_version>
<junit_jupiter_version>5.7.1</junit_jupiter_version>
<junit_platform_launcher_version>1.7.1</junit_platform_launcher_version>
<maven_surefire_version>3.0.0-M4</maven_surefire_version>