From e5b9fd80838d30edb2dfd8a4220f2589d19f3ae2 Mon Sep 17 00:00:00 2001 From: Veronika Date: Thu, 17 Mar 2016 15:49:27 +0300 Subject: [PATCH] [ADD] added module web_graph_radar --- web_graph_radar/README.md | 4 + web_graph_radar/__init__.py | 0 web_graph_radar/__openerp__.py | 35 + web_graph_radar/i18n/ar.po | 39 + web_graph_radar/i18n/de.po | 39 + web_graph_radar/i18n/en.po | 38 + web_graph_radar/i18n/es.po | 39 + web_graph_radar/i18n/fi.po | 39 + web_graph_radar/i18n/pt_BR.po | 39 + web_graph_radar/i18n/sl.po | 39 + web_graph_radar/i18n/tr.po | 39 + web_graph_radar/static/description/icon.png | Bin 0 -> 9455 bytes web_graph_radar/static/lib/nvd3-radar.js | 885 ++++++++++++++++++ .../static/src/js/web_graph_radar.js | 86 ++ .../static/src/xml/web_graph_radar.xml | 14 + web_graph_radar/view/web_graph_radar.xml | 20 + 16 files changed, 1355 insertions(+) create mode 100644 web_graph_radar/README.md create mode 100644 web_graph_radar/__init__.py create mode 100644 web_graph_radar/__openerp__.py create mode 100644 web_graph_radar/i18n/ar.po create mode 100644 web_graph_radar/i18n/de.po create mode 100644 web_graph_radar/i18n/en.po create mode 100644 web_graph_radar/i18n/es.po create mode 100644 web_graph_radar/i18n/fi.po create mode 100644 web_graph_radar/i18n/pt_BR.po create mode 100644 web_graph_radar/i18n/sl.po create mode 100644 web_graph_radar/i18n/tr.po create mode 100644 web_graph_radar/static/description/icon.png create mode 100644 web_graph_radar/static/lib/nvd3-radar.js create mode 100644 web_graph_radar/static/src/js/web_graph_radar.js create mode 100644 web_graph_radar/static/src/xml/web_graph_radar.xml create mode 100644 web_graph_radar/view/web_graph_radar.xml diff --git a/web_graph_radar/README.md b/web_graph_radar/README.md new file mode 100644 index 00000000..2cc64f27 --- /dev/null +++ b/web_graph_radar/README.md @@ -0,0 +1,4 @@ +Graph Radar Chart. +================= + +Add new graph view mode: Radar diff --git a/web_graph_radar/__init__.py b/web_graph_radar/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/web_graph_radar/__openerp__.py b/web_graph_radar/__openerp__.py new file mode 100644 index 00000000..da91b38d --- /dev/null +++ b/web_graph_radar/__openerp__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Veronika Kotovich @ IT-PROJECTS +# Copyright (C) 2016 Veronika Kotovich +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +{ + 'name': 'Radar Chart', + 'version': '8.0.0.1.0', + 'category': 'Web', + 'summary': 'Add graph radar view.', + 'author': "Veronika Kotovich,Odoo Community Association (OCA)", + 'license': 'AGPL-3', + 'website': 'https://twitter.com/vkotovi4', + 'depends': ['web_graph'], + 'qweb': ['static/src/xml/web_graph_radar.xml'], + 'data': ['view/web_graph_radar.xml'], + 'installable': True, + 'auto_install': False, +} diff --git a/web_graph_radar/i18n/ar.po b/web_graph_radar/i18n/ar.po new file mode 100644 index 00000000..9f3be626 --- /dev/null +++ b/web_graph_radar/i18n/ar.po @@ -0,0 +1,39 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_graph_improved +# +# Translators: +# SaFi J. , 2015 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-16 07:41+0000\n" +"PO-Revision-Date: 2015-12-16 17:31+0000\n" +"Last-Translator: SaFi J. \n" +"Language-Team: Arabic (http://www.transifex.com/oca/OCA-web-8-0/language/ar/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:13 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:14 +#, python-format +msgid "Total" +msgstr "المجموع الاجمالي" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:30 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:40 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:44 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:49 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:54 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:57 +#, python-format +msgid "Undefined" +msgstr "غير معرف" diff --git a/web_graph_radar/i18n/de.po b/web_graph_radar/i18n/de.po new file mode 100644 index 00000000..7efcecf6 --- /dev/null +++ b/web_graph_radar/i18n/de.po @@ -0,0 +1,39 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_graph_improved +# +# Translators: +# Rudolf Schnapka , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-10 07:31+0000\n" +"PO-Revision-Date: 2016-01-18 20:15+0000\n" +"Last-Translator: Rudolf Schnapka \n" +"Language-Team: German (http://www.transifex.com/oca/OCA-web-8-0/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:13 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:14 +#, python-format +msgid "Total" +msgstr "Gesamt" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:30 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:40 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:44 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:49 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:54 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:57 +#, python-format +msgid "Undefined" +msgstr "Undefiniert" diff --git a/web_graph_radar/i18n/en.po b/web_graph_radar/i18n/en.po new file mode 100644 index 00000000..65f7297e --- /dev/null +++ b/web_graph_radar/i18n/en.po @@ -0,0 +1,38 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_graph_improved +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-11-23 13:46+0000\n" +"PO-Revision-Date: 2015-11-07 11:20+0000\n" +"Last-Translator: OCA Transbot \n" +"Language-Team: English (http://www.transifex.com/oca/OCA-web-8-0/language/en/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: en\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:13 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:14 +#, python-format +msgid "Total" +msgstr "Total" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:30 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:40 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:44 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:49 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:54 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:57 +#, python-format +msgid "Undefined" +msgstr "Undefined" diff --git a/web_graph_radar/i18n/es.po b/web_graph_radar/i18n/es.po new file mode 100644 index 00000000..3e0787b1 --- /dev/null +++ b/web_graph_radar/i18n/es.po @@ -0,0 +1,39 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_graph_improved +# +# Translators: +# Pedro M. Baeza , 2015 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-11-23 13:46+0000\n" +"PO-Revision-Date: 2015-11-07 11:27+0000\n" +"Last-Translator: Pedro M. Baeza \n" +"Language-Team: Spanish (http://www.transifex.com/oca/OCA-web-8-0/language/es/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:13 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:14 +#, python-format +msgid "Total" +msgstr "Total" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:30 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:40 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:44 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:49 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:54 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:57 +#, python-format +msgid "Undefined" +msgstr "Sin definir" diff --git a/web_graph_radar/i18n/fi.po b/web_graph_radar/i18n/fi.po new file mode 100644 index 00000000..4afb7305 --- /dev/null +++ b/web_graph_radar/i18n/fi.po @@ -0,0 +1,39 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_graph_improved +# +# Translators: +# Jarmo Kortetjärvi , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-10 07:31+0000\n" +"PO-Revision-Date: 2016-02-01 09:54+0000\n" +"Last-Translator: Jarmo Kortetjärvi \n" +"Language-Team: Finnish (http://www.transifex.com/oca/OCA-web-8-0/language/fi/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: fi\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:13 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:14 +#, python-format +msgid "Total" +msgstr "Yhteensä" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:30 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:40 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:44 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:49 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:54 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:57 +#, python-format +msgid "Undefined" +msgstr "Ei määritelty" diff --git a/web_graph_radar/i18n/pt_BR.po b/web_graph_radar/i18n/pt_BR.po new file mode 100644 index 00000000..10175ca7 --- /dev/null +++ b/web_graph_radar/i18n/pt_BR.po @@ -0,0 +1,39 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_graph_improved +# +# Translators: +# danimaribeiro , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-11 02:17+0000\n" +"PO-Revision-Date: 2016-03-05 16:20+0000\n" +"Last-Translator: danimaribeiro \n" +"Language-Team: Portuguese (Brazil) (http://www.transifex.com/oca/OCA-web-8-0/language/pt_BR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: pt_BR\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:13 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:14 +#, python-format +msgid "Total" +msgstr "Total" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:30 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:40 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:44 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:49 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:54 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:57 +#, python-format +msgid "Undefined" +msgstr "Não definido" diff --git a/web_graph_radar/i18n/sl.po b/web_graph_radar/i18n/sl.po new file mode 100644 index 00000000..039817e3 --- /dev/null +++ b/web_graph_radar/i18n/sl.po @@ -0,0 +1,39 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_graph_improved +# +# Translators: +# Matjaž Mozetič , 2015 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-11-23 13:46+0000\n" +"PO-Revision-Date: 2015-11-08 05:45+0000\n" +"Last-Translator: Matjaž Mozetič \n" +"Language-Team: Slovenian (http://www.transifex.com/oca/OCA-web-8-0/language/sl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: sl\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:13 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:14 +#, python-format +msgid "Total" +msgstr "Skupaj" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:30 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:40 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:44 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:49 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:54 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:57 +#, python-format +msgid "Undefined" +msgstr "Nedoločeno" diff --git a/web_graph_radar/i18n/tr.po b/web_graph_radar/i18n/tr.po new file mode 100644 index 00000000..bdbdb4c7 --- /dev/null +++ b/web_graph_radar/i18n/tr.po @@ -0,0 +1,39 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_graph_improved +# +# Translators: +# Ahmet Altınışık , 2015 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-08 21:34+0000\n" +"PO-Revision-Date: 2015-12-30 22:16+0000\n" +"Last-Translator: Ahmet Altınışık \n" +"Language-Team: Turkish (http://www.transifex.com/oca/OCA-web-8-0/language/tr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: tr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:13 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:14 +#, python-format +msgid "Total" +msgstr "Toplam" + +#. module: web_graph_improved +#. openerp-web +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:30 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:40 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:44 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:49 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:54 +#: code:addons/web_graph_improved/static/src/js/web_graph_improved.js:57 +#, python-format +msgid "Undefined" +msgstr "Tanımsız" diff --git a/web_graph_radar/static/description/icon.png b/web_graph_radar/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/web_graph_radar/static/lib/nvd3-radar.js b/web_graph_radar/static/lib/nvd3-radar.js new file mode 100644 index 00000000..4c2c5a53 --- /dev/null +++ b/web_graph_radar/static/lib/nvd3-radar.js @@ -0,0 +1,885 @@ +nv.models.radar = function() { + + //============================================================ + // Public Variables with Default Settings + //------------------------------------------------------------ + + var margin = {top: 0, right: 0, bottom: 0, left: 0} + , width = 500 + , height = 500 + , color = nv.utils.defaultColor() // a function that returns a color + , getValue = function(d) { return d.value } // accessor to get the x value from a data point + , size = 5 + , scales = d3.scale.linear() + , radius + , max = 5 + , startAngle = 0 + , cursor = 0 + , clipEdge = false + ; + + var line = d3.svg.line() + .x(function(d) { return d.x}) + .y(function(d) { return d.y}); + + var scatter = nv.models.scatter() + .size(16) // default size + .sizeDomain([16,256]) + ; + + //============================================================ + + + //============================================================ + // Private Variables + //------------------------------------------------------------ + + + //============================================================ + + + function chart(selection) { + selection.each(function(data) { + + var availableWidth = width - margin.left - margin.right, + availableHeight = height - margin.top - margin.bottom, + container = d3.select(this) + ; + + // max = max || d3.max(data, getValue) > 0 ? d3.max(data, getValue) : 1 + + scales.domain([0, max]).range([0,radius]); + + var current = 0; + if (cursor < 0) { + current = Math.abs(cursor); + } + else if (cursor > 0) { + current = size - cursor; + } + + + //------------------------------------------------------------ + // Setup Scales + //compute proportions + var maxValue = 0; + for(var i=0; i maxValue) { + maxValue = serie[j].value; + } + } + } + var factor = maxValue ? (radius-40)/maxValue/max/2 : 0; + data = data.map(function(serie, i) { + serie.values = serie.values.map(function(value, j) { + value.x = calculateX(value.value*factor, j, size); + value.y = calculateY(value.value*factor, j, size); + value.serie = i; + value.focus = (current == j) ? true : false; + return value; + }); + return serie; + }); + + //------------------------------------------------------------ + + + + //------------------------------------------------------------ + // Setup containers and skeleton of chart + + var wrap = container.selectAll('g.nv-wrap.nv-radar').data([data]); + var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-radar'); + var defsEnter = wrapEnter.append('defs'); + var gEnter = wrapEnter.append('g'); + var g = wrap.select('g') + + gEnter.append('g').attr('class', 'nv-groups'); + gEnter.append('g').attr('class', 'nv-scatterWrap'); + + + // wrap.attr('transform', 'translate(' + radius + ',' + radius + ')'); + + //------------------------------------------------------------ + + // Points + scatter + .xScale(scales) + .yScale(scales) + .zScale(scales) + .color(color) + .useVoronoi(false) + .width(availableWidth) + .height(availableHeight); + + var scatterWrap = wrap.select('.nv-scatterWrap'); + //.datum(data); // Data automatically trickles down from the wrap + + d3.transition(scatterWrap).call(scatter); + + defsEnter.append('clipPath') + .attr('id', 'nv-edge-clip-' + scatter.id()) + .append('rect'); + + wrap.select('#nv-edge-clip-' + scatter.id() + ' rect') + .attr('width', availableWidth) + .attr('height', availableHeight); + + g.attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + scatter.id() + ')' : ''); + scatterWrap + .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + scatter.id() + ')' : ''); + + + // Series + var groups = wrap.select('.nv-groups').selectAll('.nv-group').data(function(d) { return d }, function(d) { return d.key }); + groups.enter().append('g') + .style('stroke-opacity', 1e-6) + .style('fill-opacity', 1e-6); + d3.transition(groups.exit()) + .style('stroke-opacity', 1e-6) + .style('fill-opacity', 1e-6) + .remove(); + groups + .attr('class', function(d,i) { return 'nv-group nv-series-' + i }) + .style('fill', function(d,i){ return color(d,i); }) + .style('stroke', function(d,i){ return color(d,i); }); + d3.transition(groups) + .style('stroke-opacity', 1) + .style('fill-opacity', .5); + + var lineRadar = groups.selectAll('path.nv-line').data(function(d) { return [d.values] }); + + lineRadar.enter().append('path') + .attr('class', 'nv-line') + .attr('d', line ); + + + d3.transition(lineRadar.exit()) + .attr('d', line) + .remove(); + + lineRadar + .style('fill', function(d){ return color(d,d[0].serie); }) + .style('stroke', function(d,i,j){ return color(d,d[0].serie); }) + + d3.transition(lineRadar) + .attr('d', line ); + + + + }); + + return chart; + } + + // compute an angle + function angle(i, length) { + return i * (2 * Math.PI / length ) + ((2 * Math.PI) * startAngle / 360) + (cursor*2*Math.PI)/length; + } + + // x-caclulator + // d is the datapoint, i is the index, length is the length of the data + function calculateX(d, i, length) { + var l = scales(d); + return Math.sin(angle(i, length)) * l; + } + + // y-calculator + function calculateY(d, i, length) { + var l = scales(d); + return Math.cos(angle(i, length)) * l; + } + + + //============================================================ + // Expose Public Variables + //------------------------------------------------------------ + + chart.dispatch = scatter.dispatch; + chart.scatter = scatter; + + chart.margin = function(_) { + if (!arguments.length) return margin; + margin.top = typeof _.top != 'undefined' ? _.top : margin.top; + margin.right = typeof _.right != 'undefined' ? _.right : margin.right; + margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom; + margin.left = typeof _.left != 'undefined' ? _.left : margin.left; + return chart; + }; + + chart.width = function(_) { + if (!arguments.length) return width; + width = _; + return chart; + }; + + chart.height = function(_) { + if (!arguments.length) return height; + height = _; + return chart; + }; + + chart.size = function(_) { + if (!arguments.length) return size; + size = _; + return chart; + }; + + chart.scales = function(_) { + if (!arguments.length) return scales; + scales = _; + return chart; + }; + + chart.max = function(_) { + if (!arguments.length) return max; + max = _; + return chart; + }; + + chart.radius = function(_) { + if (!arguments.length) return radius; + radius = _; + return chart; + }; + + chart.color = function(_) { + if (!arguments.length) return color; + color = nv.utils.getColor(_); + return chart; + }; + + chart.startAngle = function(_) { + if (!arguments.length) return startAngle; + startAngle = _; + return chart; + }; + + chart.cursor = function(_) { + if (!arguments.length) return cursor; + cursor = _; + return chart; + }; + + //============================================================ + + + return chart; +} + +nv.models.radarChart = function() { + + //============================================================ + // Public Variables with Default Settings + //------------------------------------------------------------ + + var radars = nv.models.radar() + , legend = nv.models.legend(); + + var margin = {top: 0, right: 0, bottom: 0, left: 0} + , color = nv.utils.defaultColor() + , width = null + , height = null + , showLegend = true + , legs = [] + , ticks = 10 //Temp to test radar size issue + , scales = d3.scale.linear() + , edit = false + , radius + , startAngle = 180 + , cursor = 0 + , tooltips = true + , transitionDuration = 250 + , tooltip = function(key, leg, value, e, graph) { + return '

