/**
* Copyright 2012 Universitat Pompeu Fabra.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/
package org.onexus.website.api.pages.search.figures.bar;
import org.apache.wicket.markup.head.HeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.markup.head.OnLoadHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.resource.JQueryPluginResourceReference;
import org.apache.wicket.util.string.Strings;
import org.onexus.collection.api.ICollectionManager;
import org.onexus.collection.api.IEntityTable;
import org.onexus.collection.api.query.Filter;
import org.onexus.collection.api.query.Query;
import org.onexus.collection.api.utils.QueryUtils;
import org.onexus.resource.api.ORI;
import org.onexus.website.api.pages.browser.IEntitySelection;
import org.onexus.website.api.utils.HtmlDataResourceModel;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class BarFigurePanel extends Panel {
@Inject
private ICollectionManager collectionManager;
private ORI parentOri;
private IEntitySelection selection;
private BarFigureConfig config;
private WebMarkupContainer chart;
private static final HeaderItem JS_HIGHCHARTS = JavaScriptHeaderItem.forReference(new JQueryPluginResourceReference(BarFigurePanel.class, "highcharts.js"));
public BarFigurePanel(String id, ORI parentOri, IEntitySelection selection, BarFigureConfig config) {
super(id);
this.parentOri = parentOri;
this.selection = selection;
this.config = config;
chart = new WebMarkupContainer("chart");
chart.setOutputMarkupId(true);
add(chart);
}
@Override
public void renderHead(IHeaderResponse response) {
response.render(JS_HIGHCHARTS);
response.render(OnLoadHeaderItem.forScript(newJavaScript()));
}
private Query createQuery() {
Query query = new Query();
query.setOn(parentOri);
CollectionField value = config.getValue();
CollectionField xAxis = config.getxAxis();
CollectionField yAxis = config.getyAxis();
String valueAlias = QueryUtils.newCollectionAlias(query, value.getCollection());
String xAxisAlias = QueryUtils.newCollectionAlias(query, xAxis.getCollection());
String yAxisAlias = QueryUtils.newCollectionAlias(query, yAxis.getCollection());
query.setFrom(valueAlias);
query.addSelect(valueAlias, Arrays.asList(value.getField()));
query.addSelect(xAxisAlias, Arrays.asList(xAxis.getField()));
query.addSelect(yAxisAlias, Arrays.asList(yAxis.getField()));
if (selection != null) {
Filter filter = selection.buildFilter(query);
QueryUtils.and(query, filter);
}
return query;
}
private String newJavaScript() {
StringBuilder code = new StringBuilder();
Query query = createQuery();
CollectionField value = config.getValue();
CollectionField xAxis = config.getxAxis();
CollectionField yAxis = config.getyAxis();
IEntityTable table = collectionManager.load(query);
List<String> categories = new ArrayList<String>();
Map<String, Map<String, String>> values = new HashMap<String, Map<String, String>>();
while (table.next()) {
String xAxisData = String.valueOf(table.getEntity(xAxis.getCollection()).get(xAxis.getField()));
String yAxisData = String.valueOf(table.getEntity(yAxis.getCollection()).get(yAxis.getField()));
String valueData = String.valueOf(table.getEntity(value.getCollection()).get(value.getField()));
if (!categories.contains(xAxisData)) {
categories.add(xAxisData);
}
if (!values.containsKey(yAxisData)) {
values.put(yAxisData, new HashMap<String, String>());
}
values.get(yAxisData).put(xAxisData, valueData);
}
table.close();
code.append("$(function () { $('#");
code.append(chart.getMarkupId());
String initUrl = config.getInit();
String init;
if (Strings.isEmpty(initUrl)) {
init = " chart: {\n" +
" type: 'bar'\n" +
" },\n" +
"\n" +
" title: {\n" +
" text: null\n" +
" },\n" +
"\n" +
" xAxis: {\n" +
" labels: {\n" +
" enabled: " + (categories.size() > 30 ? "false" : "true") + "\n" +
" }," +
" categories: [ ${categories} ]\n" +
" },\n" +
" yAxis: {\n" +
" min: 0,\n" +
" title: {\n" +
" text: 'mutated samples'\n" +
" }\n" +
" },\n" +
" tooltip: {\n" +
" valueDecimals: 0,\n" +
" valueSuffix: ' samples'\n" +
" },\n" +
" plotOptions: {\n" +
" series: {\n" +
" stacking: 'normal'\n" +
" }\n" +
" },\n" +
" legend: {\n" +
" layout: 'vertical',\n" +
" align: 'right',\n" +
" verticalAlign: 'top',\n" +
" x: 0,\n" +
" y: 30,\n" +
" floating: false,\n" +
" borderWidth: 1,\n" +
" backgroundColor: '#FFFFFF',\n" +
" shadow: true,\n" +
" labelFormatter: function() {\n" +
" return this.name.length>20 ? this.name.substr(0,19)+'...' : this.name;\n" +
" }" +
" },\n" +
" credits: {\n" +
" enabled: false\n" +
" },\n" +
" series: [ ${series} ] ";
} else {
IModel<String> initModel = new HtmlDataResourceModel(parentOri, initUrl);
init = initModel.getObject();
}
// Build categories
StringBuilder categoriesText = new StringBuilder();
Iterator<String> categoriesIterator = categories.iterator();
while (categoriesIterator.hasNext()) {
categoriesText.append("'").append(categoriesIterator.next()).append("'");
if (categoriesIterator.hasNext()) {
categoriesText.append(", ");
}
}
init = init.replace("${categories}", categoriesText.toString());
// Build series
StringBuilder seriesText = new StringBuilder();
Iterator<String> seriesIterator = values.keySet().iterator();
while (seriesIterator.hasNext()) {
String serieName = seriesIterator.next();
seriesText.append("{ name: '").append(serieName).append("'\n, data: [");
categoriesIterator = categories.iterator();
while (categoriesIterator.hasNext()) {
seriesText.append(values.get(serieName).get(categoriesIterator.next()));
if (categoriesIterator.hasNext()) {
seriesText.append(", ");
}
}
if (seriesIterator.hasNext()) {
seriesText.append("] }, \n");
} else {
seriesText.append("] }\n");
}
}
init = init.replace("${series}", seriesText.toString());
code.append("').highcharts({" + init + "});})");
return code.toString();
}
}