Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,11 @@ public Map<String, Obs> getLatestObservationsForConcept(
public List<Chart> getCharts(String uuid) {
Map<Long, ChartSection> tileGroupsById = new HashMap<>();
Map<Long, ChartSection> rowGroupsById = new HashMap<>();
List<Chart> Charts = new ArrayList<>();
List<Chart> charts = new ArrayList<>();
Chart currentChart = null;

LOG.start("ChartDataHelper.getCharts");

try (Cursor c = mContentResolver.query(
ChartItems.CONTENT_URI, null,
ChartItems.CHART_UUID + " = ?", new String[] {uuid}, "weight")) {
Expand All @@ -322,7 +324,7 @@ public List<Chart> getCharts(String uuid) {
if ((currentChart != null) &&
((currentChart.tileGroups.size() != 0)
|| (currentChart.rowGroups.size() != 0))) {
Charts.add(currentChart);
charts.add(currentChart);
}
break;
case "TILE_ROW":
Expand Down Expand Up @@ -361,8 +363,10 @@ public List<Chart> getCharts(String uuid) {
}
}
}
Charts.add(currentChart);
return Charts;

LOG.finish("ChartDataHelper.getCharts");
charts.add(currentChart);
return charts;
}

public List<Form> getForms() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
Expand All @@ -64,14 +65,18 @@ public class ChartRenderer {
private static final Logger LOG = Logger.create();
private static final ExecutionHistory EMPTY_HISTORY = new ExecutionHistory();

private WebView mView; // view into which the HTML table will be rendered
private Resources mResources; // resources used for localizing the rendering
private Resources mResources;
private AppSettings mSettings;

private List<Obs> mLastRenderedObs; // last set of observations rendered
private List<Order> mLastRenderedOrders; // last set of orders rendered
private int mLastRenderedZoomIndex; // last zoom level index rendered
private String mLastChartName = "";
private int mLastZoomIndex; // last zoom level index rendered
private String mLastChartName = ""; // last selected chart rendered
private List<Obs> mLastObservations; // last set of observations rendered
private List<Order> mLastOrders; // last set of orders rendered
private LocalDate mLastAdmissionDate; // last admission date rendered
private LocalDate mLastFirstSymptomsDate; // last first-symptoms date rendered

private String mLastHtml = null; // last HTML output of renderer
private WebView mLastView = null; // last WebView that was rendered into

public interface JsInterface {
@JavascriptInterface void onNewOrderPressed();
Expand All @@ -85,77 +90,88 @@ public interface JsInterface {
@JavascriptInterface void onPageUnload(int scrollX, int scrollY);
}

public ChartRenderer(WebView view, Resources resources, AppSettings settings) {
mView = view;
public ChartRenderer(Resources resources, AppSettings settings) {
mResources = resources;
mSettings = settings;
mView.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
mView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
mView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}

/** Renders a patient's history of observations to an HTML table in the WebView. */
// TODO/cleanup: Have this take the types that getObservations and getLatestObservations return.
public void render(Chart chart, Map<String, Obs> latestObservations,
public void render(WebView view, Chart chart, Map<String, Obs> latestObservations,
List<Obs> observations, List<Order> orders,
LocalDate admissionDate, LocalDate firstSymptomsDate,
JsInterface controllerInterface) {
if (chart == null) {
mView.loadUrl("file:///android_asset/no_chart.html");
view.loadUrl("file:///android_asset/no_chart.html");
return;
}

String html;
LOG.i("Rendering %d observations, %d orders, zoom index %d", observations.size(), orders.size(), mSettings.getChartZoomIndex());
if (mLastChartName.equals(chart.name) &&
mLastRenderedZoomIndex == mSettings.getChartZoomIndex() &&
observations.equals(mLastRenderedObs) &&
orders.equals(mLastRenderedOrders)) {
LOG.i("Data and zoom index have not changed; skipping render");
return;
LOG.start("render");
if (mSettings.getChartZoomIndex() == mLastZoomIndex &&
Objects.equals(chart.name, mLastChartName) &&
Objects.equals(observations, mLastObservations) &&
Objects.equals(orders, mLastOrders) &&
Objects.equals(admissionDate, mLastAdmissionDate) &&
Objects.equals(firstSymptomsDate, mLastFirstSymptomsDate) &&
mLastHtml != null) {
LOG.i("Data and zoom index have not changed; skipping HTML generation");
html = mLastHtml;
} else {
html = new GridHtmlGenerator(
chart, latestObservations, observations, orders,
admissionDate, firstSymptomsDate).getHtml();
LOG.elapsed("render", "HTML generated");
}

LOG.start("render");
if (view != mLastView) {
view.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
view.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
view.getSettings().setJavaScriptEnabled(true);
view.setWebChromeClient(new WebChromeClient());
}

// setDefaultFontSize is supposed to take a size in sp, but in practice
// the fonts don't change size when the user font size preference changes.
// So, we apply the scaling factor explicitly, defining 1 em to be 10 sp.
DisplayMetrics metrics = mResources.getDisplayMetrics();
float defaultFontSize = 10*metrics.scaledDensity/metrics.density;
mView.getSettings().setDefaultFontSize((int) defaultFontSize);

mView.getSettings().setJavaScriptEnabled(true);
mView.addJavascriptInterface(controllerInterface, "controller");
mView.setWebChromeClient(new WebChromeClient());
String html = new GridHtmlGenerator(
chart, latestObservations, observations, orders,
admissionDate, firstSymptomsDate).getHtml();

LOG.elapsed("render", "HTML generated");
float defaultFontSize = 10 * metrics.scaledDensity / metrics.density;
view.getSettings().setDefaultFontSize((int) defaultFontSize);
view.removeJavascriptInterface("controller");
view.addJavascriptInterface(controllerInterface, "controller");
LOG.elapsed("render", "WebView configured");

if (view == mLastView && html.equals(mLastHtml)) {
LOG.i("HTML and view are unchanged; skipping page load");
LOG.finish("render");
return;
}

// To avoid showing stale, possibly misleading data from a previous
// patient, clear out any previous chart HTML before showing the WebView.
mView.loadUrl("about:blank");
mView.clearView();
mView.setVisibility(View.VISIBLE);
mView.loadDataWithBaseURL(
view.loadUrl("about:blank");
view.clearView();
view.setVisibility(View.VISIBLE);
view.loadDataWithBaseURL(
"file:///android_asset/", html, "text/html; charset=utf-8", "utf-8", null);
mView.setWebContentsDebuggingEnabled(true);
view.setWebContentsDebuggingEnabled(true);

LOG.finish("render", "HTML loaded into WebView");
LOG.elapsed("render", "HTML page loaded into WebView");

mLastZoomIndex = mSettings.getChartZoomIndex();
mLastChartName = chart.name;
mLastRenderedZoomIndex = mSettings.getChartZoomIndex();
mLastRenderedObs = observations;
mLastRenderedOrders = orders;
mLastObservations = observations;
mLastOrders = orders;
mLastAdmissionDate = admissionDate;
mLastFirstSymptomsDate = firstSymptomsDate;
mLastHtml = html;
mLastView = view;

LOG.start("ChartJS");
}

/** Gets the starting times (in ms) of the segments into which the day is divided. */
public int[] getSegmentStartTimes() {
int index = mSettings.getChartZoomIndex();
return Utils.safeIndex(ZOOM_LEVELS, index).segmentStartTimes;
}

class GridHtmlGenerator {
List<Order> mOrders;
DateTime mNow;
Expand Down Expand Up @@ -254,6 +270,12 @@ void addOrders(List<Order> orders) {
}
}

/** Gets the starting times (in ms) of the segments into which the day is divided. */
public int[] getSegmentStartTimes() {
int index = mSettings.getChartZoomIndex();
return Utils.safeIndex(ZOOM_LEVELS, index).segmentStartTimes;
}

/** Gets the n + 1 boundaries of the n segments of a specific day. */
public DateTime[] getSegmentFenceposts(LocalDate date) {
DateTime start = date.toDateTimeAtStartOfDay();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ public final class PatientChartActivity extends BaseLoggedInActivity {
private boolean mIsFetchingXform = false;
private ProgressDialog mFormLoadingDialog;
private ProgressDialog mFormSubmissionDialog;
private ChartRenderer mChartRenderer;
private ProgressDialog mProgressDialog;
private DatePickerDialog mAdmissionDateDialog;
private DatePickerDialog mSymptomOnsetDateDialog;
Expand All @@ -114,8 +113,9 @@ public final class PatientChartActivity extends BaseLoggedInActivity {
@InjectView(R.id.attribute_symptoms_onset_days) PatientAttributeView mSymptomOnsetDaysView;
@InjectView(R.id.attribute_pcr) PatientAttributeView mPcr;
@InjectView(R.id.patient_chart_pregnant) TextView mPatientPregnantOrIvView;
@InjectView(R.id.chart_webview) WebView mGridWebView;
@InjectView(R.id.chart_webview) WebView mWebView;

private static ChartRenderer sChartRenderer;
private static final String EN_DASH = "\u2013";

public static void start(Context caller, String uuid) {
Expand Down Expand Up @@ -206,7 +206,7 @@ public static void start(Context caller, String uuid) {
R.string.symptoms_onset_date_picker_title, ConceptUuids.FIRST_SYMPTOM_DATE_UUID);

// Remembering scroll position and applying it after the chart finished loading.
mGridWebView.setWebViewClient(new WebViewClient() {
mWebView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
Point scrollPosition = mController.getLastScrollPosition();
if (scrollPosition != null) {
Expand All @@ -215,7 +215,10 @@ public void onPageFinished(WebView view, String url) {
}
}
});
mChartRenderer = new ChartRenderer(mGridWebView, getResources(), mSettings);

if (sChartRenderer == null) {
sChartRenderer = new ChartRenderer(getResources(), mSettings);
}

final OdkResultSender odkResultSender = new OdkResultSender() {
@Override public void sendOdkResultToServer(String patientUuid, int resultCode, Intent data) {
Expand Down Expand Up @@ -274,9 +277,10 @@ public void onPageFinished(WebView view, String url) {
@Override protected void onNewIntent(Intent intent) {
String uuid = intent.getStringExtra("uuid");
if (uuid != null) {
setIntent(intent);
// Immediately hide the current patient chart, to avoid giving the
// misleading impression that it applies to the new patient.
mGridWebView.setVisibility(View.INVISIBLE);
mWebView.setVisibility(View.INVISIBLE);
mController.setPatient(uuid);
}
}
Expand Down Expand Up @@ -511,7 +515,7 @@ private final class Ui implements PatientChartController.Ui {
List<Order> orders,
LocalDate admissionDate,
LocalDate firstSymptomsDate) {
mChartRenderer.render(chart, latestObservations, observations, orders,
sChartRenderer.render(mWebView, chart, latestObservations, observations, orders,
admissionDate, firstSymptomsDate, mController);
mRootView.invalidate();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ else if (!startMillis.isEmpty()){

@JavascriptInterface public void finish() {
LOG.finish("ChartJS");
LOG.finish("render");
}

public void setDate(String conceptUuid, LocalDate date) {
Expand Down