From 1e2d2f2495e8409b4be31ff947864167a67fd6bb Mon Sep 17 00:00:00 2001 From: tryan Date: Mon, 7 Apr 2014 16:04:45 +1000 Subject: Switch to self-hosted flotr2 graphs from Google Charts --- .../java/com/gitblit/wicket/charting/Chart.java | 145 +++++ .../java/com/gitblit/wicket/charting/Charts.java | 48 ++ .../gitblit/wicket/charting/Flotr2BarChart.java | 167 ++++++ .../com/gitblit/wicket/charting/Flotr2Charts.java | 76 +++ .../gitblit/wicket/charting/Flotr2LineChart.java | 150 +++++ .../gitblit/wicket/charting/Flotr2PieChart.java | 112 ++++ .../com/gitblit/wicket/charting/GoogleChart.java | 107 ---- .../com/gitblit/wicket/charting/GoogleCharts.java | 67 --- .../gitblit/wicket/charting/GoogleLineChart.java | 60 -- .../gitblit/wicket/charting/GooglePieChart.java | 86 --- .../com/gitblit/wicket/charting/SecureChart.java | 633 --------------------- .../wicket/charting/SecureChartDataEncoding.java | 102 ---- .../com/gitblit/wicket/pages/ActivityPage.java | 27 +- .../com/gitblit/wicket/pages/DashboardPage.java | 14 +- .../java/com/gitblit/wicket/pages/MetricsPage.html | 12 +- .../java/com/gitblit/wicket/pages/MetricsPage.java | 123 ++-- .../com/gitblit/wicket/pages/MyDashboardPage.html | 4 +- .../com/gitblit/wicket/pages/OverviewPage.java | 11 +- .../java/com/gitblit/wicket/pages/SummaryPage.html | 2 +- .../java/com/gitblit/wicket/pages/SummaryPage.java | 82 +-- 20 files changed, 838 insertions(+), 1190 deletions(-) create mode 100644 src/main/java/com/gitblit/wicket/charting/Chart.java create mode 100644 src/main/java/com/gitblit/wicket/charting/Charts.java create mode 100644 src/main/java/com/gitblit/wicket/charting/Flotr2BarChart.java create mode 100644 src/main/java/com/gitblit/wicket/charting/Flotr2Charts.java create mode 100644 src/main/java/com/gitblit/wicket/charting/Flotr2LineChart.java create mode 100644 src/main/java/com/gitblit/wicket/charting/Flotr2PieChart.java delete mode 100644 src/main/java/com/gitblit/wicket/charting/GoogleChart.java delete mode 100644 src/main/java/com/gitblit/wicket/charting/GoogleCharts.java delete mode 100644 src/main/java/com/gitblit/wicket/charting/GoogleLineChart.java delete mode 100644 src/main/java/com/gitblit/wicket/charting/GooglePieChart.java delete mode 100644 src/main/java/com/gitblit/wicket/charting/SecureChart.java delete mode 100644 src/main/java/com/gitblit/wicket/charting/SecureChartDataEncoding.java (limited to 'src/main/java/com/gitblit') diff --git a/src/main/java/com/gitblit/wicket/charting/Chart.java b/src/main/java/com/gitblit/wicket/charting/Chart.java new file mode 100644 index 00000000..331b386a --- /dev/null +++ b/src/main/java/com/gitblit/wicket/charting/Chart.java @@ -0,0 +1,145 @@ +/* + * Copyright 2011 gitblit.com. + * + * 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 com.gitblit.wicket.charting; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +import com.gitblit.Keys; +import com.gitblit.utils.StringUtils; +import com.gitblit.wicket.GitBlitWebApp; +import com.gitblit.wicket.GitBlitWebSession; + +/** + * Abstract parent class for different type of chart: bar, pie & line + * + * @author James Moger + * + */ +public abstract class Chart implements Serializable { + + private static final long serialVersionUID = 1L; + final String tagId; + final String dataName; + final String title; + final String keyName; + final String valueName; + final List values; + final List highlights; + int width; + int height; + boolean showLegend; + String dateFormat = "MMM dd"; + String clickUrl = null; + + public Chart(String tagId, String title, String keyName, String valueName) { + this.tagId = tagId; + this.dataName = StringUtils.getSHA1(tagId).substring(0, 8); + this.title = title; + this.keyName = keyName; + this.valueName = valueName; + values = new ArrayList(); + highlights = new ArrayList(); + showLegend = true; + } + + public void setWidth(int width) { + this.width = width; + } + + public void setHeight(int height) { + this.height = height; + } + + public void setShowLegend(boolean val) { + this.showLegend = val; + } + + public void addValue(String name, int value) { + values.add(new ChartValue(name, value)); + } + + public void addValue(String name, float value) { + values.add(new ChartValue(name, value)); + } + + public void addValue(String name, double value) { + values.add(new ChartValue(name, (float) value)); + } + + public void addValue(Date date, int value) { + values.add(new ChartValue(String.valueOf(date.getTime()), value)); + } + + public void addHighlight(Date date, int value) { + highlights.add(new ChartValue(String.valueOf(date.getTime()), value)); + } + + protected abstract void appendChart(StringBuilder sb); + + protected void line(StringBuilder sb, String line) { + sb.append(line); + sb.append('\n'); + } + + protected TimeZone getTimeZone() { + return GitBlitWebApp.get().settings().getBoolean(Keys.web.useClientTimezone, false) ? GitBlitWebSession.get() + .getTimezone() : GitBlitWebApp.get().getTimezone(); + } + + protected class ChartValue implements Serializable, Comparable { + + private static final long serialVersionUID = 1L; + + final String name; + final float value; + + ChartValue(String name, float value) { + this.name = name; + this.value = value; + } + + @Override + public int compareTo(ChartValue o) { + // sorts the dataset by largest value first + if (value > o.value) { + return -1; + } else if (value < o.value) { + return 1; + } + return 0; + } + } + + public String getDateFormat() { + return dateFormat; + } + + public void setDateFormat(String dateFormat) { + this.dateFormat = dateFormat; + } + + public String getClickUrl() { + return clickUrl; + } + + public void setClickUrl(String clickUrl) { + this.clickUrl = clickUrl; + } +} diff --git a/src/main/java/com/gitblit/wicket/charting/Charts.java b/src/main/java/com/gitblit/wicket/charting/Charts.java new file mode 100644 index 00000000..54a7689b --- /dev/null +++ b/src/main/java/com/gitblit/wicket/charting/Charts.java @@ -0,0 +1,48 @@ +/* + * Copyright 2011 gitblit.com. + * + * 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 com.gitblit.wicket.charting; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.wicket.markup.html.IHeaderContributor; + +/** + * Abstract parent class for Flotr2 Charts + * + * @author Tim Ryan + * + */ +public abstract class Charts implements IHeaderContributor { + + private static final long serialVersionUID = 1L; + + public final List charts = new ArrayList(); + + public void addChart(Chart chart) { + charts.add(chart); + } + + protected void line(StringBuilder sb, String line) { + sb.append(line); + sb.append('\n'); + } + + public abstract Chart createPieChart(String tagId, String title, String keyName, String valueName); + public abstract Chart createLineChart(String tagId, String title, String keyName, String valueName); + public abstract Chart createBarChart(String tagId, String title, String keyName, String valueName); + +} diff --git a/src/main/java/com/gitblit/wicket/charting/Flotr2BarChart.java b/src/main/java/com/gitblit/wicket/charting/Flotr2BarChart.java new file mode 100644 index 00000000..4f07555e --- /dev/null +++ b/src/main/java/com/gitblit/wicket/charting/Flotr2BarChart.java @@ -0,0 +1,167 @@ +/* + * Copyright 2011 gitblit.com. + * + * 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 com.gitblit.wicket.charting; + +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; + +/** + * Implementation of a Bar chart using the flotr2 library + * + * @author Tim Ryan + * + */ +public class Flotr2BarChart extends Chart { + + private static final long serialVersionUID = 1L; + boolean xAxisIsDate = false; + + public Flotr2BarChart(String tagId, String title, String keyName, + String valueName) { + super(tagId, title, keyName, valueName); + + } + + @Override + protected void appendChart(StringBuilder sb) { + + String dName = "data_" + dataName; + sb.append("var labels_" + dataName + " = ["); + if(xAxisIsDate){ + + // Generate labels for the dates + SimpleDateFormat df = new SimpleDateFormat(dateFormat); + df.setTimeZone(getTimeZone()); + + // Sort the values first + Collections.sort(values, new Comparator() { + + public int compare(ChartValue o1, ChartValue o2) { + long long1 = Long.parseLong(o1.name); + long long2 = Long.parseLong(o2.name); + return (int) (long2 - long1); + } + + }); + + + for (int i = 0; i < values.size(); i++) { + ChartValue value = values.get(i); + Date date = new Date(Long.parseLong(value.name)); + String label = df.format(date); + if(i > 0){ + sb.append(","); + } + sb.append("[\"" + label + "\", " + value.name + "]"); + } + + } + else { + for (int i = 0; i < values.size(); i++) { + ChartValue value = values.get(i); + if(i > 0){ + sb.append(","); + } + sb.append("\"" + value.name + "\""); + } + } + line(sb, "];"); + + line(sb, MessageFormat.format("var {0} = Flotr.draw(document.getElementById(''{1}''),", dName, tagId)); + + // Add the data + line(sb, "["); + line(sb, "{ data : [ "); + for (int i = 0; i < values.size(); i++) { + ChartValue value = values.get(i); + if(i > 0){ + sb.append(","); + } + if(xAxisIsDate){ + line(sb, MessageFormat.format("[{0}, {1}] ", value.name, Float.toString(value.value))); + } + else { + line(sb, MessageFormat.format("[{0}, {1}] ", Integer.toString(i), Float.toString(value.value))); + } + + } + line(sb, MessageFormat.format(" ], label : ''{0}'', color: ''#FF9900'' '}'", valueName)); + line(sb, "]"); + + // Add the options + line(sb, ", {"); + if(title != null && title.isEmpty() == false){ + line(sb, MessageFormat.format("title : ''{0}'',", title)); + } + line(sb, "bars : {"); + line(sb, " show : true,"); + line(sb, " horizontal : false,"); + line(sb, " barWidth : 1"); + line(sb, "},"); + line(sb, "points: { show: false },"); + line(sb, "mouse: {"); + line(sb, " track: true,"); + line(sb, " lineColor: '#002060',"); + line(sb, " position: 'ne',"); + line(sb, " trackFormatter: function (obj) {"); + line(sb, " return labels_" + dataName + "[obj.index] + ': ' + parseInt(obj.y) + ' ' + obj.series.label;"); + line(sb, " }"); + line(sb, "},"); + line(sb, "xaxis: {"); + line(sb, " showLabels: true,"); + line(sb, " showMinorLabels: false,"); + line(sb, " tickFormatter: function (x) {"); + line(sb, " var index = parseInt(x);"); + line(sb, " if(x % 1 == 0 && labels_" + dataName + "[index])"); + line(sb, " return labels_" + dataName + "[index];"); + line(sb, " return \"\";"); + line(sb, " },"); + line(sb, " margin: 10"); + line(sb, "},"); + line(sb, "yaxis: {"); + line(sb, " showLabels: false,"); + line(sb, " showMinorLabels: false,"); + line(sb, " tickDecimals: 0,"); + line(sb, " margin: 10"); + line(sb, "},"); + line(sb, "grid: {"); + line(sb, " verticalLines: false,"); + line(sb, " minorVerticalLines: null,"); + line(sb, " horizontalLines: true,"); + line(sb, " minorHorizontalLines: null,"); + line(sb, " outlineWidth: 1,"); + line(sb, " outline: 's'"); + line(sb, "},"); + line(sb, "legend: {"); + line(sb, " show: false"); + line(sb, "}"); + line(sb, "});"); + + } + + @Override + public void addValue(Date date, int value) { + xAxisIsDate = true; + String name = String.valueOf(date.getTime()); + super.addValue(name, value); + } + + + +} diff --git a/src/main/java/com/gitblit/wicket/charting/Flotr2Charts.java b/src/main/java/com/gitblit/wicket/charting/Flotr2Charts.java new file mode 100644 index 00000000..dd723622 --- /dev/null +++ b/src/main/java/com/gitblit/wicket/charting/Flotr2Charts.java @@ -0,0 +1,76 @@ +/* + * Copyright 2011 gitblit.com. + * + * 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 com.gitblit.wicket.charting; + +import javax.servlet.ServletContext; + +import org.apache.wicket.markup.html.IHeaderResponse; +import org.apache.wicket.protocol.http.WebApplication; + +/** + * Concrete class for Flotr2 charts + * + * @author Tim Ryan + * + */ +public class Flotr2Charts extends Charts { + + private static final long serialVersionUID = 1L; + + @Override + public void renderHead(IHeaderResponse response) { + + // add Google Chart JS API reference + ServletContext servletContext = WebApplication.get().getServletContext(); + String contextPath = servletContext.getContextPath(); + + response.renderJavascriptReference(contextPath + "/bootstrap/js/jquery.js"); + response.renderJavascriptReference(contextPath + "/flotr2/flotr2.min.js"); + response.renderCSSReference(contextPath + "/flotr2/flotr2.custom.css"); + + // prepare draw chart function + StringBuilder sb = new StringBuilder(); + + line(sb, "$( document ).ready(function() {"); + // add charts to header + for (Chart chart : charts) { + chart.appendChart(sb); + } + + // end draw chart function + line(sb, "});"); + response.renderJavascript(sb.toString(), null); + } + + @Override + public Chart createPieChart(String tagId, String title, String keyName, + String valueName) { + return new Flotr2PieChart(tagId, title, keyName, valueName); + } + + @Override + public Chart createLineChart(String tagId, String title, String keyName, + String valueName) { + return new Flotr2LineChart(tagId, title, keyName, valueName); + } + + @Override + public Chart createBarChart(String tagId, String title, String keyName, + String valueName) { + return new Flotr2BarChart(tagId, title, keyName, valueName); + } + +} diff --git a/src/main/java/com/gitblit/wicket/charting/Flotr2LineChart.java b/src/main/java/com/gitblit/wicket/charting/Flotr2LineChart.java new file mode 100644 index 00000000..f795999c --- /dev/null +++ b/src/main/java/com/gitblit/wicket/charting/Flotr2LineChart.java @@ -0,0 +1,150 @@ +/* + * Copyright 2011 gitblit.com. + * + * 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 com.gitblit.wicket.charting; + +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Implementation of a Line chart using the flotr2 library + * + * @author Tim Ryan + * + */ +public class Flotr2LineChart extends Chart { + + private static final long serialVersionUID = 1L; + boolean xAxisIsDate = false; + + public Flotr2LineChart(String tagId, String title, String keyName, + String valueName) { + super(tagId, title, keyName, valueName); + + } + + @Override + protected void appendChart(StringBuilder sb) { + + String dName = "data_" + dataName; + sb.append("var labels_" + dataName + " = ["); + if(xAxisIsDate){ + // Generate labels for the dates + SimpleDateFormat df = new SimpleDateFormat(dateFormat); + df.setTimeZone(getTimeZone()); + + for (int i = 0; i < values.size(); i++) { + ChartValue value = values.get(i); + Date date = new Date(Long.parseLong(value.name)); + String label = df.format(date); + if(i > 0){ + sb.append(","); + } + sb.append("\"" + label + "\""); + } + + } + else { + for (int i = 0; i < values.size(); i++) { + ChartValue value = values.get(i); + if(i > 0){ + sb.append(","); + } + sb.append("\"" + value.name + "\""); + } + } + line(sb, "];"); + + line(sb, MessageFormat.format("var {0} = Flotr.draw(document.getElementById(''{1}''),", dName, tagId)); + + // Add the data + line(sb, "["); + line(sb, "{ data : [ "); + for (int i = 0; i < values.size(); i++) { + ChartValue value = values.get(i); + if(i > 0){ + sb.append(","); + } + line(sb, MessageFormat.format("[{0}, {1}] ", value.name, Float.toString(value.value))); + } + line(sb, MessageFormat.format(" ], label : ''{0}'', lines : '{' show : true '}', color: ''#ff9900'' '}'", valueName)); + + if(highlights.size() > 0){ + // get the highlights + line(sb, ", { data : [ "); + for (int i = 0; i < highlights.size(); i++) { + ChartValue value = highlights.get(i); + if(i > 0){ + sb.append(","); + } + line(sb, MessageFormat.format("[{0}, {1}] ", value.name, Float.toString(value.value))); + } + line(sb, MessageFormat.format(" ], label : ''{0}'', points : '{' show : true, fill: true, fillColor:''#002060'' '}', color: ''#ff9900'' '}'", valueName)); + } + line(sb, "]"); + + // Add the options + line(sb, ", {"); + if(title != null && title.isEmpty() == false){ + line(sb, MessageFormat.format("title : ''{0}'',", title)); + } + line(sb, "mouse: {"); + line(sb, " track: true,"); + line(sb, " lineColor: '#002060',"); + line(sb, " position: 'ne',"); + line(sb, " trackFormatter: function (obj) {"); + line(sb, " return labels_" + dataName + "[obj.index] + ': ' + parseInt(obj.y) + ' ' + obj.series.label;"); + line(sb, " }"); + line(sb, "},"); + line(sb, "xaxis: {"); + line(sb, " showLabels: false,"); + line(sb, " showMinorLabels: false,"); + line(sb, " autoscale: true,"); + line(sb, " autoscaleMargin: 0,"); + line(sb, " margin: 10"); + line(sb, "},"); + line(sb, "yaxis: {"); + line(sb, " showLabels: false,"); + line(sb, " showMinorLabels: false,"); + line(sb, " tickDecimals: 0,"); + line(sb, " autoscale: true,"); + line(sb, " autoscaleMargin: 1,"); + line(sb, " margin: 10"); + line(sb, "},"); + line(sb, "grid: {"); + line(sb, " verticalLines: false,"); + line(sb, " minorVerticalLines: null,"); + line(sb, " horizontalLines: true,"); + line(sb, " minorHorizontalLines: null,"); + line(sb, " outlineWidth: 1,"); + line(sb, " outline: 's'"); + line(sb, "},"); + line(sb, "legend: {"); + line(sb, " show: false"); + line(sb, "}"); + line(sb, "});"); + + } + + @Override + public void addValue(Date date, int value) { + xAxisIsDate = true; + super.addValue(date, value); + } + + + +} diff --git a/src/main/java/com/gitblit/wicket/charting/Flotr2PieChart.java b/src/main/java/com/gitblit/wicket/charting/Flotr2PieChart.java new file mode 100644 index 00000000..ea04db94 --- /dev/null +++ b/src/main/java/com/gitblit/wicket/charting/Flotr2PieChart.java @@ -0,0 +1,112 @@ +/* + * Copyright 2011 gitblit.com. + * + * 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 com.gitblit.wicket.charting; + +import java.text.MessageFormat; + +import com.gitblit.utils.StringUtils; + +/** + * Implementation of a Pie chart using the flotr2 library + * + * @author Tim Ryan + * + */ +public class Flotr2PieChart extends Chart { + + private static final long serialVersionUID = 1L; + + public Flotr2PieChart(String tagId, String title, String keyName, String valueName) { + super(tagId, title, keyName, valueName); + } + + @Override + protected void appendChart(StringBuilder sb) { + + String dName = "data_" + dataName; + line(sb, "var selected_" + dataName + " = null;"); + line(sb, MessageFormat.format("var {0} = Flotr.draw(document.getElementById(''{1}''),", dName, tagId)); + + // Add the data + line(sb, "["); + for (int i = 0; i < values.size(); i++) { + ChartValue value = values.get(i); + if(i > 0){ + sb.append(","); + } + line(sb, MessageFormat.format("'{'data : [ [0, {0}] ], label : ''{1}'', color: ''{2}'' '}'", Float.toString(value.value), value.name, StringUtils.getColor(value.name))); + } + line(sb, "]"); + + // Add the options + line(sb, ", {"); + line(sb, MessageFormat.format("title : ''{0}'',", title)); + line(sb, "fontSize : 2,"); + line(sb, "pie : {"); + line(sb, " show : true,"); + line(sb, " labelFormatter : function (pie, slice) {"); + line(sb, " if(slice / pie > .05)"); + line(sb, " return Math.round(slice / pie * 100).toString() + \"%\";"); + line(sb, " }"); + line(sb, "}"); + line(sb, ", mouse: {"); + line(sb, " track: true,"); + line(sb, " lineColor: '#002060',"); + line(sb, " trackFormatter: function (obj)"); + line(sb, " {"); + line(sb, " selected_" + dataName + " = obj.series.label;"); + line(sb, " return obj.series.label + \": \" + parseInt(obj.y) + \" (\" + Math.round(obj.fraction * 100) + \"%)\";" ); + line(sb, " }"); + line(sb, "}"); + line(sb, ", xaxis: {"); + line(sb, " margin: false,"); + line(sb, " showLabels: false,"); + line(sb, " showMinorLabels: false"); + line(sb, "}"); + line(sb, ", yaxis: {"); + line(sb, " margin: false,"); + line(sb, " min: 20,"); + line(sb, " showLabels: false,"); + line(sb, " showMinorLabels: false"); + line(sb, "}"); + line(sb, ", grid: {"); + line(sb, " verticalLines: false,"); + line(sb, " minorVerticalLines: null,"); + line(sb, " horizontalLines: false,"); + line(sb, " minorHorizontalLines: null,"); + line(sb, " outlineWidth: 0"); + line(sb, "}"); + line(sb, ", legend: {"); + if(showLegend){ + line(sb, " show: true"); + } + else { + line(sb, " show: false"); + } + line(sb, "}"); + line(sb, "});"); + + if(clickUrl != null && clickUrl.isEmpty() == false){ + line(sb, MessageFormat.format("Flotr.EventAdapter.observe(document.getElementById(''{0}''), ''flotr:click'', function (mouse, a, b, c) '{'", tagId)); + line(sb, " window.location.href = \"" + clickUrl + "\" + selected_" + dataName + ";"); + line(sb, "});"); + } + + + + } + +} diff --git a/src/main/java/com/gitblit/wicket/charting/GoogleChart.java b/src/main/java/com/gitblit/wicket/charting/GoogleChart.java deleted file mode 100644 index a7188352..00000000 --- a/src/main/java/com/gitblit/wicket/charting/GoogleChart.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2011 gitblit.com. - * - * 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 com.gitblit.wicket.charting; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import com.gitblit.utils.StringUtils; - -/** - * Abstract parent class for Google Charts built with the Visualization API. - * - * @author James Moger - * - */ -public abstract class GoogleChart implements Serializable { - - private static final long serialVersionUID = 1L; - final String tagId; - final String dataName; - final String title; - final String keyName; - final String valueName; - final List values; - int width; - int height; - boolean showLegend; - - public GoogleChart(String tagId, String title, String keyName, String valueName) { - this.tagId = tagId; - this.dataName = StringUtils.getSHA1(title).substring(0, 8); - this.title = title; - this.keyName = keyName; - this.valueName = valueName; - values = new ArrayList(); - showLegend = true; - } - - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setShowLegend(boolean val) { - this.showLegend = val; - } - - public void addValue(String name, int value) { - values.add(new ChartValue(name, value)); - } - - public void addValue(String name, float value) { - values.add(new ChartValue(name, value)); - } - - public void addValue(String name, double value) { - values.add(new ChartValue(name, (float) value)); - } - - protected abstract void appendChart(StringBuilder sb); - - protected void line(StringBuilder sb, String line) { - sb.append(line); - sb.append('\n'); - } - - protected class ChartValue implements Serializable, Comparable { - - private static final long serialVersionUID = 1L; - - final String name; - final float value; - - ChartValue(String name, float value) { - this.name = name; - this.value = value; - } - - @Override - public int compareTo(ChartValue o) { - // sorts the dataset by largest value first - if (value > o.value) { - return -1; - } else if (value < o.value) { - return 1; - } - return 0; - } - } -} diff --git a/src/main/java/com/gitblit/wicket/charting/GoogleCharts.java b/src/main/java/com/gitblit/wicket/charting/GoogleCharts.java deleted file mode 100644 index 8b727936..00000000 --- a/src/main/java/com/gitblit/wicket/charting/GoogleCharts.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright 2011 gitblit.com. - - 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 com.gitblit.wicket.charting; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.wicket.markup.html.IHeaderContributor; -import org.apache.wicket.markup.html.IHeaderResponse; - -/** - * The Google Visualization API provides interactive JavaScript based charts and - * graphs. This class implements the JavaScript header necessary to display - * complete graphs and charts. - * - * @author James Moger - * - */ -public class GoogleCharts implements IHeaderContributor { - - private static final long serialVersionUID = 1L; - - public final List charts = new ArrayList(); - - public void addChart(GoogleChart chart) { - charts.add(chart); - } - - @Override - public void renderHead(IHeaderResponse response) { - // add Google Chart JS API reference - response.renderJavascriptReference("https://www.google.com/jsapi"); - - // prepare draw chart function - StringBuilder sb = new StringBuilder(); - line(sb, "google.load(\"visualization\", \"1\", {packages:[\"corechart\"]});"); - line(sb, "google.setOnLoadCallback(drawChart);"); - line(sb, "function drawChart() {"); - - // add charts to header - for (GoogleChart chart : charts) { - chart.appendChart(sb); - } - - // end draw chart function - line(sb, "}"); - response.renderJavascript(sb.toString(), null); - } - - private void line(StringBuilder sb, String line) { - sb.append(line); - sb.append('\n'); - } -} \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/charting/GoogleLineChart.java b/src/main/java/com/gitblit/wicket/charting/GoogleLineChart.java deleted file mode 100644 index 44da20ab..00000000 --- a/src/main/java/com/gitblit/wicket/charting/GoogleLineChart.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2011 gitblit.com. - * - * 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 com.gitblit.wicket.charting; - -import java.text.MessageFormat; - -/** - * Builds an interactive line chart using the Visualization API. - * - * @author James Moger - * - */ -public class GoogleLineChart extends GoogleChart { - - private static final long serialVersionUID = 1L; - - public GoogleLineChart(String tagId, String title, String keyName, String valueName) { - super(tagId, title, keyName, valueName); - } - - @Override - protected void appendChart(StringBuilder sb) { - String dName = "data_" + dataName; - line(sb, MessageFormat.format("var {0} = new google.visualization.DataTable();", dName)); - line(sb, MessageFormat.format("{0}.addColumn(''string'', ''{1}'');", dName, keyName)); - line(sb, MessageFormat.format("{0}.addColumn(''number'', ''{1}'');", dName, valueName)); - line(sb, MessageFormat.format("{0}.addRows({1,number,0});", dName, values.size())); - - for (int i = 0; i < values.size(); i++) { - ChartValue value = values.get(i); - line(sb, MessageFormat.format("{0}.setValue({1,number,0}, 0, \"{2}\");", dName, i, - value.name)); - line(sb, MessageFormat.format("{0}.setValue({1,number,0}, 1, {2,number,0.0});", dName, - i, value.value)); - } - - String cName = "chart_" + dataName; - line(sb, MessageFormat.format( - "var {0} = new google.visualization.LineChart(document.getElementById(''{1}''));", - cName, tagId)); - line(sb, - MessageFormat - .format("{0}.draw({1}, '{'width: {2,number,0}, height: {3,number,0}, pointSize: 4, chartArea:'{'left:20,top:20'}', vAxis: '{' textPosition: ''none'' '}', legend: ''none'', title: ''{4}'' '}');", - cName, dName, width, height, title)); - line(sb, ""); - } -} \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/charting/GooglePieChart.java b/src/main/java/com/gitblit/wicket/charting/GooglePieChart.java deleted file mode 100644 index 71191664..00000000 --- a/src/main/java/com/gitblit/wicket/charting/GooglePieChart.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2011 gitblit.com. - * - * 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 com.gitblit.wicket.charting; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.gitblit.utils.StringUtils; - -/** - * Builds an interactive pie chart using the Visualization API. - * - * @author James Moger - * - */ -public class GooglePieChart extends GoogleChart { - - private static final long serialVersionUID = 1L; - - public GooglePieChart(String tagId, String title, String keyName, String valueName) { - super(tagId, title, keyName, valueName); - } - - @Override - protected void appendChart(StringBuilder sb) { - // create dataset - String dName = "data_" + dataName; - line(sb, MessageFormat.format("var {0} = new google.visualization.DataTable();", dName)); - line(sb, MessageFormat.format("{0}.addColumn(''string'', ''{1}'');", dName, keyName)); - line(sb, MessageFormat.format("{0}.addColumn(''number'', ''{1}'');", dName, valueName)); - line(sb, MessageFormat.format("{0}.addRows({1,number,0});", dName, values.size())); - - Collections.sort(values); - List list = new ArrayList(); - - int maxSlices = 10; - - if (values.size() > maxSlices) { - list.addAll(values.subList(0, maxSlices)); - } else { - list.addAll(values); - } - - StringBuilder colors = new StringBuilder("colors:["); - for (int i = 0; i < list.size(); i++) { - ChartValue value = list.get(i); - colors.append('\''); - colors.append(StringUtils.getColor(value.name)); - colors.append('\''); - if (i < values.size() - 1) { - colors.append(','); - } - line(sb, MessageFormat.format("{0}.setValue({1,number,0}, 0, \"{2}\");", dName, i, - value.name)); - line(sb, MessageFormat.format("{0}.setValue({1,number,0}, 1, {2,number,0.0});", dName, - i, value.value)); - } - colors.append(']'); - - // instantiate chart - String cName = "chart_" + dataName; - line(sb, MessageFormat.format( - "var {0} = new google.visualization.PieChart(document.getElementById(''{1}''));", - cName, tagId)); - line(sb, - MessageFormat - .format("{0}.draw({1}, '{' title: ''{4}'', {5}, legend: '{' position:''{6}'' '}' '}');", - cName, dName, width, height, title, colors.toString(), showLegend ? "right" : "none")); - line(sb, ""); - } -} \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/charting/SecureChart.java b/src/main/java/com/gitblit/wicket/charting/SecureChart.java deleted file mode 100644 index aba25c40..00000000 --- a/src/main/java/com/gitblit/wicket/charting/SecureChart.java +++ /dev/null @@ -1,633 +0,0 @@ -/* - * Copyright 2007 Daniel Spiewak. - * Copyright 2013 gitblit.com. - * - * 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 com.gitblit.wicket.charting; - -import java.awt.Color; -import java.awt.Dimension; -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import org.apache.wicket.markup.ComponentTag; -import org.apache.wicket.markup.html.WebComponent; -import org.wicketstuff.googlecharts.ChartDataEncoding; -import org.wicketstuff.googlecharts.IChartAxis; -import org.wicketstuff.googlecharts.IChartData; -import org.wicketstuff.googlecharts.IChartFill; -import org.wicketstuff.googlecharts.IChartGrid; -import org.wicketstuff.googlecharts.IChartProvider; -import org.wicketstuff.googlecharts.IFillArea; -import org.wicketstuff.googlecharts.ILineStyle; -import org.wicketstuff.googlecharts.ILinearGradientFill; -import org.wicketstuff.googlecharts.ILinearStripesFill; -import org.wicketstuff.googlecharts.IRangeMarker; -import org.wicketstuff.googlecharts.IShapeMarker; -import org.wicketstuff.googlecharts.ISolidFill; -import org.wicketstuff.googlecharts.Range; - -/** - * This is a fork of org.wicketstuff.googlecharts.Chart whose only purpose - * is to build https urls instead of http urls. - * - * @author Daniel Spiewak - * @author James Moger - */ -public class SecureChart extends WebComponent implements Serializable { - - private static final long serialVersionUID = 6286305912682861488L; - private IChartProvider provider; - private StringBuilder url; - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - - public SecureChart(String id, IChartProvider provider) { - super(id); - - this.provider = provider; - } - - public void invalidate() { - lock.writeLock().lock(); - try { - url = null; - } finally { - lock.writeLock().unlock(); - } - } - - public CharSequence constructURL() { - lock.writeLock().lock(); - try { - if (url != null) { - return url; - } - - url = new StringBuilder("https://chart.googleapis.com/chart?"); - - addParameter(url, "chs", render(provider.getSize())); - addParameter(url, "chd", render(provider.getData())); - addParameter(url, "cht", render(provider.getType())); - addParameter(url, "chbh", render(provider.getBarWidth(), provider.getBarGroupSpacing())); - addParameter(url, "chtt", render(provider.getTitle())); - addParameter(url, "chdl", render(provider.getLegend())); - addParameter(url, "chco", render(provider.getColors())); - - IChartFill bgFill = provider.getBackgroundFill(); - IChartFill fgFill = provider.getChartFill(); - - StringBuilder fillParam = new StringBuilder(); - - if (bgFill != null) { - fillParam.append("bg,").append(render(bgFill)); - } - - if (fgFill != null) { - if (fillParam.length() > 0) { - fillParam.append('|'); - } - - fillParam.append("c,").append(render(fgFill)); - } - - if (fillParam.toString().trim().equals("")) { - fillParam = null; - } - - addParameter(url, "chf", fillParam); - - IChartAxis[] axes = provider.getAxes(); - addParameter(url, "chxt", renderTypes(axes)); - addParameter(url, "chxl", renderLabels(axes)); - addParameter(url, "chxp", renderPositions(axes)); - addParameter(url, "chxr", renderRanges(axes)); - addParameter(url, "chxs", renderStyles(axes)); - - addParameter(url, "chg", render(provider.getGrid())); - addParameter(url, "chm", render(provider.getShapeMarkers())); - addParameter(url, "chm", render(provider.getRangeMarkers())); - addParameter(url, "chls", render(provider.getLineStyles())); - addParameter(url, "chm", render(provider.getFillAreas())); - addParameter(url, "chl", render(provider.getPieLabels())); - - return url; - } finally { - lock.writeLock().unlock(); - } - } - - private void addParameter(StringBuilder url, CharSequence param, CharSequence value) { - if (value == null || value.length() == 0) { - return; - } - - if (url.charAt(url.length() - 1) != '?') { - url.append('&'); - } - - url.append(param).append('=').append(value); - } - - private CharSequence convert(ChartDataEncoding encoding, double value, double max) { - switch (encoding) { - case TEXT: - return SecureChartDataEncoding.TEXT.convert(value, max); - case EXTENDED: - return SecureChartDataEncoding.EXTENDED.convert(value, max); - case SIMPLE: - default: - return SecureChartDataEncoding.SIMPLE.convert(value, max); - } - } - - private CharSequence render(Dimension dim) { - if (dim == null) { - return null; - } - - return new StringBuilder().append(dim.width).append('x').append(dim.height); - } - - private CharSequence render(IChartData data) { - if (data == null) { - return null; - } - - ChartDataEncoding encoding = data.getEncoding(); - - StringBuilder back = new StringBuilder(); - back.append(render(encoding)).append(':'); - - for (double[] set : data.getData()) { - if (set == null || set.length == 0) { - back.append(convert(encoding, -1, data.getMax())); - } else { - for (double value : set) { - back.append(convert(encoding, value, data.getMax())).append(encoding.getValueSeparator()); - } - - if (back.substring(back.length() - encoding.getValueSeparator().length(), - back.length()).equals(encoding.getValueSeparator())) { - back.setLength(back.length() - encoding.getValueSeparator().length()); - } - } - - back.append(encoding.getSetSeparator()); - } - - if (back.substring(back.length() - encoding.getSetSeparator().length(), - back.length()).equals(encoding.getSetSeparator())) { - back.setLength(back.length() - encoding.getSetSeparator().length()); - } - - return back; - } - - private CharSequence render(Enum value) { - if (value == null) { - return null; - } - - try { - Object back = value.getClass().getMethod("getRendering").invoke(value); - - if (back != null) { - return back.toString(); - } - } catch (IllegalArgumentException e) { - } catch (SecurityException e) { - } catch (IllegalAccessException e) { - } catch (InvocationTargetException e) { - } catch (NoSuchMethodException e) { - } - - return null; - } - - private CharSequence render(int barWidth, int groupSpacing) { - if (barWidth == -1) { - return null; - } - - StringBuilder back = new StringBuilder(barWidth); - - if (groupSpacing >= 0) { - back.append(',').append(groupSpacing); - } - - return back; - } - - private CharSequence render(String[] values) { - if (values == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - for (String value : values) { - CharSequence toRender = render(value); - if (toRender == null) { - toRender = ""; - } - - back.append(toRender).append('|'); - } - - if (back.length() > 0) { - back.setLength(back.length() - 1); - } - - return back; - } - - private CharSequence render(String value) { - if (value == null) { - return value; - } - - StringBuilder back = new StringBuilder(); - - for (char c : value.toCharArray()) { - if (c == ' ') { - back.append('+'); - } else { - back.append(c); - } - } - - return back; - } - - private CharSequence render(Color[] values) { - if (values == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - for (Color value : values) { - CharSequence toRender = render(value); - if (toRender == null) { - toRender = ""; - } - - back.append(toRender).append(','); - } - - if (back.length() > 0) { - back.setLength(back.length() - 1); - } - - return back; - } - - private CharSequence render(Color value) { - if (value == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - { - String toPad = Integer.toHexString(value.getRed()); - - if (toPad.length() == 1) { - back.append(0); - } - back.append(toPad); - } - - { - String toPad = Integer.toHexString(value.getGreen()); - - if (toPad.length() == 1) { - back.append(0); - } - back.append(toPad); - } - - { - String toPad = Integer.toHexString(value.getBlue()); - - if (toPad.length() == 1) { - back.append(0); - } - back.append(toPad); - } - - { - String toPad = Integer.toHexString(value.getAlpha()); - - if (toPad.length() == 1) { - back.append(0); - } - back.append(toPad); - } - - return back; - } - - private CharSequence render(IChartFill fill) { - if (fill == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - if (fill instanceof ISolidFill) { - ISolidFill solidFill = (ISolidFill) fill; - - back.append("s,"); - back.append(render(solidFill.getColor())); - } else if (fill instanceof ILinearGradientFill) { - ILinearGradientFill gradientFill = (ILinearGradientFill) fill; - - back.append("lg,").append(gradientFill.getAngle()).append(','); - - Color[] colors = gradientFill.getColors(); - double[] offsets = gradientFill.getOffsets(); - for (int i = 0; i < colors.length; i++) { - back.append(render(colors[i])).append(',').append(offsets[i]).append(','); - } - - back.setLength(back.length() - 1); - } else if (fill instanceof ILinearStripesFill) { - ILinearStripesFill stripesFill = (ILinearStripesFill) fill; - - back.append("ls,").append(stripesFill.getAngle()).append(','); - - Color[] colors = stripesFill.getColors(); - double[] widths = stripesFill.getWidths(); - for (int i = 0; i < colors.length; i++) { - back.append(render(colors[i])).append(',').append(widths[i]).append(','); - } - - back.setLength(back.length() - 1); - } else { - return null; - } - - return back; - } - - private CharSequence renderTypes(IChartAxis[] axes) { - if (axes == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - for (IChartAxis axis : axes) { - back.append(render(axis.getType())).append(','); - } - - if (back.length() > 0) { - back.setLength(back.length() - 1); - } - - return back; - } - - private CharSequence renderLabels(IChartAxis[] axes) { - if (axes == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - for (int i = 0; i < axes.length; i++) { - if (axes[i] == null || axes[i].getLabels() == null) { - continue; - } - - back.append(i).append(":|"); - - for (String label : axes[i].getLabels()) { - if (label == null) { - back.append('|'); - continue; - } - - back.append(render(label)).append('|'); - } - - if (i == axes.length - 1) { - back.setLength(back.length() - 1); - } - } - - return back; - } - - private CharSequence renderPositions(IChartAxis[] axes) { - if (axes == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - for (int i = 0; i < axes.length; i++) { - if (axes[i] == null || axes[i].getPositions() == null) { - continue; - } - - back.append(i).append(','); - - for (double position : axes[i].getPositions()) { - back.append(position).append(','); - } - - back.setLength(back.length() - 1); - - back.append('|'); - } - - if (back.length() > 0) { - back.setLength(back.length() - 1); - } - - return back; - } - - private CharSequence renderRanges(IChartAxis[] axes) { - if (axes == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - for (int i = 0; i < axes.length; i++) { - if (axes[i] == null || axes[i].getRange() == null) { - continue; - } - - back.append(i).append(','); - - Range range = axes[i].getRange(); - back.append(range.getStart()).append(',').append(range.getEnd()).append('|'); - } - - if (back.length() > 0) { - back.setLength(back.length() - 1); - } - - return back; - } - - private CharSequence renderStyles(IChartAxis[] axes) { - if (axes == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - for (int i = 0; i < axes.length; i++) { - if (axes[i] == null || axes[i].getColor() == null - || axes[i].getFontSize() < 0 || axes[i].getAlignment() == null) { - continue; - } - - back.append(i).append(','); - back.append(render(axes[i].getColor())).append(','); - back.append(axes[i].getFontSize()).append(','); - back.append(render(axes[i].getAlignment())).append('|'); - } - - if (back.length() > 0) { - back.setLength(back.length() - 1); - } - - return back; - } - - private CharSequence render(IChartGrid grid) { - if (grid == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - back.append(grid.getXStepSize()).append(','); - back.append(grid.getYStepSize()); - - if (grid.getSegmentLength() >= 0) { - back.append(',').append(grid.getSegmentLength()); - back.append(',').append(grid.getBlankLength()); - } - - return back; - } - - private CharSequence render(IShapeMarker[] markers) { - if (markers == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - for (IShapeMarker marker : markers) { - back.append(render(marker.getType())).append(','); - back.append(render(marker.getColor())).append(','); - back.append(marker.getIndex()).append(','); - back.append(marker.getPoint()).append(','); - back.append(marker.getSize()).append('|'); - } - - if (back.length() > 0) { - back.setLength(back.length() - 1); - } - - return back; - } - - private CharSequence render(IRangeMarker[] markers) { - if (markers == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - for (IRangeMarker marker : markers) { - back.append(render(marker.getType())).append(','); - back.append(render(marker.getColor())).append(','); - back.append(0).append(','); - back.append(marker.getStart()).append(','); - back.append(marker.getEnd()).append('|'); - } - - if (back.length() > 0) { - back.setLength(back.length() - 1); - } - - return back; - } - - private CharSequence render(IFillArea[] areas) { - if (areas == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - for (IFillArea area : areas) { - back.append(render(area.getType())).append(','); - back.append(render(area.getColor())).append(','); - back.append(area.getStartIndex()).append(','); - back.append(area.getEndIndex()).append(','); - back.append(0).append('|'); - } - - if (back.length() > 0) { - back.setLength(back.length() - 1); - } - - return back; - } - - private CharSequence render(ILineStyle[] styles) { - if (styles == null) { - return null; - } - - StringBuilder back = new StringBuilder(); - - for (ILineStyle style : styles) { - if (style == null) { - back.append('|'); - continue; - } - - back.append(style.getThickness()).append(','); - back.append(style.getSegmentLength()).append(','); - back.append(style.getBlankLength()).append('|'); - } - - if (back.length() > 0) { - back.setLength(back.length() - 1); - } - - return back; - } - - @Override - protected void onComponentTag(ComponentTag tag) { - checkComponentTag(tag, "img"); - super.onComponentTag(tag); - - tag.put("src", constructURL()); - } -} diff --git a/src/main/java/com/gitblit/wicket/charting/SecureChartDataEncoding.java b/src/main/java/com/gitblit/wicket/charting/SecureChartDataEncoding.java deleted file mode 100644 index c5ac4608..00000000 --- a/src/main/java/com/gitblit/wicket/charting/SecureChartDataEncoding.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2007 Daniel Spiewak. - * Copyright 2013 gitblit.com. - * - * 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 com.gitblit.wicket.charting; - -/** - * This class is a pristine fork of org.wicketstuff.googlecharts.ChartDataEncoding - * to bring the package-protected convert methods to SecureChart. - * - * @author Daniel Spiewak - */ -public enum SecureChartDataEncoding { - - SIMPLE("s", "", ",") { - - @Override - CharSequence convert(double value, double max) { - if (value < 0) { - return "_"; - } - - value = Math.round((CHARS.length() - 1) * value / max); - - if (value > CHARS.length() - 1) { - throw new IllegalArgumentException(value + " is out of range for SIMPLE encoding"); - } - - return Character.toString(CHARS.charAt((int) value)); - } - }, - TEXT("t", ",", "|") { - - @Override - CharSequence convert(double value, double max) { - if (value < 0) { - value = -1; - } - - if (value > 100) { - throw new IllegalArgumentException(value + " is out of range for TEXT encoding"); - } - - return Double.toString(value); - } - }, - EXTENDED("e", "", ",") { - - @Override - CharSequence convert(double value, double max) { - if (value < 0) { - return "__"; - } - - value = Math.round(value); - - if (value > (EXT_CHARS.length() - 1) * (EXT_CHARS.length() - 1)) { - throw new IllegalArgumentException(value + " is out of range for EXTENDED encoding"); - } - - int rem = (int) (value % EXT_CHARS.length()); - int exp = (int) (value / EXT_CHARS.length()); - - return new StringBuilder().append(EXT_CHARS.charAt(exp)).append(EXT_CHARS.charAt(rem)); - } - }; - private static final String CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - private static final String EXT_CHARS = CHARS + "-_."; - private final String rendering, valueSeparator, setSeparator; - - private SecureChartDataEncoding(String rendering, String valueSeparator, String setSeparator) { - this.rendering = rendering; - this.valueSeparator = valueSeparator; - this.setSeparator = setSeparator; - } - - public String getRendering() { - return rendering; - } - - public String getValueSeparator() { - return valueSeparator; - } - - public String getSetSeparator() { - return setSeparator; - } - - abstract CharSequence convert(double value, double max); -} diff --git a/src/main/java/com/gitblit/wicket/pages/ActivityPage.java b/src/main/java/com/gitblit/wicket/pages/ActivityPage.java index 070caf32..f0e390dc 100644 --- a/src/main/java/com/gitblit/wicket/pages/ActivityPage.java +++ b/src/main/java/com/gitblit/wicket/pages/ActivityPage.java @@ -41,10 +41,9 @@ import com.gitblit.wicket.PageRegistration; import com.gitblit.wicket.PageRegistration.DropDownMenuItem; import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration; import com.gitblit.wicket.WicketUtils; -import com.gitblit.wicket.charting.GoogleChart; -import com.gitblit.wicket.charting.GoogleCharts; -import com.gitblit.wicket.charting.GoogleLineChart; -import com.gitblit.wicket.charting.GooglePieChart; +import com.gitblit.wicket.charting.Chart; +import com.gitblit.wicket.charting.Charts; +import com.gitblit.wicket.charting.Flotr2Charts; import com.gitblit.wicket.panels.ActivityPanel; /** @@ -118,7 +117,7 @@ public class ActivityPage extends RootPage { // create the activity charts if (app().settings().getBoolean(Keys.web.generateActivityGraph, true)) { - GoogleCharts charts = createCharts(recentActivity); + Charts charts = createCharts(recentActivity); add(new HeaderContributor(charts)); add(new Fragment("chartsPanel", "chartsFragment", this)); } else { @@ -166,7 +165,7 @@ public class ActivityPage extends RootPage { * @param recentActivity * @return */ - private GoogleCharts createCharts(List recentActivity) { + private Charts createCharts(List recentActivity) { // activity metrics Map repositoryMetrics = new HashMap(); Map authorMetrics = new HashMap(); @@ -193,34 +192,36 @@ public class ActivityPage extends RootPage { } } - // build google charts - GoogleCharts charts = new GoogleCharts(); + // build charts + Charts charts = new Flotr2Charts(); // sort in reverse-chronological order and then reverse that Collections.sort(recentActivity); Collections.reverse(recentActivity); // daily line chart - GoogleChart chart = new GoogleLineChart("chartDaily", getString("gb.dailyActivity"), "day", + Chart chart = charts.createLineChart("chartDaily", getString("gb.dailyActivity"), "day", getString("gb.commits")); SimpleDateFormat df = new SimpleDateFormat("MMM dd"); df.setTimeZone(getTimeZone()); for (Activity metric : recentActivity) { - chart.addValue(df.format(metric.startDate), metric.getCommitCount()); + chart.addValue(metric.startDate, metric.getCommitCount()); } charts.addChart(chart); - // active repositories pie chart - chart = new GooglePieChart("chartRepositories", getString("gb.activeRepositories"), + // active repositories pie chart + chart = charts.createPieChart("chartRepositories", getString("gb.activeRepositories"), getString("gb.repository"), getString("gb.commits")); for (Metric metric : repositoryMetrics.values()) { chart.addValue(metric.name, metric.count); } chart.setShowLegend(false); + String url = urlFor(SummaryPage.class, null).toString() + "?r="; + chart.setClickUrl(url); charts.addChart(chart); // active authors pie chart - chart = new GooglePieChart("chartAuthors", getString("gb.activeAuthors"), + chart = charts.createPieChart("chartAuthors", getString("gb.activeAuthors"), getString("gb.author"), getString("gb.commits")); for (Metric metric : authorMetrics.values()) { chart.addValue(metric.name, metric.count); diff --git a/src/main/java/com/gitblit/wicket/pages/DashboardPage.java b/src/main/java/com/gitblit/wicket/pages/DashboardPage.java index 959a3d31..9853449e 100644 --- a/src/main/java/com/gitblit/wicket/pages/DashboardPage.java +++ b/src/main/java/com/gitblit/wicket/pages/DashboardPage.java @@ -48,9 +48,9 @@ import com.gitblit.wicket.GitBlitWebApp; import com.gitblit.wicket.PageRegistration; import com.gitblit.wicket.PageRegistration.DropDownMenuItem; import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration; -import com.gitblit.wicket.charting.GoogleChart; -import com.gitblit.wicket.charting.GoogleCharts; -import com.gitblit.wicket.charting.GooglePieChart; +import com.gitblit.wicket.charting.Chart; +import com.gitblit.wicket.charting.Charts; +import com.gitblit.wicket.charting.Flotr2Charts; import com.gitblit.wicket.panels.DigestsPanel; import com.gitblit.wicket.panels.LinkPanel; @@ -218,19 +218,21 @@ public abstract class DashboardPage extends RootPage { if (app().settings().getBoolean(Keys.web.generateActivityGraph, true)) { // build google charts - GoogleCharts charts = new GoogleCharts(); + Charts charts = new Flotr2Charts(); // active repositories pie chart - GoogleChart chart = new GooglePieChart("chartRepositories", getString("gb.activeRepositories"), + Chart chart = charts.createPieChart("chartRepositories", getString("gb.activeRepositories"), getString("gb.repository"), getString("gb.commits")); for (Metric metric : repositoryMetrics.values()) { chart.addValue(metric.name, metric.count); } chart.setShowLegend(false); + String url = urlFor(SummaryPage.class, null).toString() + "?r="; + chart.setClickUrl(url); charts.addChart(chart); // active authors pie chart - chart = new GooglePieChart("chartAuthors", getString("gb.activeAuthors"), + chart = charts.createPieChart("chartAuthors", getString("gb.activeAuthors"), getString("gb.author"), getString("gb.commits")); for (Metric metric : authorMetrics.values()) { chart.addValue(metric.name, metric.count); diff --git a/src/main/java/com/gitblit/wicket/pages/MetricsPage.html b/src/main/java/com/gitblit/wicket/pages/MetricsPage.html index 4aefc798..302d020d 100644 --- a/src/main/java/com/gitblit/wicket/pages/MetricsPage.html +++ b/src/main/java/com/gitblit/wicket/pages/MetricsPage.html @@ -13,7 +13,7 @@ - @@ -22,19 +22,19 @@ -
+

-
+

-
+
-

-
+
+

+
diff --git a/src/main/java/com/gitblit/wicket/pages/MetricsPage.java b/src/main/java/com/gitblit/wicket/pages/MetricsPage.java index d4cfc8e9..7ae4e4ed 100644 --- a/src/main/java/com/gitblit/wicket/pages/MetricsPage.java +++ b/src/main/java/com/gitblit/wicket/pages/MetricsPage.java @@ -15,27 +15,20 @@ */ package com.gitblit.wicket.pages; -import java.awt.Color; -import java.awt.Dimension; import java.text.MessageFormat; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; +import java.util.Date; import java.util.List; import org.apache.wicket.PageParameters; +import org.apache.wicket.behavior.HeaderContributor; import org.apache.wicket.markup.html.basic.Label; import org.eclipse.jgit.lib.Repository; -import org.wicketstuff.googlecharts.ChartAxis; -import org.wicketstuff.googlecharts.ChartAxisType; -import org.wicketstuff.googlecharts.ChartProvider; -import org.wicketstuff.googlecharts.ChartType; -import org.wicketstuff.googlecharts.IChartData; -import org.wicketstuff.googlecharts.LineStyle; -import org.wicketstuff.googlecharts.MarkerType; -import org.wicketstuff.googlecharts.ShapeMarker; import com.gitblit.models.Metric; import com.gitblit.utils.MetricUtils; @@ -43,7 +36,9 @@ import com.gitblit.utils.StringUtils; import com.gitblit.wicket.CacheControl; import com.gitblit.wicket.CacheControl.LastModified; import com.gitblit.wicket.WicketUtils; -import com.gitblit.wicket.charting.SecureChart; +import com.gitblit.wicket.charting.Chart; +import com.gitblit.wicket.charting.Charts; +import com.gitblit.wicket.charting.Flotr2Charts; @CacheControl(LastModified.REPOSITORY) public class MetricsPage extends RepositoryPage { @@ -66,73 +61,71 @@ public class MetricsPage extends RepositoryPage { MessageFormat.format(getString("gb.branchStats"), metricsTotal.count, metricsTotal.tag, getTimeUtils().duration(metricsTotal.duration)))); } - insertLinePlot("commitsChart", metrics); - insertBarPlot("dayOfWeekChart", getDayOfWeekMetrics(r, objectId)); - insertPieChart("authorsChart", getAuthorMetrics(r, objectId)); + + Charts charts = new Flotr2Charts(); + + add(WicketUtils.newBlankImage("commitsChart")); + add(WicketUtils.newBlankImage("dayOfWeekChart")); + add(WicketUtils.newBlankImage("authorsChart")); + + createLineChart(charts, "commitsChart", metrics); + createBarChart(charts, "dayOfWeekChart", getDayOfWeekMetrics(r, objectId)); + createPieChart(charts, "authorsChart", getAuthorMetrics(r, objectId)); + + add(new HeaderContributor(charts)); + } - private void insertLinePlot(String wicketId, List metrics) { + private void createLineChart(Charts charts, String id, List metrics) { if ((metrics != null) && (metrics.size() > 0)) { - IChartData data = WicketUtils.getChartData(metrics); - - ChartProvider provider = new ChartProvider(new Dimension(400, 100), ChartType.LINE, - data); - ChartAxis dateAxis = new ChartAxis(ChartAxisType.BOTTOM); - dateAxis.setLabels(new String[] { metrics.get(0).name, - metrics.get(metrics.size() / 2).name, metrics.get(metrics.size() - 1).name }); - provider.addAxis(dateAxis); - - ChartAxis commitAxis = new ChartAxis(ChartAxisType.LEFT); - commitAxis.setLabels(new String[] { "", - String.valueOf((int) WicketUtils.maxValue(metrics)) }); - provider.addAxis(commitAxis); - - provider.setLineStyles(new LineStyle[] { new LineStyle(2, 4, 0), new LineStyle(0, 4, 1) }); - provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.decode("#002060"), 1, -1, 5)); - - add(new SecureChart(wicketId, provider)); - } else { - add(WicketUtils.newBlankImage(wicketId)); + + Chart chart = charts.createLineChart(id, "", "day", + getString("gb.commits")); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); + String displayFormat = "MMM dd"; + if(metrics.size() > 0 && metrics.get(0).name.length() == 7){ + df = new SimpleDateFormat("yyyy-MM"); + displayFormat = "yyyy MMM"; + } + df.setTimeZone(getTimeZone()); + chart.setDateFormat(displayFormat); + for (Metric metric : metrics) { + Date date; + try { + date = df.parse(metric.name); + } catch (ParseException e) { + logger.error("Unable to parse date: " + metric.name); + return; + } + chart.addValue(date, (int)metric.count); + if(metric.tag > 0 ){ + chart.addHighlight(date, (int)metric.count); + } + } + charts.addChart(chart); } } - - private void insertBarPlot(String wicketId, List metrics) { + + private void createPieChart(Charts charts, String id, List metrics) { if ((metrics != null) && (metrics.size() > 0)) { - IChartData data = WicketUtils.getChartData(metrics); - - ChartProvider provider = new ChartProvider(new Dimension(400, 100), - ChartType.BAR_VERTICAL_SET, data); - ChartAxis dateAxis = new ChartAxis(ChartAxisType.BOTTOM); - List labels = new ArrayList(); + + Chart chart = charts.createPieChart(id, "", "day", + getString("gb.commits")); for (Metric metric : metrics) { - labels.add(metric.name); + chart.addValue(metric.name, (int)metric.count); } - dateAxis.setLabels(labels.toArray(new String[labels.size()])); - provider.addAxis(dateAxis); - - ChartAxis commitAxis = new ChartAxis(ChartAxisType.LEFT); - commitAxis.setLabels(new String[] { "", - String.valueOf((int) WicketUtils.maxValue(metrics)) }); - provider.addAxis(commitAxis); - - add(new SecureChart(wicketId, provider)); - } else { - add(WicketUtils.newBlankImage(wicketId)); + charts.addChart(chart); } } - - private void insertPieChart(String wicketId, List metrics) { + + private void createBarChart(Charts charts, String id, List metrics) { if ((metrics != null) && (metrics.size() > 0)) { - IChartData data = WicketUtils.getChartData(metrics); - List labels = new ArrayList(); + Chart chart = charts.createBarChart(id, "", "day", + getString("gb.commits")); for (Metric metric : metrics) { - labels.add(metric.name); + chart.addValue(metric.name, (int)metric.count); } - ChartProvider provider = new ChartProvider(new Dimension(800, 200), ChartType.PIE, data); - provider.setPieLabels(labels.toArray(new String[labels.size()])); - add(new SecureChart(wicketId, provider)); - } else { - add(WicketUtils.newBlankImage(wicketId)); + charts.addChart(chart); } } diff --git a/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.html b/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.html index b55688cc..ed3754e0 100644 --- a/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.html +++ b/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.html @@ -68,8 +68,8 @@ - - + +
diff --git a/src/main/java/com/gitblit/wicket/pages/OverviewPage.java b/src/main/java/com/gitblit/wicket/pages/OverviewPage.java index efb7f4cf..1979f97f 100644 --- a/src/main/java/com/gitblit/wicket/pages/OverviewPage.java +++ b/src/main/java/com/gitblit/wicket/pages/OverviewPage.java @@ -37,9 +37,9 @@ import com.gitblit.wicket.CacheControl; import com.gitblit.wicket.CacheControl.LastModified; import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.WicketUtils; -import com.gitblit.wicket.charting.GoogleChart; -import com.gitblit.wicket.charting.GoogleCharts; -import com.gitblit.wicket.charting.GoogleLineChart; +import com.gitblit.wicket.charting.Chart; +import com.gitblit.wicket.charting.Charts; +import com.gitblit.wicket.charting.Flotr2Charts; import com.gitblit.wicket.panels.BranchesPanel; import com.gitblit.wicket.panels.LinkPanel; import com.gitblit.wicket.panels.ReflogPanel; @@ -135,8 +135,10 @@ public class OverviewPage extends RepositoryPage { if ((metrics != null) && (metrics.size() > 0) && app().settings().getBoolean(Keys.web.generateActivityGraph, true)) { + Charts charts = new Flotr2Charts(); + // daily line chart - GoogleChart chart = new GoogleLineChart("chartDaily", "", "unit", + Chart chart = charts.createLineChart("chartDaily", "", "unit", getString("gb.commits")); for (Metric metric : metrics) { chart.addValue(metric.name, metric.count); @@ -144,7 +146,6 @@ public class OverviewPage extends RepositoryPage { chart.setWidth(375); chart.setHeight(150); - GoogleCharts charts = new GoogleCharts(); charts.addChart(chart); add(new HeaderContributor(charts)); } diff --git a/src/main/java/com/gitblit/wicket/pages/SummaryPage.html b/src/main/java/com/gitblit/wicket/pages/SummaryPage.html index 42c59c48..2d1b6a56 100644 --- a/src/main/java/com/gitblit/wicket/pages/SummaryPage.html +++ b/src/main/java/com/gitblit/wicket/pages/SummaryPage.html @@ -9,7 +9,7 @@
- +
diff --git a/src/main/java/com/gitblit/wicket/pages/SummaryPage.java b/src/main/java/com/gitblit/wicket/pages/SummaryPage.java index fdc5d01d..eb6eb07a 100644 --- a/src/main/java/com/gitblit/wicket/pages/SummaryPage.java +++ b/src/main/java/com/gitblit/wicket/pages/SummaryPage.java @@ -15,14 +15,17 @@ */ package com.gitblit.wicket.pages; -import java.awt.Color; -import java.awt.Dimension; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + import org.apache.wicket.Component; import org.apache.wicket.PageParameters; +import org.apache.wicket.behavior.HeaderContributor; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.markup.html.panel.Fragment; @@ -31,14 +34,6 @@ import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.markup.repeater.data.ListDataProvider; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; -import org.wicketstuff.googlecharts.ChartAxis; -import org.wicketstuff.googlecharts.ChartAxisType; -import org.wicketstuff.googlecharts.ChartProvider; -import org.wicketstuff.googlecharts.ChartType; -import org.wicketstuff.googlecharts.IChartData; -import org.wicketstuff.googlecharts.LineStyle; -import org.wicketstuff.googlecharts.MarkerType; -import org.wicketstuff.googlecharts.ShapeMarker; import com.gitblit.Keys; import com.gitblit.models.Metric; @@ -53,7 +48,9 @@ import com.gitblit.wicket.MarkupProcessor; import com.gitblit.wicket.MarkupProcessor.MarkupDocument; import com.gitblit.wicket.MarkupProcessor.MarkupSyntax; import com.gitblit.wicket.WicketUtils; -import com.gitblit.wicket.charting.SecureChart; +import com.gitblit.wicket.charting.Chart; +import com.gitblit.wicket.charting.Charts; +import com.gitblit.wicket.charting.Flotr2Charts; import com.gitblit.wicket.panels.BranchesPanel; import com.gitblit.wicket.panels.LinkPanel; import com.gitblit.wicket.panels.LogPanel; @@ -159,38 +156,49 @@ public class SummaryPage extends RepositoryPage { // global, no readme on summary page add(new Label("readme").setVisible(false)); } - - // Display an activity line graph - insertActivityGraph(metrics); + + Charts charts = createCharts(metrics); + add(new HeaderContributor(charts)); + } @Override protected String getPageName() { return getString("gb.summary"); } - - private void insertActivityGraph(List metrics) { - if ((metrics != null) && (metrics.size() > 0) - && app().settings().getBoolean(Keys.web.generateActivityGraph, true)) { - IChartData data = WicketUtils.getChartData(metrics); - - ChartProvider provider = new ChartProvider(new Dimension(290, 100), ChartType.LINE, - data); - ChartAxis dateAxis = new ChartAxis(ChartAxisType.BOTTOM); - dateAxis.setLabels(new String[] { metrics.get(0).name, - metrics.get(metrics.size() / 2).name, metrics.get(metrics.size() - 1).name }); - provider.addAxis(dateAxis); - - ChartAxis commitAxis = new ChartAxis(ChartAxisType.LEFT); - commitAxis.setLabels(new String[] { "", - String.valueOf((int) WicketUtils.maxValue(metrics)) }); - provider.addAxis(commitAxis); - provider.setLineStyles(new LineStyle[] { new LineStyle(2, 4, 0), new LineStyle(0, 4, 1) }); - provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.decode("#002060"), 1, -1, 5)); - - add(new SecureChart("commitsChart", provider)); - } else { - add(WicketUtils.newBlankImage("commitsChart")); + + private Charts createCharts(List metrics) { + + Charts charts = new Flotr2Charts(); + + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); + String displayFormat = "MMM dd"; + if(metrics.size() > 0 && metrics.get(0).name.length() == 7){ + df = new SimpleDateFormat("yyyy-MM"); + displayFormat = "yyyy MMM"; } + df.setTimeZone(getTimeZone()); + + // build google charts + Chart chart = charts.createLineChart("commitsChart", getString("gb.activity"), "day", getString("gb.commits")); + chart.setDateFormat(displayFormat); + + for (Metric metric : metrics) { + Date date; + try { + date = df.parse(metric.name); + } catch (ParseException e) { + logger.error("Unable to parse date: " + metric.name); + return charts; + } + chart.addValue(date, (int)metric.count); + if(metric.tag > 0 ){ + chart.addHighlight(date, (int)metric.count); + } + } + charts.addChart(chart); + + return charts; } + } -- cgit v1.2.3