1 package org.argeo.tracker.ui.controls;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.util.Map;
6
7 import org.apache.commons.io.IOUtils;
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10 import org.argeo.cms.util.CmsUtils;
11 import org.argeo.eclipse.ui.EclipseUiUtils;
12 import org.argeo.tracker.TrackerException;
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.SWTException;
15 import org.eclipse.swt.browser.Browser;
16 import org.eclipse.swt.browser.ProgressEvent;
17 import org.eclipse.swt.browser.ProgressListener;
18 import org.eclipse.swt.layout.GridData;
19 import org.eclipse.swt.widgets.Composite;
20
21
22 public class RepartitionChart extends Composite {
23 private static final long serialVersionUID = -2758463753509540538L;
24 private final Log log = LogFactory.getLog(RepartitionChart.class);
25
26 private final static String[] COLORS = { "#FF6384", "#FFCE56", "#36A2EB", "#FF99FF", "#84ff63", "#CE506B",
27 "#DEB390", "#C89127", "#024913", "#b59bc6", "#0e2024" };
28
29 private String options = "options: { " + "legend: { display: true, position: 'right' } , "
30 + "title: { display: true, position: 'bottom', fontSize: 15, "
31 + "fontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\", "
32 + "fontColor: '#909B9B', fontStyle: 'normal', text: customisedTitle }, "
33 + "animation:{animateScale:true}"
34 + "}";
35
36 public RepartitionChart(Composite parent, int style) {
37 super(parent, style);
38 }
39
40 public void setInput(String title, Map<String, String> valueMap, int width, int height) {
41 Composite parent = this;
42 parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
43 CmsUtils.clear(parent);
44
45 StringBuilder labels = new StringBuilder();
46 StringBuilder data = new StringBuilder();
47 StringBuilder bgColors = new StringBuilder();
48 StringBuilder hoColors = new StringBuilder();
49
50 int i = 0;
51 for (String name : valueMap.keySet()) {
52 labels.append("'").append(name).append("', ");
53 data.append(valueMap.get(name)).append(", ");
54 bgColors.append("'").append(COLORS[i]).append("', ");
55 hoColors.append("'").append(COLORS[i]).append("', ");
56 i++;
57 }
58
59 final String jscData = "{labels: [" + labels.substring(0, labels.length() - 2) + "], datasets: [{ "
60 + "borderWidth: 0.5, borderColor:'#909B9B', data: ["
61 + data.substring(0, data.length() - 2) + "], " + " backgroundColor: [ "
62 + bgColors.substring(0, bgColors.length() - 2) + "], " + " hoverBackgroundColor: [ "
63 + hoColors.substring(0, hoColors.length() - 2) + "] " + "} ]}";
64
65 final Browser browser = new Browser(parent, SWT.NONE);
66 browser.setLayoutData(new GridData(width, height));
67 String html;
68 InputStream in = null;
69 try {
70 in = getClass().getResourceAsStream("/org/argeo/tracker/ui/charts/RepartitionPie.html");
71 html = IOUtils.toString(in);
72 } catch (IOException e) {
73 throw new TrackerException("Cannot read HTML", e);
74 } finally {
75 IOUtils.closeQuietly(in);
76 }
77 browser.addProgressListener(new ProgressListener() {
78 private static final long serialVersionUID = 2852043674756868097L;
79
80 @Override
81 public void completed(ProgressEvent event) {
82 try {
83 String type = "pie";
84 StringBuilder js = new StringBuilder();
85 js.append("var customisedTitle='").append(title).append("';\n");
86 js.append("var chartData=").append(jscData).append(";\n");
87 js.append("new Chart(").append("document.getElementById('chart').getContext('2d'),").append("{")
88 .append("type:'").append(type).append("',").append("data:chartData,\n").append(options)
89 .append("});");
90 try {
91 if (log.isTraceEnabled())
92 log.debug(js.toString());
93 browser.evaluate(js.toString());
94 } catch (SWTException e) {
95 log.error(e.getMessage() + "\n" + js + "\n");
96 }
97 } catch (Exception e) {
98 new TrackerException("Unable to prepare chart", e);
99 }
100 }
101
102 @Override
103 public void changed(ProgressEvent event) {
104 }
105 });
106 browser.setText(html);
107 parent.layout(true, true);
108 }
109
110 @Override
111 public boolean setFocus() {
112 return true;
113 }
114 }