' + key + '

' + + '

' + leg + ': ' + value + '

' + } + , dispatch = d3.dispatch('tooltipShow', 'tooltipHide','prevClick','stateChange') + ; + + var line = d3.svg.line() + .x(function(d) { return d.x}) + .y(function(d) { return d.y}); + + //============================================================ + + + //============================================================ + // Private Variables + //------------------------------------------------------------ + + var showTooltip = function(e, offsetElement) { + + // New addition to calculate position if SVG is scaled with viewBox, may move TODO: consider implementing everywhere else + if (offsetElement) { + var svg = d3.select(offsetElement).select('svg'); + var viewBox = svg.attr('viewBox'); + if (viewBox) { + viewBox = viewBox.split(' '); + var ratio = parseInt(svg.style('width')) / viewBox[2]; + e.pos[0] = e.pos[0] * ratio; + e.pos[1] = e.pos[1] * ratio; + } + } + + var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ), + top = e.pos[1] + ( offsetElement.offsetTop || 0), + val = e.series.values[e.pointIndex].value, + leg = legs[e.pointIndex].label, + content = tooltip(e.series.key, leg, val, e, chart); + nv.tooltip.show([left, top], content, null, null, offsetElement); + }; + + //============================================================ + + + function chart(selection) { + selection.each(function(data) { + legs=data[0].values;//TODO: Think in a better way to put only the legs of the radar + var container = d3.select(this), + that = this, + size = legs.length, + availableWidth = (width || parseInt(container.style('width')) || 500) - margin.left - margin.right, + availableHeight = (height || parseInt(container.style('height')) || 500) - margin.top - margin.bottom; + + chart.update = function() { container.transition().duration(transitionDuration).call(chart) }; + chart.container = this; + + var current = 0; + if (cursor < 0) { + current = Math.abs(cursor); + } + else if (cursor > 0) { + current = legs.length - cursor; + } + + //------------------------------------------------------------ + // Setup Scales + + // scales = radars.scales(); + radius = (availableWidth-300 >= availableHeight) ? (availableHeight)/2 : (availableWidth-300)/2; + scales.domain([0, ticks]).range([0,radius]); + + //------------------------------------------------------------ + + //------------------------------------------------------------ + // Setup containers and skeleton of chart + + var wrap = container.selectAll('g.nv-wrap.nv-radarChart').data([data]); + var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-radarChart'); + var gEnter = wrapEnter.append('g'); + var g = wrap.select('g'); + + gEnter.append('g').attr('class', 'nv-controlWrap'); + gEnter.append('g').attr('class', 'nv-gridWrap'); + gEnter.append('g').attr('class', 'nv-radarsWrap'); + gEnter.append('g').attr('class', 'nv-legendWrap'); + + var gridWrap = wrap.select('g.nv-gridWrap'); + gridWrap.append("g").attr("class", "grid"); + gridWrap.append("g").attr("class", "axes"); + + wrap.attr('transform', 'translate(' + parseFloat(radius + margin.left) + ',' + parseFloat(radius + margin.top) + ')'); + + //------------------------------------------------------------ + + + //------------------------------------------------------------ + // Legend + + if (showLegend) { + legend.width(30); + + g.select('.nv-legendWrap') + .datum(data) + .call(legend); + + /* + if ( margin.top != legend.height()) { + margin.top = legend.height(); + availableHeight = (height || parseInt(container.style('height')) || 400) + - margin.top - margin.bottom; + } + */ + g.select('.nv-legendWrap') + .attr('transform', 'translate(' + (radius + margin.left + margin.right) + ',' + (-radius) +')'); + } + + //------------------------------------------------------------ + + if (edit) { + startAngle = 135 + //Focus + var currentLeg = legs[current]; + var rgbLeg = hexToRgb("#000000"); + var controlWrap = wrap.select('g.nv-controlWrap'); + + wrap.select('g.control').remove(); + var controlEnter = controlWrap.append("g") + .attr("class", "control"); + + var controlLine = controlEnter.append("svg:line") + .attr('class', 'indicator') + .style("stroke", "#000000") + .style("fill", "none") + .style("opacity", 1) + .style("stroke-width", 1.5) + .attr("x1", Math.sin(angle(current, size)) * scales(scales.domain()[1])) + .attr("y1", Math.cos(angle(current, size)) * scales(scales.domain()[1])) + .attr("x2", Math.sin(angle(current, size)) * scales(scales.domain()[1])) + .attr("y2", Math.cos(angle(current, size)) * scales(scales.domain()[1])); + + var controlDescription = controlEnter.append("svg:foreignObject") + .attr('width',200) + .attr('height',0) + .attr("x", Math.sin(angle(current, size)) * scales(scales.domain()[1]) * 2) + .attr("y", Math.cos(angle(current, size)) * scales(scales.domain()[1])); + + controlDescription.append("xhtml:div") + .attr('class', 'radar-description') + .style("background-color", 'rgba('+rgbLeg.r+','+rgbLeg.g+','+rgbLeg.b+',0.1)') + .style('border-bottom', '1px solid '+"#000000") + .style("padding", "10px") + .style("text-align", "justify") + .text( currentLeg.description ); + + + var controlActionContent = controlEnter.append("svg:foreignObject") + .attr('width',200) + .attr('height',50) + .attr("x", Math.sin(angle(current, size)) * scales(scales.domain()[1]) * 2) + .attr("y", Math.cos(angle(current, size)) * scales(scales.domain()[1]) - 25); + + controlActionContent.append("xhtml:button") + .attr('type','button') + .attr('class','radar-prev btn btn-mini icon-arrow-left') + .text('prev'); + + + var controlSelect = controlActionContent.append("xhtml:select") + .attr('class','radar-select-note'); + + controlSelect.append('xhtml:option') + .attr('value',0) + // .attr('selected', function(d,i){ return (d[0].values[current].value == 0) ? true : false;}) + .text('Note') + controlSelect.append('xhtml:option') + .attr('value',1) + // .attr('selected', function(d,i){ return (d[0].values[current].value == 1) ? true : false;}) + .text('Nul') + controlSelect.append('xhtml:option') + .attr('value',2) + //.attr('selected', function(d,i){ return (d[0].values[current].value == 2) ? true : false;}) + .text('Mauvais') + controlSelect.append('xhtml:option') + .attr('value',3) + // .attr('selected', function(d,i){ return (d[0].values[current].value == 3) ? true : false;}) + .text('Nul') + controlSelect.append('xhtml:option') + .attr('value',4) + // .attr('selected', function(d,i){ return (d[0].values[current].value == 4) ? true : false;}) + .text('Bien') + controlSelect.append('xhtml:option') + .attr('value',5) + // .attr('selected', function(d,i){ return (d[0].values[current].value == 4) ? true : false;}) + .text('Très bien') + + controlActionContent.append("xhtml:button") + .attr('type','button') + .attr('class','radar-next btn btn-mini icon-arrow-right') + .text('next'); + + + var checkOption = function (d) { + if(d[0].values[current].value == this.value){ + return d3.select(this).attr("selected", "selected"); + } + }; + + controlSelect.selectAll("option").each(checkOption); + + // Animation + controlLine.transition().duration(500) + .attr("x1", Math.sin(angle(current, size)) * scales(scales.domain()[1])) + .attr("y1", Math.cos(angle(current, size)) * scales(scales.domain()[1])) + .attr("x2", Math.sin(angle(current, size)) * scales(scales.domain()[1]) * 2 + 200) + .attr("y2", Math.cos(angle(current, size)) * scales(scales.domain()[1])) + .each('end', function(d){ controlDescription.transition().duration(300).attr('height','100%') }); + + // Controls + controlWrap.select('.radar-prev') + .on('click', function(d) { + chart.prev(); + selection.transition().call(chart); + }); + controlWrap.select('.radar-next') + .on('click', function(d) { + chart.next(); + selection.transition().call(chart); + }); + + controlWrap.select('.radar-select-note') + .on('change', function(d) { + d[0].values[current].value = this.value; + chart.next(); + selection.transition().call(chart); + }); + + //change + } else { + cursor = 0; + startAngle = 180; + wrap.select('g.control').remove(); + } + + //------------------------------------------------------------ + // Main Chart Component(s) + + radars + .width(availableWidth) + .height(availableHeight) + .size(legs.length) + .max(ticks) + .startAngle(startAngle) + .cursor(cursor) + // .scales(scales) + .radius(radius) + .color(data.map(function(d,i) { + return d.color || color(d, i); + }).filter(function(d,i) { return !data[i].disabled })) + ; + + + var radarWrap = g.select('.nv-radarsWrap') + .datum(data.filter(function(d) { return !d.disabled })); + + d3.transition(radarWrap).call(radars); + + //------------------------------------------------------------ + + //------------------------------------------------------------ + // Setup Axes + + // the grid data, number of ticks + var gridData = buildAxisGrid(size, ticks); + + // Grid + var grid = wrap.select('.grid').selectAll('.gridlevel').data(gridData); + grid.exit().remove(); + + grid.enter().append("path") + .attr("class", "gridlevel") + .attr("d", line); + + + d3.transition(grid) + .attr('d', line ); + + grid.style("stroke", "#000") + .style("fill", "none") + .style("opacity", 0.3); + + // Axes + var ax = wrap.select("g.axes").selectAll("g.axis").data(legs); + ax.exit().remove(); + + var axEnter = ax.enter().append("g") + .attr("class", "axis"); + + var legText = axEnter.append("svg:text") + .style("text-anchor", function(d, i) { + var x = Math.sin(angle(i, size)) * scales(scales.domain()[1]); + if (Math.abs(x) < 0.1) { + return "middle" + } + if (x > 0) { + return "start" + } + + return "end" + }) + .attr("dy", function(d, i) { + var y = Math.cos(angle(i, size)) * scales(scales.domain()[1]); + + if (Math.abs(y) < 0.1) { + return ".72em" + } + + if (y > 0) { + return "1em" + } + return "-.3em" + }) + .style("fill", function(d){ return d.color; }) + .style("font-size", "9pt") + .style("font-weight",function(d,i){ return (i == current && edit) ? "bold": "normal"; }) + .style("opacity", function(d,i){ return (i == current && edit) ? 1: 0.4; }) + .text(function(d){ return d.label}) + .attr("x", function(d, i) { return Math.sin(angle(i, size)) * scales(scales.domain()[1]);}) + .attr("y", function(d, i) { return Math.cos(angle(i, size)) * scales(scales.domain()[1]);}) + ; + + legText.on('click', function(d,i) { + chart.cursor(legs.length - i); + selection.transition().call(chart); + }); + + d3.transition(ax) + .select("text") + .style("text-anchor", function(d, i) { + var x = Math.sin(angle(i, size)) * scales(scales.domain()[1]); + if (Math.abs(x) < 0.1) { + return "middle" + } + if (x > 0) { + return "start" + } + + return "end" + }) + .attr("dy", function(d, i) { + var y = Math.cos(angle(i, size)) * scales(scales.domain()[1]); + + if (Math.abs(y) < 0.1) { + return ".72em" + } + + if (y > 0) { + return "1em" + } + return "-.3em" + }) + .style("font-weight",function(d,i){ return (i == current && edit) ? "bold": "normal"; }) + .style("opacity", function(d,i){ return (i == current && edit) ? 1: 0.4; }) + .attr("x", function(d, i) { return Math.sin(angle(i, size)) * scales(scales.domain()[1]);}) + .attr("y", function(d, i) { return Math.cos(angle(i, size)) * scales(scales.domain()[1]);}); + + axEnter.append("svg:line") + .style("stroke", function(d){ return d.color; }) + .style("fill", "none") + .style("stroke-width", 2) + .style("opacity", function(d,i){ return (i == current && edit) ? 1: 0.4; }) + .attr("x1", function(d, i) { return Math.sin(angle(i, size)) * scales(scales.domain()[0]);}) + .attr("y1", function(d, i) { return Math.cos(angle(i, size)) * scales(scales.domain()[0]);}) + .attr("x2", function(d, i) { return Math.sin(angle(i, size)) * scales(scales.domain()[1]);}) + .attr("y2", function(d, i) { return Math.cos(angle(i, size)) * scales(scales.domain()[1]);}); + + d3.transition(ax) + .select("line") + .style("opacity", function(d,i){ return (i == current && edit) ? 1: 0.4; }) + .attr("x1", function(d, i) { return Math.sin(angle(i, size)) * scales(scales.domain()[0]);}) + .attr("y1", function(d, i) { return Math.cos(angle(i, size)) * scales(scales.domain()[0]);}) + .attr("x2", function(d, i) { return Math.sin(angle(i, size)) * scales(scales.domain()[1]);}) + .attr("y2", function(d, i) { return Math.cos(angle(i, size)) * scales(scales.domain()[1]);}); + //------------------------------------------------------------ + + //============================================================ + // Event Handling/Dispatching (in chart's scope) + //------------------------------------------------------------ + + radars.dispatch.on('elementClick', function(d,i) { + chart.cursor(legs.length - d.pointIndex); + selection.transition().call(chart); + }); + legend.dispatch.on('stateChange', function(newState) { + state = newState; + dispatch.stateChange(state); + chart.update(); + }); + /*legend.dispatch.on('legendClick', function(d,i) { + if (!d.disabled) return; + data = data.map(function(s) { + s.disabled = true; + return s; + }); + d.disabled = false; + + switch (d.key) { + case 'Grouped': + multibar.stacked(false); + break; + case 'Stacked': + multibar.stacked(true); + break; + } + + state.stacked = multibar.stacked(); + dispatch.stateChange(state); + + chart.update(); + });*/ + + /* legend.dispatch.on('legendClick', function(d,i) { + d.disabled = !d.disabled; + + if (!data.filter(function(d) { return !d.disabled }).length) { + data.map(function(d) { + d.disabled = false; + wrap.selectAll('.nv-series').classed('disabled', false); + + return d; + }); + } + chart.update(); + });*/ + + dispatch.on('tooltipShow', function(e) { + e.pos = [parseFloat(e.pos[0] + availableHeight/2 + margin.left), parseFloat(e.pos[1] + availableHeight/2 + margin.top)]; + if (tooltips) showTooltip(e, that.parentNode); + }); + + //============================================================ + + }); + + return chart; + } + + function hexToRgb(hex,opacity) { + var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? { + r: parseInt(result[1], 16), + g: parseInt(result[2], 16), + b: parseInt(result[3], 16) + } : null; + } + + function rgbToHex(r, g, b) { + return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); + } + + // compute an angle + function angle(i, length) { + return i * (2 * Math.PI / length ) + ((2 * Math.PI) * startAngle / 360) + (cursor*2*Math.PI)/length; + } + + // x-caclulator + // d is the datapoint, i is the index, length is the length of the data + function calculateX(d, i, length) { + var l = scales(d); + return Math.sin(angle(i, length)) * l; + } + + // y-calculator + function calculateY(d, i, length) { + var l = scales(d); + return Math.cos(angle(i, length)) * l; + } + + // * build the spider axis * // + // rewrite this to conform to d3 axis style? // + function buildAxisGrid(length, ticks) { + var min = scales.domain()[0]; + var max = scales.domain()[1] > 0 ? scales.domain()[1] : 1; + var increase = max/ticks; + + var gridData = [] + for (var i = 0; i <= ticks; i++ ) { + var val = min + i*increase; + var d = [val]; + var gridPoints = []; + + for (var j = 0; j <= length; j++) { + gridPoints.push({ + x: calculateX(d, j, length), + y: calculateY(d, j, length), + }); + } + + gridData.push(gridPoints) + } + + return gridData; + } + + //============================================================ + // Event Handling/Dispatching (out of chart's scope) + //------------------------------------------------------------ + + radars.dispatch.on('elementMouseover.tooltip', function(e) { + dispatch.tooltipShow(e); + }); + + radars.dispatch.on('elementMouseout.tooltip', function(e) { + dispatch.tooltipHide(e); + }); + + dispatch.on('tooltipHide', function() { + if (tooltips) nv.tooltip.cleanup(); + }); + + //============================================================ + + + //============================================================ + // Expose Public Variables + //------------------------------------------------------------ + + // expose chart's sub-components + chart.dispatch = dispatch; + chart.radars = radars; + + + chart.margin = function(_) { + if (!arguments.length) return margin; + margin.top = typeof _.top != 'undefined' ? _.top : margin.top; + margin.right = typeof _.right != 'undefined' ? _.right : margin.right; + margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom; + margin.left = typeof _.left != 'undefined' ? _.left : margin.left; + return chart; + }; + + chart.width = function(_) { + if (!arguments.length) return width; + width = _; + return chart; + }; + + chart.height = function(_) { + if (!arguments.length) return height; + height = _; + return chart; + }; + + chart.legs = function(_) { + if (!arguments.length) return legs; + legs = _; + return chart; + }; + + chart.showLegend = function(_) { + if (!arguments.length) return showLegend; + showLegend = _; + return chart; + }; + + chart.cursor = function(_) { + if (!arguments.length) return cursor; + cursor = _; + return chart; + }; + + chart.next = function(_) { + cursor = cursor - 1; + if (Math.abs(cursor) > legs.length-1) cursor = 0; + return chart; + }; + + chart.prev = function(_) { + cursor = cursor + 1; + if (cursor > legs.length-1) cursor = 0; + return chart; + }; + + chart.edit = function(_) { + if (!arguments.length) return edit; + edit = _; + return chart; + }; + //============================================================ + + + return chart; +} diff --git a/web_graph_radar/static/src/js/web_graph_radar.js b/web_graph_radar/static/src/js/web_graph_radar.js new file mode 100644 index 00000000..68b63fd0 --- /dev/null +++ b/web_graph_radar/static/src/js/web_graph_radar.js @@ -0,0 +1,86 @@ +openerp.web_graph_radar = function(instance) { + + var _t = instance.web._t; + + instance.web_graph.Graph.include({ + template: 'GraphWidgetRadar', + radar: function() { + var self = this, + dim_x = this.pivot.rows.groupby.length, + dim_y = this.pivot.cols.groupby.length, + data; + + // No groupby + if ((dim_x === 0) && (dim_y === 0)) { + data = [{key: _t('Total'), values:[{ + label: _t('Total'), + value: this.pivot.get_total()[0], + }]}]; + // Only column groupbys + } else if ((dim_x === 0) && (dim_y >= 1)){ + data = _.map(this.pivot.get_cols_with_depth(1), function (header) { + return { + key: header.title, + values: [{label:header.title, value: self.pivot.get_total(header)[0]}] + }; + }); + // Just 1 row groupby + } else if ((dim_x === 1) && (dim_y === 0)) { + data = _.map(self.pivot.measures, function(measure, i) { + var series = _.map(self.pivot.main_row().children, function (pt) { + var value = self.pivot.get_total(pt)[i], + title = (pt.title !== undefined) ? pt.title : _t('Undefined'); + return {label: title, value: value}; + }); + return {key: self.pivot.measures[i].string, values:series}; + }); + // 1 row groupby and some col groupbys + } else if ((dim_x === 1) && (dim_y >= 1)) { + data = _.map(this.pivot.get_cols_with_depth(1), function (colhdr) { + var values = _.map(self.pivot.get_rows_with_depth(1), function (header) { + return { + label: header.title || _t('Undefined'), + value: self.pivot.get_values(header.id, colhdr.id)[0] || 0 + }; + }); + return {key: colhdr.title || _t('Undefined'), values: values}; + }); + // At least two row groupby + } else { + var keys = _.uniq(_.map(this.pivot.get_rows_with_depth(2), function (hdr) { + return hdr.title || _t('Undefined'); + })); + data = _.map(keys, function (key) { + var values = _.map(self.pivot.get_rows_with_depth(1), function (hdr) { + var subhdr = _.find(hdr.children, function (child) { + return ((child.title === key) || ((child.title === undefined) && (key === _t('Undefined')))); + }); + return { + label: hdr.title || _t('Undefined'), + value: (subhdr) ? self.pivot.get_total(subhdr)[0] : 0 + }; + }); + return {key:key, values: values}; + }); + } + console.log(data); + nv.addGraph(function () { + var chart = nv.models.radarChart(); + // .stacked(self.bar_ui === 'stack') + // .showControls(show_controls); + + chart.margin({left:200, top:20, bottom:20}); + + d3.select(self.svg) + .datum(data) + .attr('width', self.width) + .attr('height', self.height) + .call(chart); + + // nv.utils.windowResize(chart.update); + return chart; + }); + + } + }); +} diff --git a/web_graph_radar/static/src/xml/web_graph_radar.xml b/web_graph_radar/static/src/xml/web_graph_radar.xml new file mode 100644 index 00000000..9e5bf4ac --- /dev/null +++ b/web_graph_radar/static/src/xml/web_graph_radar.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/web_graph_radar/view/web_graph_radar.xml b/web_graph_radar/view/web_graph_radar.xml new file mode 100644 index 00000000..50f95d50 --- /dev/null +++ b/web_graph_radar/view/web_graph_radar.xml @@ -0,0 +1,20 @@ + + + + + + + + +