[JAVA] Extend Highfaces to flip the vertical axis of the graph

I want to invert the axes of the graph

When creating a line graph of a certain ranking with Highfaces, it is necessary to set the maximum value of the y-axis to 0 because it is a ranking. However, HighCharts didn't have "reversed" (an option to flip the axis), so I'll create a custom tag so that I can specify "reversed".

Extend tag handlers and components

Extend the following tag handlers and components for graphs and graph axes. At this time, an accessor is added to the ChartAxisEx class so that the attribute "reversed" can be specified.

ChartHandler.java


public class ChartHandlerEx extends ChartHandler {
	public ChartHandlerEx(ComponentConfig config) {
		super(config);
	}
}

ChartHandler.java


@FacesComponent("hogehoge.component.ChartEx")
public class ChartEx extends Chart {
}

ChartAxis.java


@FacesComponent("hogehoge.component.ChartAxisEx")
public class ChartAxisEx extends ChartAxis {
	public Object getReversed() {
		return Object.class.cast(this.getStateHelper().eval("reversed", null));
	}

	public void setReversed(Object value) {
		this.getStateHelper().put("reversed", value);
	}
}

Extend the renderer

Extend the ChartRenderer class to output the "reversed" option and add the following to the method called "encodeAxes".

ChartRendererEx.java


@FacesRenderer(componentFamily = "org.highfaces.component", rendererType = "hogehoge.renderer,ChartRendererEx")
@ListenerFor(systemEventClass = PostAddToViewEvent.class)
public class ChartRendererEx extends ChartRenderer {

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
    //abridgement
    }

    private void encodeAxes(FacesContext context, Chart cv, JSONObject high) throws JSONException, IOException {
    //abridgement
    if (axis.getReversed() != null) {
        j.put("reversed", axis.getReversed());
    }
}

Create taglib.xml

Create taglib.xml in src / main / resources / META-INF and specify the class extended above.

xml:highfaces.taglib.xml


<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
	version="2.0">
	<namespace>http://hogehoge.jp/taglib</namespace>
	<tag>
		<tag-name>chartEx</tag-name>
		<component>
			<component-type>hogehoge.component.ChartEx</component-type>
			<renderer-type>hogehoge.renderer.ChartRendererEx</renderer-type>
			<handler-class>hogehoge.component.ChartHandlerEx</handler-class>
		</component>
		<attribute>
			<description><![CDATA[Type of the charts, possible values are line, spline, area, column, bar and pie]]></description>
			<name>type</name>
			<required>true</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[List of HTML colors for the chart series. Defaults to "#2f7ed8,#0d233a,#8bbc21,#910000,#1aadce,#492970,#f28f43,#77a1e5,#c42525,#a6c96a".]]></description>
			<name>colors</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[Datasource of the component, can be a Collection or Map type. Provide either a value, a model or chartseries as children declared in the xhtml file.]]></description>
			<name>value</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[Datasource of the component, must implement the ChartModel interface. Provide either a value, a model or chartseries as children declared in the xhtml file.]]></description>
			<name>model</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[ValueExpression of the currently selected Series.]]></description>
			<name>selectedSeries</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[ValueExpression of the currently selected Point inside the selected Series. This corresponds to the category/value of the x axis.]]></description>
			<name>selectedPoint</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[JavaScript to be executed on point selection.]]></description>
			<name>onselect</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[Height of chart in px]]></description>
			<name>height</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[Width of chart in px]]></description>
			<name>width</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[Title for the chart]]></description>
			<name>title</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[Credits text for the chart]]></description>
			<name>credits</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[Zoom type text for the chart]]></description>
			<name>zoomType</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[Sub Title for the chart]]></description>
			<name>subTitle</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[Label for x-axis]]></description>
			<name>xaxisLabel</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[Label for y-axis]]></description>
			<name>yaxisLabel</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[Name of the request scoped variable used as iterator for value]]></description>
			<name>var</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[Index of currently rendered item during iteration over the Collection in value-Attribute]]></description>
			<name>rowIndexVar</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[ValueExpression of the value of a point, bar,... Only valid if used in combinatino with value.]]></description>
			<name>point</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[ValueExpression of the tickLabel for a single point. Only valid if used in combinatino with value.]]></description>
			<name>tickLabel</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[ID of rerender component for ajax actions]]></description>
			<name>render</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[JavaScript function name for client side customization. All highcharts configuration options are available inside the function using 'this'.]]></description>
			<name>extender</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[Whether to stack the values of each series on top of each other. Possible values are 'none', 'normal' or 'percent', defaulting to 'none'.]]></description>
			<name>stacking</name>
			<required>false</required>
			<type>java.lang.String</type>
		</attribute>
		<attribute>
			<description><![CDATA[If set, this is the time interval in seconds that the updateMethod will be called and series data will change.]]></description>
			<name>updateInterval</name>
			<required>false</required>
			<type>java.lang.Integer</type>
		</attribute>
		<attribute>
			<description><![CDATA[How many points should be always visible in the chart in liveUpdate mode ? Defaults to 20.]]></description>
			<name>updateCapacity</name>
			<required>false</required>
			<type>java.lang.Integer</type>
		</attribute>
		<attribute>
			<description><![CDATA[This method will be called via AJAX each time, the chart needs to update the visible data. Use it to change or add data to the displayed series.]]></description>
			<name>updateMethod</name>
			<required>false</required>
			<type>javax.el.MethodExpression</type>
		</attribute>
		<attribute>
			<description><![CDATA[JavaScript to be executed on mouse over event.]]></description>
			<name>onmouseover</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[JavaScript to be executed on mouse over event.]]></description>
			<name>onmouseoverpoint</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
	</tag>
	<tag>
		<tag-name>chartAxisEx</tag-name>
		<component>
			<component-type>hogehoge.component.ChartAxisEx</component-type>
		</component>
		<attribute>
			<description><![CDATA[Position of this axis. Possible values are n, w, s or e.]]></description>
			<name>position</name>
			<required>true</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[Angle in degrees if the tickLabel should be rotated. Defaults to 0.]]></description>
			<name>tickAngle</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[Color of the gridline for this axis within the chart.]]></description>
			<name>gridLineColor</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[Width of the gridline for this axis within the chart. Use 0 to not display a gridline.]]></description>
			<name>gridLineWidth</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[Type of this axis. Possible values are linear, category and datetime, defaulting to linear.]]></description>
			<name>type</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[Label-Style of this axis. Use CSS definition style to e.g. define a color.]]></description>
			<name>style</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[Title of this axis.]]></description>
			<name>title</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[Label-Format of this axis. To display e.g. mm use "{value} mm"]]></description>
			<name>format</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[Minimum value for this axis]]></description>
			<name>min</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[Maximum value for this axis]]></description>
			<name>max</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
		<attribute>
			<description><![CDATA[Reversed for this axis]]></description>
			<name>reversed</name>
			<required>false</required>
			<type>java.lang.Object</type>
		</attribute>
	</tag>
</facelet-taglib>

Actually use

Now that you have a custom tag, make sure you can specify "reversed" in the "chartAxisEx" tag.

hogehoge.xhtml


<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:hf="http://highfaces.org"
	xmlns:ex="http://hogehoge.jp/taglib">
<h:head>
	<title>hogehoge graph</title>
</h:head>
<h:body>
	<ex:chartEx type="line" title="hogehoge graph">
		<hf:chartSerie name="Something ranking"
			value="#{hogehogeBean}"
			var="rank" point="#{rank.rank}" tickLabel="#{rank.time}">
		</hf:chartSerie>
		<ex:chartAxisEx position="w" min="1" max="100" reversed="true"
			title="" />
		<ex:chartAxisEx position="s" title="" type="datetime"
			format="{value:%Y.%m.%d}" />
	</ex:chartEx>
</h:body>
</html>

Done

Now you can extend Highfaces to flip the axes of the graph.

BEFORE: WS000009.JPG

AFTER: WS000008.JPG

Recommended Posts

Extend Highfaces to flip the vertical axis of the graph
Let's summarize how to extend the expiration date of Rails
[Rails] Creation of the second vertical axis and Japanese localization in graph drawing using amCharts4, etc.
The secret to the success of IntelliJ IDEA
[Eclipse] Change the color of the vertical ruler
How to determine the number of parallels
How to sort the List of SelectItem
Output of the book "Introduction to Java"
The process of introducing Vuetify to Rails
How to find the cause of the Ruby error
[Rails] Button to return to the top of the page
Add empty data to the top of the list
Customize how to divide the contents of Recyclerview
Make a margin to the left of the TextField
The story of introducing Ajax communication to ruby
Set the time of LocalDateTime to a specific time
The story of raising Spring Boot 1.5 series to 2.1 series
I want to var_dump the contents of the intent
How to get today's day of the week
Change the timezone of the https-portal container to JST
Output of how to use the slice method
[Ruby] Code to display the day of the week
The story of adding the latest Node.js to DockerFile
How to display the result of form input
[Java] How to get the authority of the folder
Java Welcome to the Swamp of 2D Arrays