IDEMPIERE-5609 Dashboard Performance Indicators incrementally redrawed on DC drag and drop (#1736)
This commit is contained in:
parent
efcd7352f2
commit
e479eb5cfb
|
@ -198,6 +198,8 @@ public class MSysConfig extends X_AD_SysConfig
|
|||
public static final String ZK_BUTTON_STYLE = "ZK_BUTTON_STYLE";
|
||||
public static final String ZK_DASHBOARD_CALENDAR_REQUEST_DISPLAY_MODE = "ZK_DASHBOARD_CALENDAR_REQUEST_DISPLAY_MODE";
|
||||
public static final String ZK_DASHBOARD_PERFORMANCE_REFRESH_INTERVAL = "ZK_DASHBOARD_PERFORMANCE_REFRESH_INTERVAL";
|
||||
/** @deprecated not use for the new billboard implementation */
|
||||
@Deprecated(forRemoval = true, since = "11")
|
||||
public static final String ZK_DASHBOARD_PERFORMANCE_TIMEOUT = "ZK_DASHBOARD_PERFORMANCE_TIMEOUT";
|
||||
public static final String ZK_DASHBOARD_REFRESH_INTERVAL = "ZK_DASHBOARD_REFRESH_INTERVAL";
|
||||
public static final String ZK_DECIMALBOX_PROCESS_DOTKEYPAD = "ZK_DECIMALBOX_PROCESS_DOTKEYPAD";
|
||||
|
|
|
@ -1,5 +1,36 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
* - carlos *
|
||||
* - elaine *
|
||||
* - hieplq *
|
||||
**********************************************************************/
|
||||
package org.adempiere.webui.apps.graph;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.webui.apps.graph.WPerformanceIndicator.Options;
|
||||
import org.adempiere.webui.component.Grid;
|
||||
import org.adempiere.webui.component.Panel;
|
||||
|
@ -16,15 +47,14 @@ import org.zkoss.zul.Label;
|
|||
|
||||
public class WPAPanel extends Panel implements EventListener<Event>
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* generated serial id
|
||||
*/
|
||||
private static final long serialVersionUID = -6367672112341229048L;
|
||||
|
||||
/**
|
||||
* Get Panel if User has Performance Goals
|
||||
* @return panel pr null
|
||||
* Load Performance Goals for current login user
|
||||
* @return MGoal[]
|
||||
*/
|
||||
public static MGoal[] loadGoal()
|
||||
{
|
||||
|
@ -33,16 +63,23 @@ public class WPAPanel extends Panel implements EventListener<Event>
|
|||
return goals;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Constructor
|
||||
/**
|
||||
* Default Constructor
|
||||
*/
|
||||
public WPAPanel ()
|
||||
{
|
||||
super ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set performance goals and render charts
|
||||
* @param goals
|
||||
* @param options color map options
|
||||
*/
|
||||
public void setGoals (MGoal[] goals, Options options){
|
||||
m_goals = goals;
|
||||
m_goals = goals;
|
||||
if (getChildren().size() > 0)
|
||||
getChildren().clear();
|
||||
init(options);
|
||||
}
|
||||
|
||||
|
@ -53,7 +90,7 @@ public class WPAPanel extends Panel implements EventListener<Event>
|
|||
private static final CLogger log = CLogger.getCLogger (WPAPanel.class);
|
||||
|
||||
/**
|
||||
* Static/Dynamic Init
|
||||
* Layout panel and render charts
|
||||
* @param options
|
||||
*/
|
||||
private void init(Options options)
|
||||
|
@ -67,6 +104,7 @@ public class WPAPanel extends Panel implements EventListener<Event>
|
|||
grid.appendChild(rows);
|
||||
|
||||
Row row = null;
|
||||
List<WPerformanceIndicator> list = new ArrayList<>();
|
||||
for (int i = 0; i < m_goals.length; i++)
|
||||
{
|
||||
if (row == null || i % 2 == 0)
|
||||
|
@ -79,6 +117,14 @@ public class WPAPanel extends Panel implements EventListener<Event>
|
|||
row.appendChild(div);
|
||||
div.setSclass("performance-indicator-box");
|
||||
WPerformanceIndicator pi = new WPerformanceIndicator(m_goals[i], options);
|
||||
list.add(pi);
|
||||
pi.addEventListener(WPerformanceIndicator.ON_AFTER_RENDER_CHART_EVENT, e -> {
|
||||
boolean removed = list.remove(e.getTarget());
|
||||
if (removed && list.isEmpty()) {
|
||||
//notify all chart have been rendered
|
||||
Events.sendEvent(WPAPanel.this, new Event(WPerformanceIndicator.ON_AFTER_RENDER_CHART_EVENT));
|
||||
}
|
||||
});
|
||||
div.appendChild(pi);
|
||||
pi.addEventListener(Events.ON_CLICK, this);
|
||||
Div titleDiv = new Div();
|
||||
|
@ -90,15 +136,17 @@ public class WPAPanel extends Panel implements EventListener<Event>
|
|||
} // init
|
||||
|
||||
/**
|
||||
* Action Listener for Drill Down
|
||||
* Event Listener for Drill Down
|
||||
* @param e event
|
||||
*/
|
||||
@Override
|
||||
public void onEvent(Event e) throws Exception
|
||||
{
|
||||
if (e.getTarget() instanceof WPerformanceIndicator)
|
||||
{
|
||||
WPerformanceIndicator pi = (WPerformanceIndicator) e.getTarget();
|
||||
log.info(pi.toString());
|
||||
if (log.isLoggable(Level.INFO))
|
||||
log.info(pi.toString());
|
||||
MGoal goal = pi.getGoal();
|
||||
if (goal.getMeasure() != null)
|
||||
new WPerformanceDetail(goal);
|
||||
|
|
|
@ -42,23 +42,29 @@ import org.zkoss.zul.Menupopup;
|
|||
*/
|
||||
public class WPerformanceIndicator extends Panel implements EventListener<Event>
|
||||
{
|
||||
/**
|
||||
* generated serial id
|
||||
*/
|
||||
private static final long serialVersionUID = 4102528939759426552L;
|
||||
|
||||
/** Event after chart have been rendered */
|
||||
public static final String ON_AFTER_RENDER_CHART_EVENT = "onAfterRenderChart";
|
||||
public static final String TICK_COLOR = "tickColor";
|
||||
public static final String NEEDLE_COLOR = "needleColor";
|
||||
public static final String DIAL_BACKGROUND = "dialBackground";
|
||||
public static final String CHART_BACKGROUND = "chartBackground";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param goal
|
||||
*/
|
||||
private static final long serialVersionUID = 3580494126343850939L;
|
||||
|
||||
public WPerformanceIndicator(MGoal goal)
|
||||
{
|
||||
this(goal, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param goal goal model
|
||||
* @param goal goal model
|
||||
* @param options
|
||||
*/
|
||||
public WPerformanceIndicator(MGoal goal, Options options)
|
||||
{
|
||||
|
@ -99,7 +105,7 @@ public class WPerformanceIndicator extends Panel implements EventListener<Event>
|
|||
/** Integer Number Format */
|
||||
private static DecimalFormat s_format = DisplayType.getNumberFormat(DisplayType.Integer);
|
||||
|
||||
Menupopup popupMenu = new Menupopup();
|
||||
protected Menupopup popupMenu = new Menupopup();
|
||||
private Menuitem mRefresh = new Menuitem(Msg.getMsg(Env.getCtx(), "Refresh"), ThemeManager.getThemeResource("images/Refresh16.png"));
|
||||
|
||||
private Color chartBackground = new Color(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
@ -107,7 +113,7 @@ public class WPerformanceIndicator extends Panel implements EventListener<Event>
|
|||
private Color needleColor = Color.darkGray;
|
||||
private Color tickColor = Color.darkGray;
|
||||
|
||||
ChartPanel chartPanel;
|
||||
protected ChartPanel chartPanel;
|
||||
|
||||
/**
|
||||
* Get Goal
|
||||
|
@ -119,7 +125,7 @@ public class WPerformanceIndicator extends Panel implements EventListener<Event>
|
|||
} // getGoal
|
||||
|
||||
/**
|
||||
* Init Graph Display
|
||||
* Initialization
|
||||
* Kinamo (pelgrim)
|
||||
*/
|
||||
private void init()
|
||||
|
@ -142,10 +148,12 @@ public class WPerformanceIndicator extends Panel implements EventListener<Event>
|
|||
text.append(" ").append(Msg.getMsg(Env.getCtx(), "of")).append(" ")
|
||||
.append(s_format.format(m_goal.getMeasureTarget()));
|
||||
setTooltiptext(text.toString());
|
||||
|
||||
|
||||
//chart render in after size event
|
||||
addEventListener(Events.ON_AFTER_SIZE, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(Event event) throws Exception
|
||||
{
|
||||
if (Events.ON_AFTER_SIZE.equals(event.getName()))
|
||||
|
@ -159,6 +167,10 @@ public class WPerformanceIndicator extends Panel implements EventListener<Event>
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle after size event. Call {@link #renderChart(int, int)}
|
||||
* @param event
|
||||
*/
|
||||
private void onAfterSize(AfterSizeEvent event) {
|
||||
int width = event.getWidth();
|
||||
if (width == 0)
|
||||
|
@ -183,14 +195,23 @@ public class WPerformanceIndicator extends Panel implements EventListener<Event>
|
|||
}
|
||||
}
|
||||
this.getChildren().clear();
|
||||
renderChart(width, height);
|
||||
renderChart(width, height);
|
||||
Events.sendEvent(this, new Event(ON_AFTER_RENDER_CHART_EVENT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return title
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return m_text;
|
||||
}
|
||||
|
||||
/**
|
||||
* render chart
|
||||
* @param chartWidth
|
||||
* @param chartHeight
|
||||
*/
|
||||
private void renderChart(int chartWidth, int chartHeight)
|
||||
{
|
||||
IndicatorModel model = new IndicatorModel();
|
||||
|
@ -207,6 +228,9 @@ public class WPerformanceIndicator extends Panel implements EventListener<Event>
|
|||
this.getFirstChild().addEventListener(Events.ON_CLICK, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for color map options
|
||||
*/
|
||||
public static class Options {
|
||||
public Map<String, Color> colorMap;
|
||||
}
|
||||
|
|
|
@ -14,16 +14,13 @@
|
|||
package org.adempiere.webui.dashboard;
|
||||
|
||||
import org.adempiere.webui.apps.graph.WPAPanel;
|
||||
import org.adempiere.webui.apps.graph.WPerformanceIndicator;
|
||||
import org.adempiere.webui.apps.graph.WPerformanceIndicator.Options;
|
||||
import org.adempiere.webui.util.ServerPushTemplate;
|
||||
import org.compiere.model.MGoal;
|
||||
import org.compiere.model.MSysConfig;
|
||||
import org.compiere.util.Env;
|
||||
import org.zkoss.zk.au.out.AuScript;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.Executions;
|
||||
import org.zkoss.zk.ui.Page;
|
||||
import org.zkoss.zk.ui.event.Events;
|
||||
import org.zkoss.zk.ui.util.Clients;
|
||||
|
||||
/**
|
||||
|
@ -31,66 +28,52 @@ import org.zkoss.zk.ui.util.Clients;
|
|||
* @author Elaine
|
||||
* @date November 20, 2008
|
||||
*/
|
||||
public class DPPerformance extends DashboardPanel {
|
||||
|
||||
private static final String ON_POST_RENDER_ATTR = "onPostRender.Event.Posted";
|
||||
public class DPPerformance extends DashboardPanel {
|
||||
/**
|
||||
*
|
||||
* generated serial id
|
||||
*/
|
||||
private static final long serialVersionUID = -8878665031716441912L;
|
||||
|
||||
/** performance chart panel */
|
||||
private WPAPanel paPanel;
|
||||
private MGoal[] performanceData;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public DPPerformance()
|
||||
{
|
||||
super();
|
||||
setSclass("performance-widget");
|
||||
// have to add at least a child component, other it will be remove from DashboardController
|
||||
// and can't update when finish load data
|
||||
paPanel = new WPAPanel();
|
||||
appendChild(paPanel);
|
||||
paPanel.addEventListener(WPerformanceIndicator.ON_AFTER_RENDER_CHART_EVENT, e -> onPostRender());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(ServerPushTemplate template) {
|
||||
performanceData = WPAPanel.loadGoal();
|
||||
performanceData = WPAPanel.loadGoal();
|
||||
//usually, this should be call in non UI/Event listener thread (i.e Executions.getCurrent() should be null)
|
||||
if (Executions.getCurrent() != null) {
|
||||
updateUI();
|
||||
if (this.getAttribute(ON_POST_RENDER_ATTR) == null && paPanel.getChildren().size() > 0) {
|
||||
setAttribute(ON_POST_RENDER_ATTR, Boolean.TRUE);
|
||||
Events.echoEvent("onPostRender", this, null);
|
||||
}
|
||||
updateUI();
|
||||
} else {
|
||||
template.executeAsync(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageAttached(Page newpage, Page oldpage) {
|
||||
super.onPageAttached(newpage, oldpage);
|
||||
if (newpage != null) {
|
||||
if (Executions.getCurrent() != null) {
|
||||
if (this.getAttribute(ON_POST_RENDER_ATTR) == null && paPanel.getChildren().size() > 0) {
|
||||
setAttribute(ON_POST_RENDER_ATTR, Boolean.TRUE);
|
||||
Events.echoEvent("onPostRender", this, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//adjust window height to match grid height
|
||||
/**
|
||||
* Adjust {@link #paPanel} height to match chart/content height
|
||||
*/
|
||||
public void onPostRender()
|
||||
{
|
||||
removeAttribute(ON_POST_RENDER_ATTR);
|
||||
if (this.getFirstChild() != null)
|
||||
{
|
||||
int timeout = MSysConfig.getIntValue(MSysConfig.ZK_DASHBOARD_PERFORMANCE_TIMEOUT, 500, Env.getAD_Client_ID(Env.getCtx()));
|
||||
//first child of paPanel, the Grid layout
|
||||
Component grid = this.getFirstChild().getFirstChild();
|
||||
String script = "setTimeout(function() { let grid = jq('#" + grid.getUuid() + "');";
|
||||
script = script + "grid.parent().height(grid.css('height'));}, " + timeout + ");";
|
||||
script = script + "grid.parent().height(grid.css('height'));}, 10);";
|
||||
if (Executions.getCurrent() != null)
|
||||
Clients.response(new AuScript(script));
|
||||
this.getFirstChild().invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue