Commit 1e6b8dc2 authored by Boxiang Sun's avatar Boxiang Sun

erp5_officejs: Add a wrapper for ECharts chart library.

parent 8db07be4
<!DOCTYPE html>
<!--html style="height: 100%"-->
<html style="height: 300px">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>ERP5 Widget Graph</title>
<!-- interfaces -->
<link rel="http://www.renderjs.org/rel/interface" href="gadget_field_graph_interface.html">
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<!-- libraries needed for graphs -->
<script src="echarts-all.js" type="text/javascript"></script>
<!-- custom script -->
<script src="unsafe/gadget_field_graph_echarts.js" type="text/javascript"></script>
</head>
<body style="height: 100%; margin: 0">
<div class="graph-content" style="height: 95%; width: 95%">
</div>
</body>
</html>
\ No newline at end of file
/*global window, rJS, RSVP, echarts */
/*jslint nomen: true, indent: 2 */
(function (window, rJS, RSVP, echarts) {
"use strict";
/////////////////////////////////////////////////////////////////
// templates
/////////////////////////////////////////////////////////////////
var gadget_klass = rJS(window),
getGraphDataAndParameterFromConfiguration = function (configuration_dict) {
var graph_data_and_parameter = {},
data,
trace,
trace_type,
type_list = [],
label_list = [],
trace_value_dict,
dataset_list = [],
dataset,
i,
j,
layout,
title;
if (configuration_dict.constructor === String) {
configuration_dict = JSON.parse(configuration_dict);
}
data = configuration_dict.data || [];
layout = configuration_dict.layout || {};
title = layout.title;
// title
// The position of the title in plotly was fixed, like the "x:center" in echarts.
// For now, every graph have to provide a title.
if (title === undefined) {
throw new Error("No title provided", data);
}
graph_data_and_parameter.title = {text: title, x: "center"};
// tooltip
// ECharts have to enable the tooltip manually.
graph_data_and_parameter.tooltip = {};
graph_data_and_parameter.tooltip.trigger = "item";
// legend
// Initialize the legend.
graph_data_and_parameter.legend = {};
graph_data_and_parameter.legend.y = 25;
graph_data_and_parameter.legend.data = [];
// Axis
// Initialize the axis
graph_data_and_parameter.xAxis = [];
graph_data_and_parameter.yAxis = [];
for (i = 0; i < data.length; i = i + 1) {
trace = data[i];
trace_type = trace.type || 'bar';
type_list.push(trace_type);
trace_value_dict = trace.value_dict || {};
if (trace_value_dict[0] === undefined || trace_value_dict[1] === undefined) {
throw new Error("Unexpected data for ECharts", data);
}
dataset = {};
dataset.type = trace_type;
dataset.name = trace.title || {};
// If the graph type is pie, set the pie radius
// plotly doesn't have this option.
if (trace_type === 'pie') {
dataset.radius = '55%';
dataset.center = ['50%', '60%'];
}
// For pie graph, the legend labels come from each item's title(aka trace.title)
// For graph which contains the axis, the legend labels come from the item's value_dict[0].
// See the trace_value_dict in below. But the duplicated value_dict[0] seems for 2D graph
// seems is redandunt.
if (trace.type !== 'pie') {
graph_data_and_parameter.legend.data.push(dataset.name);
}
dataset.data = [];
for (j = 0; j < trace_value_dict[0].length; j = j + 1) {
if (label_list.length !== trace_value_dict[0].length) {
label_list[j] = trace_value_dict[0][j];
}
}
// Value
for (j = 0; j < trace_value_dict[1].length; j = j + 1) {
dataset.data.push(
{
value: trace_value_dict[1][j],
name: label_list[j],
itemStyle: null
}
);
// Handle the colors in different ways. Maybe enhanced latter
if (trace.colors) {
// In the pie graph, set the color each individual "data" item.
if (trace.type === 'pie') {
dataset.data[j].itemStyle = {normal: {color: trace.colors[j]}};
} else {
// In other types of graph, set the color for each group.
dataset.itemStyle = {normal: {color: trace.colors[0]}};
}
}
}
dataset_list.push(dataset);
}
// For the pie graph, the legend label is the value_dict[0]
if (trace.type === 'pie') {
graph_data_and_parameter.legend.data = label_list;
}
// Axis
if (trace.type !== 'pie') {
// if not value type provided, set it as "value".
graph_data_and_parameter.yAxis.push({type: 'value', name: layout.axis_dict[1].title});
graph_data_and_parameter.xAxis.push({data: label_list, name: layout.axis_dict[0].title});
} else {
graph_data_and_parameter.xAxis = null;
graph_data_and_parameter.yAxis = null;
}
graph_data_and_parameter.series = dataset_list;
return graph_data_and_parameter;
};
/////////////////////////////////////////////////////////////////
// some methods
/////////////////////////////////////////////////////////////////
gadget_klass
.declareAcquiredMethod("chartItemClick", "chartItemClick")
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
.ready(function (gadget) {
gadget.property_dict = {};
})
/////////////////////////////////////////////////////////////////
// published methods
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
// acquired methods
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod('render', function (option_dict) {
var gadget = this;
//delegate rendering to onStateChange to avoid redrawing the graph
//every time render is called (a form might call render every time
//some other fields needs update)
gadget.changeState({value: option_dict.value});
})
.onStateChange(function (modification_dict) {
var gadget = this,
container,
graph_data_and_parameter,
chart;
container = gadget.element.querySelector(".graph-content");
chart = echarts.init(container);
graph_data_and_parameter = getGraphDataAndParameterFromConfiguration(modification_dict.value);
chart.setOption(graph_data_and_parameter);
this.listenToClickEventOnTheChart(chart);
// XXX
window.onresize = function () {
chart.resize();
};
gadget.property_dict.chart = chart;
})
.declareJob('listenToClickEventOnTheChart', function (chart) {
var gadget = this,
defer = RSVP.defer();
// XXX https://lab.nexedi.com/nexedi/renderjs/blob/master/renderjs.js#L25
chart.on('click', function (params) {
return gadget.chartItemClick([params.name, params.seriesName])
.push(undefined, defer.reject);
});
return defer.promise;
});
}(window, rJS, RSVP, echarts));
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment