IDEMPIERE-5797 Zk: Upgrade Billboard chart to 3.9.0 (#1930)
* IDEMPIERE-5797 Zk: Upgrade Billboard chart to 3.9.0 * IDEMPIERE-5797 Zk: Upgrade Billboard chart to 3.9.0 - Add basic localization support * IDEMPIERE-5797 Zk: Upgrade Billboard chart to 3.9.0 - update Readme * IDEMPIERE-5797 Zk: Upgrade Billboard chart to 3.9.0 - Fix intermittent sizing and rendering issue
This commit is contained in:
parent
47e5f01206
commit
b47544b55a
|
@ -57,6 +57,6 @@ Copyright (C) 2007 Ashley G Ramdass (ADempiere WebUI).
|
||||||
|
|
||||||
<!-- this js module doesn't actually exists and it is here for default theme version -->
|
<!-- this js module doesn't actually exists and it is here for default theme version -->
|
||||||
<!-- since loading of js module is on demand, it doesn't cause any error as long as you don't try to load it -->
|
<!-- since loading of js module is on demand, it doesn't cause any error as long as you don't try to load it -->
|
||||||
<javascript-module name="idempiere.theme.default" version="202306220900" />
|
<javascript-module name="idempiere.theme.default" version="202307100900" />
|
||||||
|
|
||||||
</language>
|
</language>
|
||||||
|
|
|
@ -196,7 +196,7 @@ public class WPerformanceIndicator extends Panel implements EventListener<Event>
|
||||||
}
|
}
|
||||||
this.getChildren().clear();
|
this.getChildren().clear();
|
||||||
renderChart(width, height);
|
renderChart(width, height);
|
||||||
Events.sendEvent(this, new Event(ON_AFTER_RENDER_CHART_EVENT));
|
Events.sendEvent(this, new Event(ON_AFTER_RENDER_CHART_EVENT, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,6 +21,9 @@ import org.compiere.model.MGoal;
|
||||||
import org.zkoss.zk.au.out.AuScript;
|
import org.zkoss.zk.au.out.AuScript;
|
||||||
import org.zkoss.zk.ui.Component;
|
import org.zkoss.zk.ui.Component;
|
||||||
import org.zkoss.zk.ui.Executions;
|
import org.zkoss.zk.ui.Executions;
|
||||||
|
import org.zkoss.zk.ui.event.Events;
|
||||||
|
import org.zkoss.zk.ui.event.MaximizeEvent;
|
||||||
|
import org.zkoss.zk.ui.event.OpenEvent;
|
||||||
import org.zkoss.zk.ui.util.Clients;
|
import org.zkoss.zk.ui.util.Clients;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,6 +52,30 @@ public class DPPerformance extends DashboardPanel {
|
||||||
paPanel = new WPAPanel();
|
paPanel = new WPAPanel();
|
||||||
appendChild(paPanel);
|
appendChild(paPanel);
|
||||||
paPanel.addEventListener(WPerformanceIndicator.ON_AFTER_RENDER_CHART_EVENT, e -> onPostRender());
|
paPanel.addEventListener(WPerformanceIndicator.ON_AFTER_RENDER_CHART_EVENT, e -> onPostRender());
|
||||||
|
this.addEventListener(Events.ON_OPEN, (OpenEvent e) -> {
|
||||||
|
if (e.isOpen())
|
||||||
|
onPostRestore();
|
||||||
|
});
|
||||||
|
this.addEventListener(Events.ON_MAXIMIZE, (MaximizeEvent e) -> {
|
||||||
|
if (!e.isMaximized())
|
||||||
|
onPostRestore();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After state of dashboard panel change from collapse to open or from maximize to normal.
|
||||||
|
*/
|
||||||
|
private void onPostRestore() {
|
||||||
|
if (this.getFirstChild() != null && this.getParent() != null) {
|
||||||
|
Component grid = this.getFirstChild().getFirstChild();
|
||||||
|
String script = "setTimeout(function() { let grid = jq('#" + grid.getUuid() + "');";
|
||||||
|
script = script + "let pa = jq('#" + this.getFirstChild().getUuid() + "');";
|
||||||
|
script = script + "let pc = jq('#" + this.getParent().getUuid() + "');";
|
||||||
|
script = script + "pa.height(grid.css('height'));";
|
||||||
|
script = script + "pc.height(grid.css('height'));}, 10);";
|
||||||
|
if (Executions.getCurrent() != null)
|
||||||
|
Clients.response(new AuScript(script));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1142,6 +1142,13 @@ public class DashboardController implements EventListener<Event> {
|
||||||
//following 2 line needed for restore to size the panel correctly
|
//following 2 line needed for restore to size the panel correctly
|
||||||
ZKUpdateUtil.setHflex(panel, (String)panel.getAttribute(FLEX_GROW_ATTRIBUTE));
|
ZKUpdateUtil.setHflex(panel, (String)panel.getAttribute(FLEX_GROW_ATTRIBUTE));
|
||||||
ZKUpdateUtil.setHeight(panel, "100%");
|
ZKUpdateUtil.setHeight(panel, "100%");
|
||||||
|
|
||||||
|
//notify panel content component
|
||||||
|
if (panel.getPanelchildren() != null) {
|
||||||
|
panel.getPanelchildren().getChildren().forEach(child -> {
|
||||||
|
Executions.schedule(dashboardLayout.getDesktop(), e -> Events.postEvent(child, event), new Event("onPostRestore"));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(eventName.equals(Events.ON_CLICK))
|
else if(eventName.equals(Events.ON_CLICK))
|
||||||
|
@ -1252,6 +1259,13 @@ public class DashboardController implements EventListener<Event> {
|
||||||
PO.clearCrossTenantSafe();
|
PO.clearCrossTenantSafe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//notify panel content component
|
||||||
|
if (panel.getPanelchildren() != null) {
|
||||||
|
for(Component c : panel.getPanelchildren().getChildren()) {
|
||||||
|
Events.postEvent(c, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.adempiere.webui.component.Tabpanel;
|
||||||
import org.adempiere.webui.component.ToolBar;
|
import org.adempiere.webui.component.ToolBar;
|
||||||
import org.adempiere.webui.component.ToolBarButton;
|
import org.adempiere.webui.component.ToolBarButton;
|
||||||
import org.adempiere.webui.component.Window;
|
import org.adempiere.webui.component.Window;
|
||||||
|
import org.adempiere.webui.dashboard.DashboardPanel;
|
||||||
import org.adempiere.webui.event.MenuListener;
|
import org.adempiere.webui.event.MenuListener;
|
||||||
import org.adempiere.webui.event.ZKBroadCastManager;
|
import org.adempiere.webui.event.ZKBroadCastManager;
|
||||||
import org.adempiere.webui.panel.ADForm;
|
import org.adempiere.webui.panel.ADForm;
|
||||||
|
@ -49,6 +50,7 @@ import org.adempiere.webui.panel.BroadcastMessageWindow;
|
||||||
import org.adempiere.webui.panel.HeaderPanel;
|
import org.adempiere.webui.panel.HeaderPanel;
|
||||||
import org.adempiere.webui.panel.HelpController;
|
import org.adempiere.webui.panel.HelpController;
|
||||||
import org.adempiere.webui.panel.TimeoutPanel;
|
import org.adempiere.webui.panel.TimeoutPanel;
|
||||||
|
import org.adempiere.webui.part.ITabOnSelectHandler;
|
||||||
import org.adempiere.webui.session.SessionManager;
|
import org.adempiere.webui.session.SessionManager;
|
||||||
import org.adempiere.webui.theme.ThemeManager;
|
import org.adempiere.webui.theme.ThemeManager;
|
||||||
import org.adempiere.webui.util.UserPreference;
|
import org.adempiere.webui.util.UserPreference;
|
||||||
|
@ -604,6 +606,13 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
||||||
|
|
||||||
dashboardController.render(homeTab, this, true);
|
dashboardController.render(homeTab, this, true);
|
||||||
|
|
||||||
|
if (homeTab.getFirstChild() != null) {
|
||||||
|
ITabOnSelectHandler handler = () -> {
|
||||||
|
invalidateDashboardPanel(homeTab.getFirstChild().getChildren());
|
||||||
|
};
|
||||||
|
homeTab.getFirstChild().setAttribute(ITabOnSelectHandler.ATTRIBUTE_KEY, handler);
|
||||||
|
}
|
||||||
|
|
||||||
homeTab.setAttribute(HOME_TAB_RENDER_ATTR, Boolean.TRUE);
|
homeTab.setAttribute(HOME_TAB_RENDER_ATTR, Boolean.TRUE);
|
||||||
|
|
||||||
West w = layout.getWest();
|
West w = layout.getWest();
|
||||||
|
@ -656,6 +665,20 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
||||||
homeTab.invalidate();
|
homeTab.invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redraw dashboard panel after switching back to home tab
|
||||||
|
* @param childrens
|
||||||
|
*/
|
||||||
|
private void invalidateDashboardPanel(List<Component> childrens) {
|
||||||
|
for (Component children : childrens) {
|
||||||
|
if (children instanceof DashboardPanel) {
|
||||||
|
children.invalidate();
|
||||||
|
} else {
|
||||||
|
invalidateDashboardPanel(children.getChildren());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set width of popup for side panel
|
* Set width of popup for side panel
|
||||||
* @param popup
|
* @param popup
|
||||||
|
|
|
@ -212,7 +212,7 @@
|
||||||
.performance-indicator-box {
|
.performance-indicator-box {
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
border: 1px solid #d8d8d8;
|
border: 1px solid #d8d8d8;
|
||||||
border-radius: 11px;
|
border-radius: 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.performance-indicator-title {
|
.performance-indicator-title {
|
||||||
|
|
|
@ -458,6 +458,7 @@ public class ChartBuilder {
|
||||||
billboard.setValueAxisLabel(mChart.get_Translation(MChart.COLUMNNAME_RangeLabel));
|
billboard.setValueAxisLabel(mChart.get_Translation(MChart.COLUMNNAME_RangeLabel));
|
||||||
billboard.setTitle(mChart.get_Translation(MChart.COLUMNNAME_Name));
|
billboard.setTitle(mChart.get_Translation(MChart.COLUMNNAME_Name));
|
||||||
billboard.setType(type);
|
billboard.setType(type);
|
||||||
|
billboard.setLocale(Env.getContext(Env.getCtx(), Env.LOCALE));
|
||||||
return billboard;
|
return billboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,8 +68,6 @@ public class PerformanceGraphBuilder {
|
||||||
|
|
||||||
private void buildDialRendererOptions(Billboard billboard, DialModel dialModel) {
|
private void buildDialRendererOptions(Billboard billboard, DialModel dialModel) {
|
||||||
DialModelScale dialScale = dialModel.getScale(0);
|
DialModelScale dialScale = dialModel.getScale(0);
|
||||||
billboard.addRendererOptions("min", 0);
|
|
||||||
billboard.addRendererOptions("max", dialScale.getScaleUpperBound());
|
|
||||||
List<Double> intervals = new ArrayList<Double>();
|
List<Double> intervals = new ArrayList<Double>();
|
||||||
List<String> intervalColors = new ArrayList<String>();
|
List<String> intervalColors = new ArrayList<String>();
|
||||||
for(int i = 0; i < dialScale.rangeSize(); i++) {
|
for(int i = 0; i < dialScale.rangeSize(); i++) {
|
||||||
|
@ -78,13 +76,10 @@ public class PerformanceGraphBuilder {
|
||||||
intervals.add(upperBound);
|
intervals.add(upperBound);
|
||||||
intervalColors.add(dialRange.getRangeColor());
|
intervalColors.add(dialRange.getRangeColor());
|
||||||
}
|
}
|
||||||
List<Double> ticks = new ArrayList<Double>(intervals);
|
|
||||||
ticks.add(0, 0d);
|
|
||||||
billboard.addRendererOptions("ticks", ticks.toArray(new Double[0]));
|
|
||||||
billboard.addRendererOptions("intervals", intervals.toArray(new Double[0]));
|
billboard.addRendererOptions("intervals", intervals.toArray(new Double[0]));
|
||||||
billboard.addRendererOptions("intervalColors", intervalColors.toArray(new String[0]));
|
billboard.addRendererOptions("intervalColors", intervalColors.toArray(new String[0]));
|
||||||
billboard.addRendererOptions("tickColor", dialScale.getTickColor());
|
|
||||||
billboard.addRendererOptions("background", dialModel.getFrameBgColor());
|
billboard.addRendererOptions("background", dialModel.getFrameBgColor());
|
||||||
|
billboard.addRendererOptions("showNeedle", Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DialModel createDialModel(IndicatorModel model)
|
private DialModel createDialModel(IndicatorModel model)
|
||||||
|
|
|
@ -2,6 +2,20 @@
|
||||||
|
|
||||||
1. Wrap https://github.com/naver/billboard.js as zk component.
|
1. Wrap https://github.com/naver/billboard.js as zk component.
|
||||||
|
|
||||||
2. To update, replace billboard.pkgd.js and billboard.pkgd.src.js with latest billboard.pkgd.js and billboard.pkgd.min.js from https://github.com/naver/billboard.js (Note that due to naming convention of zk, billboard.pkgd.js=billboard.pkgd.min.js and billboard.pkgd.src.js=billboard.pkgd.js ).
|
2. Get latest billboard.min.js and billboard.js from https://github.com/naver/billboard.js. Following Zk naming convention, rename billboard.min.js to billboard.js and rename billboard.js to billboard.src.js.
|
||||||
|
|
||||||
3. To update, replace billboard.css with latest billboard.css from https://github.com/naver/billboard.js. Add !important to padding and text-align of .bb-tooltip th and padding of .bb-tooltip td to fix conflict with zk css
|
3. Get d3 from https://d3js.org/. The current version use by billboard is v6 so the corresponding link is https://d3js.org/d3.v6.js and https://d3js.org/d3.v6.min.js. Again, following Zk naming conversion, we need to rename d3.v6.js to d3.v6.src.js and rename d3.v6.min.js to d3.v6.js.
|
||||||
|
|
||||||
|
4. Replace billboard.css with latest billboard.css from https://github.com/naver/billboard.js.
|
||||||
|
* Add !important to padding and text-align of .bb-tooltip th and padding of .bb-tooltip td to fix conflict with zk css
|
||||||
|
* Change font-size of text.bb-chart-arcs-gauge-title from 2.7em to 1.5em.
|
||||||
|
* Original: text.bb-chart-arcs-gauge-title {
|
||||||
|
dominant-baseline: middle;
|
||||||
|
font-size: 2.7em; }
|
||||||
|
* Updated: text.bb-chart-arcs-gauge-title {
|
||||||
|
dominant-baseline: middle;
|
||||||
|
font-size: 1.5em; }
|
||||||
|
|
||||||
|
5. Update version-uid in metainfo.zk/lang-addon.xml and org.idempiere.zk.billboard.Version.UID (both value must match).
|
||||||
|
|
||||||
|
6. Update version of "zul.billboard" and "zul.billboard.css" javascript-module in metainfo.zk/lang-addon.xml.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<language-name>xul/html</language-name>
|
<language-name>xul/html</language-name>
|
||||||
<version>
|
<version>
|
||||||
<version-class>org.idempiere.zk.billboard.Version</version-class>
|
<version-class>org.idempiere.zk.billboard.Version</version-class>
|
||||||
<version-uid>3.5.1.20220908</version-uid>
|
<version-uid>3.9.0.20230713</version-uid>
|
||||||
</version>
|
</version>
|
||||||
<component>
|
<component>
|
||||||
<component-name>billboard</component-name>
|
<component-name>billboard</component-name>
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
</component>
|
</component>
|
||||||
|
|
||||||
<stylesheet href="~./js/zul/billboard/css/billboard.css" type="text/css"/>
|
<stylesheet href="~./js/zul/billboard/css/billboard.css" type="text/css"/>
|
||||||
<javascript-module name="zul.billboard" version="3.5.1.20221027"/>
|
<javascript-module name="zul.billboard" version="3.9.0.202307131000"/>
|
||||||
<!-- this js module doesn't actually exists and it is here for billboard.css version -->
|
<!-- this js module doesn't actually exists and it is here for billboard.css version -->
|
||||||
<javascript-module name="zul.billboard.css" version="3.5.1.20220905"/>
|
<javascript-module name="zul.billboard.css" version="3.9.0.202307131000"/>
|
||||||
</language-addon>
|
</language-addon>
|
|
@ -53,7 +53,7 @@ public class Billboard extends XulElement {
|
||||||
/**
|
/**
|
||||||
* generated serial id
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -3888636406033151303L;
|
private static final long serialVersionUID = -2164790050418874185L;
|
||||||
|
|
||||||
// Must
|
// Must
|
||||||
private ChartModel _model;
|
private ChartModel _model;
|
||||||
|
@ -73,6 +73,7 @@ public class Billboard extends XulElement {
|
||||||
private String valueAxisLabel = null;
|
private String valueAxisLabel = null;
|
||||||
private String[] seriesColors = null;
|
private String[] seriesColors = null;
|
||||||
private int xAxisAngle = 0;
|
private int xAxisAngle = 0;
|
||||||
|
private String locale = null;
|
||||||
|
|
||||||
public static final String ON_DATA_CLICK_EVENT = "onDataClick";
|
public static final String ON_DATA_CLICK_EVENT = "onDataClick";
|
||||||
|
|
||||||
|
@ -95,6 +96,7 @@ public class Billboard extends XulElement {
|
||||||
render(renderer, "orient", _orient);
|
render(renderer, "orient", _orient);
|
||||||
render(renderer, "timeSeries", timeSeries);
|
render(renderer, "timeSeries", timeSeries);
|
||||||
render(renderer, "xAxisAngle", xAxisAngle);
|
render(renderer, "xAxisAngle", xAxisAngle);
|
||||||
|
render(renderer, "locale", toD3Locale(locale));
|
||||||
if (timeSeries) {
|
if (timeSeries) {
|
||||||
if (timeSeriesInterval != null)
|
if (timeSeriesInterval != null)
|
||||||
render(renderer, "timeSeriesInterval", timeSeriesInterval);
|
render(renderer, "timeSeriesInterval", timeSeriesInterval);
|
||||||
|
@ -139,6 +141,15 @@ public class Billboard extends XulElement {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String toD3Locale(String locale) {
|
||||||
|
if (locale == null)
|
||||||
|
return null;
|
||||||
|
if ("es_CO".equals(locale))
|
||||||
|
return "es-ES";
|
||||||
|
else
|
||||||
|
return locale.replaceFirst("[_]", "-");
|
||||||
|
}
|
||||||
|
|
||||||
private JSONObject mapToJSON(Map<String, Object> map) {
|
private JSONObject mapToJSON(Map<String, Object> map) {
|
||||||
JSONObject jData = new JSONObject();
|
JSONObject jData = new JSONObject();
|
||||||
for(String key : map.keySet()) {
|
for(String key : map.keySet()) {
|
||||||
|
@ -466,4 +477,8 @@ public class Billboard extends XulElement {
|
||||||
public void setXAxisAngle(int xAxisAngle) {
|
public void setXAxisAngle(int xAxisAngle) {
|
||||||
this.xAxisAngle = xAxisAngle;
|
this.xAxisAngle = xAxisAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLocale(String locale) {
|
||||||
|
this.locale = locale;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,9 @@ package org.idempiere.zk.billboard;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Version {
|
public class Version {
|
||||||
/** Returns the version UID.
|
/**
|
||||||
|
* Returns the version UID.<br/>
|
||||||
|
* Must match with version-uid value in lang-addon.xml
|
||||||
*/
|
*/
|
||||||
public static final String UID = "3.5.1.20220908";
|
public static final String UID = "3.9.0.20230713";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
|
const __d3_formatLocaleCache = new Map();
|
||||||
|
const __d3_timeFormatLocaleCache = new Map();
|
||||||
|
|
||||||
var Billboard =
|
var Billboard =
|
||||||
zul.billboard.Billboard = zk.$extends(zk.Widget,
|
zul.billboard.Billboard = zk.$extends(zk.Widget,
|
||||||
{
|
{
|
||||||
|
@ -10,6 +13,7 @@
|
||||||
_cursor : false,
|
_cursor : false,
|
||||||
_highlighter : true,
|
_highlighter : true,
|
||||||
_dataClickTS : 0,
|
_dataClickTS : 0,
|
||||||
|
_locale: null,
|
||||||
|
|
||||||
$define : {
|
$define : {
|
||||||
title: null,
|
title: null,
|
||||||
|
@ -35,10 +39,51 @@
|
||||||
timeSeriesInterval: null,
|
timeSeriesInterval: null,
|
||||||
timeSeriesFormat: null,
|
timeSeriesFormat: null,
|
||||||
xAxisAngle: null,
|
xAxisAngle: null,
|
||||||
chart: null
|
chart: null,
|
||||||
|
locale: null
|
||||||
|
},
|
||||||
|
|
||||||
|
_loadFormatLocale: async function(url) {
|
||||||
|
try {
|
||||||
|
const definition = await d3.json(url);
|
||||||
|
d3.formatDefaultLocale(definition);
|
||||||
|
__d3_formatLocaleCache.set(url, definition);
|
||||||
|
} catch (error) {
|
||||||
|
__d3_formatLocaleCache.set(url, null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_loadTimeFormatLocale: async function(url) {
|
||||||
|
try {
|
||||||
|
const definition = await d3.json(url);
|
||||||
|
d3.timeFormatDefaultLocale(definition);
|
||||||
|
__d3_timeFormatLocaleCache.set(url, definition);
|
||||||
|
} catch (error) {
|
||||||
|
__d3_timeFormatLocaleCache.set(url, null);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_dataPrepare : function() {
|
_dataPrepare : function() {
|
||||||
|
//load locale
|
||||||
|
if (this.getLocale() != null) {
|
||||||
|
const formatURL = "https://unpkg.com/d3-format@3.1.0/locale/"+this.getLocale()+".json";
|
||||||
|
if (__d3_formatLocaleCache.has(formatURL)) {
|
||||||
|
const definition = __d3_formatLocaleCache.get(formatURL);
|
||||||
|
if (definition != null)
|
||||||
|
d3.formatDefaultLocale(definition);
|
||||||
|
} else {
|
||||||
|
this._loadFormatLocale(formatURL);
|
||||||
|
}
|
||||||
|
const timeFormatURL = "https://unpkg.com/d3-time-format@4.1.0/locale/"+this.getLocale()+".json";
|
||||||
|
if (__d3_timeFormatLocaleCache.has(timeFormatURL)) {
|
||||||
|
const definition = __d3_timeFormatLocaleCache.get(timeFormatURL);
|
||||||
|
if (definition != null)
|
||||||
|
d3.timeFormatDefaultLocale(definition);
|
||||||
|
} else {
|
||||||
|
this._loadTimeFormatLocale(timeFormatURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var dataModel = this.getModel();
|
var dataModel = this.getModel();
|
||||||
var data = [];
|
var data = [];
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* billboard.js, JavaScript chart library
|
* billboard.js, JavaScript chart library
|
||||||
* https://naver.github.io/billboard.js/
|
* https://naver.github.io/billboard.js/
|
||||||
*
|
*
|
||||||
* @version 3.5.1
|
* @version 3.9.0
|
||||||
*/
|
*/
|
||||||
/*-- Chart --*/
|
/*-- Chart --*/
|
||||||
.bb svg {
|
.bb svg {
|
||||||
|
@ -24,11 +24,12 @@
|
||||||
.bb-legend-item-tile,
|
.bb-legend-item-tile,
|
||||||
.bb-xgrid-focus,
|
.bb-xgrid-focus,
|
||||||
.bb-ygrid-focus,
|
.bb-ygrid-focus,
|
||||||
.bb-ygrid,
|
.bb-ygrid {
|
||||||
.bb-event-rect,
|
|
||||||
.bb-bars path {
|
|
||||||
shape-rendering: crispEdges; }
|
shape-rendering: crispEdges; }
|
||||||
|
|
||||||
|
.bb-chart-arcs .bb-needle {
|
||||||
|
fill: #000; }
|
||||||
|
|
||||||
.bb-chart-arc .bb-gauge-value {
|
.bb-chart-arc .bb-gauge-value {
|
||||||
fill: #000; }
|
fill: #000; }
|
||||||
|
|
||||||
|
@ -131,6 +132,11 @@
|
||||||
.bb-title {
|
.bb-title {
|
||||||
font: 14px sans-serif; }
|
font: 14px sans-serif; }
|
||||||
|
|
||||||
|
/*-- Treemap --*/
|
||||||
|
.bb-chart-treemaps rect {
|
||||||
|
stroke: #fff;
|
||||||
|
stroke-width: 1px; }
|
||||||
|
|
||||||
/*-- Tooltip --*/
|
/*-- Tooltip --*/
|
||||||
.bb-tooltip-container {
|
.bb-tooltip-container {
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
@ -142,9 +148,8 @@
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
empty-cells: show;
|
empty-cells: show;
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
-webkit-box-shadow: 7px 7px 12px -9px #777777;
|
box-shadow: 7px 7px 12px -9px #777777;
|
||||||
-moz-box-shadow: 7px 7px 12px -9px #777777;
|
white-space: nowrap; }
|
||||||
box-shadow: 7px 7px 12px -9px #777777; }
|
|
||||||
.bb-tooltip tr {
|
.bb-tooltip tr {
|
||||||
border: 1px solid #CCC; }
|
border: 1px solid #CCC; }
|
||||||
.bb-tooltip th {
|
.bb-tooltip th {
|
||||||
|
@ -164,7 +169,7 @@
|
||||||
height: 10px;
|
height: 10px;
|
||||||
margin-right: 6px; }
|
margin-right: 6px; }
|
||||||
.bb-tooltip.value {
|
.bb-tooltip.value {
|
||||||
text-align: right; }
|
text-align: right !important; }
|
||||||
|
|
||||||
/*-- Area --*/
|
/*-- Area --*/
|
||||||
.bb-area {
|
.bb-area {
|
||||||
|
@ -178,7 +183,7 @@
|
||||||
|
|
||||||
text.bb-chart-arcs-gauge-title {
|
text.bb-chart-arcs-gauge-title {
|
||||||
dominant-baseline: middle;
|
dominant-baseline: middle;
|
||||||
font-size: 2.7em; }
|
font-size: 1.5em; }
|
||||||
|
|
||||||
.bb-chart-arcs {
|
.bb-chart-arcs {
|
||||||
/*-- Polar --*/ }
|
/*-- Polar --*/ }
|
||||||
|
|
|
@ -105,7 +105,7 @@ billboard.AreaRenderer.prototype.render = function(wgt) {
|
||||||
var h = '<table class="bb-tooltip"><tbody><tr><th>';
|
var h = '<table class="bb-tooltip"><tbody><tr><th>';
|
||||||
h = h + defaultTitleFormat(c.x);
|
h = h + defaultTitleFormat(c.x);
|
||||||
h = h + '</th></tr><tr class="bb-tooltip-name-data"><td class="value">';
|
h = h + '</th></tr><tr class="bb-tooltip-name-data"><td class="value">';
|
||||||
h = h + c.value + '</td></tr></tbody></table>';
|
h = h + d3.format('.2f')(c.value) + '</td></tr></tbody></table>';
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -105,7 +105,7 @@ billboard.BarRenderer.prototype.render = function(wgt) {
|
||||||
var h = '<table class="bb-tooltip"><tbody><tr><th>';
|
var h = '<table class="bb-tooltip"><tbody><tr><th>';
|
||||||
h = h + defaultTitleFormat(c.x);
|
h = h + defaultTitleFormat(c.x);
|
||||||
h = h + '</th></tr><tr class="bb-tooltip-name-data"><td class="value">';
|
h = h + '</th></tr><tr class="bb-tooltip-name-data"><td class="value">';
|
||||||
h = h + c.value + '</td></tr></tbody></table>';
|
h = h + d3.format('.2f')(c.value) + '</td></tr></tbody></table>';
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -54,7 +54,6 @@ billboard.DonutRenderer.prototype.render = function(wgt) {
|
||||||
};
|
};
|
||||||
if (wgt.getTitle())
|
if (wgt.getTitle())
|
||||||
model["donut"]["title"] = wgt.getTitle();
|
model["donut"]["title"] = wgt.getTitle();
|
||||||
//model["title"] = {text: wgt.getTitle()};
|
|
||||||
return model;
|
return model;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,56 +1,82 @@
|
||||||
var billboard = billboard || {};
|
var billboard = billboard || {};
|
||||||
|
|
||||||
billboard.GaugeRenderer = function() {};
|
billboard.GaugeRenderer = class {
|
||||||
|
constructor() { }
|
||||||
|
render(wgt) {
|
||||||
|
var columns = [wgt.getSeriesData()[0], wgt.getSeriesData()[1]];
|
||||||
|
var color = {};
|
||||||
|
var gauge = {
|
||||||
|
units: ""
|
||||||
|
};
|
||||||
|
let showNeedle = false;
|
||||||
|
var rendererOptions = wgt._rendererOptions ? jq.evalJSON(wgt._rendererOptions) : null;
|
||||||
|
if (rendererOptions) {
|
||||||
|
if (rendererOptions["showNeedle"] && rendererOptions["showNeedle"] == true) {
|
||||||
|
showNeedle = true;
|
||||||
|
gauge.title = "\n{=NEEDLE_VALUE}%";
|
||||||
|
gauge.width = 20;
|
||||||
|
gauge.label = {
|
||||||
|
format: function(_value, _ratio, id) { return id; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (rendererOptions["intervalColors"]) {
|
||||||
|
color["pattern"] = new Array();
|
||||||
|
rendererOptions["intervalColors"].forEach((x, _i) => color["pattern"].push(x));
|
||||||
|
}
|
||||||
|
if (rendererOptions["intervals"]) {
|
||||||
|
if (!showNeedle) {
|
||||||
|
color["threshold"] = {values: []};
|
||||||
|
rendererOptions["intervals"].forEach((x, _i) => color["threshold"]["values"].push(x));
|
||||||
|
} else {
|
||||||
|
columns = [];
|
||||||
|
let prev = 0;
|
||||||
|
rendererOptions["intervals"].forEach((x, _i) => {
|
||||||
|
let step = x - prev;
|
||||||
|
prev = x;
|
||||||
|
columns.push([x + "%", step]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
billboard.GaugeRenderer.prototype.render = function(wgt) {
|
if (rendererOptions["background"]) {
|
||||||
var columns = [wgt.getSeriesData()[0], wgt.getSeriesData()[1]];
|
gauge["background"] = rendererOptions["background"];
|
||||||
var color = {};
|
}
|
||||||
var gauge = {units: ""};
|
}
|
||||||
var rendererOptions = wgt._rendererOptions ? jq.evalJSON(wgt._rendererOptions) : null;
|
var model = {
|
||||||
if (rendererOptions) {
|
bindto: "#" + wgt.$n().id,
|
||||||
if (rendererOptions["intervalColors"]) {
|
data: {
|
||||||
color["pattern"] = new Array();
|
columns: showNeedle ? columns : [columns],
|
||||||
rendererOptions["intervalColors"].forEach((x, i) => color["pattern"].push(x));
|
type: wgt._type
|
||||||
}
|
},
|
||||||
if (rendererOptions["intervals"]) {
|
color: color,
|
||||||
color["threshold"] = {values: []};
|
gauge: gauge,
|
||||||
rendererOptions["intervals"].forEach((x, i) => color["threshold"]["values"].push(x));
|
tooltip: {
|
||||||
}
|
show: true,
|
||||||
|
doNotHide: false,
|
||||||
/*
|
grouped: false,
|
||||||
if (rendererOptions["min"]) {
|
format: {
|
||||||
gauge["min"] = rendererOptions["min"];
|
title: function(_x) { return ""; },
|
||||||
}
|
name: function(_name, _ratio, _id, _index) { return ""; },
|
||||||
if (rendererOptions["max"]) {
|
value: function(value, _ratio, _id, _index) { return value; }
|
||||||
gauge["max"] = rendererOptions["max"];
|
}
|
||||||
}
|
},
|
||||||
*/
|
legend: { show: false }
|
||||||
if (rendererOptions["background"]) {
|
};
|
||||||
gauge["background"] = rendererOptions["background"];
|
if (showNeedle) {
|
||||||
}
|
model.arc = {
|
||||||
}
|
needle: {
|
||||||
var model = {
|
show: true,
|
||||||
bindto: "#"+wgt.$n().id,
|
value: wgt.getSeriesData()[1][0]
|
||||||
data: {
|
}
|
||||||
columns: [columns],
|
};
|
||||||
type: wgt._type
|
model.interaction = {
|
||||||
},
|
enabled: false
|
||||||
color: color,
|
};
|
||||||
gauge: gauge,
|
}
|
||||||
tooltip: {
|
return model;
|
||||||
show: true,
|
}
|
||||||
doNotHide: false,
|
|
||||||
grouped: false,
|
|
||||||
format: {
|
|
||||||
title: function(x) { return ""; },
|
|
||||||
name: function(name, ratio, id, index) { return ""; },
|
|
||||||
value: function(value, ratio, id, index) { return value; }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legend: {show: false}
|
|
||||||
};
|
|
||||||
return model;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
zul.billboard.Billboard._renderers["gauge"] = new billboard.GaugeRenderer();
|
zul.billboard.Billboard._renderers["gauge"] = new billboard.GaugeRenderer();
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -105,7 +105,7 @@ billboard.LineRenderer.prototype.render = function(wgt) {
|
||||||
var h = '<table class="bb-tooltip"><tbody><tr><th>';
|
var h = '<table class="bb-tooltip"><tbody><tr><th>';
|
||||||
h = h + defaultTitleFormat(c.x);
|
h = h + defaultTitleFormat(c.x);
|
||||||
h = h + '</th></tr><tr class="bb-tooltip-name-data"><td class="value">';
|
h = h + '</th></tr><tr class="bb-tooltip-name-data"><td class="value">';
|
||||||
h = h + c.value + '</td></tr></tbody></table>';
|
h = h + d3.format('.2f')(c.value) + '</td></tr></tbody></table>';
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -110,7 +110,7 @@ billboard.WaterfallRenderer.prototype.render = function(wgt) {
|
||||||
var h = '<table class="bb-tooltip"><tbody><tr><th>';
|
var h = '<table class="bb-tooltip"><tbody><tr><th>';
|
||||||
h = h + defaultTitleFormat(c.x);
|
h = h + defaultTitleFormat(c.x);
|
||||||
h = h + '</th></tr><tr class="bb-tooltip-name-data"><td class="value">';
|
h = h + '</th></tr><tr class="bb-tooltip-name-data"><td class="value">';
|
||||||
h = h + c.value[1] + '</td></tr></tbody></table>';
|
h = h + d3.format('.2f')(c.value[1]) + '</td></tr></tbody></table>';
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,8 @@
|
||||||
<package name="zul.billboard" language="xul/html" depends="zul">
|
<package name="zul.billboard" language="xul/html" depends="zul">
|
||||||
<widget name="Billboard" />
|
<widget name="Billboard" />
|
||||||
|
|
||||||
<script src="ext/billboard.pkgd.js" />
|
<script src="ext/d3.v6.js" />
|
||||||
|
<script src="ext/billboard.js" />
|
||||||
<script src="ext/billboard.gauge.js" />
|
<script src="ext/billboard.gauge.js" />
|
||||||
<script src="ext/billboard.bar.js" />
|
<script src="ext/billboard.bar.js" />
|
||||||
<script src="ext/billboard.line.js" />
|
<script src="ext/billboard.line.js" />
|
||||||
|
|
Loading…
Reference in New Issue