/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.core.gui.components.chart;
import java.util.List;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.DefaultComponentRenderer;
import org.olat.core.gui.components.chart.RadarSeries.RadarPoint;
import org.olat.core.gui.render.RenderResult;
import org.olat.core.gui.render.Renderer;
import org.olat.core.gui.render.StringOutput;
import org.olat.core.gui.render.URLBuilder;
import org.olat.core.gui.translator.Translator;
import org.olat.core.util.StringHelper;
/**
*
* Initial date: 20 déc. 2016<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class RadarChartComponentRenderer extends DefaultComponentRenderer {
@Override
public void render(Renderer renderer, StringOutput sb, Component source, URLBuilder ubu, Translator translator, RenderResult renderResult, String[] args) {
RadarChartComponent soc = (RadarChartComponent)source;
String cmpId = soc.getDispatchID();
List<RadarSeries> series = soc.getSeries();
sb.append("<div id='d").append(cmpId).append("d3holder' class='radarChart' style='max-width:800px; max-height:650px; margin:0 auto;'></div>\n");
sb.append("<script type='text/javascript'>\n")
.append("/* <![CDATA[ */ \n")
.append("jQuery(function() {\n")
.append(" var render = function() {\n")
.append(" var placeholderWidth = jQuery('#d").append(cmpId).append("d3holder').width();\n")
.append(" var margin = {top: 75, right: 150, bottom: 75, left: 150};\n")
.append(" var radarWidth = (placeholderWidth - margin.right - margin.left);\n")
.append(" var radarHeight = radarWidth * (6.0 / 8.0);\n");
renderColorRange(sb, series);
sb.append(" jQuery('#d").append(cmpId).append("d3holder').ooRadarChart({\n")
.append(" w: radarWidth,\n")
.append(" h: radarHeight,\n")
.append(" margin: margin,\n")
.append(" labelFactor: 1.25,\n")
.append(" maxValue: ").append(soc.getMaxValue()).append(",\n")
.append(" levels: ").append(soc.getLevels()).append(",\n")
.append(" roundStrokes: true,\n")
.append(" wrapWidth: 100,\n")
.append(" format: '").append(soc.getFormat().format()).append("',")
.append(" color: color,\n");
if(soc.getAxis() != null && soc.getAxis().size() > 0) {
sb.append(" axis: ");
renderAxis(sb, soc.getAxis());
sb.append(",\n");
}
if(soc.isShowLegend()) {
sb.append(" legendOptions: ");
renderLegends(sb, series);
sb.append(",\n");
}
sb.append(" values: ");
renderValues(sb, series);
sb.append(" });\n")
.append(" }\n")//end render function
.append(" render();\n")
.append(" jQuery(window).on('resize', render);\n")
.append("});\n")
.append("/* ]]> */\n")
.append("</script>");
}
private void renderColorRange(StringOutput sb, List<RadarSeries> series) {
int hasColor = 0;
for(RadarSeries serie:series) {
if(StringHelper.containsNonWhitespace(serie.getColor())) {
hasColor++;
}
}
int numOfSeries = series.size();
if(hasColor == numOfSeries) {
sb.append(" var color = d3.scale.ordinal().range([");
for(int i=0;i<numOfSeries; i++) {
if(i > 0) {
sb.append(",");
}
sb.append("\"").append(series.get(i).getColor()).append("\"");
}
sb.append("]);\n");
} else if(numOfSeries < 4) {
sb.append(" var color = d3.scale.ordinal().range([\"#EDC951\",\"#CC333F\",\"#00A0B0\"]);\n");
} else {
sb.append(" var color = d3.scale.category10();\n");
}
}
private void renderAxis(StringOutput sb, List<String> axis) {
int numOfSeries = axis.size();
sb.append("[");
for(int i=0; i<numOfSeries; i++) {
String name = StringHelper.escapeJavaScript(axis.get(i));
sb.append("\"").append(name).append("\"");
if(i < (numOfSeries - 1)) {
sb.append(",");
}
}
sb.append("]");
}
private void renderLegends(StringOutput sb, List<RadarSeries> series) {
int numOfSeries = series.size();
sb.append("[");
for(int i=0; i<numOfSeries; i++) {
String name = StringHelper.escapeJavaScript(series.get(i).getName());
sb.append("\"").append(name).append("\"");
if(i < (numOfSeries - 1)) {
sb.append(",");
}
}
sb.append("]");
}
private void renderValues(StringOutput sb, List<RadarSeries> series) {
int numOfSeries = series.size();
sb.append("[");
for(int i=0; i<numOfSeries; i++) {
sb.append("[");
List<RadarPoint> points = series.get(i).getPoints();
int numOfPoints = points.size();
for(int j=0; j<numOfPoints; j++) {
RadarPoint point = points.get(j);
String axis = StringHelper.escapeJavaScript(point.getAxis());
sb.append("{axis:\"").append(axis).append("\",value:").append(point.getValue()).append("}");
if(j < (numOfPoints - 1)) {
sb.append(",");
}
}
sb.append("]");
if(i < (numOfSeries - 1)) {
sb.append(",");
}
}
sb.append("]");
}
}