| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.apache.openmeetings.web.room.poll; |
| |
| import static org.apache.openmeetings.web.app.Application.getBean; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import org.apache.openmeetings.db.dao.room.PollDao; |
| import org.apache.openmeetings.db.entity.room.RoomPoll; |
| import org.apache.openmeetings.db.entity.room.RoomPollAnswers; |
| import org.apache.openmeetings.web.app.Application; |
| import org.apache.wicket.ajax.AjaxRequestTarget; |
| import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; |
| import org.apache.wicket.core.request.handler.IPartialPageRequestHandler; |
| 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.html.WebMarkupContainer; |
| import org.apache.wicket.markup.html.basic.Label; |
| import org.apache.wicket.markup.html.form.ChoiceRenderer; |
| import org.apache.wicket.markup.html.form.DropDownChoice; |
| import org.apache.wicket.markup.html.form.Form; |
| import org.apache.wicket.model.IModel; |
| import org.apache.wicket.model.Model; |
| import org.apache.wicket.request.resource.JavaScriptResourceReference; |
| import org.wicketstuff.jqplot.behavior.JqPlotBehavior; |
| import org.wicketstuff.jqplot.behavior.JqPlotCssResourceReference; |
| import org.wicketstuff.jqplot.behavior.JqPlotJavascriptResourceReference; |
| |
| import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractDialog; |
| import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton; |
| import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButtons; |
| import com.googlecode.wicket.jquery.ui.widget.dialog.DialogIcon; |
| import com.googlecode.wicket.jquery.ui.widget.dialog.MessageDialog; |
| |
| import br.com.digilabs.jqplot.Chart; |
| import br.com.digilabs.jqplot.ChartConfiguration; |
| import br.com.digilabs.jqplot.JqPlotResources; |
| import br.com.digilabs.jqplot.JqPlotUtils; |
| import br.com.digilabs.jqplot.chart.BarChart; |
| import br.com.digilabs.jqplot.chart.PieChart; |
| import br.com.digilabs.jqplot.elements.Highlighter; |
| import br.com.digilabs.jqplot.elements.Location; |
| import br.com.digilabs.jqplot.elements.RendererOptions; |
| |
| /** |
| * @author solomax |
| * |
| */ |
| public class PollResultsDialog extends AbstractDialog<RoomPoll> { |
| private static final long serialVersionUID = 1L; |
| private final WebMarkupContainer chartDiv = new WebMarkupContainer("chart"); |
| private final long roomId; |
| private final PollSelectForm selForm; |
| private final PollResultsForm dispForm; |
| private final DialogButton cancel = new DialogButton("cancel", Application.getString(25)); |
| private final DialogButton close = new DialogButton("close", Application.getString(1418)); |
| private final DialogButton delete = new DialogButton("delete", Application.getString(1420)); |
| private boolean moderator = false; |
| private final MessageDialog closeConfirm; |
| private final MessageDialog deleteConfirm; |
| |
| public PollResultsDialog(String id, long _roomId) { |
| super(id, Application.getString(37)); |
| this.roomId = _roomId; |
| add(selForm = new PollSelectForm("selForm")); |
| add(dispForm = new PollResultsForm("dispForm")); |
| add(closeConfirm = new MessageDialog("closeConfirm", Application.getString(1418), Application.getString(1419), DialogButtons.YES_NO, DialogIcon.WARN) { |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| public void onClose(IPartialPageRequestHandler handler, DialogButton button) { |
| // TODO should rights be additionally checked here???? |
| if(button != null && button.match(YES)) { |
| Long id = dispForm.getModelObject().getRoomPollId(); |
| getBean(PollDao.class).closePoll(roomId); |
| selForm.updateModel(handler); |
| |
| RoomPoll p = getBean(PollDao.class).getPoll(id); |
| selForm.select.setModelObject(p); |
| dispForm.updateModel(p, false, handler); |
| //TODO result dialogs of other users should also be updated |
| } |
| } |
| }); |
| add(deleteConfirm = new MessageDialog("deleteConfirm", Application.getString(1420), Application.getString(1421), DialogButtons.YES_NO, DialogIcon.WARN) { |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| public void onClose(IPartialPageRequestHandler handler, DialogButton button) { |
| // TODO should rights be additionally checked here???? |
| if(button != null && button.match(YES)) { |
| getBean(PollDao.class).deletePoll(dispForm.getModelObject().getRoomPollId()); |
| selForm.updateModel(handler); |
| dispForm.updateModel(selForm.select.getModelObject(), true, handler); |
| //TODO result dialogs of other users should also be updated |
| } |
| } |
| }); |
| } |
| |
| @Override |
| public int getWidth() { |
| return 500; |
| } |
| |
| @Override |
| protected List<DialogButton> getButtons() { |
| return Arrays.asList(delete, close, cancel); |
| } |
| |
| public void updateModel(AjaxRequestTarget target, boolean moderator) { |
| selForm.updateModel(target); |
| this.moderator = moderator; |
| RoomPoll p = selForm.select.getModelObject(); |
| dispForm.updateModel(p, false, target); |
| StringBuilder builder = new StringBuilder(); |
| builder.append("$('#").append(PollResultsDialog.this.getMarkupId()).append("').on('dialogopen', function( event, ui ) {"); |
| builder.append(getScript(barChart(p))); |
| builder.append("});"); |
| |
| target.appendJavaScript(builder.toString()); |
| } |
| |
| private StringBuilder getScript(Chart<?> chart) { |
| StringBuilder builder = new StringBuilder(); |
| builder.append("$('#").append(chartDiv.getMarkupId()).append("').html(''); "); |
| builder.append("$.jqplot('").append(chartDiv.getMarkupId()).append("', "); |
| builder.append(chart.getChartData().toJsonString()); |
| builder.append(", "); |
| builder.append(JqPlotUtils.jqPlotToJson(chart.getChartConfiguration())); |
| builder.append(");"); |
| return builder; |
| } |
| |
| @Override |
| public void renderHead(IHeaderResponse response) { |
| super.renderHead(response); |
| response.render(JavaScriptHeaderItem.forReference(JqPlotJavascriptResourceReference.get())); |
| response.render(CssHeaderItem.forReference(JqPlotCssResourceReference.get())); |
| Chart<?> c1 = new PieChart<Number>(null); |
| c1.getChartConfiguration().setHighlighter(new Highlighter()); |
| for (Chart<?> chart : new Chart<?>[]{c1, new BarChart<Integer>(null)}) { |
| for (String resource : JqPlotUtils.retriveJavaScriptResources(chart)) { |
| response.render(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(JqPlotBehavior.class, removeMinified(resource)))); |
| } |
| } |
| } |
| |
| private String removeMinified(String name_) { |
| String name = name_; |
| int idxOfExtension = name.lastIndexOf('.'); |
| if (idxOfExtension > -1) { |
| String extension = name.substring(idxOfExtension); |
| name = name.substring(0, name.length() - extension.length() + 1); |
| if (name.endsWith(".min.")) |
| { |
| name = name.substring(0, name.length() - 5) + extension; |
| } |
| } |
| return name; |
| } |
| |
| @Override |
| public void onClick(AjaxRequestTarget target, DialogButton button) { |
| if (close.equals(button)) { |
| closeConfirm.open(target); |
| } else if (delete.equals(button)) { |
| deleteConfirm.open(target); |
| } else { |
| super.onClick(target, button); |
| } |
| } |
| |
| @Override |
| public void onClose(IPartialPageRequestHandler handler, DialogButton button) { |
| } |
| |
| private String[] getTicks(RoomPoll p) { |
| return p != null && p.getPollType().getIsNumericAnswer() |
| ? new String[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"} |
| : new String[] {Application.getString(34), Application.getString(35)}; |
| } |
| |
| private Integer[] initValues(int size) { |
| Integer[] values = new Integer[size]; |
| for (int i = 0; i < size; ++i) { |
| values[i] = 0; |
| } |
| return values; |
| } |
| |
| private Integer[] getValues(RoomPoll p) { |
| Integer[] values = initValues(p != null && p.getPollType().getIsNumericAnswer() ? 10 : 2); |
| if (p != null && p.getPollType().getIsNumericAnswer()) { |
| for (RoomPollAnswers a : p.getRoomPollAnswerList()) { |
| values[a.getPointList() - 1] ++; |
| } |
| } else if (p != null) { |
| for (RoomPollAnswers a : p.getRoomPollAnswerList()) { |
| values[a.getAnswer() ? 0 : 1] ++; |
| } |
| } |
| return values; |
| } |
| |
| private PieChart<Integer> pieChart(RoomPoll p) { |
| PieChart<Integer> pieChart = new PieChart<Integer>(null); |
| String[] ticks = getTicks(p); |
| Integer[] values = getValues(p); |
| for (int i = 0; i < values.length; ++i) { |
| pieChart.addValue(ticks[i], values[i]); |
| } |
| |
| pieChart.getSeriesDefaults().setRendererOptions( |
| new RendererOptions().setHighlightMouseDown(true).setShowDataLabels(true) |
| .setFill(false).setSliceMargin(4).setLineWidth(5)); |
| |
| Highlighter h = new Highlighter(); |
| h.setShow(true); |
| h.setFormatString("%s, %P"); |
| h.setTooltipLocation(Location.ne); |
| h.setShowTooltip(true); |
| h.setUseAxesFormatters(false); |
| |
| pieChart.getChartConfiguration().setLegend(null).setHighlighter(h); |
| return pieChart; |
| } |
| |
| private BarChart<Integer> barChart(RoomPoll p) { |
| String[] ticks = getTicks(p); |
| BarChart<Integer> barChart = new BarChart<Integer>(null); |
| barChart.addValue(Arrays.asList(getValues(p))); |
| |
| barChart.getSeriesDefaults().setRendererOptions( |
| new RendererOptions().setHighlightMouseDown(true).setShowDataLabels(true) |
| .setFill(false).setSliceMargin(4).setLineWidth(5).setBarDirection("horizontal")); |
| |
| Highlighter h = new Highlighter(); |
| h.setShow(true); |
| h.setFormatString("%s, %P"); |
| h.setTooltipLocation(Location.ne); |
| h.setShowTooltip(true); |
| h.setUseAxesFormatters(false); |
| |
| ChartConfiguration<Long> cfg = barChart.getChartConfiguration(); |
| cfg.setLegend(null).setHighlighter(h); |
| cfg.axesInstance().setXaxis(null); |
| /*cfg.axesInstance().xAxisInstance().setRenderer(JqPlotResources.AxisTickRenderer);*/ |
| cfg.axesInstance() |
| .yAxisInstance() |
| .setTicks(ticks) |
| .setRenderer(JqPlotResources.CategoryAxisRenderer); |
| return barChart; |
| } |
| |
| private class PollSelectForm extends Form<RoomPoll> { |
| private static final long serialVersionUID = 1L; |
| private final DropDownChoice<RoomPoll> select; |
| |
| PollSelectForm(String id) { |
| super(id); |
| add((select = new DropDownChoice<RoomPoll>("polls", Model.of((RoomPoll)null), new ArrayList<RoomPoll>(), new ChoiceRenderer<RoomPoll>() { |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| public Object getDisplayValue(RoomPoll object) { |
| return object == null ? "" : String.format("%s%s", object.getPollName(), object.isArchived() ? "" : String.format(" (%s)", Application.getString(1413))); |
| } |
| |
| @Override |
| public String getIdValue(RoomPoll object, int index) { |
| return object == null ? "" : "" + object.getRoomPollId(); |
| } |
| })).add(new AjaxFormComponentUpdatingBehavior("change") { |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| protected void onUpdate(AjaxRequestTarget target) { |
| dispForm.updateModel(select.getModelObject(), true, target); |
| } |
| })); |
| updateModel(null); |
| } |
| |
| public void updateModel(IPartialPageRequestHandler handler) { |
| List<RoomPoll> list = new ArrayList<RoomPoll>(); |
| RoomPoll p = getBean(PollDao.class).getPoll(roomId); |
| if (p != null) { |
| list.add(p); |
| } |
| list.addAll(getBean(PollDao.class).getArchivedPollList(roomId)); |
| select.setChoices(list); |
| select.setModelObject(list.isEmpty() ? null : list.get(0)); |
| if (handler != null) { |
| handler.add(this); |
| } |
| } |
| } |
| |
| private class PollResultsForm extends Form<RoomPoll> { |
| private static final long serialVersionUID = 1L; |
| private final String SIMPLE_CHART = Application.getString(1414); |
| private final String PIE_CHART = Application.getString(1415); |
| private final IModel<String> name = Model.of((String)null); |
| private final IModel<Integer> count = Model.of(0); |
| private final DropDownChoice<String> chartType = new DropDownChoice<String>("chartType", Model.of(SIMPLE_CHART), Arrays.asList(SIMPLE_CHART, PIE_CHART)); |
| |
| PollResultsForm(String id) { |
| super(id, Model.of((RoomPoll)null)); |
| setOutputMarkupId(true); |
| add(new Label("name", name)); |
| add(new Label("question")); |
| add(new Label("count", count)); |
| add(chartType.add(new AjaxFormComponentUpdatingBehavior("change") { |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| protected void onUpdate(AjaxRequestTarget target) { |
| redraw(target); |
| } |
| })); |
| add(chartDiv.setOutputMarkupId(true)); |
| } |
| |
| public void updateModel(RoomPoll poll, boolean redraw, IPartialPageRequestHandler handler) { |
| setModelObject(poll); |
| name.setObject(poll == null ? "" : VoteDialog.getName(poll.getCreatedBy())); |
| count.setObject(poll == null ? 0 : poll.getRoomPollAnswerList().size()); |
| handler.add(this); |
| close.setVisible(moderator && (poll != null && !poll.isArchived()), handler); |
| delete.setVisible(moderator, handler); |
| if (redraw) { |
| redraw(handler); |
| } |
| } |
| |
| private void redraw(IPartialPageRequestHandler handler) { |
| RoomPoll poll = getModelObject(); |
| Chart<?> chart = SIMPLE_CHART.equals(chartType.getModelObject()) ? barChart(poll) : pieChart(poll); |
| handler.appendJavaScript(getScript(chart)); |
| } |
| |
| @Override |
| protected void onDetach() { |
| name.detach(); |
| count.detach(); |
| super.onDetach(); |
| } |
| } |
| } |