├── dist └── .gitkeep ├── lib └── .gitkeep ├── .eslintignore ├── .npmignore ├── docs ├── screanshot.png ├── profile_photo.jpg ├── personality-sunburst-chart.png ├── personality-sunburst-chart-small.png ├── index-test.html ├── index.html ├── index-d3v4-test.html ├── index-d3v4.html └── profiles │ ├── en_v3_2.json │ ├── en_v3.json │ ├── en_v2_2.json │ └── en_v2.json ├── .gitignore ├── .eslintrc.yml ├── .travis.yml ├── webpack.config.js ├── src ├── index.js ├── utilities │ └── colors.js ├── charts │ ├── v2-d3v3.js │ ├── v2-d3v4.js │ ├── v3-d3v3.js │ ├── v3-d3v4.js │ ├── d3v3.js │ ├── d3v4.js │ └── index.js ├── d3-renderers │ ├── svg-single-arc.js │ ├── utils.js │ ├── v4 │ │ └── personality-chart-renderer.js │ └── v3 │ │ └── personality-chart-renderer.js ├── d3-profile-wrappers │ ├── v3 │ │ └── index.js │ └── v2 │ │ └── index.js ├── personality-sunburst-chart.js └── widget.js ├── index.d.ts ├── test ├── d3-renderers.js └── d3-profile-wrappers.js ├── package.json ├── README.md └── LICENSE /dist/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage 2 | node_modules 3 | dist 4 | lib/ 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | .travis.yml 3 | .eslint* 4 | docs 5 | src 6 | -------------------------------------------------------------------------------- /docs/screanshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/personality-insights/sunburst-chart/HEAD/docs/screanshot.png -------------------------------------------------------------------------------- /docs/profile_photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/personality-insights/sunburst-chart/HEAD/docs/profile_photo.jpg -------------------------------------------------------------------------------- /docs/personality-sunburst-chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/personality-insights/sunburst-chart/HEAD/docs/personality-sunburst-chart.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage 2 | dist/* 3 | !dist/.gitkeep 4 | lib/* 5 | !lib/.gitkeep 6 | node_modules 7 | npm-debug.log 8 | .project 9 | docs/dist 10 | -------------------------------------------------------------------------------- /docs/personality-sunburst-chart-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/personality-insights/sunburst-chart/HEAD/docs/personality-sunburst-chart-small.png -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | env: 2 | node: true 3 | es6: true 4 | mocha: true 5 | globals: 6 | d3: true 7 | 8 | extends: 'eslint:recommended' 9 | rules: 10 | indent: 11 | - error 12 | - 2 13 | linebreak-style: 14 | - error 15 | - unix 16 | quotes: 17 | - error 18 | - single 19 | semi: 20 | - error 21 | - always 22 | no-console: 23 | - warn 24 | no-alert: 25 | - warn 26 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | dist: trusty 3 | sudo: required 4 | node_js: 6 5 | script: npm test 6 | cache: 7 | directories: 8 | - node_modules 9 | notifications: 10 | email: 11 | recipients: 12 | - aprilweb@gmail.com 13 | deploy: 14 | provider: npm 15 | email: germanattanasio@gmail.com 16 | api_key: "${npm_api_key}" 17 | skip_cleanup: true 18 | on: 19 | tags: true 20 | repo: personality-insights/sunburst-chart 21 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const MinifyPlugin = require('babel-minify-webpack-plugin'); 2 | 3 | module.exports = { 4 | entry: './src/index.js', 5 | output: { 6 | filename: 'dist/index.js', 7 | library: 'PersonalitySunburstChart', 8 | libraryTarget: 'umd', 9 | umdNamedDefine: true, 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.js$/, 15 | exclude: /(node_modules|bower_components)/, 16 | use: { 17 | loader: 'babel-loader', 18 | options: { 19 | presets: ['babel-preset-env'], 20 | }, 21 | }, 22 | }, 23 | ], 24 | }, 25 | stats: { 26 | colors: true, 27 | }, 28 | plugins: [ 29 | new MinifyPlugin({}, {}), 30 | ] 31 | }; 32 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | 'use strict'; 18 | 19 | const PersonalitySunburstChart = require('./charts/d3v3'); 20 | module.exports = PersonalitySunburstChart; 21 | -------------------------------------------------------------------------------- /src/utilities/colors.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 'use strict'; 18 | 19 | // Default colors for V3 are from the IBM Design PI Color Wheel 20 | // XColorDark is the color to be used on the inner rings to show the score for the trait, need or value 21 | // XColorLight is the color used on the inner rings and has a value of (1 - score) 22 | // XColor is the color used for an individual facet, need or value 23 | 24 | var colors = { 25 | traits_dark: '#5aaafa', 26 | traits_light: '#c0e6ff', 27 | facet: '#4178be', 28 | needs_dark: '#41d6c3', 29 | needs_light: '#a7fae6', 30 | need: '#008571', 31 | values_dark: '#ba8ff7', 32 | values_light: '#eed2ff', 33 | value: '#9855d4' 34 | }; 35 | 36 | module.exports = colors; 37 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | export = PersonalitySunburstChart; 2 | 3 | declare type Exclude = 'personality' | 'needs' | 'values'; 4 | declare type Locale = 'ar' | 'de' | 'en' | 'es' | 'fr' | 'it' | 'ja' | 'ko' | 'pt-br' | 'zh-tw' | 'zh'; 5 | declare type Version = 'v2' | 'v3'; 6 | declare type D3Version = 'v3' | 'v4'; 7 | declare type SunburstChartOptions = { 8 | selector?: string, 9 | element?: any, 10 | version?: Version, 11 | d3version?: D3Version, 12 | locale?: Locale, 13 | scale?: number, 14 | colors?: SunburstChartColors, 15 | exclude?: Exclude[] 16 | }; 17 | declare type SunburstChartColors = { 18 | traits_dark: string, 19 | traits_light: string, 20 | facet: string, 21 | needs_dark: string, 22 | needs_light: string, 23 | need: string, 24 | values_dark: string, 25 | values_light: string, 26 | value: string 27 | }; 28 | 29 | declare class PersonalitySunburstChart { 30 | constructor(options?: SunburstChartOptions); 31 | 32 | defaultOptions(): { 33 | locale: Locale, 34 | version: Version, 35 | d3version: D3Version, 36 | scale: number, 37 | colors: SunburstChartColors 38 | }; 39 | 40 | setLocale(locale: Locale, render?: boolean): void; 41 | 42 | setImage(url: string, render?: boolean): void; 43 | 44 | setProfile(profile: any, render?: boolean): void; 45 | 46 | setColors(colors: SunburstChartColors, render?: boolean); 47 | 48 | render(): void; 49 | 50 | show(profile: any, imageUrl?: string): void; 51 | } 52 | -------------------------------------------------------------------------------- /test/d3-renderers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 'use strict'; 18 | const expect = require('chai').expect; 19 | const ChartRendererV3 = require('../src/d3-renderers/v3/personality-chart-renderer'); 20 | const ChartRendererV4 = require('../src/d3-renderers/v4/personality-chart-renderer'); 21 | 22 | describe('D3 Renderers', () => { 23 | 24 | describe('Version 3', () => { 25 | it('should export render', () => { 26 | expect(ChartRendererV3.render).to.be.a('function'); 27 | }); 28 | it('should export d3', () => { 29 | expect(ChartRendererV3.d3).to.be.ok; 30 | expect(ChartRendererV3.d3.select).to.be.a('function'); 31 | }); 32 | }); 33 | 34 | describe('Version 4', () => { 35 | it('should export render', () => { 36 | expect(ChartRendererV4.render).to.be.a('function'); 37 | }); 38 | it('should export d3', () => { 39 | expect(ChartRendererV4.d3).to.be.ok; 40 | expect(ChartRendererV3.d3.select).to.be.a('function'); 41 | }); 42 | }); 43 | 44 | }); 45 | -------------------------------------------------------------------------------- /test/d3-profile-wrappers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 'use strict'; 18 | const expect = require('chai').expect; 19 | const PersonalityTraitNames = require('personality-trait-names'); 20 | const D3PersonalityProfileWrapperV2 = require('../src/d3-profile-wrappers/v2/index'); 21 | const D3PersonalityProfileWrapperV3 = require('../src/d3-profile-wrappers/v3/index'); 22 | const v2Profile = require('../docs/profiles/en_v2'); 23 | const v3Profile = require('../docs/profiles/en_v3'); 24 | 25 | describe('D3 Profile Wrappers', () => { 26 | const traitNames = new PersonalityTraitNames(); 27 | 28 | describe('Version 2', () => { 29 | it('should construct wrapper', () => { 30 | const wrapper = new D3PersonalityProfileWrapperV2(v2Profile, traitNames); 31 | expect(wrapper).to.be.ok; 32 | }); 33 | }); 34 | 35 | describe('Version 3', () => { 36 | it('should construct wrapper', () => { 37 | const wrapper = new D3PersonalityProfileWrapperV3(v3Profile, traitNames); 38 | expect(wrapper).to.be.ok; 39 | }); 40 | }); 41 | 42 | }); 43 | -------------------------------------------------------------------------------- /src/charts/v2-d3v3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | 'use strict'; 18 | 19 | const pick = require('lodash.pick'); 20 | const colors = require('../utilities/colors'); 21 | const ChartRendererV3 = require('../d3-renderers/v3/personality-chart-renderer'); 22 | const D3PersonalityProfileV2 = require('../d3-profile-wrappers/v2/index'); 23 | const PersonalityTraitNamesV2 = require('personality-trait-names/lib/index-v2'); 24 | const PersonalitySunburstChartImpl = require('../personality-sunburst-chart'); 25 | 26 | const DEFAULT_OPTIONS = { 27 | locale: 'en', 28 | version: 'v2', 29 | d3version: 'v3', 30 | colors: colors 31 | }; 32 | 33 | class PersonalitySunburstChart extends PersonalitySunburstChartImpl { 34 | 35 | constructor(options) { 36 | const _options = Object.assign({}, DEFAULT_OPTIONS, pick(options, ['element', 'selector', 'locale', 'colors', 'exclude'])); 37 | super(_options, D3PersonalityProfileV2, ChartRendererV3, PersonalityTraitNamesV2); 38 | } 39 | 40 | defaultOptions() { 41 | return DEFAULT_OPTIONS; 42 | } 43 | } 44 | 45 | module.exports = PersonalitySunburstChart; 46 | -------------------------------------------------------------------------------- /src/charts/v2-d3v4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | 'use strict'; 18 | 19 | const pick = require('lodash.pick'); 20 | const colors = require('../utilities/colors'); 21 | const ChartRendererV4 = require('../d3-renderers/v4/personality-chart-renderer'); 22 | const D3PersonalityProfileV2 = require('../d3-profile-wrappers/v2/index'); 23 | const PersonalityTraitNamesV2 = require('personality-trait-names/lib/index-v2'); 24 | const PersonalitySunburstChartImpl = require('../personality-sunburst-chart'); 25 | 26 | const DEFAULT_OPTIONS = { 27 | locale: 'en', 28 | version: 'v2', 29 | d3version: 'v4', 30 | colors: colors 31 | }; 32 | 33 | class PersonalitySunburstChart extends PersonalitySunburstChartImpl { 34 | 35 | constructor(options) { 36 | const _options = Object.assign({}, DEFAULT_OPTIONS, pick(options, ['element', 'selector', 'locale', 'colors', 'exclude'])); 37 | super(_options, D3PersonalityProfileV2, ChartRendererV4, PersonalityTraitNamesV2); 38 | } 39 | 40 | defaultOptions() { 41 | return DEFAULT_OPTIONS; 42 | } 43 | } 44 | 45 | module.exports = PersonalitySunburstChart; 46 | -------------------------------------------------------------------------------- /src/charts/v3-d3v3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | 'use strict'; 18 | 19 | const pick = require('lodash.pick'); 20 | const colors = require('../utilities/colors'); 21 | const ChartRendererV3 = require('../d3-renderers/v3/personality-chart-renderer'); 22 | const D3PersonalityProfileV3 = require('../d3-profile-wrappers/v3/index'); 23 | const PersonalityTraitNamesV3 = require('personality-trait-names/lib/index-v3'); 24 | const PersonalitySunburstChartImpl = require('../personality-sunburst-chart'); 25 | 26 | const DEFAULT_OPTIONS = { 27 | locale: 'en', 28 | version: 'v3', 29 | d3version: 'v3', 30 | colors: colors 31 | }; 32 | 33 | class PersonalitySunburstChart extends PersonalitySunburstChartImpl { 34 | 35 | constructor(options) { 36 | const _options = Object.assign({}, DEFAULT_OPTIONS, pick(options, ['element', 'selector', 'locale', 'colors', 'exclude'])); 37 | super(_options, D3PersonalityProfileV3, ChartRendererV3, PersonalityTraitNamesV3); 38 | } 39 | 40 | defaultOptions() { 41 | return DEFAULT_OPTIONS; 42 | } 43 | } 44 | 45 | module.exports = PersonalitySunburstChart; 46 | -------------------------------------------------------------------------------- /src/charts/v3-d3v4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | 'use strict'; 18 | 19 | const pick = require('lodash.pick'); 20 | const colors = require('../utilities/colors'); 21 | const ChartRendererV4 = require('../d3-renderers/v4/personality-chart-renderer'); 22 | const D3PersonalityProfileV3 = require('../d3-profile-wrappers/v3/index'); 23 | const PersonalityTraitNamesV3 = require('personality-trait-names/lib/index-v3'); 24 | const PersonalitySunburstChartImpl = require('../personality-sunburst-chart'); 25 | 26 | const DEFAULT_OPTIONS = { 27 | locale: 'en', 28 | version: 'v3', 29 | d3version: 'v4', 30 | colors: colors 31 | }; 32 | 33 | class PersonalitySunburstChart extends PersonalitySunburstChartImpl { 34 | 35 | constructor(options) { 36 | const _options = Object.assign({}, DEFAULT_OPTIONS, pick(options, ['element', 'selector', 'locale', 'colors', 'exclude'])); 37 | super(_options, D3PersonalityProfileV3, ChartRendererV4, PersonalityTraitNamesV3); 38 | } 39 | 40 | defaultOptions() { 41 | return DEFAULT_OPTIONS; 42 | } 43 | } 44 | 45 | module.exports = PersonalitySunburstChart; 46 | -------------------------------------------------------------------------------- /src/d3-renderers/svg-single-arc.js: -------------------------------------------------------------------------------- 1 | function d3_svg_singleArcRadius(d) { 2 | return d.radius; 3 | } 4 | 5 | function d3_svg_singleArcStartAngle(d) { 6 | return d.startAngle; 7 | } 8 | 9 | function d3_svg_singleArcEndAngle(d) { 10 | return d.endAngle; 11 | } 12 | 13 | function functor(v) { 14 | return typeof v === 'function' ? v : function() { return v; }; 15 | } 16 | 17 | function singleArc() { 18 | var radius = d3_svg_singleArcRadius, 19 | startAngle = d3_svg_singleArcStartAngle, 20 | endAngle = d3_svg_singleArcEndAngle, 21 | d3_svg_arcOffset = -Math.PI / 2; 22 | 23 | function arc() { 24 | var r0 = radius.apply(this, arguments), 25 | a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset, 26 | a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset, 27 | da = (a1 < a0 && (da = a0, a0 = a1, a1 = da), a1 - a0), 28 | df = da < Math.PI ? '0' : '1', 29 | c0 = Math.cos(a0), 30 | s0 = Math.sin(a0), 31 | c1 = Math.cos(a1), 32 | s1 = Math.sin(a1); 33 | return 'M' + r0 * c0 + ',' + r0 * s0 + 'A' + r0 + ',' + 34 | r0 + ' 0 ' + df + ',1 ' + r0 * c1 + ',' + r0 * s1; 35 | } 36 | 37 | arc.radius = function(v) { 38 | if (!arguments.length) return radius; 39 | radius = functor(v); 40 | return arc; 41 | }; 42 | 43 | arc.startAngle = function(v) { 44 | if (!arguments.length) return startAngle; 45 | startAngle = functor(v); 46 | return arc; 47 | }; 48 | 49 | arc.endAngle = function(v) { 50 | if (!arguments.length) return endAngle; 51 | endAngle = functor(v); 52 | return arc; 53 | }; 54 | 55 | arc.centroid = function() { 56 | var r = radius.apply(this, arguments), 57 | a = (startAngle.apply(this, arguments) + 58 | endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset; 59 | return [Math.cos(a) * r, Math.sin(a) * r]; 60 | }; 61 | 62 | return arc; 63 | } 64 | 65 | module.exports = singleArc; 66 | -------------------------------------------------------------------------------- /src/charts/d3v3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | 'use strict'; 18 | 19 | const pick = require('lodash.pick'); 20 | const colors = require('../utilities/colors'); 21 | const ChartRendererV3 = require('../d3-renderers/v3/personality-chart-renderer'); 22 | const D3PersonalityProfileV2 = require('../d3-profile-wrappers/v2/index'); 23 | const D3PersonalityProfileV3 = require('../d3-profile-wrappers/v3/index'); 24 | const PersonalityTraitNamesV2 = require('personality-trait-names/lib/index-v2'); 25 | const PersonalityTraitNamesV3 = require('personality-trait-names/lib/index-v3'); 26 | const PersonalitySunburstChartImpl = require('../personality-sunburst-chart'); 27 | 28 | const DEFAULT_OPTIONS = { 29 | locale: 'en', 30 | version: 'v2', 31 | d3version: 'v3', 32 | colors: colors 33 | }; 34 | 35 | class PersonalitySunburstChart extends PersonalitySunburstChartImpl { 36 | 37 | constructor(options) { 38 | const _options = Object.assign({}, DEFAULT_OPTIONS, pick(options, ['element', 'selector', 'version', 'locale', 'colors', 'exclude'])); 39 | super(_options, _options.version === 'v2' ? D3PersonalityProfileV2 : D3PersonalityProfileV3, ChartRendererV3, _options.version === 'v2' ? PersonalityTraitNamesV2 : PersonalityTraitNamesV3); 40 | } 41 | 42 | defaultOptions() { 43 | return DEFAULT_OPTIONS; 44 | } 45 | } 46 | 47 | module.exports = PersonalitySunburstChart; 48 | -------------------------------------------------------------------------------- /src/charts/d3v4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | 'use strict'; 18 | 19 | const pick = require('lodash.pick'); 20 | const colors = require('../utilities/colors'); 21 | const ChartRendererV4 = require('../d3-renderers/v4/personality-chart-renderer'); 22 | const D3PersonalityProfileV2 = require('../d3-profile-wrappers/v2/index'); 23 | const D3PersonalityProfileV3 = require('../d3-profile-wrappers/v3/index'); 24 | const PersonalityTraitNamesV2 = require('personality-trait-names/lib/index-v2'); 25 | const PersonalityTraitNamesV3 = require('personality-trait-names/lib/index-v3'); 26 | const PersonalitySunburstChartImpl = require('../personality-sunburst-chart'); 27 | 28 | const DEFAULT_OPTIONS = { 29 | locale: 'en', 30 | version: 'v2', 31 | d3version: 'v4', 32 | colors: colors 33 | }; 34 | 35 | class PersonalitySunburstChart extends PersonalitySunburstChartImpl { 36 | 37 | constructor(options) { 38 | const _options = Object.assign({}, DEFAULT_OPTIONS, pick(options, ['element', 'selector', 'version', 'locale', 'colors', 'exclude'])); 39 | super(_options, _options.version === 'v2' ? D3PersonalityProfileV2 : D3PersonalityProfileV3, ChartRendererV4, _options.version === 'v2' ? PersonalityTraitNamesV2 : PersonalityTraitNamesV3); 40 | } 41 | 42 | defaultOptions() { 43 | return DEFAULT_OPTIONS; 44 | } 45 | } 46 | 47 | module.exports = PersonalitySunburstChart; 48 | -------------------------------------------------------------------------------- /src/charts/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | 'use strict'; 18 | 19 | const pick = require('lodash.pick'); 20 | const colors = require('../utilities/colors'); 21 | const ChartRendererV3 = require('../d3-renderers/v3/personality-chart-renderer'); 22 | const ChartRendererV4 = require('../d3-renderers/v4/personality-chart-renderer'); 23 | const D3PersonalityProfileV2 = require('../d3-profile-wrappers/v2/index'); 24 | const D3PersonalityProfileV3 = require('../d3-profile-wrappers/v3/index'); 25 | const PersonalityTraitNamesV2 = require('personality-trait-names/lib/index-v2'); 26 | const PersonalityTraitNamesV3 = require('personality-trait-names/lib/index-v3'); 27 | const PersonalitySunburstChartImpl = require('../personality-sunburst-chart'); 28 | 29 | const DEFAULT_OPTIONS = { 30 | locale: 'en', 31 | version: 'v2', 32 | d3version: 'v3', 33 | colors: colors 34 | }; 35 | 36 | class PersonalitySunburstChart extends PersonalitySunburstChartImpl { 37 | 38 | constructor(options) { 39 | const _options = Object.assign({}, DEFAULT_OPTIONS, pick(options, ['element', 'selector', 'version', 'd3version', 'locale', 'colors', 'exclude'])); 40 | super(_options, _options.version === 'v2' ? D3PersonalityProfileV2 : D3PersonalityProfileV3, _options.d3version === 'v3' ? ChartRendererV3 : ChartRendererV4, _options.version === 'v2' ? PersonalityTraitNamesV2 : PersonalityTraitNamesV3); 41 | } 42 | 43 | defaultOptions() { 44 | return DEFAULT_OPTIONS; 45 | } 46 | } 47 | 48 | module.exports = PersonalitySunburstChart; 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "personality-sunburst-chart", 3 | "version": "2.2.4", 4 | "description": "Generate Sunburst Chart for Personality Insights Profile", 5 | "main": "lib/index.js", 6 | "exportName": "PersonalitySunburstChart", 7 | "scripts": { 8 | "prestart": "npm run compile-docs", 9 | "start": "npm run watch & npm run serve", 10 | "serve": "autoreload-server -w \"**/**.{html,css,js}\" -d ./docs -b 'http://localhost:8080/index-test.html'", 11 | "watch": "nodemon --watch src -x \"npm run compile-docs\"", 12 | "prepublish": "npm run compile && npm run build", 13 | "compile": "node_modules/.bin/webpack", 14 | "compile-docs": "node_modules/.bin/webpack --devtool 'eval-cheap-module-source-map' --output-path docs --entry ./src/charts/index.js", 15 | "build": "./node_modules/.bin/babel src --presets env --out-dir lib", 16 | "test": "npm run lint && npm run codecov", 17 | "lint": "eslint .", 18 | "autofix": "eslint . --fix", 19 | "codecov": "istanbul cover mocha test && codecov" 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "git@github.com:personality-insights/sunburst-chart.git" 24 | }, 25 | "engines": { 26 | "node": ">4.0" 27 | }, 28 | "author": "IBM Corp.", 29 | "license": "Apache-2.0", 30 | "keywords": [ 31 | "personality", 32 | "insights", 33 | "sunburst", 34 | "chart", 35 | "visualization", 36 | "ibm", 37 | "watson" 38 | ], 39 | "dependencies": { 40 | "d3-color": "^1.0.3", 41 | "d3-hierarchy": "^1.1.5", 42 | "d3-selection": "^1.3.0", 43 | "d3-shape": "^1.2.0", 44 | "lodash.pick": "^4.4.0", 45 | "personality-trait-names": "^2.2.0" 46 | }, 47 | "devDependencies": { 48 | "babel-cli": "^6.26.0", 49 | "babel-core": "^6.26.0", 50 | "babel-loader": "^7.1.4", 51 | "babel-minify-webpack-plugin": "^0.3.1", 52 | "babel-preset-env": "^1.6.1", 53 | "chai": "^4.1.2", 54 | "codecov": "^3.0.0", 55 | "d3": "^3.5.14", 56 | "eslint": "^4.19.1", 57 | "istanbul": "^0.4.3", 58 | "mocha": "^5.0.5", 59 | "nodemon": "^1.17.2", 60 | "simple-autoreload-server": "^0.2.7", 61 | "webpack": "^3.11.0" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/d3-renderers/utils.js: -------------------------------------------------------------------------------- 1 | function expandOrFoldSector(g, d, d3elem) { 2 | if (d.expand !== null && d.depth > 1) { 3 | //ignore root node and first level sectors 4 | if (d.expand === 0) { 5 | if (d.children) d3elem.attr('opacity', 1); 6 | g.filter(function(a) { 7 | if (a.parent) 8 | return getValue(a.parent, 'id') === getValue(d, 'id'); 9 | }) 10 | .attr('visibility', 'visible'); 11 | d.expand = 1; 12 | } else { 13 | //if the sector is expanded 14 | if (d.children) 15 | d3elem.attr('opacity', 1); 16 | hideSector(d, g); 17 | } 18 | } 19 | } 20 | 21 | function hideSector(d, g) { 22 | g.filter(function(a) { 23 | if (a.parent) 24 | return getValue(a.parent, 'id') === getValue(d, 'id'); 25 | }) 26 | .attr('visibility', 'hidden') 27 | .attr('opacity', 1) 28 | .each(function(a) { 29 | if (a.children) 30 | hideSector(a, g); 31 | }); 32 | d.expand = 0; 33 | } 34 | 35 | function arc(start, end, r0) { 36 | var c0 = Math.cos(start), 37 | s0 = Math.sin(start), 38 | c1 = Math.cos(end), 39 | s1 = Math.sin(end); 40 | return 'M' + r0 * c0 + ',' + r0 * s0 + 'A' + r0 + ',' + r0 + ' 0' + ' 0 , 0 ' + r0 * c1 + ',' + r0 * s1; 41 | } 42 | 43 | function isLocatedBottom(d) { 44 | var x0 = d.x ? d.x : d.x0; 45 | var x1 = d.x ? (d.x + d.dx) : d.x1; 46 | var bottom = (x0 > Math.PI / 2 && x1 < 5.0); 47 | return bottom; 48 | } 49 | 50 | function getValue(d, prop) { 51 | return d.data ? d.data[prop] : d[prop]; 52 | } 53 | 54 | function getBarLengthFactor(d) { 55 | var bar_length_factor = 10 / (d.depth - 2); 56 | 57 | //different bar_length factors 58 | if (d.parent) { 59 | if (d.parent.parent) { 60 | if (getValue(d.parent.parent, 'id') === 'needs' || getValue(d.parent.parent, 'id') === 'values') { 61 | bar_length_factor = 1; 62 | } 63 | if (d.parent.parent.parent) { 64 | if (getValue(d.parent.parent.parent, 'id') === 'personality') { 65 | bar_length_factor = 1; 66 | } 67 | } 68 | } 69 | } 70 | 71 | return bar_length_factor; 72 | } 73 | 74 | module.exports = { 75 | isLocatedBottom: isLocatedBottom, 76 | arc: arc, 77 | expandOrFoldSector: expandOrFoldSector, 78 | getValue: getValue, 79 | getBarLengthFactor: getBarLengthFactor 80 | }; 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Personality Sunburst Chart 2 | 3 | [![npm-version](https://img.shields.io/npm/v/personality-sunburst-chart.svg)](https://www.npmjs.com/package/personality-sunburst-chart) 4 | [![npm-license](https://img.shields.io/npm/l/personality-sunburst-chart.svg)](https://www.npmjs.com/package/personality-sunburst-chart) 5 | [![Build Status](https://travis-ci.org/personality-insights/sunburst-chart.svg?branch=master)](https://travis-ci.org/personality-insights/sunburst-chart) 6 | [![codecov.io](https://codecov.io/github/personality-insights/sunburst-chart/coverage.svg?branch=master)](https://codecov.io/github/personality-insights/sunburst-chart?branch=master) 7 | 8 | Obtain a sunburst chart visualization for a personality profile. For use in an HTML page. 9 | 10 | ![Personality Sunburst Chart](./docs/screanshot.png) 11 | 12 | 13 | ## Usage 14 | #### Importing through HTML 15 | Include the library index.js script from the /dist folder and D3 (**v3**) in your HTML page. 16 | ```html 17 | 18 | ``` 19 | 20 | Create an element to contain the chart in your HTML page. 21 | ```html 22 |
23 | ``` 24 | 25 | Generate the visualization for a personality profile. 26 | ```JavaScript 27 | // Create the chart, specifying the css selector that identifies the element to contain the chart 28 | // and the version of Watson Personality Insights profile to use, v2 or v3. Default is v2. 29 | var chart = new PersonalitySunburstChart({ 30 | 'selector':'#sunburstChart', 31 | 'version': 'v3' 32 | }); 33 | 34 | // Render the sunburst chart for a personality profile (version as specified in creating the chart) 35 | // and optionally a profile photo. The photo will be inserted into the center of the sunburst chart. 36 | chart.show('jsonObject', 'path/to/profile_photo.jpg'); 37 | ``` 38 | 39 | Also works with DOM element input 40 | ```JavaScript 41 | var element = document.querySelector('#sunburstChart'); 42 | var chart = new PersonalitySunburstChart({ 43 | 'element': element, 44 | 'version': 'v3' 45 | }); 46 | chart.show('jsonObject', 'path/to/profile_photo.jpg'); 47 | ``` 48 | 49 | See the [complete example](./docs/index.html) 50 | 51 | #### Importing through JavaScript 52 | Use one of the following based on your version of Watson Personality Insights and D3 53 | ```javascript 54 | // Watson Personality Insights Version 2, D3 Version 3 55 | import PersonalitySunburstChart from 'personality-sunburst-chart/lib/charts/v2-d3v3'; 56 | 57 | // Watson Personality Insights Version 2, D3 Version 4 58 | import PersonalitySunburstChart from 'personality-sunburst-chart/lib/charts/v2-d3v4'; 59 | 60 | // Watson Personality Insights Version 3, D3 Version 3 61 | import PersonalitySunburstChart from 'personality-sunburst-chart/lib/charts/v3-d3v3'; 62 | 63 | // Watson Personality Insights Version 3, D3 Version 4 64 | import PersonalitySunburstChart from 'personality-sunburst-chart/lib/charts/v3-d3v4'; 65 | ``` 66 | 67 | ## Development 68 | Test changes in the browser: 69 | ```bash 70 | npm start 71 | ``` 72 | 73 | Run unit tests: 74 | ```bash 75 | npm test 76 | ``` 77 | 78 | ## License 79 | 80 | This library is licensed under Apache 2.0. Full license text is 81 | available in [LICENSE](LICENSE). 82 | 83 | ## CHANGELOG 84 | 85 | __10-05-2017__ 86 | * Removed d3 from `window` 87 | * Added to package.json: 88 | * `"d3":"v3.5.14"` 89 | * `"d3-color":"^1.0.3"` 90 | 91 | __26-01-2017__ 92 | * Removed jQuery 93 | * Add support for selectors and DOM nodes 94 | 95 | __15-01-2017__ 96 | * Added support for v3 profiles - d3 tree json wrapper provided for v2 and v3 personality profiles to generate the input required by the d3 sunburst-chart created in lib/personality-chart-renderer.js 97 | * Only traits, needs and values will be displayed by the sunburst-chart. 98 | -------------------------------------------------------------------------------- /src/d3-profile-wrappers/v3/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /* eslint-disable no-console */ 17 | 18 | 'use strict'; 19 | 20 | class PersonalityProfile { 21 | 22 | constructor(profile, traitNames) { 23 | this._traitNames = traitNames; 24 | this._traits = profile.personality; 25 | this._needs = profile.needs; 26 | this._values = profile.values; 27 | } 28 | 29 | /** 30 | * Creates a tree object matching the format used by D3 tree visualizations: 31 | * each node in the tree must have a 'name' and 'children' attribute except leaf nodes 32 | * which only require a 'name' attribute 33 | **/ 34 | d3Json(){ 35 | return { 36 | tree: { 37 | children: [ 38 | { 39 | name: 'Big 5', 40 | id: 'personality', 41 | children: [this.traitsTree()] 42 | }, 43 | { 44 | name: 'Values', 45 | id: 'values', 46 | children: [this.valuesTree()] 47 | }, 48 | { 49 | name: 'Needs', 50 | id: 'needs', 51 | children: [this.needsTree()] 52 | } 53 | ] 54 | } 55 | }; 56 | } 57 | 58 | traitsTree(){ 59 | var self = this; 60 | const mostSignificantTrait = this.mostSignificantChild(this._traits); 61 | return { 62 | name: self._traitNames.name(mostSignificantTrait.trait_id), 63 | id: mostSignificantTrait.trait_id + '_parent', 64 | category: mostSignificantTrait.category, 65 | score: mostSignificantTrait.percentile, 66 | children: this._traits.map(function(t) { 67 | return { 68 | name: self._traitNames.name(t.trait_id), 69 | id: t.trait_id, 70 | category: t.category, 71 | score: t.percentile, 72 | children: t.children.map(function(f) { 73 | return { 74 | name: self._traitNames.name(f.trait_id), 75 | id: f.trait_id, 76 | category: f.category, 77 | score: f.percentile 78 | }; 79 | }) 80 | }; 81 | }) 82 | }; 83 | } 84 | 85 | 86 | needsTree(){ 87 | var self = this; 88 | const mostSignificantNeed = this.mostSignificantChild(this._needs); 89 | return { 90 | name: self._traitNames.name(mostSignificantNeed.trait_id), 91 | id: mostSignificantNeed.trait_id + '_parent', 92 | category: mostSignificantNeed.category, 93 | score: mostSignificantNeed.percentile, 94 | children: this._needs.map(function(n) { 95 | return { 96 | name: self._traitNames.name(n.trait_id), 97 | id: n.trait_id, 98 | category: n.category, 99 | score: n.percentile 100 | }; 101 | }) 102 | }; 103 | } 104 | 105 | valuesTree(){ 106 | var self = this; 107 | const mostSignificantValue = this.mostSignificantChild(this._values); 108 | return { 109 | name: self._traitNames.name(mostSignificantValue.trait_id), 110 | id: mostSignificantValue.trait_id + '_parent', 111 | category: mostSignificantValue.category, 112 | score: mostSignificantValue.percentile, 113 | children: this._values.map(function(v) { 114 | return { 115 | name: self._traitNames.name(v.trait_id), 116 | id: v.trait_id, 117 | category: v.category, 118 | score: v.percentile 119 | }; 120 | }) 121 | }; 122 | } 123 | 124 | mostSignificantChild(children){ 125 | const threshold = 0.5; 126 | let farthestDistance = 0; 127 | let childWithScoreFarthestFromThreshold = {}; 128 | 129 | for (let i = 0; i < children.length; i++) { 130 | const distance = Math.abs(children[i].percentile - threshold); 131 | if(distance >= farthestDistance){ 132 | childWithScoreFarthestFromThreshold = children[i]; 133 | farthestDistance = distance; 134 | } 135 | } 136 | return childWithScoreFarthestFromThreshold; 137 | } 138 | } 139 | 140 | module.exports = PersonalityProfile; 141 | -------------------------------------------------------------------------------- /src/d3-profile-wrappers/v2/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /* eslint-disable no-console */ 17 | 18 | 'use strict'; 19 | 20 | class PersonalityProfile { 21 | 22 | constructor(profile, traitNames) { 23 | this._traitNames = traitNames; 24 | this._traits = profile.tree.children[0].children[0]; 25 | this._needs = profile.tree.children[1].children[0]; 26 | this._values = profile.tree.children[2].children[0]; 27 | } 28 | 29 | /** 30 | * Creates a tree object matching the format used by D3 tree visualizations: 31 | * each node in the tree must have a 'name' and 'children' attribute except leaf nodes 32 | * which only require a 'name' attribute 33 | **/ 34 | d3Json(){ 35 | return { 36 | tree: { 37 | children: [ 38 | { 39 | name: 'Big 5', 40 | id: 'personality', 41 | children: [this.traitsTree()] 42 | }, 43 | { 44 | name: 'Values', 45 | id: 'values', 46 | children: [this.valuesTree()] 47 | }, 48 | { 49 | name: 'Needs', 50 | id: 'needs', 51 | children: [this.needsTree()] 52 | } 53 | ] 54 | } 55 | }; 56 | } 57 | 58 | traitsTree(){ 59 | var self = this; 60 | const mostSignificantValue = this.mostSignificantChild(this._traits.children); 61 | return { 62 | name: self._traitNames.name(mostSignificantValue.id), 63 | id: mostSignificantValue.id + '_parent', 64 | category: mostSignificantValue.category, 65 | score: mostSignificantValue.percentage, 66 | children: this._traits.children.map(function(t) { 67 | return { 68 | name: self._traitNames.name(t.id), 69 | id: t.id, 70 | category: t.category, 71 | score: t.percentage, 72 | children: t.children.map(function(f) { 73 | return { 74 | name: self._traitNames.name(f.id), 75 | id: f.id, 76 | category: f.category, 77 | score: f.percentage 78 | }; 79 | }) 80 | }; 81 | }) 82 | }; 83 | } 84 | 85 | needsTree(){ 86 | var self = this; 87 | const mostSignificantValue = this.mostSignificantChild(this._needs.children); 88 | return { 89 | name: self._traitNames.name(mostSignificantValue.id), 90 | id: mostSignificantValue.id + '_parent', 91 | category: mostSignificantValue.category, 92 | score: mostSignificantValue.percentage, 93 | children: this._needs.children.map(function(n) { 94 | return { 95 | name: self._traitNames.name(n.id), 96 | id: n.id, 97 | category: n.category, 98 | score: n.percentage 99 | }; 100 | }) 101 | }; 102 | } 103 | 104 | valuesTree(){ 105 | var self = this; 106 | const mostSignificantValue = this.mostSignificantChild(this._values.children); 107 | return { 108 | name: self._traitNames.name(mostSignificantValue.id), 109 | id: mostSignificantValue.id + '_parent', 110 | category: mostSignificantValue.category, 111 | score: mostSignificantValue.percentage, 112 | children: this._values.children.map(function(v) { 113 | return { 114 | name: self._traitNames.name(v.id), 115 | id: v.id, 116 | category: v.category, 117 | score: v.percentage 118 | }; 119 | }) 120 | }; 121 | } 122 | 123 | mostSignificantChild(children){ 124 | const threshold = 0.5; 125 | let farthestDistance = 0; 126 | let childWithScoreFarthestFromThreshold = null; 127 | 128 | for (let i = 0; i < children.length; i++) { 129 | const distance = Math.abs(children[i].percentage - threshold); 130 | if(distance >= farthestDistance){ 131 | childWithScoreFarthestFromThreshold = children[i]; 132 | farthestDistance = distance; 133 | } 134 | } 135 | return childWithScoreFarthestFromThreshold; 136 | } 137 | } 138 | 139 | module.exports = PersonalityProfile; 140 | -------------------------------------------------------------------------------- /src/personality-sunburst-chart.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | /* global document */ 18 | 'use strict'; 19 | 20 | const SunburstWidget = require('./widget'); 21 | 22 | class PersonalitySunburstChartImpl { 23 | 24 | constructor(options, D3PersonalityProfile, ChartRenderer, PersonalityTraitNames) { 25 | this.D3PersonalityProfile = D3PersonalityProfile; 26 | this.ChartRenderer = ChartRenderer; 27 | this._options = options; 28 | this._selector = options.selector; 29 | this._element = options.element; 30 | this._locale = options.locale; 31 | this._colors = options.colors; 32 | this._imageUrl = ''; 33 | this._profile = null; 34 | this._widget = null; 35 | this._traitNames = new PersonalityTraitNames({ locale: this._locale }); 36 | } 37 | 38 | setLocale(locale, render = true) { 39 | if (this._locale !== locale) { 40 | this._locale = locale; 41 | this._traitNames.setLocale(locale); 42 | 43 | if (this._profile && this._widget) { 44 | const d3Profile = new this.D3PersonalityProfile(this._profile, this._traitNames); 45 | this._widget.setData(d3Profile.d3Json()); 46 | 47 | if (render) { 48 | this._widget.updateText(); 49 | } 50 | } 51 | } 52 | } 53 | 54 | setImage(url, render = true) { 55 | if (this._imageUrl !== url) { 56 | this._imageUrl = url; 57 | 58 | if (this._widget && render) { 59 | this._widget.changeImage(url); 60 | } 61 | } 62 | } 63 | 64 | setProfile(profile, render = true) { 65 | if (this._profile !== profile) { 66 | this._profile = profile; 67 | 68 | if (this._widget) { 69 | if (this._profile) { 70 | const d3Profile = new this.D3PersonalityProfile(this._profile, this._traitNames); 71 | this._widget.setData(d3Profile.d3Json()); 72 | } else { 73 | this._widget.clearData(); 74 | } 75 | } 76 | } else if (this._widget && this._profile && !this._widget.hasData()) { 77 | // initilize data 78 | const d3Profile = new this.D3PersonalityProfile(this._profile, this._traitNames); 79 | this._widget.setData(d3Profile.d3Json()); 80 | } 81 | 82 | if (render) { 83 | this.render(); 84 | } 85 | } 86 | 87 | setColors(colors, render = true) { 88 | if (!colors) { 89 | return; 90 | } 91 | this._colors = colors; 92 | if (this._widget) { 93 | this._widget.setColors(this._colors); 94 | 95 | if (render) { 96 | this._widget.updateColors(); 97 | } 98 | } 99 | } 100 | 101 | render() { 102 | if (this._widget) { 103 | this._widget.init(); 104 | 105 | // Render widget 106 | this._widget.render(); 107 | this._widget.updateText(); 108 | this._widget.updateColors(); 109 | 110 | // Expand all sectors of the sunburst chart - sectors at each level can be hidden 111 | this._widget.expandAll(); 112 | 113 | // Add an image of the person for whom the profile was generated 114 | if (this._imageUrl) { 115 | this._widget.addImage(this._imageUrl); 116 | } 117 | } else { 118 | this.show(); 119 | } 120 | } 121 | 122 | /** 123 | * Renders the sunburst visualization. The parameter is the tree as returned 124 | * from the Personality Insights JSON API. 125 | * It uses the arguments widgetId, widgetWidth, widgetHeight and personImageUrl 126 | * declared on top of this script. 127 | */ 128 | show(theProfile, personImageUrl, colors) { 129 | if (!this._widget) { 130 | // Create widget 131 | this._widget = new SunburstWidget(this._options, this.ChartRenderer); 132 | const element = this._element || document.querySelector(this._selector); 133 | this._widget.setElement(element); 134 | } 135 | 136 | // Clear DOM element that will display the sunburst chart 137 | this._widget.clear(); 138 | 139 | this.setProfile(theProfile || this._profile, false); 140 | this.setImage(personImageUrl || this._imageUrl, false); 141 | this.setColors(colors || this._colors, false); 142 | 143 | // Render widget 144 | this.render(); 145 | } 146 | 147 | } 148 | 149 | module.exports = PersonalitySunburstChartImpl; 150 | -------------------------------------------------------------------------------- /docs/index-test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Personality Insights Sunburst Chart 6 | 7 | 8 | 9 | 10 | 11 | 12 | 20 | 21 | 22 | 23 |
24 |
25 |

D3 Version

26 | Version 3 27 | Version 4 28 |
29 |
30 |

Personality Insights Version

31 | 32 | 33 |
34 |
35 |

Locale

36 | 37 | 38 |
39 |
40 |

Colors

41 | 42 | 43 |
44 |
45 | 46 |
47 |

Personality Insights Sunburst Chart

48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | 58 | 192 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Personality Insights Sunburst Chart 6 | 7 | 8 | 9 | 10 | 11 | 12 | 20 | 21 | 22 | 23 |
24 |
25 |

D3 Version

26 | Version 3 27 | Version 4 28 |
29 |
30 |

Personality Insights Version

31 | 32 | 33 |
34 |
35 |

Locale

36 | 37 | 38 |
39 |
40 |

Colors

41 | 42 | 43 |
44 |
45 | 46 |
47 |

Personality Insights Sunburst Chart

48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | 58 | 192 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /docs/index-d3v4-test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Personality Insights Sunburst Chart 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 | 24 | 25 |
26 |
27 |

D3 Version

28 | Version 3 29 | Version 4 30 |
31 |
32 |

Personality Insights Version

33 | 34 | 35 |
36 |
37 |

Locale

38 | 39 | 40 |
41 |
42 |

Colors

43 | 44 | 45 |
46 |
47 | 48 |
49 |

Personality Insights Sunburst Chart

50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | 60 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /docs/index-d3v4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Personality Insights Sunburst Chart 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 | 24 | 25 |
26 |
27 |

D3 Version

28 | Version 3 29 | Version 4 30 |
31 |
32 |

Personality Insights Version

33 | 34 | 35 |
36 |
37 |

Locale

38 | 39 | 40 |
41 |
42 |

Colors

43 | 44 | 45 |
46 |
47 | 48 |
49 |

Personality Insights Sunburst Chart

50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | 60 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /src/d3-renderers/v4/personality-chart-renderer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 'use strict'; 17 | const d3 = Object.assign({}, 18 | require('d3-color'), 19 | require('d3-hierarchy'), 20 | require('d3-selection'), 21 | require('d3-shape') 22 | ); 23 | 24 | const d3SvgSingleArc = require('../svg-single-arc'); 25 | const utils = require('../utils'); 26 | 27 | function renderChart(widget) { 28 | if (!widget.data || !widget.loadingDiv) { 29 | return; 30 | } 31 | 32 | var dummyData = false; 33 | var tree = widget.data ? (widget.data.tree ? widget.data.tree : widget.data) : null; 34 | if (!tree || !tree.children || !tree.children.length) { 35 | return; 36 | } 37 | 38 | widget.switchState(1); 39 | widget._layout(); 40 | 41 | var sector_right_pad = dummyData ? 0.0001 : 0.04 * 2 * Math.PI, 42 | sector_bottom_pad = 5.0; 43 | //Render a sector with two adjcent arcs in a style of odometor 44 | function twoArcsRender() { 45 | // For each small multiple 46 | function twoArcs(g) { 47 | g.each(function(d) { 48 | g = d3.select(this); 49 | widget.createParts(g, d); 50 | 51 | var right_pad = d.depth > 0 ? sector_right_pad / (3 * d.depth) : sector_right_pad; 52 | var score = widget.getScore(d); 53 | 54 | if (!d.children) { 55 | var inner_r = sector_bottom_pad + d.y0; 56 | var out_r = sector_bottom_pad + d.y0 + utils.getBarLengthFactor(d) * Math.abs(score) * (d.y1 - d.y0); 57 | 58 | var _bar = d3.arc() 59 | .startAngle(d.x0) 60 | .endAngle(d.x1) 61 | .innerRadius(inner_r) 62 | .outerRadius(out_r); // Draw leaf arcs 63 | 64 | widget._childElements.parts[widget.getUniqueId(d, 'bar')] 65 | .attr('d', _bar); 66 | 67 | //add label; 68 | var rotate = 0, 69 | lbl_anchor = 'start', 70 | dy_init = 0; 71 | 72 | if (d.x0 > Math.PI) { 73 | rotate = d.x0 * 180 / Math.PI + 90; 74 | lbl_anchor = 'end'; 75 | dy_init = -(d.x1 - d.x0) * 20 * Math.PI; 76 | } else { 77 | rotate = d.x0 * 180 / Math.PI - 90; 78 | lbl_anchor = 'start'; 79 | dy_init = 5 + (d.x1 - d.x0) * 20 * Math.PI; 80 | } 81 | 82 | widget._childElements.parts[widget.getUniqueId(d, 'sector_leaf_text')] 83 | .attr('dy', dy_init) 84 | .attr('text-anchor', lbl_anchor) 85 | .attr('transform', 'translate(' + (out_r + 5) * Math.sin(d.x0) + ',' + (-(out_r + 5) * Math.cos(d.x0)) + ') ' + 'rotate(' + rotate + ')'); 86 | } else { 87 | var arc1_extend = Math.max(Math.abs(score) * (d.x1 - d.x0) - right_pad, 0); 88 | //Regular renders 89 | var arc1 = d3.arc() 90 | .startAngle(function(d) { 91 | return d.x0; 92 | }) //x:startangle, 93 | .endAngle(function(d) { 94 | return d.x0 + arc1_extend; 95 | }) //dx: endangle, 96 | .innerRadius(function(d) { 97 | return sector_bottom_pad + d.y0; 98 | }) 99 | .outerRadius(function(d) { 100 | return d.y1; 101 | }); 102 | 103 | widget._childElements.parts[widget.getUniqueId(d, 'arc1')] 104 | .attr('d', arc1); 105 | 106 | var arc2 = d3.arc() 107 | .startAngle(function(d) { 108 | return d.x0 + arc1_extend; 109 | }) //x:startangle, 110 | .endAngle(function(d) { 111 | return d.x0 + (d.x1 - d.x0) - right_pad; 112 | }) //dx: endangle, 113 | .innerRadius(function(d) { 114 | return sector_bottom_pad + d.y0; 115 | }) 116 | .outerRadius(function(d) { 117 | return d.y1; 118 | }); 119 | widget._childElements.parts[widget.getUniqueId(d, 'arc2')] 120 | .attr('d', arc2); 121 | 122 | var bottom = utils.isLocatedBottom(d); 123 | var arc_for_label, arc_for_label_number; 124 | var arc_label_radius, arc_label_number_radius; 125 | if (d.depth === 1 && bottom) { 126 | arc_label_radius = d.y1 - (d.y1 - sector_bottom_pad - d.y0) / 6; 127 | arc_label_number_radius = d.y1 - (d.y1 - sector_bottom_pad - d.y0) / 8; 128 | } else { 129 | arc_label_radius = sector_bottom_pad + d.y0 + (d.y1 - sector_bottom_pad - d.y0) * 5 / 12; 130 | arc_label_number_radius = d.y1 - (d.y1 - sector_bottom_pad - d.y0) / 7; 131 | } 132 | 133 | if (bottom) { 134 | //special reversed label for bottom data 135 | arc_for_label = utils.arc(d.x1 - right_pad - Math.PI / 2, d.x0 - Math.PI / 2, arc_label_radius); 136 | arc_for_label_number = utils.arc(d.x1 - right_pad - Math.PI / 2, d.x0 - Math.PI / 2, arc_label_number_radius); 137 | } else { 138 | arc_for_label = d3SvgSingleArc() 139 | .startAngle(function(d) { 140 | return d.x0; 141 | }) 142 | .endAngle(function(d) { 143 | return d.x1 - right_pad; 144 | }) 145 | .radius(function(d) { 146 | return d.depth === 1 ? d.y1 - (d.y1 - sector_bottom_pad - d.y0) / 3 : sector_bottom_pad + d.y0 + (d.y1 - sector_bottom_pad - d.y0) * 3 / 5; 147 | }); 148 | 149 | arc_for_label_number = d3SvgSingleArc() 150 | .startAngle(function(d) { 151 | return d.x0; 152 | }) 153 | .endAngle(function(d) { 154 | return d.x1 - right_pad; 155 | }) 156 | .radius(function(d) { 157 | return d.depth === 1 ? d.y1 - (d.y1 - sector_bottom_pad - d.y0) / 3 : sector_bottom_pad + d.y0 + (d.y1 - sector_bottom_pad - d.y0) / 5; 158 | }); 159 | } 160 | widget._childElements.parts[widget.getUniqueId(d, 'arc_for_label')] 161 | .attr('d', arc_for_label); 162 | if (d.depth > 1) { 163 | widget._childElements.parts[widget.getUniqueId(d, 'arc_for_label_number')] 164 | .attr('d', arc_for_label_number); 165 | } 166 | } 167 | }); 168 | } 169 | 170 | return twoArcs; 171 | } 172 | 173 | // The flower had a radius of 640 / 1.9 = 336.84 in the original. 174 | var radius = Math.min(widget.dimW, widget.dimH) / 3.2; 175 | var sector = twoArcsRender(radius); 176 | 177 | // Center the graph of 'g' 178 | widget.vis = widget.d3vis.append('g') 179 | .attr('transform', 'translate(' + (widget.dimW / 2) + ',' + widget.dimH / 2 + ')') 180 | .append('g'); 181 | 182 | var profile = { 183 | children: tree.children.filter(function (child) { 184 | return widget.exclude.indexOf(child.id) === -1; 185 | }) 186 | }; 187 | 188 | var root = d3.hierarchy(profile) 189 | .sum(function(d) { 190 | if (!d.hasOwnProperty('size') && !d.hasOwnProperty('children')) return 1; 191 | return d.size; 192 | }); 193 | 194 | var partition = d3.partition() 195 | .size([2 * Math.PI, radius]); 196 | 197 | var g = widget.vis.selectAll('g') 198 | .data(partition(root).descendants()) 199 | .enter().append('g') 200 | .attr('class', 'sector') 201 | .attr('visibility', function(d) { 202 | return d.depth === 2 || d.forceVisible ? 'visible' : 'hidden'; 203 | }) // hide non-first level rings 204 | .call(sector) 205 | .each(function(d) { 206 | d.expand = 1; 207 | }) 208 | .on('click', function(d) { 209 | utils.expandOrFoldSector(g, d, d3.select(this)); 210 | }) 211 | .on('mouseover', function(d) { 212 | widget.showTooltip(d, this); 213 | }) 214 | .on('mouseout', function() { 215 | widget.showTooltip(); 216 | }); 217 | 218 | widget.updateText(); 219 | } 220 | 221 | module.exports = { 222 | render: renderChart, 223 | d3: d3 224 | }; 225 | -------------------------------------------------------------------------------- /src/d3-renderers/v3/personality-chart-renderer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 'use strict'; 17 | const d3 = require('d3'); 18 | Object.assign(d3, 19 | require('d3-color') 20 | ); 21 | 22 | const d3SvgSingleArc = require('../svg-single-arc'); 23 | const utils = require('../utils'); 24 | 25 | function renderChart(widget) { 26 | if (!widget.data || !widget.loadingDiv) { 27 | return; 28 | } 29 | 30 | var dummyData = false; 31 | var tree = widget.data ? (widget.data.tree ? widget.data.tree : widget.data) : null; 32 | if (!tree || !tree.children || !tree.children.length) { 33 | return; 34 | } 35 | 36 | widget.switchState(1); 37 | widget._layout(); 38 | 39 | var sector_right_pad = dummyData ? 0.0001 : 0.04 * 2 * Math.PI, 40 | sector_bottom_pad = 5.0; 41 | //Render a sector with two adjcent arcs in a style of odometor 42 | function twoArcsRender() { 43 | // For each small multiple 44 | function twoArcs(g) { 45 | g.each(function(d) { 46 | g = d3.select(this); 47 | widget.createParts(g, d); 48 | 49 | var right_pad = d.depth > 0 ? sector_right_pad / (3 * d.depth) : sector_right_pad; 50 | var score = widget.getScore(d); 51 | 52 | if (!d.children) { 53 | var inner_r = sector_bottom_pad + d.y; 54 | var out_r = sector_bottom_pad + d.y + utils.getBarLengthFactor(d) * Math.abs(score) * d.dy; 55 | 56 | var _bar = d3.svg.arc() 57 | .startAngle(d.x) 58 | .endAngle(d.x + d.dx) 59 | .innerRadius(inner_r) 60 | .outerRadius(out_r); // Draw leaf arcs 61 | 62 | widget._childElements.parts[widget.getUniqueId(d, 'bar')] 63 | .attr('d', _bar); 64 | 65 | //add label; 66 | var rotate = 0, 67 | lbl_anchor = 'start', 68 | dy_init = 0; 69 | 70 | if (d.x > Math.PI) { 71 | rotate = d.x * 180 / Math.PI + 90; 72 | lbl_anchor = 'end'; 73 | dy_init = -d.dx * 20 * Math.PI; 74 | } else { 75 | rotate = d.x * 180 / Math.PI - 90; 76 | lbl_anchor = 'start'; 77 | dy_init = 5 + d.dx * 20 * Math.PI; 78 | } 79 | 80 | widget._childElements.parts[widget.getUniqueId(d, 'sector_leaf_text')] 81 | .attr('dy', dy_init) 82 | .attr('text-anchor', lbl_anchor) 83 | .attr('transform', 'translate(' + (out_r + 5) * Math.sin(d.x) + ',' + (-(out_r + 5) * Math.cos(d.x)) + ') ' + 'rotate(' + rotate + ')'); 84 | } else { 85 | var arc1_extend = (Math.abs(score) * d.dx - right_pad) > 0 ? (Math.abs(score) * d.dx - right_pad) : 0; 86 | //Regular renders 87 | var arc1 = d3.svg.arc() 88 | .startAngle(function(d) { 89 | return d.x; 90 | }) //x:startangle, 91 | .endAngle(function(d) { 92 | return d.x + arc1_extend; 93 | }) //dx: endangle, 94 | .innerRadius(function(d) { 95 | return sector_bottom_pad + d.y; 96 | }) 97 | .outerRadius(function(d) { 98 | return d.y + d.dy; 99 | }); 100 | widget._childElements.parts[widget.getUniqueId(d, 'arc1')] 101 | .attr('d', arc1); 102 | 103 | var arc2 = d3.svg.arc() 104 | .startAngle(function(d) { 105 | return d.x + arc1_extend; 106 | }) //x:startangle, 107 | .endAngle(function(d) { 108 | return d.x + d.dx - right_pad; 109 | }) //dx: endangle, 110 | .innerRadius(function(d) { 111 | return sector_bottom_pad + d.y; 112 | }) 113 | .outerRadius(function(d) { 114 | return d.y + d.dy; 115 | }); 116 | widget._childElements.parts[widget.getUniqueId(d, 'arc2')] 117 | .attr('d', arc2); 118 | 119 | //used for label path 120 | var bottom = utils.isLocatedBottom(d); 121 | var arc_for_label, arc_for_label_number; 122 | var arc_label_radius, arc_label_number_radius; 123 | if (d.depth === 1 && bottom) { 124 | arc_label_radius = d.y + d.dy - (d.y + d.dy - sector_bottom_pad - d.y) / 6; 125 | arc_label_number_radius = d.y + d.dy - (d.y + d.dy - sector_bottom_pad - d.y) / 8; 126 | } else { 127 | arc_label_radius = sector_bottom_pad + d.y + (d.y + d.dy - sector_bottom_pad - d.y) * 5 / 12; 128 | arc_label_number_radius = d.y + d.dy - (d.y + d.dy - sector_bottom_pad - d.y) / 7; 129 | } 130 | if (bottom) { 131 | //special reversed label for bottom data 132 | arc_for_label = utils.arc(d.x + d.dx - right_pad - Math.PI / 2, d.x - Math.PI / 2, arc_label_radius); 133 | arc_for_label_number = utils.arc(d.x + d.dx - right_pad - Math.PI / 2, d.x - Math.PI / 2, arc_label_number_radius); 134 | } else { 135 | arc_for_label = d3SvgSingleArc() 136 | .startAngle(function(d) { 137 | return d.x; 138 | }) 139 | .endAngle(function(d) { 140 | return d.x + d.dx - right_pad; 141 | }) 142 | .radius(function(d) { 143 | return d.depth === 1 ? d.y + d.dy - (d.y + d.dy - sector_bottom_pad - d.y) / 3 : sector_bottom_pad + d.y + (d.y + d.dy - sector_bottom_pad - d.y) * 3 / 5; 144 | }); 145 | 146 | arc_for_label_number = d3SvgSingleArc() 147 | .startAngle(function(d) { 148 | return d.x; 149 | }) 150 | .endAngle(function(d) { 151 | return d.x + d.dx - right_pad; 152 | }) 153 | .radius(function(d) { 154 | return d.depth === 1 ? d.y + d.dy - (d.y + d.dy - sector_bottom_pad - d.y) / 3 : sector_bottom_pad + d.y + (d.y + d.dy - sector_bottom_pad - d.y) / 5; 155 | }); 156 | } 157 | 158 | widget._childElements.parts[widget.getUniqueId(d, 'arc_for_label')] 159 | .attr('d', arc_for_label); 160 | 161 | //draw label number 162 | //path used for label number 163 | if (d.depth > 1) { 164 | widget._childElements.parts[widget.getUniqueId(d, 'arc_for_label_number')] 165 | .attr('d', arc_for_label_number); 166 | } 167 | } 168 | }); 169 | } 170 | 171 | return twoArcs; 172 | } 173 | 174 | // The flower had a radius of 640 / 1.9 = 336.84 in the original. 175 | var radius = Math.min(widget.dimW, widget.dimH) / 3.2; 176 | var sector = twoArcsRender(radius); 177 | 178 | // Center the graph of 'g' 179 | widget.vis = widget.d3vis.append('g') 180 | .attr('transform', 'translate(' + (widget.dimW / 2) + ',' + widget.dimH / 2 + ')') 181 | .append('g'); 182 | 183 | var profile = { 184 | children: tree.children.filter(function (child) { 185 | return widget.exclude.indexOf(child.id) === -1; 186 | }) 187 | }; 188 | 189 | var partition = d3.layout.partition() 190 | .sort(null) 191 | .size([2 * Math.PI, radius]) 192 | .value(function(d) { 193 | if (!d.hasOwnProperty('size') && !d.hasOwnProperty('children')) return 1; 194 | return d.size; 195 | }); 196 | 197 | var g = widget.vis.data([profile]).selectAll('g') 198 | .data(partition.nodes) 199 | .enter().append('g') 200 | .attr('class', 'sector') 201 | .attr('visibility', function(d) { 202 | return d.depth === 2 || d.forceVisible ? 'visible' : 'hidden'; 203 | }) // hide non-first level rings 204 | .call(sector) 205 | .each(function(d) { 206 | d.expand = 1; 207 | }) 208 | .on('click', function(d) { 209 | utils.expandOrFoldSector(g, d, d3.select(this)); 210 | }) 211 | .on('mouseover', function(d) { 212 | widget.showTooltip(d, this); 213 | }) 214 | .on('mouseout', function() { 215 | widget.showTooltip(); 216 | }); 217 | 218 | widget.updateText(); 219 | } 220 | 221 | module.exports = { 222 | render: renderChart, 223 | d3: d3 224 | }; 225 | -------------------------------------------------------------------------------- /docs/profiles/en_v3_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "word_count": 6582, 3 | "processed_language": "en", 4 | "personality": [ 5 | { 6 | "trait_id": "big5_openness", 7 | "name": "Openness", 8 | "category": "personality", 9 | "percentile": 0.4, 10 | "children": [ 11 | { 12 | "trait_id": "facet_adventurousness", 13 | "name": "Adventurousness", 14 | "category": "personality", 15 | "percentile": 0.7 16 | }, 17 | { 18 | "trait_id": "facet_artistic_interests", 19 | "name": "Artistic interests", 20 | "category": "personality", 21 | "percentile": 0.2 22 | }, 23 | { 24 | "trait_id": "facet_emotionality", 25 | "name": "Emotionality", 26 | "category": "personality", 27 | "percentile": 0.9 28 | }, 29 | { 30 | "trait_id": "facet_imagination", 31 | "name": "Imagination", 32 | "category": "personality", 33 | "percentile": 0.3 34 | }, 35 | { 36 | "trait_id": "facet_intellect", 37 | "name": "Intellect", 38 | "category": "personality", 39 | "percentile": 0.1 40 | }, 41 | { 42 | "trait_id": "facet_liberalism", 43 | "name": "Authority-challenging", 44 | "category": "personality", 45 | "percentile": 0.7 46 | } 47 | ] 48 | }, 49 | { 50 | "trait_id": "big5_conscientiousness", 51 | "name": "Conscientiousness", 52 | "category": "personality", 53 | "percentile": 0.8936538116484918, 54 | "children": [ 55 | { 56 | "trait_id": "facet_achievement_striving", 57 | "name": "Achievement striving", 58 | "category": "personality", 59 | "percentile": 0.9216597978352439 60 | }, 61 | { 62 | "trait_id": "facet_cautiousness", 63 | "name": "Cautiousness", 64 | "category": "personality", 65 | "percentile": 0.9589003591814163 66 | }, 67 | { 68 | "trait_id": "facet_dutifulness", 69 | "name": "Dutifulness", 70 | "category": "personality", 71 | "percentile": 0.7565446465573455 72 | }, 73 | { 74 | "trait_id": "facet_orderliness", 75 | "name": "Orderliness", 76 | "category": "personality", 77 | "percentile": 0.48132376796768517 78 | }, 79 | { 80 | "trait_id": "facet_self_discipline", 81 | "name": "Self-discipline", 82 | "category": "personality", 83 | "percentile": 0.8215063478296609 84 | }, 85 | { 86 | "trait_id": "facet_self_efficacy", 87 | "name": "Self-efficacy", 88 | "category": "personality", 89 | "percentile": 0.908624607288198 90 | } 91 | ] 92 | }, 93 | { 94 | "trait_id": "big5_extraversion", 95 | "name": "Extraversion", 96 | "category": "personality", 97 | "percentile": 0.3362575928970771, 98 | "children": [ 99 | { 100 | "trait_id": "facet_activity_level", 101 | "name": "Activity level", 102 | "category": "personality", 103 | "percentile": 0.9789796271350255 104 | }, 105 | { 106 | "trait_id": "facet_assertiveness", 107 | "name": "Assertiveness", 108 | "category": "personality", 109 | "percentile": 0.9825306758805727 110 | }, 111 | { 112 | "trait_id": "facet_cheerfulness", 113 | "name": "Cheerfulness", 114 | "category": "personality", 115 | "percentile": 0.19465786707554655 116 | }, 117 | { 118 | "trait_id": "facet_excitement_seeking", 119 | "name": "Excitement-seeking", 120 | "category": "personality", 121 | "percentile": 0.21503977702456123 122 | }, 123 | { 124 | "trait_id": "facet_friendliness", 125 | "name": "Outgoing", 126 | "category": "personality", 127 | "percentile": 0.6005946078251523 128 | }, 129 | { 130 | "trait_id": "facet_gregariousness", 131 | "name": "Gregariousness", 132 | "category": "personality", 133 | "percentile": 0.24206546142537544 134 | } 135 | ] 136 | }, 137 | { 138 | "trait_id": "big5_agreeableness", 139 | "name": "Agreeableness", 140 | "category": "personality", 141 | "percentile": 0.0533865832349148, 142 | "children": [ 143 | { 144 | "trait_id": "facet_altruism", 145 | "name": "Altruism", 146 | "category": "personality", 147 | "percentile": 0.8722252950552395 148 | }, 149 | { 150 | "trait_id": "facet_cooperation", 151 | "name": "Cooperation", 152 | "category": "personality", 153 | "percentile": 0.7599846803277625 154 | }, 155 | { 156 | "trait_id": "facet_modesty", 157 | "name": "Modesty", 158 | "category": "personality", 159 | "percentile": 0.34947264959955104 160 | }, 161 | { 162 | "trait_id": "facet_morality", 163 | "name": "Uncompromising", 164 | "category": "personality", 165 | "percentile": 0.6480217001263691 166 | }, 167 | { 168 | "trait_id": "facet_sympathy", 169 | "name": "Sympathy", 170 | "category": "personality", 171 | "percentile": 0.9812271982935261 172 | }, 173 | { 174 | "trait_id": "facet_trust", 175 | "name": "Trust", 176 | "category": "personality", 177 | "percentile": 0.9240876717984589 178 | } 179 | ] 180 | }, 181 | { 182 | "trait_id": "big5_neuroticism", 183 | "name": "Emotional range", 184 | "category": "personality", 185 | "percentile": 0.9212642329050765, 186 | "children": [ 187 | { 188 | "trait_id": "facet_anger", 189 | "name": "Fiery", 190 | "category": "personality", 191 | "percentile": 0.016657350192117615 192 | }, 193 | { 194 | "trait_id": "facet_anxiety", 195 | "name": "Prone to worry", 196 | "category": "personality", 197 | "percentile": 0.049689060282152586 198 | }, 199 | { 200 | "trait_id": "facet_depression", 201 | "name": "Melancholy", 202 | "category": "personality", 203 | "percentile": 0.2725502659709549 204 | }, 205 | { 206 | "trait_id": "facet_immoderation", 207 | "name": "Immoderation", 208 | "category": "personality", 209 | "percentile": 0.006015482455870191 210 | }, 211 | { 212 | "trait_id": "facet_self_consciousness", 213 | "name": "Self-consciousness", 214 | "category": "personality", 215 | "percentile": 0.1257492389288613 216 | }, 217 | { 218 | "trait_id": "facet_vulnerability", 219 | "name": "Susceptible to stress", 220 | "category": "personality", 221 | "percentile": 0.057796181331887075 222 | } 223 | ] 224 | } 225 | ], 226 | "needs": [ 227 | { 228 | "trait_id": "need_challenge", 229 | "name": "Challenge", 230 | "category": "needs", 231 | "percentile": 0.009295974292889309 232 | }, 233 | { 234 | "trait_id": "need_closeness", 235 | "name": "Closeness", 236 | "category": "needs", 237 | "percentile": 0.16009921929894821 238 | }, 239 | { 240 | "trait_id": "need_curiosity", 241 | "name": "Curiosity", 242 | "category": "needs", 243 | "percentile": 0.6536846492707111 244 | }, 245 | { 246 | "trait_id": "need_excitement", 247 | "name": "Excitement", 248 | "category": "needs", 249 | "percentile": 0.09364803322659232 250 | }, 251 | { 252 | "trait_id": "need_harmony", 253 | "name": "Harmony", 254 | "category": "needs", 255 | "percentile": 0.0576922917475059 256 | }, 257 | { 258 | "trait_id": "need_ideal", 259 | "name": "Ideal", 260 | "category": "needs", 261 | "percentile": 0.008168529100234745 262 | }, 263 | { 264 | "trait_id": "need_liberty", 265 | "name": "Liberty", 266 | "category": "needs", 267 | "percentile": 0.06366682309101934 268 | }, 269 | { 270 | "trait_id": "need_love", 271 | "name": "Love", 272 | "category": "needs", 273 | "percentile": 0.028469441069982115 274 | }, 275 | { 276 | "trait_id": "need_practicality", 277 | "name": "Practicality", 278 | "category": "needs", 279 | "percentile": 0.050598475805181176 280 | }, 281 | { 282 | "trait_id": "need_self_expression", 283 | "name": "Self-expression", 284 | "category": "needs", 285 | "percentile": 0.040949707563547155 286 | }, 287 | { 288 | "trait_id": "need_stability", 289 | "name": "Stability", 290 | "category": "needs", 291 | "percentile": 0.3829004285272741 292 | }, 293 | { 294 | "trait_id": "need_structure", 295 | "name": "Structure", 296 | "category": "needs", 297 | "percentile": 0.8207207759334644 298 | } 299 | ], 300 | "values": [ 301 | { 302 | "trait_id": "value_conservation", 303 | "name": "Conservation", 304 | "category": "values", 305 | "percentile": 0.16063478087796923 306 | }, 307 | { 308 | "trait_id": "value_openness_to_change", 309 | "name": "Openness to change", 310 | "category": "values", 311 | "percentile": 0.5883913392447956 312 | }, 313 | { 314 | "trait_id": "value_hedonism", 315 | "name": "Hedonism", 316 | "category": "values", 317 | "percentile": 0.0029501441024047392 318 | }, 319 | { 320 | "trait_id": "value_self_enhancement", 321 | "name": "Self-enhancement", 322 | "category": "values", 323 | "percentile": 0.01213256688793024 324 | }, 325 | { 326 | "trait_id": "value_self_transcendence", 327 | "name": "Self-transcendence", 328 | "category": "values", 329 | "percentile": 0.10538088756987435 330 | } 331 | ], 332 | "warnings": [] 333 | } 334 | -------------------------------------------------------------------------------- /docs/profiles/en_v3.json: -------------------------------------------------------------------------------- 1 | { 2 | "word_count": 6582, 3 | "processed_language": "en", 4 | "personality": [ 5 | { 6 | "trait_id": "big5_openness", 7 | "name": "Openness", 8 | "category": "personality", 9 | "percentile": 0.9805667785359738, 10 | "children": [ 11 | { 12 | "trait_id": "facet_adventurousness", 13 | "name": "Adventurousness", 14 | "category": "personality", 15 | "percentile": 0.950428146311326 16 | }, 17 | { 18 | "trait_id": "facet_artistic_interests", 19 | "name": "Artistic interests", 20 | "category": "personality", 21 | "percentile": 0.8849147656630096 22 | }, 23 | { 24 | "trait_id": "facet_emotionality", 25 | "name": "Emotionality", 26 | "category": "personality", 27 | "percentile": 0.17046533752727244 28 | }, 29 | { 30 | "trait_id": "facet_imagination", 31 | "name": "Imagination", 32 | "category": "personality", 33 | "percentile": 0.20111675093062387 34 | }, 35 | { 36 | "trait_id": "facet_intellect", 37 | "name": "Intellect", 38 | "category": "personality", 39 | "percentile": 0.9823942785877824 40 | }, 41 | { 42 | "trait_id": "facet_liberalism", 43 | "name": "Authority-challenging", 44 | "category": "personality", 45 | "percentile": 0.9648675417313879 46 | } 47 | ] 48 | }, 49 | { 50 | "trait_id": "big5_conscientiousness", 51 | "name": "Conscientiousness", 52 | "category": "personality", 53 | "percentile": 0.8936538116484918, 54 | "children": [ 55 | { 56 | "trait_id": "facet_achievement_striving", 57 | "name": "Achievement striving", 58 | "category": "personality", 59 | "percentile": 0.9216597978352439 60 | }, 61 | { 62 | "trait_id": "facet_cautiousness", 63 | "name": "Cautiousness", 64 | "category": "personality", 65 | "percentile": 0.9589003591814163 66 | }, 67 | { 68 | "trait_id": "facet_dutifulness", 69 | "name": "Dutifulness", 70 | "category": "personality", 71 | "percentile": 0.7565446465573455 72 | }, 73 | { 74 | "trait_id": "facet_orderliness", 75 | "name": "Orderliness", 76 | "category": "personality", 77 | "percentile": 0.48132376796768517 78 | }, 79 | { 80 | "trait_id": "facet_self_discipline", 81 | "name": "Self-discipline", 82 | "category": "personality", 83 | "percentile": 0.8215063478296609 84 | }, 85 | { 86 | "trait_id": "facet_self_efficacy", 87 | "name": "Self-efficacy", 88 | "category": "personality", 89 | "percentile": 0.908624607288198 90 | } 91 | ] 92 | }, 93 | { 94 | "trait_id": "big5_extraversion", 95 | "name": "Extraversion", 96 | "category": "personality", 97 | "percentile": 0.3362575928970771, 98 | "children": [ 99 | { 100 | "trait_id": "facet_activity_level", 101 | "name": "Activity level", 102 | "category": "personality", 103 | "percentile": 0.9789796271350255 104 | }, 105 | { 106 | "trait_id": "facet_assertiveness", 107 | "name": "Assertiveness", 108 | "category": "personality", 109 | "percentile": 0.9825306758805727 110 | }, 111 | { 112 | "trait_id": "facet_cheerfulness", 113 | "name": "Cheerfulness", 114 | "category": "personality", 115 | "percentile": 0.19465786707554655 116 | }, 117 | { 118 | "trait_id": "facet_excitement_seeking", 119 | "name": "Excitement-seeking", 120 | "category": "personality", 121 | "percentile": 0.21503977702456123 122 | }, 123 | { 124 | "trait_id": "facet_friendliness", 125 | "name": "Outgoing", 126 | "category": "personality", 127 | "percentile": 0.6005946078251523 128 | }, 129 | { 130 | "trait_id": "facet_gregariousness", 131 | "name": "Gregariousness", 132 | "category": "personality", 133 | "percentile": 0.24206546142537544 134 | } 135 | ] 136 | }, 137 | { 138 | "trait_id": "big5_agreeableness", 139 | "name": "Agreeableness", 140 | "category": "personality", 141 | "percentile": 0.0533865832349148, 142 | "children": [ 143 | { 144 | "trait_id": "facet_altruism", 145 | "name": "Altruism", 146 | "category": "personality", 147 | "percentile": 0.8722252950552395 148 | }, 149 | { 150 | "trait_id": "facet_cooperation", 151 | "name": "Cooperation", 152 | "category": "personality", 153 | "percentile": 0.7599846803277625 154 | }, 155 | { 156 | "trait_id": "facet_modesty", 157 | "name": "Modesty", 158 | "category": "personality", 159 | "percentile": 0.34947264959955104 160 | }, 161 | { 162 | "trait_id": "facet_morality", 163 | "name": "Uncompromising", 164 | "category": "personality", 165 | "percentile": 0.6480217001263691 166 | }, 167 | { 168 | "trait_id": "facet_sympathy", 169 | "name": "Sympathy", 170 | "category": "personality", 171 | "percentile": 0.9812271982935261 172 | }, 173 | { 174 | "trait_id": "facet_trust", 175 | "name": "Trust", 176 | "category": "personality", 177 | "percentile": 0.9240876717984589 178 | } 179 | ] 180 | }, 181 | { 182 | "trait_id": "big5_neuroticism", 183 | "name": "Emotional range", 184 | "category": "personality", 185 | "percentile": 0.9212642329050765, 186 | "children": [ 187 | { 188 | "trait_id": "facet_anger", 189 | "name": "Fiery", 190 | "category": "personality", 191 | "percentile": 0.016657350192117615 192 | }, 193 | { 194 | "trait_id": "facet_anxiety", 195 | "name": "Prone to worry", 196 | "category": "personality", 197 | "percentile": 0.049689060282152586 198 | }, 199 | { 200 | "trait_id": "facet_depression", 201 | "name": "Melancholy", 202 | "category": "personality", 203 | "percentile": 0.2725502659709549 204 | }, 205 | { 206 | "trait_id": "facet_immoderation", 207 | "name": "Immoderation", 208 | "category": "personality", 209 | "percentile": 0.006015482455870191 210 | }, 211 | { 212 | "trait_id": "facet_self_consciousness", 213 | "name": "Self-consciousness", 214 | "category": "personality", 215 | "percentile": 0.1257492389288613 216 | }, 217 | { 218 | "trait_id": "facet_vulnerability", 219 | "name": "Susceptible to stress", 220 | "category": "personality", 221 | "percentile": 0.057796181331887075 222 | } 223 | ] 224 | } 225 | ], 226 | "needs": [ 227 | { 228 | "trait_id": "need_challenge", 229 | "name": "Challenge", 230 | "category": "needs", 231 | "percentile": 0.009295974292889309 232 | }, 233 | { 234 | "trait_id": "need_closeness", 235 | "name": "Closeness", 236 | "category": "needs", 237 | "percentile": 0.16009921929894821 238 | }, 239 | { 240 | "trait_id": "need_curiosity", 241 | "name": "Curiosity", 242 | "category": "needs", 243 | "percentile": 0.6536846492707111 244 | }, 245 | { 246 | "trait_id": "need_excitement", 247 | "name": "Excitement", 248 | "category": "needs", 249 | "percentile": 0.09364803322659232 250 | }, 251 | { 252 | "trait_id": "need_harmony", 253 | "name": "Harmony", 254 | "category": "needs", 255 | "percentile": 0.0576922917475059 256 | }, 257 | { 258 | "trait_id": "need_ideal", 259 | "name": "Ideal", 260 | "category": "needs", 261 | "percentile": 0.008168529100234745 262 | }, 263 | { 264 | "trait_id": "need_liberty", 265 | "name": "Liberty", 266 | "category": "needs", 267 | "percentile": 0.06366682309101934 268 | }, 269 | { 270 | "trait_id": "need_love", 271 | "name": "Love", 272 | "category": "needs", 273 | "percentile": 0.028469441069982115 274 | }, 275 | { 276 | "trait_id": "need_practicality", 277 | "name": "Practicality", 278 | "category": "needs", 279 | "percentile": 0.050598475805181176 280 | }, 281 | { 282 | "trait_id": "need_self_expression", 283 | "name": "Self-expression", 284 | "category": "needs", 285 | "percentile": 0.040949707563547155 286 | }, 287 | { 288 | "trait_id": "need_stability", 289 | "name": "Stability", 290 | "category": "needs", 291 | "percentile": 0.3829004285272741 292 | }, 293 | { 294 | "trait_id": "need_structure", 295 | "name": "Structure", 296 | "category": "needs", 297 | "percentile": 0.8207207759334644 298 | } 299 | ], 300 | "values": [ 301 | { 302 | "trait_id": "value_conservation", 303 | "name": "Conservation", 304 | "category": "values", 305 | "percentile": 0.16063478087796923 306 | }, 307 | { 308 | "trait_id": "value_openness_to_change", 309 | "name": "Openness to change", 310 | "category": "values", 311 | "percentile": 0.5883913392447956 312 | }, 313 | { 314 | "trait_id": "value_hedonism", 315 | "name": "Hedonism", 316 | "category": "values", 317 | "percentile": 0.0029501441024047392 318 | }, 319 | { 320 | "trait_id": "value_self_enhancement", 321 | "name": "Self-enhancement", 322 | "category": "values", 323 | "percentile": 0.01213256688793024 324 | }, 325 | { 326 | "trait_id": "value_self_transcendence", 327 | "name": "Self-transcendence", 328 | "category": "values", 329 | "percentile": 0.10538088756987435 330 | } 331 | ], 332 | "warnings": [] 333 | } 334 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /docs/profiles/en_v2_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "*UNKNOWN*", 3 | "source": "*UNKNOWN*", 4 | "word_count": 6582, 5 | "processed_lang": "en", 6 | "tree": { 7 | "id": "r", 8 | "name": "root", 9 | "children": [ 10 | { 11 | "id": "personality", 12 | "name": "Big 5", 13 | "children": [ 14 | { 15 | "id": "Openness_parent", 16 | "name": "Openness", 17 | "category": "personality", 18 | "percentage": 0.9805667785359738, 19 | "children": [ 20 | { 21 | "id": "Openness", 22 | "name": "Openness", 23 | "category": "personality", 24 | "percentage": 0.1, 25 | "sampling_error": 0.05055925272, 26 | "children": [ 27 | { 28 | "id": "Adventurousness", 29 | "name": "Adventurousness", 30 | "category": "personality", 31 | "percentage": 0.3, 32 | "sampling_error": 0.0446642816 33 | }, 34 | { 35 | "id": "Artistic interests", 36 | "name": "Artistic interests", 37 | "category": "personality", 38 | "percentage": 0.4, 39 | "sampling_error": 0.09146252496 40 | }, 41 | { 42 | "id": "Emotionality", 43 | "name": "Emotionality", 44 | "category": "personality", 45 | "percentage": 0.5, 46 | "sampling_error": 0.04151224904 47 | }, 48 | { 49 | "id": "Imagination", 50 | "name": "Imagination", 51 | "category": "personality", 52 | "percentage": 0.6, 53 | "sampling_error": 0.05539459304 54 | }, 55 | { 56 | "id": "Intellect", 57 | "name": "Intellect", 58 | "category": "personality", 59 | "percentage": 0.7, 60 | "sampling_error": 0.04812533736 61 | }, 62 | { 63 | "id": "Liberalism", 64 | "name": "Authority-challenging", 65 | "category": "personality", 66 | "percentage": 0.8, 67 | "sampling_error": 0.07417368224 68 | } 69 | ] 70 | }, 71 | { 72 | "id": "Conscientiousness", 73 | "name": "Conscientiousness", 74 | "category": "personality", 75 | "percentage": 0.8936538116484918, 76 | "sampling_error": 0.06413948688, 77 | "children": [ 78 | { 79 | "id": "Achievement striving", 80 | "name": "Achievement striving", 81 | "category": "personality", 82 | "percentage": 0.9216597978352439, 83 | "sampling_error": 0.08711601256 84 | }, 85 | { 86 | "id": "Cautiousness", 87 | "name": "Cautiousness", 88 | "category": "personality", 89 | "percentage": 0.9589003591814163, 90 | "sampling_error": 0.08097586712 91 | }, 92 | { 93 | "id": "Dutifulness", 94 | "name": "Dutifulness", 95 | "category": "personality", 96 | "percentage": 0.7565446465573455, 97 | "sampling_error": 0.05347717848 98 | }, 99 | { 100 | "id": "Orderliness", 101 | "name": "Orderliness", 102 | "category": "personality", 103 | "percentage": 0.48132376796768517, 104 | "sampling_error": 0.06152930288 105 | }, 106 | { 107 | "id": "Self-discipline", 108 | "name": "Self-discipline", 109 | "category": "personality", 110 | "percentage": 0.8215063478296609, 111 | "sampling_error": 0.04176505304 112 | }, 113 | { 114 | "id": "Self-efficacy", 115 | "name": "Self-efficacy", 116 | "category": "personality", 117 | "percentage": 0.908624607288198, 118 | "sampling_error": 0.080106246 119 | } 120 | ] 121 | }, 122 | { 123 | "id": "Extraversion", 124 | "name": "Extraversion", 125 | "category": "personality", 126 | "percentage": 0.3362575928970771, 127 | "sampling_error": 0.0484772776, 128 | "children": [ 129 | { 130 | "id": "Activity level", 131 | "name": "Activity level", 132 | "category": "personality", 133 | "percentage": 0.9789796271350255, 134 | "sampling_error": 0.06734960408 135 | }, 136 | { 137 | "id": "Assertiveness", 138 | "name": "Assertiveness", 139 | "category": "personality", 140 | "percentage": 0.9825306758805727, 141 | "sampling_error": 0.07159494336 142 | }, 143 | { 144 | "id": "Cheerfulness", 145 | "name": "Cheerfulness", 146 | "category": "personality", 147 | "percentage": 0.19465786707554655, 148 | "sampling_error": 0.08989876216 149 | }, 150 | { 151 | "id": "Excitement-seeking", 152 | "name": "Excitement-seeking", 153 | "category": "personality", 154 | "percentage": 0.21503977702456123, 155 | "sampling_error": 0.07371680448000001 156 | }, 157 | { 158 | "id": "Friendliness", 159 | "name": "Outgoing", 160 | "category": "personality", 161 | "percentage": 0.6005946078251523, 162 | "sampling_error": 0.06625280248 163 | }, 164 | { 165 | "id": "Gregariousness", 166 | "name": "Gregariousness", 167 | "category": "personality", 168 | "percentage": 0.24206546142537544, 169 | "sampling_error": 0.051361828320000004 170 | } 171 | ] 172 | }, 173 | { 174 | "id": "Agreeableness", 175 | "name": "Agreeableness", 176 | "category": "personality", 177 | "percentage": 0.0533865832349148, 178 | "sampling_error": 0.08605852776, 179 | "children": [ 180 | { 181 | "id": "Altruism", 182 | "name": "Altruism", 183 | "category": "personality", 184 | "percentage": 0.8722252950552395, 185 | "sampling_error": 0.0616772748 186 | }, 187 | { 188 | "id": "Cooperation", 189 | "name": "Cooperation", 190 | "category": "personality", 191 | "percentage": 0.7599846803277625, 192 | "sampling_error": 0.07160543208 193 | }, 194 | { 195 | "id": "Modesty", 196 | "name": "Modesty", 197 | "category": "personality", 198 | "percentage": 0.34947264959955104, 199 | "sampling_error": 0.0473912608 200 | }, 201 | { 202 | "id": "Morality", 203 | "name": "Uncompromising", 204 | "category": "personality", 205 | "percentage": 0.6480217001263691, 206 | "sampling_error": 0.05506624192 207 | }, 208 | { 209 | "id": "Sympathy", 210 | "name": "Sympathy", 211 | "category": "personality", 212 | "percentage": 0.9812271982935261, 213 | "sampling_error": 0.0855425504 214 | }, 215 | { 216 | "id": "Trust", 217 | "name": "Trust", 218 | "category": "personality", 219 | "percentage": 0.9240876717984589, 220 | "sampling_error": 0.0480956124 221 | } 222 | ] 223 | }, 224 | { 225 | "id": "Neuroticism", 226 | "name": "Emotional range", 227 | "category": "personality", 228 | "percentage": 0.9212642329050765, 229 | "sampling_error": 0.07824502704, 230 | "children": [ 231 | { 232 | "id": "Anger", 233 | "name": "Fiery", 234 | "category": "personality", 235 | "percentage": 0.016657350192117615, 236 | "sampling_error": 0.082303344 237 | }, 238 | { 239 | "id": "Anxiety", 240 | "name": "Prone to worry", 241 | "category": "personality", 242 | "percentage": 0.049689060282152586, 243 | "sampling_error": 0.047158873680000005 244 | }, 245 | { 246 | "id": "Depression", 247 | "name": "Melancholy", 248 | "category": "personality", 249 | "percentage": 0.2725502659709549, 250 | "sampling_error": 0.049190098960000005 251 | }, 252 | { 253 | "id": "Immoderation", 254 | "name": "Immoderation", 255 | "category": "personality", 256 | "percentage": 0.006015482455870191, 257 | "sampling_error": 0.04641930216 258 | }, 259 | { 260 | "id": "Self-consciousness", 261 | "name": "Self-consciousness", 262 | "category": "personality", 263 | "percentage": 0.1257492389288613, 264 | "sampling_error": 0.04831067336 265 | }, 266 | { 267 | "id": "Vulnerability", 268 | "name": "Susceptible to stress", 269 | "category": "personality", 270 | "percentage": 0.057796181331887075, 271 | "sampling_error": 0.07381514336 272 | } 273 | ] 274 | } 275 | ] 276 | } 277 | ] 278 | }, 279 | { 280 | "id": "needs", 281 | "name": "Needs", 282 | "children": [ 283 | { 284 | "id": "Ideal_parent", 285 | "name": "Ideal", 286 | "category": "needs", 287 | "percentage": 0.008168529100234745, 288 | "children": [ 289 | { 290 | "id": "Challenge", 291 | "name": "Challenge", 292 | "category": "needs", 293 | "percentage": 0.009295974292889309, 294 | "sampling_error": 0.07250047111999999 295 | }, 296 | { 297 | "id": "Closeness", 298 | "name": "Closeness", 299 | "category": "needs", 300 | "percentage": 0.16009921929894821, 301 | "sampling_error": 0.07185326736 302 | }, 303 | { 304 | "id": "Curiosity", 305 | "name": "Curiosity", 306 | "category": "needs", 307 | "percentage": 0.6536846492707111, 308 | "sampling_error": 0.10148057399999999 309 | }, 310 | { 311 | "id": "Excitement", 312 | "name": "Excitement", 313 | "category": "needs", 314 | "percentage": 0.09364803322659232, 315 | "sampling_error": 0.09141073559999999 316 | }, 317 | { 318 | "id": "Harmony", 319 | "name": "Harmony", 320 | "category": "needs", 321 | "percentage": 0.0576922917475059, 322 | "sampling_error": 0.09109986024 323 | }, 324 | { 325 | "id": "Ideal", 326 | "name": "Ideal", 327 | "category": "needs", 328 | "percentage": 0.008168529100234745, 329 | "sampling_error": 0.08273161456 330 | }, 331 | { 332 | "id": "Liberty", 333 | "name": "Liberty", 334 | "category": "needs", 335 | "percentage": 0.06366682309101934, 336 | "sampling_error": 0.12363695304 337 | }, 338 | { 339 | "id": "Love", 340 | "name": "Love", 341 | "category": "needs", 342 | "percentage": 0.028469441069982115, 343 | "sampling_error": 0.08342424904 344 | }, 345 | { 346 | "id": "Practicality", 347 | "name": "Practicality", 348 | "category": "needs", 349 | "percentage": 0.050598475805181176, 350 | "sampling_error": 0.07383623287999999 351 | }, 352 | { 353 | "id": "Self-expression", 354 | "name": "Self-expression", 355 | "category": "needs", 356 | "percentage": 0.040949707563547155, 357 | "sampling_error": 0.07089691736 358 | }, 359 | { 360 | "id": "Stability", 361 | "name": "Stability", 362 | "category": "needs", 363 | "percentage": 0.3829004285272741, 364 | "sampling_error": 0.09041000471999999 365 | }, 366 | { 367 | "id": "Structure", 368 | "name": "Structure", 369 | "category": "needs", 370 | "percentage": 0.8207207759334644, 371 | "sampling_error": 0.06856271552 372 | } 373 | ] 374 | } 375 | ] 376 | }, 377 | { 378 | "id": "values", 379 | "name": "Values", 380 | "children": [ 381 | { 382 | "id": "Hedonism_parent", 383 | "name": "Hedonism", 384 | "category": "values", 385 | "percentage": 0.0029501441024047392, 386 | "children": [ 387 | { 388 | "id": "Conservation", 389 | "name": "Conservation", 390 | "category": "values", 391 | "percentage": 0.16063478087796923, 392 | "sampling_error": 0.0626580212 393 | }, 394 | { 395 | "id": "Openness to change", 396 | "name": "Openness to change", 397 | "category": "values", 398 | "percentage": 0.5883913392447956, 399 | "sampling_error": 0.056673731920000005 400 | }, 401 | { 402 | "id": "Hedonism", 403 | "name": "Hedonism", 404 | "category": "values", 405 | "percentage": 0.0029501441024047392, 406 | "sampling_error": 0.11365988424 407 | }, 408 | { 409 | "id": "Self-enhancement", 410 | "name": "Self-enhancement", 411 | "category": "values", 412 | "percentage": 0.01213256688793024, 413 | "sampling_error": 0.08692075272000001 414 | }, 415 | { 416 | "id": "Self-transcendence", 417 | "name": "Self-transcendence", 418 | "category": "values", 419 | "percentage": 0.10538088756987435, 420 | "sampling_error": 0.0655695888 421 | } 422 | ] 423 | } 424 | ] 425 | } 426 | ] 427 | }, 428 | "warnings": [] 429 | } 430 | -------------------------------------------------------------------------------- /docs/profiles/en_v2.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "*UNKNOWN*", 3 | "source": "*UNKNOWN*", 4 | "word_count": 6582, 5 | "processed_lang": "en", 6 | "tree": { 7 | "id": "r", 8 | "name": "root", 9 | "children": [ 10 | { 11 | "id": "personality", 12 | "name": "Big 5", 13 | "children": [ 14 | { 15 | "id": "Openness_parent", 16 | "name": "Openness", 17 | "category": "personality", 18 | "percentage": 0.9805667785359738, 19 | "children": [ 20 | { 21 | "id": "Openness", 22 | "name": "Openness", 23 | "category": "personality", 24 | "percentage": 0.9805667785359738, 25 | "sampling_error": 0.05055925272, 26 | "children": [ 27 | { 28 | "id": "Adventurousness", 29 | "name": "Adventurousness", 30 | "category": "personality", 31 | "percentage": 0.950428146311326, 32 | "sampling_error": 0.0446642816 33 | }, 34 | { 35 | "id": "Artistic interests", 36 | "name": "Artistic interests", 37 | "category": "personality", 38 | "percentage": 0.8849147656630096, 39 | "sampling_error": 0.09146252496 40 | }, 41 | { 42 | "id": "Emotionality", 43 | "name": "Emotionality", 44 | "category": "personality", 45 | "percentage": 0.17046533752727244, 46 | "sampling_error": 0.04151224904 47 | }, 48 | { 49 | "id": "Imagination", 50 | "name": "Imagination", 51 | "category": "personality", 52 | "percentage": 0.20111675093062387, 53 | "sampling_error": 0.05539459304 54 | }, 55 | { 56 | "id": "Intellect", 57 | "name": "Intellect", 58 | "category": "personality", 59 | "percentage": 0.9823942785877824, 60 | "sampling_error": 0.04812533736 61 | }, 62 | { 63 | "id": "Liberalism", 64 | "name": "Authority-challenging", 65 | "category": "personality", 66 | "percentage": 0.9648675417313879, 67 | "sampling_error": 0.07417368224 68 | } 69 | ] 70 | }, 71 | { 72 | "id": "Conscientiousness", 73 | "name": "Conscientiousness", 74 | "category": "personality", 75 | "percentage": 0.8936538116484918, 76 | "sampling_error": 0.06413948688, 77 | "children": [ 78 | { 79 | "id": "Achievement striving", 80 | "name": "Achievement striving", 81 | "category": "personality", 82 | "percentage": 0.9216597978352439, 83 | "sampling_error": 0.08711601256 84 | }, 85 | { 86 | "id": "Cautiousness", 87 | "name": "Cautiousness", 88 | "category": "personality", 89 | "percentage": 0.9589003591814163, 90 | "sampling_error": 0.08097586712 91 | }, 92 | { 93 | "id": "Dutifulness", 94 | "name": "Dutifulness", 95 | "category": "personality", 96 | "percentage": 0.7565446465573455, 97 | "sampling_error": 0.05347717848 98 | }, 99 | { 100 | "id": "Orderliness", 101 | "name": "Orderliness", 102 | "category": "personality", 103 | "percentage": 0.48132376796768517, 104 | "sampling_error": 0.06152930288 105 | }, 106 | { 107 | "id": "Self-discipline", 108 | "name": "Self-discipline", 109 | "category": "personality", 110 | "percentage": 0.8215063478296609, 111 | "sampling_error": 0.04176505304 112 | }, 113 | { 114 | "id": "Self-efficacy", 115 | "name": "Self-efficacy", 116 | "category": "personality", 117 | "percentage": 0.908624607288198, 118 | "sampling_error": 0.080106246 119 | } 120 | ] 121 | }, 122 | { 123 | "id": "Extraversion", 124 | "name": "Extraversion", 125 | "category": "personality", 126 | "percentage": 0.3362575928970771, 127 | "sampling_error": 0.0484772776, 128 | "children": [ 129 | { 130 | "id": "Activity level", 131 | "name": "Activity level", 132 | "category": "personality", 133 | "percentage": 0.9789796271350255, 134 | "sampling_error": 0.06734960408 135 | }, 136 | { 137 | "id": "Assertiveness", 138 | "name": "Assertiveness", 139 | "category": "personality", 140 | "percentage": 0.9825306758805727, 141 | "sampling_error": 0.07159494336 142 | }, 143 | { 144 | "id": "Cheerfulness", 145 | "name": "Cheerfulness", 146 | "category": "personality", 147 | "percentage": 0.19465786707554655, 148 | "sampling_error": 0.08989876216 149 | }, 150 | { 151 | "id": "Excitement-seeking", 152 | "name": "Excitement-seeking", 153 | "category": "personality", 154 | "percentage": 0.21503977702456123, 155 | "sampling_error": 0.07371680448000001 156 | }, 157 | { 158 | "id": "Friendliness", 159 | "name": "Outgoing", 160 | "category": "personality", 161 | "percentage": 0.6005946078251523, 162 | "sampling_error": 0.06625280248 163 | }, 164 | { 165 | "id": "Gregariousness", 166 | "name": "Gregariousness", 167 | "category": "personality", 168 | "percentage": 0.24206546142537544, 169 | "sampling_error": 0.051361828320000004 170 | } 171 | ] 172 | }, 173 | { 174 | "id": "Agreeableness", 175 | "name": "Agreeableness", 176 | "category": "personality", 177 | "percentage": 0.0533865832349148, 178 | "sampling_error": 0.08605852776, 179 | "children": [ 180 | { 181 | "id": "Altruism", 182 | "name": "Altruism", 183 | "category": "personality", 184 | "percentage": 0.8722252950552395, 185 | "sampling_error": 0.0616772748 186 | }, 187 | { 188 | "id": "Cooperation", 189 | "name": "Cooperation", 190 | "category": "personality", 191 | "percentage": 0.7599846803277625, 192 | "sampling_error": 0.07160543208 193 | }, 194 | { 195 | "id": "Modesty", 196 | "name": "Modesty", 197 | "category": "personality", 198 | "percentage": 0.34947264959955104, 199 | "sampling_error": 0.0473912608 200 | }, 201 | { 202 | "id": "Morality", 203 | "name": "Uncompromising", 204 | "category": "personality", 205 | "percentage": 0.6480217001263691, 206 | "sampling_error": 0.05506624192 207 | }, 208 | { 209 | "id": "Sympathy", 210 | "name": "Sympathy", 211 | "category": "personality", 212 | "percentage": 0.9812271982935261, 213 | "sampling_error": 0.0855425504 214 | }, 215 | { 216 | "id": "Trust", 217 | "name": "Trust", 218 | "category": "personality", 219 | "percentage": 0.9240876717984589, 220 | "sampling_error": 0.0480956124 221 | } 222 | ] 223 | }, 224 | { 225 | "id": "Neuroticism", 226 | "name": "Emotional range", 227 | "category": "personality", 228 | "percentage": 0.9212642329050765, 229 | "sampling_error": 0.07824502704, 230 | "children": [ 231 | { 232 | "id": "Anger", 233 | "name": "Fiery", 234 | "category": "personality", 235 | "percentage": 0.016657350192117615, 236 | "sampling_error": 0.082303344 237 | }, 238 | { 239 | "id": "Anxiety", 240 | "name": "Prone to worry", 241 | "category": "personality", 242 | "percentage": 0.049689060282152586, 243 | "sampling_error": 0.047158873680000005 244 | }, 245 | { 246 | "id": "Depression", 247 | "name": "Melancholy", 248 | "category": "personality", 249 | "percentage": 0.2725502659709549, 250 | "sampling_error": 0.049190098960000005 251 | }, 252 | { 253 | "id": "Immoderation", 254 | "name": "Immoderation", 255 | "category": "personality", 256 | "percentage": 0.006015482455870191, 257 | "sampling_error": 0.04641930216 258 | }, 259 | { 260 | "id": "Self-consciousness", 261 | "name": "Self-consciousness", 262 | "category": "personality", 263 | "percentage": 0.1257492389288613, 264 | "sampling_error": 0.04831067336 265 | }, 266 | { 267 | "id": "Vulnerability", 268 | "name": "Susceptible to stress", 269 | "category": "personality", 270 | "percentage": 0.057796181331887075, 271 | "sampling_error": 0.07381514336 272 | } 273 | ] 274 | } 275 | ] 276 | } 277 | ] 278 | }, 279 | { 280 | "id": "needs", 281 | "name": "Needs", 282 | "children": [ 283 | { 284 | "id": "Ideal_parent", 285 | "name": "Ideal", 286 | "category": "needs", 287 | "percentage": 0.008168529100234745, 288 | "children": [ 289 | { 290 | "id": "Challenge", 291 | "name": "Challenge", 292 | "category": "needs", 293 | "percentage": 0.009295974292889309, 294 | "sampling_error": 0.07250047111999999 295 | }, 296 | { 297 | "id": "Closeness", 298 | "name": "Closeness", 299 | "category": "needs", 300 | "percentage": 0.16009921929894821, 301 | "sampling_error": 0.07185326736 302 | }, 303 | { 304 | "id": "Curiosity", 305 | "name": "Curiosity", 306 | "category": "needs", 307 | "percentage": 0.6536846492707111, 308 | "sampling_error": 0.10148057399999999 309 | }, 310 | { 311 | "id": "Excitement", 312 | "name": "Excitement", 313 | "category": "needs", 314 | "percentage": 0.09364803322659232, 315 | "sampling_error": 0.09141073559999999 316 | }, 317 | { 318 | "id": "Harmony", 319 | "name": "Harmony", 320 | "category": "needs", 321 | "percentage": 0.0576922917475059, 322 | "sampling_error": 0.09109986024 323 | }, 324 | { 325 | "id": "Ideal", 326 | "name": "Ideal", 327 | "category": "needs", 328 | "percentage": 0.008168529100234745, 329 | "sampling_error": 0.08273161456 330 | }, 331 | { 332 | "id": "Liberty", 333 | "name": "Liberty", 334 | "category": "needs", 335 | "percentage": 0.06366682309101934, 336 | "sampling_error": 0.12363695304 337 | }, 338 | { 339 | "id": "Love", 340 | "name": "Love", 341 | "category": "needs", 342 | "percentage": 0.028469441069982115, 343 | "sampling_error": 0.08342424904 344 | }, 345 | { 346 | "id": "Practicality", 347 | "name": "Practicality", 348 | "category": "needs", 349 | "percentage": 0.050598475805181176, 350 | "sampling_error": 0.07383623287999999 351 | }, 352 | { 353 | "id": "Self-expression", 354 | "name": "Self-expression", 355 | "category": "needs", 356 | "percentage": 0.040949707563547155, 357 | "sampling_error": 0.07089691736 358 | }, 359 | { 360 | "id": "Stability", 361 | "name": "Stability", 362 | "category": "needs", 363 | "percentage": 0.3829004285272741, 364 | "sampling_error": 0.09041000471999999 365 | }, 366 | { 367 | "id": "Structure", 368 | "name": "Structure", 369 | "category": "needs", 370 | "percentage": 0.8207207759334644, 371 | "sampling_error": 0.06856271552 372 | } 373 | ] 374 | } 375 | ] 376 | }, 377 | { 378 | "id": "values", 379 | "name": "Values", 380 | "children": [ 381 | { 382 | "id": "Hedonism_parent", 383 | "name": "Hedonism", 384 | "category": "values", 385 | "percentage": 0.0029501441024047392, 386 | "children": [ 387 | { 388 | "id": "Conservation", 389 | "name": "Conservation", 390 | "category": "values", 391 | "percentage": 0.16063478087796923, 392 | "sampling_error": 0.0626580212 393 | }, 394 | { 395 | "id": "Openness to change", 396 | "name": "Openness to change", 397 | "category": "values", 398 | "percentage": 0.5883913392447956, 399 | "sampling_error": 0.056673731920000005 400 | }, 401 | { 402 | "id": "Hedonism", 403 | "name": "Hedonism", 404 | "category": "values", 405 | "percentage": 0.0029501441024047392, 406 | "sampling_error": 0.11365988424 407 | }, 408 | { 409 | "id": "Self-enhancement", 410 | "name": "Self-enhancement", 411 | "category": "values", 412 | "percentage": 0.01213256688793024, 413 | "sampling_error": 0.08692075272000001 414 | }, 415 | { 416 | "id": "Self-transcendence", 417 | "name": "Self-transcendence", 418 | "category": "values", 419 | "percentage": 0.10538088756987435, 420 | "sampling_error": 0.0655695888 421 | } 422 | ] 423 | } 424 | ] 425 | } 426 | ] 427 | }, 428 | "warnings": [] 429 | } -------------------------------------------------------------------------------- /src/widget.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | 'use strict'; 18 | 19 | const utils = require('./d3-renderers/utils'); 20 | 21 | class SunburstWidget { 22 | 23 | constructor(options, renderer) { 24 | this.renderer = renderer; 25 | this.d3 = renderer.d3; 26 | this.visualizationWidth = options.width || '100%'; 27 | this.visualizationHeight = options.height || '100%'; 28 | this.dimW = ((1/options.scale || 1) * 45) * 16.58; 29 | this.dimH = ((1/options.scale || 1) * 45) * 16.58; 30 | this.id = 'SystemUWidget_' + Math.random().toString().replace('0.',''); 31 | this.exclude = options.exclude || []; 32 | this.loadingDiv = 'dummy'; 33 | this.d3vis = null; 34 | this.vis = null; 35 | this.data = null; 36 | this._colors = options.colors; 37 | this._d3version = options.d3version; 38 | this._element = null; 39 | this._childElements = { 40 | icondefs: null, 41 | image: null, 42 | pattern: null, 43 | circle: null, 44 | parts: {} 45 | }; 46 | } 47 | 48 | setElement(element) { 49 | this._element = element; 50 | } 51 | 52 | setData(data) { 53 | this.data = data; 54 | } 55 | 56 | clearData() { 57 | this.data = null; 58 | } 59 | 60 | hasData() { 61 | return this.data !== null; 62 | } 63 | 64 | setColors(colors) { 65 | if (colors) { 66 | this._colors = colors; 67 | } 68 | } 69 | 70 | switchState() {} 71 | 72 | _layout() {} 73 | 74 | showTooltip() {} 75 | 76 | init() { 77 | if (!this.d3vis) { 78 | this.d3vis = this.d3.select(this._element).append('svg:svg'); 79 | } 80 | 81 | this.d3vis 82 | .attr('width', this.visualizationWidth) 83 | .attr('height', this.visualizationHeight) 84 | .attr('viewBox', '0 0 ' + this.dimH + ', ' + this.dimW); 85 | } 86 | 87 | clear() { 88 | this._element.innerHTML = null; 89 | } 90 | 91 | expandAll() { 92 | if (!this.vis) { 93 | return; 94 | } 95 | 96 | var self = this; 97 | this.vis.selectAll('g').each(function() { 98 | var g = self.d3.select(this); 99 | if (g.datum().parent && // Isn't the root g object. 100 | g.datum().parent.parent && // Isn't the feature trait. 101 | g.datum().parent.parent.parent) { // Isn't the feature dominant trait. 102 | g.attr('visibility', 'visible'); 103 | } 104 | }); 105 | } 106 | 107 | collapseAll() { 108 | if (!this.vis) { 109 | return; 110 | } 111 | 112 | var self = this; 113 | this.vis.selectAll('g').each(function() { 114 | var g = self.d3.select(this); 115 | if (g.datum().parent !== null && // Isn't the root g object. 116 | g.datum().parent.parent !== null && // Isn't the feature trait. 117 | g.datum().parent.parent.parent !== null) { // Isn't the feature dominant trait. 118 | g.attr('visibility', 'hidden'); 119 | } 120 | }); 121 | } 122 | 123 | render() { 124 | this.renderer.render(this); 125 | this.updateText(); 126 | } 127 | 128 | updateText() { 129 | if (!this.vis) { 130 | return; 131 | } 132 | 133 | var tree = this.data ? (this.data.tree ? this.data.tree : this.data) : null; 134 | if (!tree || !tree.children || !tree.children.length) { 135 | return; 136 | } 137 | 138 | var self = this; 139 | tree.children.forEach(function(child) { 140 | if (self._childElements.parts[self.getUniqueId(child, 'sector_label_path')]) { 141 | self._childElements.parts[self.getUniqueId(child, 'sector_label_path')].text(self.getNameLabelText(child)); 142 | } 143 | 144 | child.children.forEach(function(category) { 145 | if (self._childElements.parts[self.getUniqueId(category, 'sector_label_path')]) { 146 | self._childElements.parts[self.getUniqueId(category, 'sector_label_path')].text(category.name); 147 | } 148 | if (self._childElements.parts[self.getUniqueId(category, 'sector_label_number_path')]) { 149 | self._childElements.parts[self.getUniqueId(category, 'sector_label_number_path')].text(self.getScoreLabelText(category)); 150 | } 151 | 152 | category.children.forEach(function(trait) { 153 | if (trait.category === 'personality') { 154 | // personality traits 155 | if (self._childElements.parts[self.getUniqueId(trait, 'sector_label_path')]) { 156 | self._childElements.parts[self.getUniqueId(trait, 'sector_label_path')].text(trait.name); 157 | } 158 | if (self._childElements.parts[self.getUniqueId(trait, 'sector_label_number_path')]) { 159 | self._childElements.parts[self.getUniqueId(trait, 'sector_label_number_path')].text(self.getScoreLabelText(trait)); 160 | } 161 | 162 | trait.children.forEach(function(facet) { 163 | if (self._childElements.parts[self.getUniqueId(facet, 'sector_leaf_text')]) { 164 | self._childElements.parts[self.getUniqueId(facet, 'sector_leaf_text')].text(self.getNameLabelText(facet)); 165 | } 166 | }); 167 | } else { 168 | if (self._childElements.parts[self.getUniqueId(trait, 'sector_leaf_text')]) { 169 | self._childElements.parts[self.getUniqueId(trait, 'sector_leaf_text')].text(self.getNameLabelText(trait)); 170 | } 171 | } 172 | }); 173 | }); 174 | }); 175 | 176 | this.updateLabelLayout(); 177 | } 178 | 179 | updateLabelLayout() { 180 | this.updateLabelLayoutWithClass('.sector_label_path'); 181 | this.updateLabelLayoutWithClass('.sector_label_number_path'); 182 | } 183 | 184 | updateLabelLayoutWithClass(_class) { 185 | if (!this.d3vis) { 186 | return; 187 | } 188 | 189 | var max_font_size_base = 16; 190 | var self = this; 191 | this.d3vis.selectAll(_class).each(function(d) { 192 | var d3this = self.d3.select(this); 193 | var curNd = d3this.node(); 194 | var text = d3this.text(); 195 | if (text && text.length > 0) { 196 | var position = self.d3.select(this).attr('position-in-sector'); 197 | var frac = position === 'center' ? 0.5 : position === 'outer' ? 2 / 3 : 1 / 3; 198 | var sector_length = self._d3version === 'v3' ? 199 | (d.y + d.dy * frac) * d.dx : 200 | (d.y0 + (d.y1 - d.y0) * frac) * (d.x1 - d.x0); 201 | var text_length = curNd.getComputedTextLength(); 202 | var cur_font_size = self.d3.select(this).attr('font-size'); 203 | var new_font_size = cur_font_size * sector_length / text_length; 204 | 205 | if (new_font_size > max_font_size_base / (0.4 * d.depth + 0.6)) { 206 | new_font_size = max_font_size_base / (0.4 * d.depth + 0.6); 207 | } 208 | 209 | self.d3.select(this).attr('font-size', new_font_size); 210 | //set new offset: 211 | self.d3.select(this).attr('startOffset', (sector_length - curNd.getComputedTextLength()) / 2); 212 | } 213 | }); 214 | } 215 | 216 | updateColors() { 217 | var self = this; 218 | this.d3vis.selectAll('.arc2').each(function(d) { 219 | self.updatePartColor(d); 220 | }); 221 | this.d3vis.selectAll('.arc1').each(function(d) { 222 | self.updatePartColor(d); 223 | }); 224 | this.d3vis.selectAll('._bar').each(function(d) { 225 | self.updatePartColor(d); 226 | }); 227 | } 228 | 229 | updatePartColor(d) { 230 | var colors = this.getColors(d); 231 | var arc1color = d.depth < 2 ? this.d3.color(colors.innerRingLightColor) : this.d3.color(colors.innerRingDarkColor); 232 | var strokecolor = arc1color; 233 | 234 | if (!d.children) { 235 | this._childElements.parts[this.getUniqueId(d, 'bar')] 236 | .style('stroke', '#EEE') 237 | .style('fill', this.d3.color(colors.outerRingColor)); 238 | } else { 239 | this._childElements.parts[this.getUniqueId(d, 'arc1')] 240 | .style('stroke', strokecolor) 241 | .style('fill', arc1color); 242 | 243 | this._childElements.parts[this.getUniqueId(d, 'arc2')] 244 | .style('stroke', strokecolor) 245 | .style('fill', arc1color) 246 | .style('fill-opacity', 0.15); 247 | } 248 | } 249 | 250 | addImage(url) { 251 | if (!this.vis || !url) { 252 | if (this.hasImage()) { 253 | this.removeImage(); 254 | } 255 | return; 256 | } 257 | 258 | if (!this.hasImage()) { 259 | this._childElements.icondefs = this.vis.append('defs'); 260 | 261 | var radius = Math.min(this.dimW, this.dimH) / 16.58; 262 | var scaled_w = radius * 2; 263 | 264 | var id = 'user_icon_' + this.id; 265 | const pattern = this._childElements.icondefs.append('pattern'); 266 | pattern 267 | .attr('id', id) 268 | .attr('height', 1) 269 | .attr('width', 1) 270 | .attr('patternUnits', 'objectBoundingBox'); 271 | 272 | this._childElements.image = pattern.append('image'); 273 | 274 | this._childElements.image 275 | .attr('width', scaled_w) 276 | .attr('height', scaled_w) 277 | .attr('x', 0) 278 | .attr('y', 0) 279 | .attr('opacity', 1.0) 280 | .on('dblclick.zoom', null); 281 | 282 | this._childElements.circle = this.vis.append('circle'); 283 | 284 | this._childElements.circle 285 | .attr('r', radius) 286 | .attr('stroke-width', 0) 287 | .attr('fill', 'url(#' + id + ')'); 288 | } 289 | 290 | this.changeImage(url); 291 | } 292 | 293 | changeImage(url) { 294 | if (!url) { 295 | this.removeImage(); 296 | } else { 297 | if (!this.hasImage()) { 298 | this.addImage(url); 299 | } else { 300 | this._childElements.image.attr('xlink:href', url); 301 | } 302 | } 303 | } 304 | 305 | removeImage() { 306 | if (this._childElements.icondefs) { 307 | this._childElements.icondefs.remove(); 308 | this._childElements.icondefs = null; 309 | this._childElements.image = null; 310 | } 311 | if (this._childElements.circle) { 312 | this._childElements.circle.remove(); 313 | this._childElements.circle = null; 314 | } 315 | } 316 | 317 | hasImage() { 318 | return this._childElements.icondefs !== null; 319 | } 320 | 321 | getScore(d) { 322 | var score = utils.getValue(d, 'score'); 323 | var name = utils.getValue(d, 'name'); 324 | if (typeof score === 'undefined' || typeof name === 'undefined') { 325 | score = 0; 326 | } else { 327 | if (score === null) { 328 | score = 0.99; 329 | } else if (score >= 1) { 330 | score = 0.99; 331 | } else if (score <= -1) { 332 | score = -0.99; 333 | } 334 | } 335 | 336 | return score; 337 | } 338 | 339 | getScoreLabelText(d) { 340 | var score = utils.getValue(d, 'score'); 341 | return score === null || isNaN(score) ? '' : ' (' + (this.getScore(d) * 100).toFixed(0) + '%)'; 342 | } 343 | 344 | getNameLabelText(d) { 345 | var name = utils.getValue(d, 'name'); 346 | if (!name) { 347 | return ''; 348 | } 349 | 350 | var score = this.getScore(d); 351 | var id = utils.getValue(d, 'id'); 352 | var category = utils.getValue(d, 'category'); 353 | var label = name; 354 | 355 | if (id === 'sbh_dom' || id === 'sbh_parent'){ 356 | label = name; 357 | } else if (category === 'values') { 358 | label = name + ((score * 100).toFixed(0) === 'NaN' || isNaN(score) ? '' : ' (' + (score * 100).toFixed(0) + '%)'); 359 | } else { 360 | label = name + ((score * 100).toFixed(0) === 'NaN' || isNaN(score) ? '' : ' (' + (score * 100).toFixed(0) + '%)'); 361 | 362 | if ((Math.round(parseFloat(score) * 100) / 100) === 0) { 363 | label = name; 364 | } 365 | } 366 | 367 | return label; 368 | } 369 | 370 | getUniqueId(d, _class) { 371 | var uid = this.id + '_' + utils.getValue(d, 'id'); 372 | if (_class) { 373 | uid += '.' + _class; 374 | } 375 | return uid; 376 | } 377 | 378 | getColors(d) { 379 | d.coloridx = (d.depth === 1 || d.depth === 0) ? utils.getValue(d, 'id') : d.parent.coloridx; 380 | if (d.coloridx === 'personality') { 381 | return { 382 | innerRingDarkColor: this._colors.traits_dark, 383 | innerRingLightColor: this._colors.traits_light, 384 | outerRingColor: this._colors.facet 385 | }; 386 | } else if (d.coloridx === 'needs') { 387 | return { 388 | innerRingDarkColor: this._colors.needs_dark, 389 | innerRingLightColor: this._colors.needs_light, 390 | outerRingColor: this._colors.need 391 | }; 392 | } else if (d.coloridx === 'values') { 393 | return { 394 | innerRingDarkColor: this._colors.values_dark, 395 | innerRingLightColor: this._colors.values_light, 396 | outerRingColor: this._colors.value 397 | }; 398 | } else { 399 | return { 400 | innerRingDarkColor: this._colors.traits_dark, 401 | innerRingLightColor: this._colors.traits_light, 402 | outerRingColor: this._colors.facet 403 | }; 404 | } 405 | } 406 | 407 | createParts(g, d) { 408 | var self = this; 409 | var uid; 410 | var bottom = utils.isLocatedBottom(d); 411 | 412 | if (!d.children) { 413 | uid = this.getUniqueId(d, 'bar'); 414 | if (!this._childElements.parts[uid]) { 415 | this._childElements.parts[uid] = g.append('path') 416 | .attr('class', '_bar'); 417 | } 418 | 419 | uid = this.getUniqueId(d, 'sector_leaf_text'); 420 | if (!this._childElements.parts[uid]) { 421 | this._childElements.parts[uid] = g.append('text') 422 | .attr('class', 'sector_leaf_text'); 423 | } 424 | } else { 425 | uid = this.getUniqueId(d, 'arc1'); 426 | if (!this._childElements.parts[uid]) { 427 | this._childElements.parts[uid] = g.append('path') 428 | .attr('class', 'arc1'); 429 | } 430 | 431 | uid = this.getUniqueId(d, 'arc2'); 432 | if (!this._childElements.parts[uid]) { 433 | this._childElements.parts[uid] = g.append('path') 434 | .attr('class', 'arc2'); 435 | } 436 | 437 | uid = this.getUniqueId(d, 'arc_for_label'); 438 | if (!this._childElements.parts[uid]) { 439 | this._childElements.parts[uid] = g.append('path') 440 | .attr('class', 'arc_for_label') 441 | .attr('id', function(d) { 442 | return self.getUniqueId(d, 'arc_for_label'); 443 | }) 444 | .style('stroke-opacity', 0) 445 | .style('fill-opacity', 0); 446 | } 447 | 448 | uid = this.getUniqueId(d, 'sector_label_path'); 449 | if (!this._childElements.parts[uid]) { 450 | this._childElements.parts[uid] = g.append('text') 451 | .attr('class', 'sector_label') 452 | .attr('visibility', function(d) { 453 | return d.depth === 1 ? 'visible' : null; 454 | }) 455 | .attr('class', 'sector_nonleaf_text') 456 | .append('textPath') 457 | .attr('class', 'sector_label_path') 458 | .attr('position-in-sector', d.depth <= 1 ? 'center' : (bottom ? 'inner' : 'outer')) // Since both text lines share the same 'd', this class annotation tells where is the text, helping to determine the real arc length 459 | .attr('font-size', function(d) { 460 | return 30 / Math.sqrt(d.depth + 1); 461 | }) 462 | .attr('xlink:href', function(d) { 463 | return '#' + self.getUniqueId(d, 'arc_for_label'); 464 | }); 465 | } 466 | 467 | if (d.depth > 1) { 468 | uid = this.getUniqueId(d, 'arc_for_label_number'); 469 | if (!this._childElements.parts[uid]) { 470 | this._childElements.parts[uid] = g.append('path') 471 | .attr('class', 'arc_for_label_number') 472 | .attr('id', function(d) { 473 | return self.getUniqueId(d, 'arc_for_label_number'); 474 | }) 475 | .style('stroke-opacity', 0) 476 | .style('fill-opacity', 0); 477 | } 478 | 479 | uid = this.getUniqueId(d, 'sector_label_number_path'); 480 | if (!this._childElements.parts[uid]) { 481 | this._childElements.parts[uid] = g.append('text') 482 | .attr('class', 'sector_label_number ') 483 | .attr('visibility', function(d) { 484 | return d.depth === 1 ? 'visible' : null; 485 | }) 486 | .attr('class', 'sector_nonleaf_text') 487 | .append('textPath') 488 | .attr('class', 'sector_label_number_path') 489 | .attr('position-in-sector', bottom ? 'outer' : 'inner') // Since both text lines share the same 'd', this class annotation tells where is the text, helping to determine the real arc length 490 | .attr('font-size', function() { 491 | return 10; 492 | }) 493 | .attr('xlink:href', function(d) { 494 | return '#' + self.getUniqueId(d, 'arc_for_label_number'); 495 | }); 496 | } 497 | } 498 | } 499 | } 500 | } 501 | 502 | module.exports = SunburstWidget; 503 | --------------------------------------------------------------------------------