package org.orienteer.pivottable.component; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import org.apache.wicket.Component; import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.attributes.AjaxRequestAttributes; import org.apache.wicket.ajax.attributes.AjaxRequestAttributes.Method; import org.apache.wicket.core.util.lang.WicketObjects; import org.apache.wicket.event.IEvent; import org.apache.wicket.markup.head.CssHeaderItem; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.head.OnDomReadyHeaderItem; import org.apache.wicket.markup.html.panel.GenericPanel; import org.apache.wicket.model.IModel; import org.apache.wicket.request.cycle.RequestCycle; import org.apache.wicket.request.resource.CssResourceReference; import org.apache.wicket.request.resource.JavaScriptResourceReference; import org.apache.wicket.util.string.Strings; import org.apache.wicket.util.template.PackageTextTemplate; import org.apache.wicket.util.template.TextTemplate; import org.orienteer.core.component.property.DisplayMode; import org.orienteer.core.widget.support.jquery.JQueryDashboardSupport; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.MapMaker; import de.agilecoders.wicket.webjars.request.resource.WebjarsCssResourceReference; import de.agilecoders.wicket.webjars.request.resource.WebjarsJavaScriptResourceReference; /** * Panel to show pivot */ public class PivotPanel extends GenericPanel<String> { private static final WebjarsCssResourceReference PIVOT_CSS = new WebjarsCssResourceReference("/webjars/pivottable/current/dist/pivot.min.css"); private static final WebjarsJavaScriptResourceReference PIVOT_JS = new WebjarsJavaScriptResourceReference("/webjars/pivottable/current/dist/pivot.min.js"); private static final CssResourceReference PIVOT_CSS_FIX = new CssResourceReference(PivotPanel.class, "pivottable.css"); private static final WebjarsJavaScriptResourceReference D3_JS = new WebjarsJavaScriptResourceReference("/webjars/d3/current/d3.min.js"); private static final WebjarsJavaScriptResourceReference D3_RENDERERS_JS = new WebjarsJavaScriptResourceReference("/webjars/pivottable/current/dist/d3_renderers.min.js"); private static final WebjarsCssResourceReference C3_CSS = new WebjarsCssResourceReference("/webjars/c3/current/c3.min.css"); private static final WebjarsJavaScriptResourceReference C3_JS = new WebjarsJavaScriptResourceReference("/webjars/c3/current/c3.min.js"); private static final WebjarsJavaScriptResourceReference C3_RENDERERS_JS = new WebjarsJavaScriptResourceReference("/webjars/pivottable/current/dist/c3_renderers.min.js"); private static final List<String> SUPPORTED_LANGS = Arrays.asList("en", "es", "fr", "nl", "pt", "ru", "tr", "zh"); private static final Map<String, WebjarsJavaScriptResourceReference> LANGUAGES_MAP = new HashMap<>(); private final IModel<String> configModel; private final IModel<DisplayMode> modeModel; private final UpdatePivotTableBehavior updatePivotTableBehavior; private class UpdatePivotTableBehavior extends AbstractDefaultAjaxBehavior { @Override protected void updateAjaxAttributes(AjaxRequestAttributes attributes) { super.updateAjaxAttributes(attributes); attributes.getDynamicExtraParameters().add("return {config: JSON.stringify(cfg)};"); attributes.setMethod(Method.POST); } @Override protected void respond(AjaxRequestTarget target) { if(configModel!=null) configModel.setObject(RequestCycle.get().getRequest().getRequestParameters() .getParameterValue("config").toString()); } @Override public boolean isEnabled(Component component) { DisplayMode mode = modeModel!=null?modeModel.getObject():DisplayMode.VIEW; return DisplayMode.EDIT.equals(mode); } } public PivotPanel(String id, IModel<String> urlModel, IModel<DisplayMode> modeModel, IModel<String> configModel) { super(id, urlModel); setOutputMarkupId(true); this.modeModel = modeModel; this.configModel = configModel; add(updatePivotTableBehavior = new UpdatePivotTableBehavior()); } @Override public void detachModels() { super.detachModels(); modeModel.detach(); configModel.detach(); } protected JavaScriptResourceReference getLocalizationJSResource(String lang) { if(Strings.isEmpty(lang) || "en".equals(lang)) return null; WebjarsJavaScriptResourceReference ret = LANGUAGES_MAP.get(lang); if(ret==null) { ret = new WebjarsJavaScriptResourceReference("/webjars/pivottable/current/dist/pivot."+lang+".min.js"); LANGUAGES_MAP.put(lang, ret); } return ret; } @Override public void renderHead(IHeaderResponse response) { super.renderHead(response); response.render(CssHeaderItem.forReference(PIVOT_CSS)); response.render(CssHeaderItem.forReference(PIVOT_CSS_FIX)); response.render(CssHeaderItem.forReference(C3_CSS)); response.render(JavaScriptHeaderItem.forReference(JQueryDashboardSupport.JQUERY_UI_JS)); response.render(JavaScriptHeaderItem.forReference(PIVOT_JS)); response.render(JavaScriptHeaderItem.forReference(D3_JS)); response.render(JavaScriptHeaderItem.forReference(C3_JS)); response.render(JavaScriptHeaderItem.forReference(D3_RENDERERS_JS)); response.render(JavaScriptHeaderItem.forReference(C3_RENDERERS_JS)); String lang = getLocale().getLanguage(); if(SUPPORTED_LANGS.indexOf(lang)<0) lang = "en"; JavaScriptResourceReference langRes = getLocalizationJSResource(lang); if(langRes!=null) response.render(JavaScriptHeaderItem.forReference(langRes)); TextTemplate template = new PackageTextTemplate(PivotPanel.class, "pivottable.tmpl.js"); Map<String, Object> params = new HashMap<String, Object>(); params.put("componentId", getMarkupId()); params.put("dataUrl", getModelObject().replace("'", "\\'")); params.put("config", Strings.defaultIfEmpty(configModel.getObject(), "{}")); params.put("editMode", DisplayMode.EDIT.equals(modeModel.getObject())); params.put("callBackScript", updatePivotTableBehavior.getCallbackScript()); params.put("language", lang); template.interpolate(params); response.render(OnDomReadyHeaderItem.forScript(template.asString())); } }