├── .babelrc ├── .eslintrc ├── .gitignore ├── .npmignore ├── README.md ├── component-kit.png ├── docs ├── AreaChart.md ├── BarChart.md ├── Cards.md ├── FooterNavigation.md ├── LineChart.md ├── Panels.md ├── PieChart.md ├── Platter.md ├── README.md ├── RadarArea.md ├── RadarChart.md ├── Responsive.md ├── ScatterPlot.md ├── Tabs.md ├── XYAxis.md └── docsAssets │ ├── AreaChartExample.png │ ├── BarChartExample.png │ ├── CardExample.png │ ├── DonutChartExample.png │ ├── LineChartExample.png │ ├── PanelsExample.png │ ├── PanelsExampleOpen.png │ ├── PieChartExample.png │ ├── PlatterExample.png │ ├── RadarChartExample.png │ ├── ScatterPlotExample.png │ ├── TabsExample.png │ └── XYAxisExample.png ├── examples ├── .babelrc ├── .eslintrc ├── index.html ├── index.js ├── main.css ├── package.json ├── server.js └── webpack.config.js ├── package.json ├── src ├── index.js ├── layout │ ├── Cards.js │ ├── Chips.js │ ├── FooterNavigation.js │ ├── Navigation.js │ ├── Panels.js │ ├── Platter.js │ ├── Snackbar.js │ ├── Tabs.js │ └── Tooltips.js ├── styles │ └── main.css ├── utils │ ├── Dividends.js │ └── DynamicScales.js └── visualization │ ├── AreaChart.js │ ├── BarChart.js │ ├── Legend.js │ ├── LineChart.js │ ├── PieChart.js │ ├── RadarArea.js │ ├── RadarChart.js │ ├── RadialBarChart.js │ ├── Responsive.js │ ├── ScatterPlot.js │ ├── TreeMap.js │ └── XYAxis.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "mocha": true, 5 | "node": true 6 | }, 7 | "presets": [ 8 | "es2015", 9 | "react" 10 | ], 11 | "plugins": [ 12 | "syntax-jsx" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaFeatures": { 3 | "jsx": true, 4 | "modules": true 5 | }, 6 | "env": { 7 | "browser": true, 8 | "mocha": true, 9 | "node": true, 10 | "es6": true 11 | }, 12 | "parserOptions": { 13 | "sourceType": "module", 14 | "ecmaFeatures": { 15 | "modules": true, 16 | "jsx": true 17 | } 18 | }, 19 | "rules": { 20 | "strict": [2, "never"], 21 | "react/jsx-uses-react": 2, 22 | "react/jsx-uses-vars": 2, 23 | "react/react-in-jsx-scope": 2 24 | }, 25 | "plugins": [ 26 | "react", 27 | "babel" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | .DS_Store 4 | __build__ 5 | dist 6 | coverage 7 | esdoc 8 | barChart 9 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | README.md 2 | examples 3 | docs 4 | component-kit.png 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | > UI-Kit for Rapidly Creating Dashboards 5 | 6 | [![version](https://img.shields.io/npm/v/component-kit.svg?style=flat-square)](http://npm.im/component-kit) 7 | [![downloads](https://img.shields.io/npm/dm/component-kit.svg?style=flat-square)](http://npm-stat.com/charts.html?package=component-kit&from=2016-06-13) 8 | [![MIT License](https://img.shields.io/npm/l/component-kit.svg?style=flat-square)](http://opensource.org/licenses/MIT) 9 | 10 | I made component-kit a project that mixes both UI and Charting Components. This 11 | makes it easier to get a dashboard up and running in a few minutes cake. This Library 12 | allows you to create charts individually as well as compose them together. 13 | 14 | ## How it Works 15 | Component-Kit under the hood is powered by React, D3, and React-Faux-DOM. If 16 | you're interested in knowing why I chose these three to power this library keep 17 | reading, otherwise scroll down to the examples. As I began building this Library 18 | I realized that both React and D3 want to be in charge of rendering and updating 19 | the charting components. I knew I wanted to leverage React's efficient rendering 20 | capabilities, but I also wanted to be able to use D3's rich manipulation and selection 21 | functionality. After researching for a little while I discovered React-Faux-DOM, 22 | a library that provides a light-weight object-like DOM that is bare enough to 23 | support all of D3 API and then can be converted to react elements. This gave me 24 | a few benefits. I get to use D3 like anyone normally would without react. Second, 25 | since react is in charge or rendering and updating the view I don't have to think 26 | about how the charts will react to updates in data, essentially can disregard for 27 | the most part D3's General Update Pattern as React will update them accordingly. 28 | 29 | ## The State of Component-Kit and Whats Next 30 | I've just recently began working on component-kit, so there are a few charting 31 | component that are finished (XYAxis, LineChart, AreaChart, BarChart, PieChart, 32 | RadarChart, ScatterPlot). As of now you can compose the finished charts together 33 | to visualize the same data-set in different ways on the same axes, as well as 34 | compose different data sets on the same axes. What I need to finish is the RadialBarChart, 35 | and TreeMap. Also, I will be adding animation to the charts with `react-motion`. 36 | Most of the Layout components that are included in the library are also finished. 37 | I am also open to taking requests for charts that developers want. Big thanks to @alaingalvan for creating the logo and brand. 38 | 39 | ## Install 40 | ```bash 41 | npm install --save component-kit 42 | ``` 43 | 44 | ## examples 45 | Make sure to import the styles for the UI/Layout Portion of `component-kit`. The charting 46 | part of `component-kit` doesn't require the css, but the layout components require it to render properly. 47 | It is essentially just Bootstraps grid system. So if you have bootstrap already on your project 48 | you don't need the css from `component-kit`. 49 | ```html 50 | 51 | ``` 52 | ```js 53 | import { 54 | XYAxis, 55 | LineChart, 56 | AreaChart, 57 | BarChart, 58 | PieChart 59 | } from 'component-kit'; 60 | 61 | var data = [ 62 | {x: 5, y: 63584, l: 62573, a: 62573}, 63 | {x: 10, y: 42839, l: 31729, a: 51729}, 64 | {x: 12, y: 35894, l: 24783, a: 41729}, 65 | {x: 18, y: 58934, l: 47823, a: 31729}, 66 | {x: 25, y: 74323, l: 64312, a: 21729}, 67 | {x: 30, y: 24839, l: 23728, a: 11729}, 68 | {x: 50, y: 12839, l: 12849, a: 31929} 69 | ]; 70 | 71 | // composed Chart 72 | 79 | 80 | 81 | 82 | 83 | var data2 = [ 84 | {x: 5, y: 63584}, 85 | {x: 10, y: 42839}, 86 | {x: 12, y: 35894}, 87 | {x: 18, y: 58934}, 88 | {x: 25, y: 74323}, 89 | {x: 30, y: 24839}, 90 | {x: 50, y: 12839} 91 | ]; 92 | 93 | //Filled PieChart 94 | 100 | //Unfilled center PieChart "Donut Chart" 101 | 108 | var data3 = [ 109 | {x: 'Kennet', y: 18}, 110 | {x: 'Jon', y: 12}, 111 | {x: 'David', y: 16}, 112 | {x: 'Simon', y: 8}, 113 | {x: 'Kendri', y: 20}, 114 | {x: 'SomeGuy', y: 2}, 115 | ]; 116 | 117 | 124 | 125 | 126 | ``` 127 | ## License 128 | MIT 129 | -------------------------------------------------------------------------------- /component-kit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/component-kit.png -------------------------------------------------------------------------------- /docs/AreaChart.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component Renders graphically quantitative data. 4 | 5 | ### Props 6 | 7 | #### `width || ` 8 | The width you want to set the chart too. If used within [``](XYAxis.md) you don't set this prop as `` will pass down it's width. 9 | 10 | #### `height || ` 11 | The height you want to set the chart too. If used within [``](XYAxis.md) you don't set this prop as `` will pass down it's height. 12 | 13 | #### `data ` 14 | The data you want to the chart to use. If used within [``](XYAxis.md) you don't set this prop as `` will pass down the data. 15 | 16 | #### `dataKey || ` 17 | A key on the `data` prop for which to use to draw the `AreaChart`. This prop has to be set. if not set it will default to the `yDataKey` on the ``. 18 | 19 | #### `color ` 20 | The color that you want the AreaChart to have. 21 | 22 | #### `colorOpacity ` 23 | The opacity you want to AreaChart to have. 24 | 25 | ### Examples 26 | 27 | ```js 28 | var data = [ 29 | {x: 5, y: 63584, c: 62573}, 30 | {x: 10, y: 42839, c: 31729}, 31 | {x: 12, y: 35894, c: 24783}, 32 | {x: 18, y: 58934, c: 47823}, 33 | {x: 25, y: 74323, c: 64312}, 34 | {x: 30, y: 24839, c: 23728}, 35 | {x: 50, y: 12839, c: 12849} 36 | ]; 37 | 38 | 47 | 48 | 49 | 50 | ``` 51 |

Sample AreaChart

52 |

53 | 54 |

55 | -------------------------------------------------------------------------------- /docs/BarChart.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component Renders vertical bars to show comparisons among categories. 4 | 5 | ### Props 6 | 7 | #### `width || ` 8 | The width you want to set the chart too. If used within [``](XYAxis.md) you don't set this prop as `` will pass down it's width. 9 | 10 | #### `height || ` 11 | The height you want to set the chart too. If used within [``](XYAxis.md) you don't set this prop as `` will pass down it's height. 12 | 13 | #### `data ` 14 | The data you want to the chart to use. If used within [``](XYAxis.md) you don't set this prop as `` will pass down the data. 15 | 16 | #### `dataKey || ` 17 | A key on the `data` prop for which to use to draw the `BarChart`. This prop has to be set. if not set it will default to the `yDataKey` on the ``. 18 | 19 | #### `color ` 20 | The color that you want the BarChart to have. 21 | 22 | #### `colorOpacity || ` 23 | The opacity you want to BarChart to have. 24 | 25 | ### Examples 26 | ```js 27 | var data = [ 28 | {x: 'Kennet', y: 18}, 29 | {x: 'Jon', y: 12}, 30 | {x: 'David', y: 16}, 31 | {x: 'Simon', y: 8}, 32 | {x: 'Kendri', y: 20}, 33 | {x: 'SomeGuy', y: 2}, 34 | ]; 35 | 36 | 41 | 42 | 43 | ``` 44 |

Sample BarChart

45 |

46 | 47 |

48 | -------------------------------------------------------------------------------- /docs/Cards.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component renders a card that may take in a chart followed by some descriptions and optionally links. 4 | 5 | ### Props 6 | 7 | #### `imgURI ` 8 | The imgURI to pass for the Card. 9 | 10 | #### `width || ` 11 | The width you want to set the card too. 12 | 13 | #### `height || ` 14 | The height you want to set the card too. 15 | 16 | #### `imgWidth || ` 17 | The width you want the imgWidth too. 18 | 19 | #### `imgHeight || ` 20 | The height you want the imgHeight too. 21 | 22 | #### `header ` 23 | The header(title) for the Cards 24 | 25 | #### `detail ` 26 | The detail you want to give the Cards. 27 | 28 | #### `links ` 29 | An array of objects that has to have the shape of 30 | ```js 31 | { 32 | link: 33 | title: 34 | } 35 | ``` 36 | 37 | #### `linkColor ` 38 | The color you want the link to be. 39 | 40 | #### `graph ` 41 | Optional parameter to place one of the graphs (Line, Area, etc.) in place of an img. 42 | 43 | ### Examples 44 | ```js 45 | 51 | 52 | 53 | } 54 | width='100%' 55 | height={450} 56 | header="Lonely Radar Chart" 57 | detail="Representation of some data that is important and relevant to the world 2..." 58 | links={[ 59 | { 60 | href: 'http://google.com', 61 | title: 'google' 62 | }, 63 | { 64 | href: 'http://facebook.com', 65 | title: 'facebook' 66 | } 67 | ]}> 68 | 69 | ``` 70 |

Sample Card

71 |

72 | 73 |

74 | -------------------------------------------------------------------------------- /docs/FooterNavigation.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component renders a navigation at the footer of the page. Lets you navigate between Dashboards. 4 | 5 | ### Props 6 | 7 | #### `Views ` 8 | The array should be an array of objects in the shape of: 9 | ```js 10 | { 11 | link: , 12 | icon: , 13 | title: 14 | } 15 | ``` 16 | 17 | #### `height || ` 18 | The height you want the FooterNavigation to be. 19 | -------------------------------------------------------------------------------- /docs/LineChart.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component Renders a series of data points connected by straight line segments. 4 | 5 | ### Props 6 | 7 | #### `width || ` 8 | The width you want to set the chart too. If used within [``](XYAxis.md) you don't set this prop as `` will pass down it's width. 9 | 10 | #### `height || ` 11 | The height you want to set the chart too. If used within [``](XYAxis.md) you don't set this prop as `` will pass down it's height. 12 | 13 | #### `data ` 14 | The data you want to the chart to use. If used within [``](XYAxis.md) you don't set this prop as `` will pass down the data. 15 | 16 | #### `dataKey || ` 17 | A key on the `data` prop for which to use to draw the `LineChart`. This prop has to be set. if not set it will default to the `yDataKey` on the ``. 18 | 19 | #### `color ` 20 | The color that you want the Lines of the LineChart to have. 21 | 22 | #### `pointColor ` 23 | The color that you want the Points on the LineChart to have. 24 | 25 | #### `pointBorderColor ` 26 | The color that you want the Points border on the LineChart to have. 27 | 28 | ### Examples 29 | ```js 30 | var data = [ 31 | {x: 5, y: 63584}, 32 | {x: 10, y: 42839}, 33 | {x: 12, y: 35894}, 34 | {x: 18, y: 58934}, 35 | {x: 25, y: 74323}, 36 | {x: 30, y: 24839}, 37 | {x: 50, y: 12839} 38 | ]; 39 | 40 | 53 | 54 | 55 | ``` 56 |

Sample LineChart

57 |

58 | 59 |

60 | -------------------------------------------------------------------------------- /docs/Panels.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component renders a slim rectangle with a title. When toggled displays content. 4 | 5 | ### Props 6 | 7 | #### `width || ` 8 | The width you want the Panels to be. 9 | 10 | #### `height || ` 11 | The height you want the Panels to be. 12 | 13 | #### `Title ` 14 | The title you want the Panels React Element to be. 15 | 16 | ### Examples 17 | ```js 18 | 19 | 32 | 33 | 34 | 35 | ``` 36 |

Sample Panels

37 |

38 | 39 |

40 |

41 | 42 |

43 | -------------------------------------------------------------------------------- /docs/PieChart.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component Renders a circle is divided into sectors that each represent a proportion of the whole. (set it to Donut chart by passing in donut prop) 4 | 5 | ### Props 6 | 7 | #### `width || ` 8 | The width you want to set the chart too. If used within [``](XYAxis.md) you don't set this prop as `` will pass down it's width. 9 | 10 | #### `height || ` 11 | The height you want to set the chart too. If used within [``](XYAxis.md) you don't set this prop as `` will pass down it's height. 12 | 13 | #### `radius ` 14 | a straight line from the center to the circumference of a circle. 15 | 16 | #### `data ` 17 | The data you want to the chart to use. If used within [``](XYAxis.md) you don't set this prop as `` will pass down the data. 18 | 19 | #### `dataKey || ` 20 | A key on the `data` prop for which to use to draw the `PieChart`. This prop has to be set. if not set it will default to the `yDataKey` on the ``. 21 | 22 | #### `labelKey || ` 23 | A key on the `data` prop for which to use to label the slices of the `PieChart`. This prop has to be set. if not set it will default to the `xDataKey` on the ``. 24 | 25 | #### `colors ` 26 | The color that you want the points of the ScatterPlot to have. 27 | 28 | #### `textColor ` 29 | The color you want the text on the `PieChart` to be. 30 | 31 | #### `donut ` 32 | This property is used to turn the PieChart into a donut chart. It takes a number and should be at least 2.5 or larger to make the center of the chart unfill. 33 | 34 | ### Examples 35 | ```js 36 | var data = [ 37 | {x: 5, y: 63584}, 38 | {x: 10, y: 42839}, 39 | {x: 12, y: 35894}, 40 | {x: 18, y: 58934}, 41 | {x: 25, y: 74323}, 42 | {x: 30, y: 24839}, 43 | {x: 50, y: 12839} 44 | ]; 45 | 46 | var color = [ 47 | "#e1eef6","#ff5f2e","#fcbe32","#004e66","#ff7473","#ffc952","#47b8e0", 48 | "#34314c","#47b8e0","#47b8e0", 49 | ]; 50 | 51 | //Pie 52 | 59 | //Donut 60 | 69 | ``` 70 |

Sample PieChart

71 |

72 | 73 |

74 |

Sample PieChart (Donut)

75 |

76 | 77 |

78 | -------------------------------------------------------------------------------- /docs/Platter.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component renders a rectangle with a nice shadow to that takes in a chart and provides contrast from background. 4 | 5 | ### Props 6 | 7 | #### `width || ` 8 | The width you want the Platter to be. 9 | 10 | #### `height || ` 11 | The height you want the Platter to be. 12 | 13 | #### `backgroundColor ` 14 | The backgroundColor you want the `` to be. Keep in mind this can be 15 | set with a class/className on the Platter element. 16 | 17 | ### Examples 18 | ```js 19 | 20 | 27 | 28 | 29 | 30 | 31 | ``` 32 |

Sample Platter

33 |

34 | 35 |

36 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Component-Kit is a powerful charting library that combines UI-Components and 4 | Charting Components. It aids in rapidly creating data driven dashboards. 5 | 6 | Charting Components: 7 | + __[``](XYAxis.md)__ - Component Renders XY Axis, as well as optionally a grid. 8 | + __[``](AreaChart.md)__ - Component Renders graphically quantitative data. 9 | + __[``](LineChart.md)__ - Component Renders a series of data points connected by straight line segments. 10 | + __[``](BarChart.md)__ - Component Renders vertical bars to show comparisons among categories. 11 | + __[``](ScatterPlot.md)__ - Component Renders a plot based on one or many datasets. 12 | + __[``](PieChart.md)__ - Component Renders a circle is divided into sectors that each represent a proportion of the whole. (set it to Donut chart by passing in donut prop) 13 | + __[``](RadarChart.md)__ - Component Renders a sequence of equi-angular spokes called radii with an overlayed area ([``](RadarArea.md)) to provide comparisons of the dataset. 14 | 15 | Utility Component: 16 | + __[``](Responsive.md)__ - Component Wraps Charting Components and makes them Responsive and Mobile-Friendly. 17 | 18 | Charts Coming soon: 19 | + __``__ 20 | + __``__ 21 | 22 | UI Components: 23 | + __[``](Cards.md)__ - Component renders a card that may take in a chart followed by some descriptions and optionally links. 24 | + __[``](FooterNavigation.md)__ - Component renders a navigation at the footer of the page. Lets you navigate between Dashboards. 25 | + __[``](Platter.md)__ - Component renders a rectangle with a nice shadow to that takes in a chart and provides contrast from background. 26 | + __[``](Panels.md)__ - Component renders a slim rectangle with a title. When toggled displays content. 27 | + __[``](Tabs.md)__ - Component renders tabs that represent what content to show based on the active tab. 28 | 29 | UI Component Coming soon: 30 | + __``__ 31 | + __``__ 32 | + __``__ 33 | -------------------------------------------------------------------------------- /docs/RadarArea.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | This component Renders the layers on top of the RadarChart. 4 | 5 | ### Props 6 | 7 | #### `dataKey || ` 8 | A key on the `data` prop for which to use to determine how much of the RadarChart to cover. 9 | 10 | #### `color ` 11 | The color that you want the RadarArea to have. 12 | 13 | #### `colorOpacity ` 14 | The opacity you want the RadarArea to have. 15 | 16 | ### Examples 17 | See [RadarChart for Usage](RadarArea.md) 18 | -------------------------------------------------------------------------------- /docs/RadarChart.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component Renders a sequence of equi-angular spokes called radii with an overlayed area(([``](RadarArea.md)) to provide comparisons of the dataset. 4 | 5 | ### Props 6 | 7 | #### `width || ` 8 | The width you want to set the chart too. 9 | 10 | #### `height || ` 11 | The height you want to set the chart too. 12 | 13 | #### `data ` 14 | The data you want to the chart to use. 15 | 16 | #### `rangeKey || ` 17 | A key on the `data` prop for which to use to draw the `RadarChart`. This prop has to be set. 18 | 19 | #### `labelKey || ` 20 | A key on the `data` prop for which to use to label the slices of the `RadarChart`. This prop has to be set. 21 | 22 | ### Examples 23 | ```js 24 | var data5 = [ 25 | { "skill": "field", y: 16, k1: 10, k2: 20 }, 26 | { "skill": "field1", y: 10, k1: 12, k2: 22 }, 27 | { "skill": "field2", y: 10, k1: 13, k2: 9 }, 28 | { "skill": "field3", y: 11, k1: 14, k2: 16 }, 29 | { "skill": "field4", y: 15, k1: 15, k2: 19 }, 30 | { "skill": "field5", y: 22, k1: 16, k2: 22 } 31 | ]; 32 | 33 | 38 | 39 | 40 | 41 | ``` 42 |

Sample RadarChart

43 |

44 | 45 |

46 | -------------------------------------------------------------------------------- /docs/Responsive.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component Wraps Charting Components and makes them Responsive and Mobile-Friendly. 4 | 5 | ### Props 6 | 7 | #### `width || ` 8 | The initial width of the content you want to display. 9 | 10 | #### `height || ` 11 | The initial height of the content you want to display. 12 | 13 | ### Examples 14 | ```js 15 | 16 | 21 | 22 | 23 | 24 | 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/ScatterPlot.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component Renders a plot based on one or many datasets. 4 | 5 | ### Props 6 | 7 | #### `width || ` 8 | The width you want to set the chart too. If used within [``](XYAxis.md) you don't set this prop as `` will pass down it's width. 9 | 10 | #### `height || ` 11 | The height you want to set the chart too. If used within [``](XYAxis.md) you don't set this prop as `` will pass down it's height. 12 | 13 | #### `data ` 14 | The data you want to the chart to use. If used within [``](XYAxis.md) you don't set this prop as `` will pass down the data. 15 | 16 | #### `dataKey || ` 17 | A key on the `data` prop for which to use to draw the `ScatterPlot`. This prop has to be set. if not set it will default to the `yDataKey` on the ``. 18 | 19 | #### `scatterKey || ` 20 | ScatterPlot's can be used to display lots of data on one plane. Sometimes its to see how groups of data are different from each other, and other times to see how one group of data fluctuates. scatterKey is optional but should be used for differentiating between 2 groups of data. i.e. the percentage of people who prefer dessert over dinner and scatterKey would be 'desert' and 'dinner' each of which would have their own color to differentiate. 21 | 22 | #### `pointRadius ` 23 | The radius that you want the Points on the ScatterPlot to have. 24 | 25 | #### `colors ` 26 | The color that you want the points of the ScatterPlot to have. 27 | 28 | ### Examples 29 | ```js 30 | var data = [ 31 | {x: 5, y: 63584, c: 62573}, 32 | {x: 10, y: 42839, c: 31729}, 33 | {x: 12, y: 35894, c: 24783}, 34 | {x: 18, y: 58934, c: 47823}, 35 | {x: 25, y: 74323, c: 64312}, 36 | {x: 30, y: 24839, c: 23728}, 37 | {x: 50, y: 12839, c: 12849} 38 | ]; 39 | 40 | 47 | 50 | 51 | ``` 52 |

Sample ScatterPlot

53 |

54 | 55 |

56 | -------------------------------------------------------------------------------- /docs/Tabs.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component renders tabs that represent what content to show based on the active tab. 4 | 5 | ### Props 6 | 7 | #### `width || ` 8 | The width you want to set the Tabs too. 9 | 10 | #### `height || ` 11 | The height you want to set the Tabs too. 12 | 13 | #### `backgroundColor ` 14 | The backgroundColor you want the Tabs to be. However you can also add styles by adding a class/className to the Tabs component. 15 | 16 | #### `tabColor ` 17 | The color you want the "Active" tab that is showing content to be. 18 | 19 | #### `tabs ` 20 | The number of tabs you want the `` component to have. 21 | ```js 22 | { 23 | title: , 24 | Component 25 | } 26 | ``` 27 | 28 | ### Examples 29 | ```js 30 | 42 | }, 43 | { 44 | title: 'Scatter Plot', 45 | component: 52 | 54 | 55 | }, 56 | { 57 | title: 'Composed', 58 | component: 65 | 66 | 67 | 68 | } 69 | ]} 70 | /> 71 | ``` 72 |

Sample Tabs

73 |

74 | 75 |

76 | -------------------------------------------------------------------------------- /docs/XYAxis.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | Component Renders XY Axis, as well as optionally a grid. 4 | 5 | ### Props 6 | 7 | #### `xyConfig` 8 | The xyConfig is an optional prop on the component, it should be used if you don't want to have a bunch or different props but rather just on prop that takes in an object config. 9 | 10 | #### `width` 11 | Takes in a number as the width that you want to set the XYAxis too. 12 | 13 | #### `height` 14 | Takes in a number as the height you want to set the XYAxis too 15 | 16 | #### `data` 17 | The data the XYAxis will consume to create the scales of the Axis 18 | 19 | #### `xDataKey` 20 | Takes in a number or a string as the field on the `data` prop to use to populate the xAxis scale 21 | 22 | #### `yDataKey` 23 | takes in a number or a string as the field on the `data` prop to use to populate the yAxis scale 24 | 25 | #### `defaultOrdinal` 26 | Say you pass in numbers for a scale, by default they will be treated as a linear scale. However say there are to represent years the XYAxis 27 | will show it as `2,009 2,010 etc.` when you really want it to be shown as `2009 2010 etc.` this prop takes in one of the following options: 28 | `x`, `y`, `xy` as the value of the prop. This means if you pass in `x` 29 | the x-axis will be treated as an ordinal scale even if it is numbers. 30 | 31 | #### `xTicks` 32 | Takes in a number as The number of ticks to show on the xAxis 33 | 34 | #### `yTicks` 35 | Takes in a number as The number of ticks to show on the yAxis 36 | 37 | #### `xLabel` 38 | Takes in a String for what you want to label the `xAxis`. 39 | 40 | #### `yLabel` 41 | Takes in a String for what you want to label the `yAxis`. 42 | 43 | #### `grid` 44 | Takes in either `true` or `false`, if you pass in `true` then it will 45 | draw grid lines. Otherwise it won't 46 | 47 | #### `gridLines` 48 | Takes in either `solid` or `dashed`, if solid the grid lines will be solid, if you pass in dashed the grid lines will be dashed. 49 | 50 | ### Examples 51 | ```js 52 | //Without xyConfig 53 | 66 | ... // the child chart component 67 | 68 | 69 | //With xyConfig 70 | 85 | ... // the child chart component 86 | 87 | 88 | //With A chart 89 | 102 | 103 | 104 | ``` 105 |

Sample XYAxis

106 |

107 | 108 |

109 | -------------------------------------------------------------------------------- /docs/docsAssets/AreaChartExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/AreaChartExample.png -------------------------------------------------------------------------------- /docs/docsAssets/BarChartExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/BarChartExample.png -------------------------------------------------------------------------------- /docs/docsAssets/CardExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/CardExample.png -------------------------------------------------------------------------------- /docs/docsAssets/DonutChartExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/DonutChartExample.png -------------------------------------------------------------------------------- /docs/docsAssets/LineChartExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/LineChartExample.png -------------------------------------------------------------------------------- /docs/docsAssets/PanelsExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/PanelsExample.png -------------------------------------------------------------------------------- /docs/docsAssets/PanelsExampleOpen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/PanelsExampleOpen.png -------------------------------------------------------------------------------- /docs/docsAssets/PieChartExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/PieChartExample.png -------------------------------------------------------------------------------- /docs/docsAssets/PlatterExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/PlatterExample.png -------------------------------------------------------------------------------- /docs/docsAssets/RadarChartExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/RadarChartExample.png -------------------------------------------------------------------------------- /docs/docsAssets/ScatterPlotExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/ScatterPlotExample.png -------------------------------------------------------------------------------- /docs/docsAssets/TabsExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/TabsExample.png -------------------------------------------------------------------------------- /docs/docsAssets/XYAxisExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennetpostigo/component-kit/b9ae3c0b618630ffafff68b4fa34eb2c3d1368ff/docs/docsAssets/XYAxisExample.png -------------------------------------------------------------------------------- /examples/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "mocha": true, 5 | "node": true 6 | }, 7 | "presets": [ 8 | "es2015", 9 | "react" 10 | ], 11 | "plugins": [ 12 | "syntax-jsx" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /examples/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaFeatures": { 3 | "jsx": true, 4 | "modules": true 5 | }, 6 | "env": { 7 | "browser": true, 8 | "mocha": true, 9 | "node": true, 10 | "es6": true 11 | }, 12 | "parserOptions": { 13 | "sourceType": "module", 14 | "ecmaFeatures": { 15 | "modules": true, 16 | "jsx": true 17 | } 18 | }, 19 | "rules": { 20 | "strict": [2, "never"], 21 | "react/jsx-uses-react": 2, 22 | "react/jsx-uses-vars": 2, 23 | "react/react-in-jsx-scope": 2 24 | }, 25 | "plugins": [ 26 | "react", 27 | "babel" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Examples 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render } from 'react-dom'; 3 | import { 4 | Cards, 5 | Panels, 6 | Platter, 7 | FooterNavigation, 8 | Tabs, 9 | XYAxis, 10 | Legend, 11 | BarChart, 12 | AreaChart, 13 | LineChart, 14 | PieChart, 15 | ScatterPlot, 16 | TreeMap, 17 | RadarChart, 18 | RadarArea, 19 | RadialBarChart, 20 | Responsive 21 | } from './../dist/component-kit.js'; 22 | 23 | var data = [ 24 | {x: 'Kennet', y: 18}, 25 | {x: 'Jon', y: 12}, 26 | {x: 'David', y: 16}, 27 | {x: 'Simon', y: 8}, 28 | {x: 'Kendri', y: 20}, 29 | {x: 'SomeGuy', y: 2}, 30 | ]; 31 | var datay = [ 32 | {x: 1, y: 'a'}, 33 | {x: 2, y: 'b'}, 34 | {x: 3, y: 'c'}, 35 | {x: 4, y: 'd'}, 36 | {x: 5, y: 'e'}, 37 | {x: 6, y: 'f'}, 38 | {x: 7, y: 'g'}, 39 | {x: 8, y: 'h'}, 40 | {x: 9, y: 'i'}, 41 | {x: 10, y: 'j'}, 42 | {x: 11, y: 'k'}, 43 | {x: 12, y: 'l'}, 44 | {x: 13, y: 'm'}, 45 | {x: 14, y: 'n'}, 46 | {x: 15, y: 'o'}, 47 | {x: 16, y: 'p'} 48 | ]; 49 | var data2 = [ 50 | {x: 'A', y: 20}, 51 | {x: 'B', y: 0}, 52 | {x: 'C', y: 30}, 53 | {x: 'D', y: 45}, 54 | {x: 'E', y: 46}, 55 | {x: 'F', y: 37}, 56 | {x: 'G', y: 20}, 57 | {x: 'H', y: 15}, 58 | {x: 'I', y: 30}, 59 | {x: 'J', y: 11}, 60 | {x: 'K', y: 12}, 61 | {x: 'L', y: 22}, 62 | {x: 'M', y: 23}, 63 | {x: 'N', y: 33}, 64 | {x: 'O', y: 30}, 65 | {x: 'P', y: 44}, 66 | {x: 'Q', y: 40}, 67 | {x: 'R', y: 55}, 68 | {x: 'S', y: 50}, 69 | {x: 'T', y: 66}, 70 | {x: 'U', y: 60}, 71 | {x: 'V', y: 75}, 72 | {x: 'W', y: 70}, 73 | {x: 'X', y: 80}, 74 | {x: 'Y', y: 60}, 75 | {x: 'Z', y: 40}, 76 | {x: 'AA', y: 100}, 77 | {x: 'BB', y: 92}, 78 | {x: 'CC', y: 32}, 79 | {x: 'DD', y: 72}, 80 | {x: 'EE', y: 74}, 81 | ]; 82 | var data3 = [ 83 | {x: 5, y: 63584}, 84 | {x: 10, y: 42839}, 85 | {x: 12, y: 35894}, 86 | {x: 18, y: 58934}, 87 | {x: 25, y: 74323}, 88 | {x: 30, y: 24839}, 89 | {x: 50, y: 12839} 90 | ]; 91 | var data3Check = [ 92 | {xShit: 5, yShit: 63584, cShit: 62573, lShit: 62573, aShit: 62573}, 93 | {xShit: 10, yShit: 42839, cShit: 31729, lShit: 31729, aShit: 51729}, 94 | {xShit: 12, yShit: 35894, cShit: 24783, lShit: 24783, aShit: 41729}, 95 | {xShit: 18, yShit: 58934, cShit: 47823, lShit: 47823, aShit: 31729}, 96 | {xShit: 25, yShit: 74323, cShit: 64312, lShit: 64312, aShit: 21729}, 97 | {xShit: 30, yShit: 24839, cShit: 23728, lShit: 23728, aShit: 11729}, 98 | {xShit: 50, yShit: 12839, cShit: 12849, lShit: 12849, aShit: 31929} 99 | ]; 100 | var data4Check = [ 101 | {xShit: 5, yShit: 63584, cShit: 62573, lShit: 62573, tshit: 'k1', uShit: 't1'}, 102 | {xShit: 10, yShit: 42839, cShit: 31729, lShit: 51729, tshit: 'k2', uShit: 't2'}, 103 | {xShit: 12, yShit: 35894, cShit: 24783, lShit: 41729, tshit: 'k3', uShit: 't3'}, 104 | {xShit: 18, yShit: 58934, cShit: 47823, lShit: 31729, tshit: 'k4', uShit: 't4'}, 105 | {xShit: 25, yShit: 74323, cShit: 64312, lShit: 21729, tshit: 'k5', uShit: 't5'}, 106 | {xShit: 30, yShit: 24839, cShit: 23728, lShit: 11729, tshit: 'k6', uShit: 't6'}, 107 | {xShit: 50, yShit: 12839, cShit: 12849, lShit: 31929, tshit: 'k7', uShit: 't7'} 108 | ]; 109 | var color = [ 110 | "#e1eef6","#ff5f2e","#fcbe32","#004e66","#ff7473","#ffc952","#47b8e0", 111 | "#34314c","#47b8e0","#47b8e0", 112 | ]; 113 | var data4 = [ 114 | {x: 2001, y: 0, t: 'k1'}, 115 | {x: 2002, y: 30, t: 'k2'}, 116 | {x: 2003, y: 45, t: 'k3'}, 117 | {x: 2004, y: 46, t: 'k1'}, 118 | {x: 2005, y: 37, t: 'k1'}, 119 | {x: 2006, y: 20, t: 'k2'}, 120 | {x: 2007, y: 15, t: 'k2'}, 121 | {x: 2008, y: 30, t: 'k3'} 122 | ]; 123 | var dataRB = [ 124 | {religion: 'Christian', population: 2173100000}, 125 | {religion: 'Muslim', population: 1598360000}, 126 | {religion: 'Unaffiliated', population: 1126280000}, 127 | {religion: 'Hindu', population: 1032860000}, 128 | {religion: 'Buddhist', population: 487320000}, 129 | {religion: 'Folk Religions', population: 404890000}, 130 | {religion: 'Other Religions', population: 57770000}, 131 | {religion: 'Jewish', population: 173100000}, 132 | ]; 133 | var data5 = [ 134 | { "skill": "field", y: 16, k1: 10, k2: 20 }, 135 | { "skill": "field1", y: 10, k1: 12, k2: 22 }, 136 | { "skill": "field2", y: 10, k1: 13, k2: 9 }, 137 | { "skill": "field3", y: 11, k1: 14, k2: 16 }, 138 | { "skill": "field4", y: 15, k1: 15, k2: 19 }, 139 | { "skill": "field5", y: 22, k1: 16, k2: 22 } 140 | ]; 141 | 142 | var treeMapData = { 143 | "name": "flare", 144 | "children": [ 145 | { 146 | "name": "analytics", 147 | "children": [ 148 | { 149 | "name": "cluster", 150 | "children": [ 151 | {"name": "AgglomerativeCluster", "size": 3938}, 152 | {"name": "CommunityStructure", "size": 3812}, 153 | {"name": "HierarchicalCluster", "size": 6714}, 154 | {"name": "MergeEdge", "size": 743} 155 | ] 156 | }, 157 | { 158 | "name": "graph", 159 | "children": [ 160 | {"name": "BetweennessCentrality", "size": 3534}, 161 | {"name": "LinkDistance", "size": 5731}, 162 | {"name": "MaxFlowMinCut", "size": 7840}, 163 | {"name": "ShortestPaths", "size": 5914}, 164 | {"name": "SpanningTree", "size": 3416} 165 | ] 166 | }, 167 | { 168 | "name": "optimization", 169 | "children": [ 170 | {"name": "AspectRatioBanker", "size": 7074} 171 | ] 172 | } 173 | ] 174 | }, 175 | { 176 | "name": "animate", 177 | "children": [ 178 | {"name": "Easing", "size": 17010}, 179 | {"name": "FunctionSequence", "size": 5842}, 180 | { 181 | "name": "interpolate", 182 | "children": [ 183 | {"name": "ArrayInterpolator", "size": 1983}, 184 | {"name": "ColorInterpolator", "size": 2047}, 185 | {"name": "DateInterpolator", "size": 1375}, 186 | {"name": "Interpolator", "size": 8746}, 187 | {"name": "MatrixInterpolator", "size": 2202}, 188 | {"name": "NumberInterpolator", "size": 1382}, 189 | {"name": "ObjectInterpolator", "size": 1629}, 190 | {"name": "PointInterpolator", "size": 1675}, 191 | {"name": "RectangleInterpolator", "size": 2042} 192 | ] 193 | }, 194 | {"name": "ISchedulable", "size": 1041}, 195 | {"name": "Parallel", "size": 5176}, 196 | {"name": "Pause", "size": 449}, 197 | {"name": "Scheduler", "size": 5593}, 198 | {"name": "Sequence", "size": 5534}, 199 | {"name": "Transition", "size": 9201}, 200 | {"name": "Transitioner", "size": 19975}, 201 | {"name": "TransitionEvent", "size": 1116}, 202 | {"name": "Tween", "size": 6006} 203 | ] 204 | }, 205 | { 206 | "name": "data", 207 | "children": [ 208 | { 209 | "name": "converters", 210 | "children": [ 211 | {"name": "Converters", "size": 721}, 212 | {"name": "DelimitedTextConverter", "size": 4294}, 213 | {"name": "GraphMLConverter", "size": 9800}, 214 | {"name": "IDataConverter", "size": 1314}, 215 | {"name": "JSONConverter", "size": 2220} 216 | ] 217 | }, 218 | {"name": "DataField", "size": 1759}, 219 | {"name": "DataSchema", "size": 2165}, 220 | {"name": "DataSet", "size": 586}, 221 | {"name": "DataSource", "size": 3331}, 222 | {"name": "DataTable", "size": 772}, 223 | {"name": "DataUtil", "size": 3322} 224 | ] 225 | }, 226 | { 227 | "name": "display", 228 | "children": [ 229 | {"name": "DirtySprite", "size": 8833}, 230 | {"name": "LineSprite", "size": 1732}, 231 | {"name": "RectSprite", "size": 3623}, 232 | {"name": "TextSprite", "size": 10066} 233 | ] 234 | }, 235 | { 236 | "name": "flex", 237 | "children": [ 238 | {"name": "FlareVis", "size": 4116} 239 | ] 240 | }, 241 | { 242 | "name": "physics", 243 | "children": [ 244 | {"name": "DragForce", "size": 1082}, 245 | {"name": "GravityForce", "size": 1336}, 246 | {"name": "IForce", "size": 319}, 247 | {"name": "NBodyForce", "size": 10498}, 248 | {"name": "Particle", "size": 2822}, 249 | {"name": "Simulation", "size": 9983}, 250 | {"name": "Spring", "size": 2213}, 251 | {"name": "SpringForce", "size": 1681} 252 | ] 253 | } 254 | ] 255 | }; 256 | 257 | function App (props) { 258 | return ( 259 |
260 |
261 |
262 |
263 | 264 | 277 | 278 | 279 | 280 |
281 |
282 | 283 | 292 | 293 | 294 | 295 |
296 |
297 | 298 | 299 | 304 | 305 | 306 | 307 | 308 |
309 |
310 |
311 |
312 | 313 | 314 | 319 | 320 | 321 | 322 | 323 | 324 |
325 |
326 | 327 | 328 | 335 | 336 | 337 |
338 |
339 |
340 |
341 | 353 | }, 354 | { 355 | title: 'Scatter Plot', 356 | component: 363 | 366 | 367 | }, 368 | { 369 | title: 'Composed', 370 | component: 377 | 378 | 379 | 380 | } 381 | ]} 382 | /> 383 |
384 |
385 | 391 | 392 | 393 | 394 | } 395 | width='100%' 396 | height={450} 397 | header="Composed Radar Chart" 398 | detail="Representation of some data that is important and relevant to the world..." 399 | links={[ 400 | { 401 | href: 'http://google.com', 402 | title: 'google' 403 | }, 404 | { 405 | href: 'http://facebook.com', 406 | title: 'facebook' 407 | } 408 | ]}> 409 | 410 |
411 |
412 | 418 | 419 | 420 | } 421 | width='100%' 422 | height={450} 423 | header="Lonely Radar Chart" 424 | detail="Representation of some data that is important and relevant to the world 2..." 425 | links={[ 426 | { 427 | href: 'http://google.com', 428 | title: 'google' 429 | }, 430 | { 431 | href: 'http://facebook.com', 432 | title: 'facebook' 433 | } 434 | ]}> 435 | 436 |
437 |
438 |
439 |
440 | ); 441 | } 442 | render(, document.getElementById('app')); 443 | -------------------------------------------------------------------------------- /examples/main.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-family: sans-serif; 3 | -ms-text-size-adjust: 100%; 4 | -webkit-text-size-adjust: 100%; 5 | } 6 | body { 7 | margin: 0; 8 | } 9 | article, 10 | aside, 11 | details, 12 | figcaption, 13 | figure, 14 | footer, 15 | header, 16 | hgroup, 17 | main, 18 | menu, 19 | nav, 20 | section, 21 | summary { 22 | display: block; 23 | } 24 | audio, 25 | canvas, 26 | progress, 27 | video { 28 | display: inline-block; 29 | vertical-align: baseline; 30 | } 31 | audio:not([controls]) { 32 | display: none; 33 | height: 0; 34 | } 35 | [hidden], 36 | template { 37 | display: none; 38 | } 39 | a { 40 | background-color: transparent; 41 | } 42 | a:active, 43 | a:hover { 44 | outline: 0; 45 | } 46 | abbr[title] { 47 | border-bottom: 1px dotted; 48 | } 49 | b, 50 | strong { 51 | font-weight: bold; 52 | } 53 | dfn { 54 | font-style: italic; 55 | } 56 | h1 { 57 | font-size: 2em; 58 | margin: 0.67em 0; 59 | } 60 | mark { 61 | background: #ff0; 62 | color: #000; 63 | } 64 | small { 65 | font-size: 80%; 66 | } 67 | sub, 68 | sup { 69 | font-size: 75%; 70 | line-height: 0; 71 | position: relative; 72 | vertical-align: baseline; 73 | } 74 | sup { 75 | top: -0.5em; 76 | } 77 | sub { 78 | bottom: -0.25em; 79 | } 80 | img { 81 | border: 0; 82 | } 83 | svg:not(:root) { 84 | overflow: hidden; 85 | } 86 | figure { 87 | margin: 1em 40px; 88 | } 89 | hr { 90 | -webkit-box-sizing: content-box; 91 | -moz-box-sizing: content-box; 92 | box-sizing: content-box; 93 | height: 0; 94 | } 95 | pre { 96 | overflow: auto; 97 | } 98 | code, 99 | kbd, 100 | pre, 101 | samp { 102 | font-family: monospace, monospace; 103 | font-size: 1em; 104 | } 105 | button, 106 | input, 107 | optgroup, 108 | select, 109 | textarea { 110 | color: inherit; 111 | font: inherit; 112 | margin: 0; 113 | } 114 | button { 115 | overflow: visible; 116 | } 117 | button, 118 | select { 119 | text-transform: none; 120 | } 121 | button, 122 | html input[type="button"], 123 | input[type="reset"], 124 | input[type="submit"] { 125 | -webkit-appearance: button; 126 | cursor: pointer; 127 | } 128 | button[disabled], 129 | html input[disabled] { 130 | cursor: default; 131 | } 132 | button::-moz-focus-inner, 133 | input::-moz-focus-inner { 134 | border: 0; 135 | padding: 0; 136 | } 137 | input { 138 | line-height: normal; 139 | } 140 | input[type="checkbox"], 141 | input[type="radio"] { 142 | -webkit-box-sizing: border-box; 143 | -moz-box-sizing: border-box; 144 | box-sizing: border-box; 145 | padding: 0; 146 | } 147 | input[type="number"]::-webkit-inner-spin-button, 148 | input[type="number"]::-webkit-outer-spin-button { 149 | height: auto; 150 | } 151 | input[type="search"] { 152 | -webkit-appearance: textfield; 153 | -webkit-box-sizing: content-box; 154 | -moz-box-sizing: content-box; 155 | box-sizing: content-box; 156 | } 157 | input[type="search"]::-webkit-search-cancel-button, 158 | input[type="search"]::-webkit-search-decoration { 159 | -webkit-appearance: none; 160 | } 161 | fieldset { 162 | border: 1px solid #c0c0c0; 163 | margin: 0 2px; 164 | padding: 0.35em 0.625em 0.75em; 165 | } 166 | legend { 167 | border: 0; 168 | padding: 0; 169 | } 170 | textarea { 171 | overflow: auto; 172 | } 173 | optgroup { 174 | font-weight: bold; 175 | } 176 | table { 177 | border-collapse: collapse; 178 | border-spacing: 0; 179 | } 180 | td, 181 | th { 182 | padding: 0; 183 | } 184 | * { 185 | -webkit-box-sizing: border-box; 186 | -moz-box-sizing: border-box; 187 | box-sizing: border-box; 188 | } 189 | *:before, 190 | *:after { 191 | -webkit-box-sizing: border-box; 192 | -moz-box-sizing: border-box; 193 | box-sizing: border-box; 194 | } 195 | html { 196 | font-size: 10px; 197 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 198 | } 199 | body { 200 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 201 | font-size: 14px; 202 | line-height: 1.42857143; 203 | color: #333333; 204 | background-color: #ffffff; 205 | } 206 | input, 207 | button, 208 | select, 209 | textarea { 210 | font-family: inherit; 211 | font-size: inherit; 212 | line-height: inherit; 213 | } 214 | a { 215 | color: #337ab7; 216 | text-decoration: none; 217 | } 218 | a:hover, 219 | a:focus { 220 | color: #23527c; 221 | text-decoration: underline; 222 | } 223 | a:focus { 224 | outline: thin dotted; 225 | outline: 5px auto -webkit-focus-ring-color; 226 | outline-offset: -2px; 227 | } 228 | figure { 229 | margin: 0; 230 | } 231 | img { 232 | vertical-align: middle; 233 | } 234 | .img-responsive { 235 | display: block; 236 | max-width: 100%; 237 | height: auto; 238 | } 239 | .img-rounded { 240 | border-radius: 6px; 241 | } 242 | .img-thumbnail { 243 | padding: 4px; 244 | line-height: 1.42857143; 245 | background-color: #ffffff; 246 | border: 1px solid #dddddd; 247 | border-radius: 4px; 248 | -webkit-transition: all 0.2s ease-in-out; 249 | -o-transition: all 0.2s ease-in-out; 250 | transition: all 0.2s ease-in-out; 251 | display: inline-block; 252 | max-width: 100%; 253 | height: auto; 254 | } 255 | .img-circle { 256 | border-radius: 50%; 257 | } 258 | hr { 259 | margin-top: 20px; 260 | margin-bottom: 20px; 261 | border: 0; 262 | border-top: 1px solid #eeeeee; 263 | } 264 | .sr-only { 265 | position: absolute; 266 | width: 1px; 267 | height: 1px; 268 | margin: -1px; 269 | padding: 0; 270 | overflow: hidden; 271 | clip: rect(0, 0, 0, 0); 272 | border: 0; 273 | } 274 | .sr-only-focusable:active, 275 | .sr-only-focusable:focus { 276 | position: static; 277 | width: auto; 278 | height: auto; 279 | margin: 0; 280 | overflow: visible; 281 | clip: auto; 282 | } 283 | [role="button"] { 284 | cursor: pointer; 285 | } 286 | .container { 287 | margin-right: auto; 288 | margin-left: auto; 289 | padding-left: 15px; 290 | padding-right: 15px; 291 | } 292 | @media (min-width: 768px) { 293 | .container { 294 | width: 750px; 295 | } 296 | } 297 | @media (min-width: 992px) { 298 | .container { 299 | width: 970px; 300 | } 301 | } 302 | @media (min-width: 1200px) { 303 | .container { 304 | width: 1170px; 305 | } 306 | } 307 | .container-fluid { 308 | margin-right: auto; 309 | margin-left: auto; 310 | padding-left: 15px; 311 | padding-right: 15px; 312 | } 313 | .row { 314 | margin-left: -15px; 315 | margin-right: -15px; 316 | } 317 | .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { 318 | position: relative; 319 | min-height: 1px; 320 | padding-left: 15px; 321 | padding-right: 15px; 322 | } 323 | .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { 324 | float: left; 325 | } 326 | .col-xs-12 { 327 | width: 100%; 328 | } 329 | .col-xs-11 { 330 | width: 91.66666667%; 331 | } 332 | .col-xs-10 { 333 | width: 83.33333333%; 334 | } 335 | .col-xs-9 { 336 | width: 75%; 337 | } 338 | .col-xs-8 { 339 | width: 66.66666667%; 340 | } 341 | .col-xs-7 { 342 | width: 58.33333333%; 343 | } 344 | .col-xs-6 { 345 | width: 50%; 346 | } 347 | .col-xs-5 { 348 | width: 41.66666667%; 349 | } 350 | .col-xs-4 { 351 | width: 33.33333333%; 352 | } 353 | .col-xs-3 { 354 | width: 25%; 355 | } 356 | .col-xs-2 { 357 | width: 16.66666667%; 358 | } 359 | .col-xs-1 { 360 | width: 8.33333333%; 361 | } 362 | .col-xs-pull-12 { 363 | right: 100%; 364 | } 365 | .col-xs-pull-11 { 366 | right: 91.66666667%; 367 | } 368 | .col-xs-pull-10 { 369 | right: 83.33333333%; 370 | } 371 | .col-xs-pull-9 { 372 | right: 75%; 373 | } 374 | .col-xs-pull-8 { 375 | right: 66.66666667%; 376 | } 377 | .col-xs-pull-7 { 378 | right: 58.33333333%; 379 | } 380 | .col-xs-pull-6 { 381 | right: 50%; 382 | } 383 | .col-xs-pull-5 { 384 | right: 41.66666667%; 385 | } 386 | .col-xs-pull-4 { 387 | right: 33.33333333%; 388 | } 389 | .col-xs-pull-3 { 390 | right: 25%; 391 | } 392 | .col-xs-pull-2 { 393 | right: 16.66666667%; 394 | } 395 | .col-xs-pull-1 { 396 | right: 8.33333333%; 397 | } 398 | .col-xs-pull-0 { 399 | right: auto; 400 | } 401 | .col-xs-push-12 { 402 | left: 100%; 403 | } 404 | .col-xs-push-11 { 405 | left: 91.66666667%; 406 | } 407 | .col-xs-push-10 { 408 | left: 83.33333333%; 409 | } 410 | .col-xs-push-9 { 411 | left: 75%; 412 | } 413 | .col-xs-push-8 { 414 | left: 66.66666667%; 415 | } 416 | .col-xs-push-7 { 417 | left: 58.33333333%; 418 | } 419 | .col-xs-push-6 { 420 | left: 50%; 421 | } 422 | .col-xs-push-5 { 423 | left: 41.66666667%; 424 | } 425 | .col-xs-push-4 { 426 | left: 33.33333333%; 427 | } 428 | .col-xs-push-3 { 429 | left: 25%; 430 | } 431 | .col-xs-push-2 { 432 | left: 16.66666667%; 433 | } 434 | .col-xs-push-1 { 435 | left: 8.33333333%; 436 | } 437 | .col-xs-push-0 { 438 | left: auto; 439 | } 440 | .col-xs-offset-12 { 441 | margin-left: 100%; 442 | } 443 | .col-xs-offset-11 { 444 | margin-left: 91.66666667%; 445 | } 446 | .col-xs-offset-10 { 447 | margin-left: 83.33333333%; 448 | } 449 | .col-xs-offset-9 { 450 | margin-left: 75%; 451 | } 452 | .col-xs-offset-8 { 453 | margin-left: 66.66666667%; 454 | } 455 | .col-xs-offset-7 { 456 | margin-left: 58.33333333%; 457 | } 458 | .col-xs-offset-6 { 459 | margin-left: 50%; 460 | } 461 | .col-xs-offset-5 { 462 | margin-left: 41.66666667%; 463 | } 464 | .col-xs-offset-4 { 465 | margin-left: 33.33333333%; 466 | } 467 | .col-xs-offset-3 { 468 | margin-left: 25%; 469 | } 470 | .col-xs-offset-2 { 471 | margin-left: 16.66666667%; 472 | } 473 | .col-xs-offset-1 { 474 | margin-left: 8.33333333%; 475 | } 476 | .col-xs-offset-0 { 477 | margin-left: 0%; 478 | } 479 | @media (min-width: 768px) { 480 | .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { 481 | float: left; 482 | } 483 | .col-sm-12 { 484 | width: 100%; 485 | } 486 | .col-sm-11 { 487 | width: 91.66666667%; 488 | } 489 | .col-sm-10 { 490 | width: 83.33333333%; 491 | } 492 | .col-sm-9 { 493 | width: 75%; 494 | } 495 | .col-sm-8 { 496 | width: 66.66666667%; 497 | } 498 | .col-sm-7 { 499 | width: 58.33333333%; 500 | } 501 | .col-sm-6 { 502 | width: 50%; 503 | } 504 | .col-sm-5 { 505 | width: 41.66666667%; 506 | } 507 | .col-sm-4 { 508 | width: 33.33333333%; 509 | } 510 | .col-sm-3 { 511 | width: 25%; 512 | } 513 | .col-sm-2 { 514 | width: 16.66666667%; 515 | } 516 | .col-sm-1 { 517 | width: 8.33333333%; 518 | } 519 | .col-sm-pull-12 { 520 | right: 100%; 521 | } 522 | .col-sm-pull-11 { 523 | right: 91.66666667%; 524 | } 525 | .col-sm-pull-10 { 526 | right: 83.33333333%; 527 | } 528 | .col-sm-pull-9 { 529 | right: 75%; 530 | } 531 | .col-sm-pull-8 { 532 | right: 66.66666667%; 533 | } 534 | .col-sm-pull-7 { 535 | right: 58.33333333%; 536 | } 537 | .col-sm-pull-6 { 538 | right: 50%; 539 | } 540 | .col-sm-pull-5 { 541 | right: 41.66666667%; 542 | } 543 | .col-sm-pull-4 { 544 | right: 33.33333333%; 545 | } 546 | .col-sm-pull-3 { 547 | right: 25%; 548 | } 549 | .col-sm-pull-2 { 550 | right: 16.66666667%; 551 | } 552 | .col-sm-pull-1 { 553 | right: 8.33333333%; 554 | } 555 | .col-sm-pull-0 { 556 | right: auto; 557 | } 558 | .col-sm-push-12 { 559 | left: 100%; 560 | } 561 | .col-sm-push-11 { 562 | left: 91.66666667%; 563 | } 564 | .col-sm-push-10 { 565 | left: 83.33333333%; 566 | } 567 | .col-sm-push-9 { 568 | left: 75%; 569 | } 570 | .col-sm-push-8 { 571 | left: 66.66666667%; 572 | } 573 | .col-sm-push-7 { 574 | left: 58.33333333%; 575 | } 576 | .col-sm-push-6 { 577 | left: 50%; 578 | } 579 | .col-sm-push-5 { 580 | left: 41.66666667%; 581 | } 582 | .col-sm-push-4 { 583 | left: 33.33333333%; 584 | } 585 | .col-sm-push-3 { 586 | left: 25%; 587 | } 588 | .col-sm-push-2 { 589 | left: 16.66666667%; 590 | } 591 | .col-sm-push-1 { 592 | left: 8.33333333%; 593 | } 594 | .col-sm-push-0 { 595 | left: auto; 596 | } 597 | .col-sm-offset-12 { 598 | margin-left: 100%; 599 | } 600 | .col-sm-offset-11 { 601 | margin-left: 91.66666667%; 602 | } 603 | .col-sm-offset-10 { 604 | margin-left: 83.33333333%; 605 | } 606 | .col-sm-offset-9 { 607 | margin-left: 75%; 608 | } 609 | .col-sm-offset-8 { 610 | margin-left: 66.66666667%; 611 | } 612 | .col-sm-offset-7 { 613 | margin-left: 58.33333333%; 614 | } 615 | .col-sm-offset-6 { 616 | margin-left: 50%; 617 | } 618 | .col-sm-offset-5 { 619 | margin-left: 41.66666667%; 620 | } 621 | .col-sm-offset-4 { 622 | margin-left: 33.33333333%; 623 | } 624 | .col-sm-offset-3 { 625 | margin-left: 25%; 626 | } 627 | .col-sm-offset-2 { 628 | margin-left: 16.66666667%; 629 | } 630 | .col-sm-offset-1 { 631 | margin-left: 8.33333333%; 632 | } 633 | .col-sm-offset-0 { 634 | margin-left: 0%; 635 | } 636 | } 637 | @media (min-width: 992px) { 638 | .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { 639 | float: left; 640 | } 641 | .col-md-12 { 642 | width: 100%; 643 | } 644 | .col-md-11 { 645 | width: 91.66666667%; 646 | } 647 | .col-md-10 { 648 | width: 83.33333333%; 649 | } 650 | .col-md-9 { 651 | width: 75%; 652 | } 653 | .col-md-8 { 654 | width: 66.66666667%; 655 | } 656 | .col-md-7 { 657 | width: 58.33333333%; 658 | } 659 | .col-md-6 { 660 | width: 50%; 661 | } 662 | .col-md-5 { 663 | width: 41.66666667%; 664 | } 665 | .col-md-4 { 666 | width: 33.33333333%; 667 | } 668 | .col-md-3 { 669 | width: 25%; 670 | } 671 | .col-md-2 { 672 | width: 16.66666667%; 673 | } 674 | .col-md-1 { 675 | width: 8.33333333%; 676 | } 677 | .col-md-pull-12 { 678 | right: 100%; 679 | } 680 | .col-md-pull-11 { 681 | right: 91.66666667%; 682 | } 683 | .col-md-pull-10 { 684 | right: 83.33333333%; 685 | } 686 | .col-md-pull-9 { 687 | right: 75%; 688 | } 689 | .col-md-pull-8 { 690 | right: 66.66666667%; 691 | } 692 | .col-md-pull-7 { 693 | right: 58.33333333%; 694 | } 695 | .col-md-pull-6 { 696 | right: 50%; 697 | } 698 | .col-md-pull-5 { 699 | right: 41.66666667%; 700 | } 701 | .col-md-pull-4 { 702 | right: 33.33333333%; 703 | } 704 | .col-md-pull-3 { 705 | right: 25%; 706 | } 707 | .col-md-pull-2 { 708 | right: 16.66666667%; 709 | } 710 | .col-md-pull-1 { 711 | right: 8.33333333%; 712 | } 713 | .col-md-pull-0 { 714 | right: auto; 715 | } 716 | .col-md-push-12 { 717 | left: 100%; 718 | } 719 | .col-md-push-11 { 720 | left: 91.66666667%; 721 | } 722 | .col-md-push-10 { 723 | left: 83.33333333%; 724 | } 725 | .col-md-push-9 { 726 | left: 75%; 727 | } 728 | .col-md-push-8 { 729 | left: 66.66666667%; 730 | } 731 | .col-md-push-7 { 732 | left: 58.33333333%; 733 | } 734 | .col-md-push-6 { 735 | left: 50%; 736 | } 737 | .col-md-push-5 { 738 | left: 41.66666667%; 739 | } 740 | .col-md-push-4 { 741 | left: 33.33333333%; 742 | } 743 | .col-md-push-3 { 744 | left: 25%; 745 | } 746 | .col-md-push-2 { 747 | left: 16.66666667%; 748 | } 749 | .col-md-push-1 { 750 | left: 8.33333333%; 751 | } 752 | .col-md-push-0 { 753 | left: auto; 754 | } 755 | .col-md-offset-12 { 756 | margin-left: 100%; 757 | } 758 | .col-md-offset-11 { 759 | margin-left: 91.66666667%; 760 | } 761 | .col-md-offset-10 { 762 | margin-left: 83.33333333%; 763 | } 764 | .col-md-offset-9 { 765 | margin-left: 75%; 766 | } 767 | .col-md-offset-8 { 768 | margin-left: 66.66666667%; 769 | } 770 | .col-md-offset-7 { 771 | margin-left: 58.33333333%; 772 | } 773 | .col-md-offset-6 { 774 | margin-left: 50%; 775 | } 776 | .col-md-offset-5 { 777 | margin-left: 41.66666667%; 778 | } 779 | .col-md-offset-4 { 780 | margin-left: 33.33333333%; 781 | } 782 | .col-md-offset-3 { 783 | margin-left: 25%; 784 | } 785 | .col-md-offset-2 { 786 | margin-left: 16.66666667%; 787 | } 788 | .col-md-offset-1 { 789 | margin-left: 8.33333333%; 790 | } 791 | .col-md-offset-0 { 792 | margin-left: 0%; 793 | } 794 | } 795 | @media (min-width: 1200px) { 796 | .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { 797 | float: left; 798 | } 799 | .col-lg-12 { 800 | width: 100%; 801 | } 802 | .col-lg-11 { 803 | width: 91.66666667%; 804 | } 805 | .col-lg-10 { 806 | width: 83.33333333%; 807 | } 808 | .col-lg-9 { 809 | width: 75%; 810 | } 811 | .col-lg-8 { 812 | width: 66.66666667%; 813 | } 814 | .col-lg-7 { 815 | width: 58.33333333%; 816 | } 817 | .col-lg-6 { 818 | width: 50%; 819 | } 820 | .col-lg-5 { 821 | width: 41.66666667%; 822 | } 823 | .col-lg-4 { 824 | width: 33.33333333%; 825 | } 826 | .col-lg-3 { 827 | width: 25%; 828 | } 829 | .col-lg-2 { 830 | width: 16.66666667%; 831 | } 832 | .col-lg-1 { 833 | width: 8.33333333%; 834 | } 835 | .col-lg-pull-12 { 836 | right: 100%; 837 | } 838 | .col-lg-pull-11 { 839 | right: 91.66666667%; 840 | } 841 | .col-lg-pull-10 { 842 | right: 83.33333333%; 843 | } 844 | .col-lg-pull-9 { 845 | right: 75%; 846 | } 847 | .col-lg-pull-8 { 848 | right: 66.66666667%; 849 | } 850 | .col-lg-pull-7 { 851 | right: 58.33333333%; 852 | } 853 | .col-lg-pull-6 { 854 | right: 50%; 855 | } 856 | .col-lg-pull-5 { 857 | right: 41.66666667%; 858 | } 859 | .col-lg-pull-4 { 860 | right: 33.33333333%; 861 | } 862 | .col-lg-pull-3 { 863 | right: 25%; 864 | } 865 | .col-lg-pull-2 { 866 | right: 16.66666667%; 867 | } 868 | .col-lg-pull-1 { 869 | right: 8.33333333%; 870 | } 871 | .col-lg-pull-0 { 872 | right: auto; 873 | } 874 | .col-lg-push-12 { 875 | left: 100%; 876 | } 877 | .col-lg-push-11 { 878 | left: 91.66666667%; 879 | } 880 | .col-lg-push-10 { 881 | left: 83.33333333%; 882 | } 883 | .col-lg-push-9 { 884 | left: 75%; 885 | } 886 | .col-lg-push-8 { 887 | left: 66.66666667%; 888 | } 889 | .col-lg-push-7 { 890 | left: 58.33333333%; 891 | } 892 | .col-lg-push-6 { 893 | left: 50%; 894 | } 895 | .col-lg-push-5 { 896 | left: 41.66666667%; 897 | } 898 | .col-lg-push-4 { 899 | left: 33.33333333%; 900 | } 901 | .col-lg-push-3 { 902 | left: 25%; 903 | } 904 | .col-lg-push-2 { 905 | left: 16.66666667%; 906 | } 907 | .col-lg-push-1 { 908 | left: 8.33333333%; 909 | } 910 | .col-lg-push-0 { 911 | left: auto; 912 | } 913 | .col-lg-offset-12 { 914 | margin-left: 100%; 915 | } 916 | .col-lg-offset-11 { 917 | margin-left: 91.66666667%; 918 | } 919 | .col-lg-offset-10 { 920 | margin-left: 83.33333333%; 921 | } 922 | .col-lg-offset-9 { 923 | margin-left: 75%; 924 | } 925 | .col-lg-offset-8 { 926 | margin-left: 66.66666667%; 927 | } 928 | .col-lg-offset-7 { 929 | margin-left: 58.33333333%; 930 | } 931 | .col-lg-offset-6 { 932 | margin-left: 50%; 933 | } 934 | .col-lg-offset-5 { 935 | margin-left: 41.66666667%; 936 | } 937 | .col-lg-offset-4 { 938 | margin-left: 33.33333333%; 939 | } 940 | .col-lg-offset-3 { 941 | margin-left: 25%; 942 | } 943 | .col-lg-offset-2 { 944 | margin-left: 16.66666667%; 945 | } 946 | .col-lg-offset-1 { 947 | margin-left: 8.33333333%; 948 | } 949 | .col-lg-offset-0 { 950 | margin-left: 0%; 951 | } 952 | } 953 | .clearfix:before, 954 | .clearfix:after, 955 | .container:before, 956 | .container:after, 957 | .container-fluid:before, 958 | .container-fluid:after, 959 | .row:before, 960 | .row:after { 961 | content: " "; 962 | display: table; 963 | } 964 | .clearfix:after, 965 | .container:after, 966 | .container-fluid:after, 967 | .row:after { 968 | clear: both; 969 | } 970 | .center-block { 971 | display: block; 972 | margin-left: auto; 973 | margin-right: auto; 974 | } 975 | .pull-right { 976 | float: right !important; 977 | } 978 | .pull-left { 979 | float: left !important; 980 | } 981 | .hide { 982 | display: none !important; 983 | } 984 | .show { 985 | display: block !important; 986 | } 987 | .invisible { 988 | visibility: hidden; 989 | } 990 | .text-hide { 991 | font: 0/0 a; 992 | color: transparent; 993 | text-shadow: none; 994 | background-color: transparent; 995 | border: 0; 996 | } 997 | .hidden { 998 | display: none !important; 999 | } 1000 | .affix { 1001 | position: fixed; 1002 | } 1003 | -------------------------------------------------------------------------------- /examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "component-kit-examples", 3 | "version": "0.1.1", 4 | "description": "component-kit lib", 5 | "main": "./index.js", 6 | "scripts": { 7 | "start": "node server.js", 8 | "build": "webpack --config webpack.config.js", 9 | "build:watch": "webpack --watch --config webpack.config.js" 10 | }, 11 | "keywords": [ 12 | "component-kit-examples" 13 | ], 14 | "author": "Kennet Postigo (http://kpostigo.com/)", 15 | "license": "MIT", 16 | "dependencies": { 17 | "component-kit": "0.1.5", 18 | "fetch": "1.1.0", 19 | "react": "15.0.2", 20 | "react-dom": "15.0.2" 21 | }, 22 | "devDependencies": { 23 | "babel-cli": "6.8.0", 24 | "babel-core": "6.8.0", 25 | "babel-loader": "6.2.4", 26 | "babel-plugin-syntax-jsx": "6.8.0", 27 | "babel-preset-es2015": "6.6.0", 28 | "babel-preset-react": "6.5.0", 29 | "css-loader": "0.23.1", 30 | "eslint": "2.9.0", 31 | "eslint-plugin-babel": "3.2.0", 32 | "eslint-plugin-react": "5.0.1", 33 | "express": "4.13.4", 34 | "mocha": "2.4.5", 35 | "node-sass": "3.7.0", 36 | "react-hot-loader": "1.3.0", 37 | "sass-loader": "3.2.0", 38 | "style-loader": "0.13.1", 39 | "webpack": "1.12.2", 40 | "webpack-dev-server": "1.12.1" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/server.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var WebpackDevServer = require('webpack-dev-server'); 3 | var config = require('./webpack.config'); 4 | 5 | new WebpackDevServer(webpack(config), { 6 | publicPath: config.output.publicPath, 7 | hot: true, 8 | historyApiFallback: true 9 | }).listen(3000, 'localhost', function (err, result) { 10 | if (err) { 11 | return console.log(err); 12 | } 13 | 14 | console.log('Listening at http://localhost:3000/'); 15 | }); 16 | -------------------------------------------------------------------------------- /examples/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | 4 | module.exports = { 5 | devtool: 'eval', 6 | entry: [ 7 | 'webpack-dev-server/client?http://localhost:3000', 8 | 'webpack/hot/only-dev-server', 9 | './index.js' 10 | ], 11 | output: { 12 | path: path.join(__dirname, 'dist'), 13 | filename: 'bundle.js', 14 | publicPath: '/static/' 15 | }, 16 | plugins: [ 17 | new webpack.HotModuleReplacementPlugin(), 18 | new webpack.optimize.OccurenceOrderPlugin(), 19 | new webpack.optimize.DedupePlugin(), 20 | ], 21 | module: { 22 | loaders: [ 23 | { 24 | test: /\.js$/, 25 | exclude: /node_modules/, 26 | loaders: ['react-hot', 'babel-loader'], 27 | include: path.join(__dirname, 'index.js') 28 | }, 29 | { 30 | test: /(\.scss|\.css)$/, 31 | loader: 'style!css!sass' 32 | } 33 | ] 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "component-kit", 3 | "version": "0.1.15", 4 | "description": "component-kit, a library for modern data-driven applications", 5 | "main": "./dist/component-kit.js", 6 | "scripts": { 7 | "build:develop": "cross-env NODE_ENV=development webpack src/index.js dist/component-kit.js", 8 | "build:production": "cross-env NODE_ENV=production webpack src/index.js dist/component-kit.min.js", 9 | "build:publish": "npm run build:develop && npm run build:production", 10 | "build-watch": "npm run webpack --watch" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/kennetpostigo/component-kit.git" 15 | }, 16 | "keywords": [ 17 | "component-kit", 18 | "component", 19 | "UI", 20 | "data-driven" 21 | ], 22 | "author": "Kennet Postigo (http://kpostigo.com/)", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/kennetpostigo/component-kit/issues" 26 | }, 27 | "homepage": "https://github.com/kennetpostigo/component-kit#readme", 28 | "peerDependencies": { 29 | "react": "^0.14.0 || ^15.0.0" 30 | }, 31 | "devDependencies": { 32 | "babel-cli": "6.10.1", 33 | "babel-core": "6.9.1", 34 | "babel-loader": "6.2.4", 35 | "babel-plugin-syntax-jsx": "6.8.0", 36 | "babel-preset-es2015": "6.9.0", 37 | "babel-preset-react": "6.5.0", 38 | "cross-env": "1.0.8", 39 | "eslint": "2.12.0", 40 | "eslint-plugin-babel": "3.2.0", 41 | "eslint-plugin-react": "5.1.1", 42 | "webpack": "1.13.1" 43 | }, 44 | "dependencies": { 45 | "aphrodite": "0.3.3", 46 | "d3": "3.5.17", 47 | "react-faux-dom": "2.5.0", 48 | "react-motion": "0.4.4" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Cards from './layout/Cards.js'; 2 | // import Chips from './layout/Chips.js'; 3 | import FooterNavigation from './layout/FooterNavigation.js'; 4 | // import Navigation from './layout/Navigation.js'; 5 | import Panels from './layout/Panels.js'; 6 | import Platter from './layout/Platter.js'; 7 | // import Snackbar from './layout/Snackbar.js'; 8 | import Tabs from './layout/Tabs.js'; 9 | // import Tooltips from './layout/Tooltips.js'; 10 | import XYAxis from './visualization/XYAxis.js'; 11 | import Legend from './visualization/Legend.js'; 12 | import AreaChart from './visualization/AreaChart.js'; 13 | import BarChart from './visualization/BarChart.js'; 14 | import LineChart from './visualization/LineChart.js'; 15 | import PieChart from './visualization/PieChart.js'; 16 | import RadarChart from './visualization/RadarChart.js'; 17 | import RadarArea from './visualization/RadarArea.js'; 18 | import RadialBarChart from './visualization/RadialBarChart.js'; 19 | import Responsive from './visualization/Responsive.js'; 20 | import ScatterPlot from './visualization/ScatterPlot.js'; 21 | import TreeMap from './visualization/TreeMap.js'; 22 | 23 | export { 24 | Cards, 25 | // Chips, 26 | FooterNavigation, 27 | // Navigation, 28 | Panels, 29 | Platter, 30 | // Snackbar, 31 | Tabs, 32 | // Tooltips, 33 | XYAxis, 34 | Legend, 35 | AreaChart, 36 | BarChart, 37 | LineChart, 38 | PieChart, 39 | RadarChart, 40 | RadarArea, 41 | RadialBarChart, 42 | Responsive, 43 | ScatterPlot, 44 | TreeMap, 45 | } 46 | -------------------------------------------------------------------------------- /src/layout/Cards.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, css } from 'aphrodite'; 3 | 4 | function Cards (props) { 5 | const styles = StyleSheet.create({ 6 | cards: { 7 | boxShadow: "0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)", 8 | width: props.width || 300, 9 | height: props.height || 350, 10 | }, 11 | img: { 12 | width: props.imgWidth || 300, 13 | height: props.imgHeight || 200 14 | }, 15 | graphBox: { 16 | display: 'flex', 17 | alignItem: 'center', 18 | justifyContent: 'center', 19 | borderBottom: "1px solid #CFCCCC" 20 | }, 21 | graphInner: { 22 | 23 | }, 24 | fill: { 25 | padding: 10 26 | }, 27 | h3: { 28 | color: '48494c', 29 | fontWeight: 300, 30 | lineHeight: 1.5, 31 | font: 'helvetica, sans-serif', 32 | fontSize: 20, 33 | marginTop: 6, 34 | marginBottom: 0 35 | }, 36 | p: { 37 | marginTop: 5, 38 | lineHeight: 1.5, 39 | font: 'helvetica, sans-serif', 40 | fontSize: 15, 41 | color: '#636363' 42 | }, 43 | link: { 44 | textDecoration: 'none', 45 | marginRight: 20, 46 | font: 'helvetica, sans-serif', 47 | color: props.linkColor || '#505052', 48 | padding: 5, 49 | ':hover': { 50 | backgroundColor: '#f1f1f1', 51 | } 52 | } 53 | }); 54 | if(props.graph) var graph = props.graph 55 | return ( 56 |
57 | { 58 | (props.graph) 59 | ? 60 |
61 | {props.graph} 62 |
63 | : 64 | 65 | } 66 |
67 | { 68 | (props.children) 69 | ? 70 | props.children 71 | : 72 |
73 |

{props.header}

74 |

{props.detail}

75 | {props.links.map((link, key) => { 76 | return {link.title.toUpperCase()} 77 | })} 78 |
79 | } 80 |
81 |
82 | ); 83 | } 84 | 85 | Cards.propTypes = { 86 | imgURI: React.PropTypes.string, 87 | width: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 88 | height: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 89 | imgWidth: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 90 | imgHeight: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 91 | header: React.PropTypes.string, 92 | detail: React.PropTypes.string, 93 | links: React.PropTypes.arrayOf(React.PropTypes.shape({ 94 | link: React.PropTypes.string, 95 | title: React.PropTypes.string 96 | })), 97 | linkColor: React.PropTypes.string, 98 | graph: React.PropTypes.element 99 | }; 100 | 101 | export default Cards; 102 | -------------------------------------------------------------------------------- /src/layout/Chips.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function Chips (props) { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } 10 | 11 | export default Chips; 12 | -------------------------------------------------------------------------------- /src/layout/FooterNavigation.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { css, StyleSheet } from 'aphrodite'; 3 | 4 | function FooterNavigation (props) { 5 | var cols = Math.round(12 /props.views.length); 6 | 7 | var styles = StyleSheet.create({ 8 | footerNav: { 9 | width: '100%', 10 | height: props.height || 60, 11 | position: 'fixed', 12 | bottom: 0, 13 | backgroundColor: props.backgroundColor || '#fff', 14 | boxShadow: '0px 0px 5px rgba(0,0,0,.3);' 15 | }, 16 | icon: { 17 | textDecoration: 'none', 18 | textAlign: 'center', 19 | fontSize: 20, 20 | marginTop: 5, 21 | marginBottom: 3 22 | }, 23 | center: { 24 | textDecoration: 'none', 25 | textAlign: 'center' 26 | }, 27 | title: { 28 | textAlign: 'center', 29 | fontSize: 16, 30 | marginTop: 0, 31 | marginBottom: 5, 32 | textDecoration: 'none' 33 | } 34 | }); 35 | 36 | return ( 37 |
38 |
39 |
40 | { 41 | (props.children) 42 | ? 43 | props.children 44 | : 45 | props.views.map((view, key) => { 46 | return ( 47 | 53 | ); 54 | }) 55 | } 56 |
57 |
58 |
59 | ); 60 | } 61 | FooterNavigation.propTypes = { 62 | views: React.PropTypes.arrayOf(React.PropTypes.shape({ 63 | link: React.PropTypes.string, 64 | icon: React.PropTypes.string, 65 | title: React.PropTypes.string 66 | })), 67 | height: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 68 | }; 69 | 70 | export default FooterNavigation; 71 | -------------------------------------------------------------------------------- /src/layout/Navigation.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function Navigation (props) { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } 10 | 11 | export default Navigation; 12 | -------------------------------------------------------------------------------- /src/layout/Panels.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, css } from 'aphrodite'; 3 | 4 | class Panels extends React.Component { 5 | 6 | constructor(props) { 7 | super(props); 8 | this.state = { 9 | open: false 10 | }; 11 | this.toggle = this.toggle.bind(this); 12 | } 13 | 14 | toggle () { 15 | this.setState({open: !this.state.open}); 16 | } 17 | 18 | render () { 19 | const styles = StyleSheet.create({ 20 | panels: { 21 | boxShadow: "0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)", 22 | width: this.props.width || 400, 23 | minHeight: this.props.height || 35, 24 | }, 25 | title: { 26 | color: '#212121', 27 | fontSize: 15, 28 | padding: 0, 29 | marginTop: 15, 30 | float: 'left' 31 | }, 32 | toggle: { 33 | height: 25, 34 | width: 25, 35 | textAlign: 'center', 36 | color: '#212121', 37 | fontSize: 15, 38 | paddingTop: 0, 39 | marginTop: 15, 40 | borderRadius: '50%', 41 | float: 'right', 42 | ':hover': { 43 | backgroundColor: '#f1f1f1', 44 | } 45 | }, 46 | body:{ 47 | display: 'flex', 48 | justifyContent: 'center', 49 | alignItems: 'center', 50 | textAlign: 'center', 51 | } 52 | }); 53 | return ( 54 |
55 | { 56 | (!this.state.open) 57 | ? 58 |
59 |
60 |
61 |

{this.props.title}

62 |
63 |
64 |

65 |
66 |
67 |
68 | 69 | : 70 |
71 |
72 |
73 |

{this.props.title}

74 |
75 |
76 |

77 |
78 |
79 |
80 | {this.props.children} 81 |
82 |
83 | } 84 |
85 | ); 86 | } 87 | } 88 | 89 | Panels.propTypes = { 90 | width: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 91 | height: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 92 | title: React.PropTypes.string 93 | }; 94 | 95 | export default Panels; 96 | -------------------------------------------------------------------------------- /src/layout/Platter.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { css, StyleSheet } from 'aphrodite'; 3 | 4 | function Platter (props) { 5 | const styles = StyleSheet.create({ 6 | platter: { 7 | backgroundColor: props.backgroundColor || '#fff', 8 | boxShadow: "0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)", 9 | width: props.width || 400, 10 | height: props.height || 350, 11 | paddingTop: 15, 12 | paddingLeft: 15, 13 | paddingRight: 15, 14 | paddingBottom: 15, 15 | display: 'flex', 16 | justifyContent: 'center', 17 | alignItems: 'center', 18 | textAlign: 'center', 19 | } 20 | }); 21 | 22 | return ( 23 |
24 | {props.children} 25 |
26 | ); 27 | } 28 | 29 | Platter.PropTypes = { 30 | width: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 31 | height: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 32 | backgroundColor: React.PropTypes.string 33 | }; 34 | 35 | export default Platter; 36 | -------------------------------------------------------------------------------- /src/layout/Snackbar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function Snackbar (props) { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } 10 | 11 | export default Snackbar; 12 | -------------------------------------------------------------------------------- /src/layout/Tabs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, css } from 'aphrodite'; 3 | 4 | class Tabs extends React.Component { 5 | constructor (props) { 6 | super(props); 7 | this.state = { 8 | activeTab: 0 9 | } 10 | } 11 | 12 | toggle (tab) { 13 | this.setState({activeTab: tab}); 14 | } 15 | render () { 16 | const styles = StyleSheet.create({ 17 | tabs: { 18 | width: this.props.width || 300, 19 | height: this.props.height || 500, 20 | backgroundColor: this.props.backGroundColor || '#fff', 21 | boxShadow: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)' 22 | }, 23 | tabList: { 24 | margin: 0, 25 | padding: 0, 26 | width: '100%' 27 | }, 28 | tabItem: { 29 | textAlign: 'center', 30 | display: 'inline-block', 31 | listStyle: 'none', 32 | boxShadow: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)' 33 | }, 34 | activeTab: { 35 | textAlign: 'center', 36 | display: 'inline-block', 37 | listStyle: 'none', 38 | boxShadow: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)', 39 | borderBottom: `2px solid ${this.props.tabColor || '#3949AB'}` 40 | }, 41 | component: { 42 | display: 'flex', 43 | justifyContent: 'center', 44 | alignItems: 'center', 45 | textAlign: 'center', 46 | paddingTop: 20 47 | } 48 | }) 49 | const cols = Math.round(12 / this.props.tabs.length); 50 | const TabComponent = this.props.tabs[this.state.activeTab].component; 51 | return ( 52 |
53 |
    54 | { 55 | this.props.tabs.map((tab, key) => { 56 | return ( 57 |
  • this.toggle(key)} 58 | key={key} 59 | className={(this.state.activeTab === key) 60 | ? `${css(styles.activeTab)} col-xs-${cols}` 61 | : `${css(styles.tabItem)} col-xs-${cols}` 62 | } 63 | > 64 |

    {tab.title}

    65 |
  • 66 | ) 67 | }) 68 | } 69 |
70 |
71 | {TabComponent} 72 |
73 | 74 |
75 | ); 76 | } 77 | } 78 | 79 | Tabs.propTypes = { 80 | width: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 81 | height: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 82 | backGroundColor: React.PropTypes.string, 83 | tabColor: React.PropTypes.string, 84 | tabs: React.PropTypes.arrayOf(React.PropTypes.shape({ 85 | title: React.PropTypes.string, 86 | component: React.PropTypes.element 87 | })) 88 | }; 89 | 90 | export default Tabs; 91 | -------------------------------------------------------------------------------- /src/layout/Tooltips.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function Tooltips (props) { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } 10 | 11 | export default Tooltips; 12 | -------------------------------------------------------------------------------- /src/styles/main.css: -------------------------------------------------------------------------------- 1 | .AreaChart, .LineChart, .ScatterPlot, .BarChart{ 2 | /*z-index: 10;*/ 3 | position: absolute; 4 | } 5 | .plane{ 6 | display: inline-block; 7 | } 8 | /* Chart Start*/ 9 | .XYAxis{ 10 | z-index:1; 11 | position: relative; 12 | } 13 | 14 | .XYC{ 15 | display: inline-block; 16 | } 17 | 18 | .axis path, 19 | .axis line{ 20 | /*fill: none;*/ 21 | stroke: rgb(102, 102, 102); 22 | } 23 | 24 | .axis text { 25 | font-size: 12px; 26 | fill: rgb(102, 102, 102) 27 | } 28 | 29 | .tick text{ 30 | font-size: 12px; 31 | fill: rgb(102, 102, 102); 32 | } 33 | 34 | .tick line{ 35 | opacity: 0.2; 36 | stroke: rgb(102, 102, 102); 37 | } 38 | 39 | /* Chart End*/ 40 | 41 | /* BarChart Start */ 42 | 43 | .bar { 44 | fill: rgb(136, 132, 216); 45 | fill-opacity: 0.6; 46 | } 47 | 48 | /* BarChart End */ 49 | 50 | /* AreaChart Start */ 51 | .area { 52 | stroke-linecap:round; 53 | stroke-linehoin: round; 54 | } 55 | /* AreaChart End */ 56 | 57 | /* LineChart Start */ 58 | 59 | .circle{ 60 | fill: rgb(255, 255, 255); 61 | stroke: rgb(136, 132, 216); 62 | } 63 | 64 | .line{ 65 | fill: none; 66 | stroke: #ffc952; 67 | stroke-width: 2px; 68 | } 69 | /* LineChart End */ 70 | 71 | /* PieChart Start */ 72 | .PieChart{ 73 | display:inline-block; 74 | } 75 | .arc text { 76 | font: 10px sans-serif; 77 | fill: #fff; 78 | text-anchor: middle; 79 | } 80 | 81 | /*.area { 82 | fill: rgb(136, 132, 216); 83 | stroke-width: 0; 84 | }*/ 85 | 86 | /* PieChart End */ 87 | 88 | /* TreeMap */ 89 | .node { 90 | border: solid 1px white; 91 | font: 10px sans-serif; 92 | line-height: 12px; 93 | overflow: hidden; 94 | position: absolute; 95 | text-indent: 2px; 96 | } 97 | 98 | /* TreeMap End */ 99 | 100 | 101 | /* Radar */ 102 | .RadarChart{ 103 | display: block; 104 | } 105 | /* Radar End */ 106 | 107 | 108 | 109 | 110 | 111 | 112 | html { 113 | font-family: sans-serif; 114 | -ms-text-size-adjust: 100%; 115 | -webkit-text-size-adjust: 100%; 116 | } 117 | body { 118 | margin: 0; 119 | } 120 | article, 121 | aside, 122 | details, 123 | figcaption, 124 | figure, 125 | footer, 126 | header, 127 | hgroup, 128 | main, 129 | menu, 130 | nav, 131 | section, 132 | summary { 133 | display: block; 134 | } 135 | audio, 136 | canvas, 137 | progress, 138 | video { 139 | display: inline-block; 140 | vertical-align: baseline; 141 | } 142 | audio:not([controls]) { 143 | display: none; 144 | height: 0; 145 | } 146 | [hidden], 147 | template { 148 | display: none; 149 | } 150 | a { 151 | background-color: transparent; 152 | } 153 | a:active, 154 | a:hover { 155 | outline: 0; 156 | } 157 | abbr[title] { 158 | border-bottom: 1px dotted; 159 | } 160 | b, 161 | strong { 162 | font-weight: bold; 163 | } 164 | dfn { 165 | font-style: italic; 166 | } 167 | h1 { 168 | font-size: 2em; 169 | margin: 0.67em 0; 170 | } 171 | mark { 172 | background: #ff0; 173 | color: #000; 174 | } 175 | small { 176 | font-size: 80%; 177 | } 178 | sub, 179 | sup { 180 | font-size: 75%; 181 | line-height: 0; 182 | position: relative; 183 | vertical-align: baseline; 184 | } 185 | sup { 186 | top: -0.5em; 187 | } 188 | sub { 189 | bottom: -0.25em; 190 | } 191 | img { 192 | border: 0; 193 | } 194 | svg:not(:root) { 195 | overflow: hidden; 196 | } 197 | figure { 198 | margin: 1em 40px; 199 | } 200 | hr { 201 | -webkit-box-sizing: content-box; 202 | -moz-box-sizing: content-box; 203 | box-sizing: content-box; 204 | height: 0; 205 | } 206 | pre { 207 | overflow: auto; 208 | } 209 | code, 210 | kbd, 211 | pre, 212 | samp { 213 | font-family: monospace, monospace; 214 | font-size: 1em; 215 | } 216 | button, 217 | input, 218 | optgroup, 219 | select, 220 | textarea { 221 | color: inherit; 222 | font: inherit; 223 | margin: 0; 224 | } 225 | button { 226 | overflow: visible; 227 | } 228 | button, 229 | select { 230 | text-transform: none; 231 | } 232 | button, 233 | html input[type="button"], 234 | input[type="reset"], 235 | input[type="submit"] { 236 | -webkit-appearance: button; 237 | cursor: pointer; 238 | } 239 | button[disabled], 240 | html input[disabled] { 241 | cursor: default; 242 | } 243 | button::-moz-focus-inner, 244 | input::-moz-focus-inner { 245 | border: 0; 246 | padding: 0; 247 | } 248 | input { 249 | line-height: normal; 250 | } 251 | input[type="checkbox"], 252 | input[type="radio"] { 253 | -webkit-box-sizing: border-box; 254 | -moz-box-sizing: border-box; 255 | box-sizing: border-box; 256 | padding: 0; 257 | } 258 | input[type="number"]::-webkit-inner-spin-button, 259 | input[type="number"]::-webkit-outer-spin-button { 260 | height: auto; 261 | } 262 | input[type="search"] { 263 | -webkit-appearance: textfield; 264 | -webkit-box-sizing: content-box; 265 | -moz-box-sizing: content-box; 266 | box-sizing: content-box; 267 | } 268 | input[type="search"]::-webkit-search-cancel-button, 269 | input[type="search"]::-webkit-search-decoration { 270 | -webkit-appearance: none; 271 | } 272 | fieldset { 273 | border: 1px solid #c0c0c0; 274 | margin: 0 2px; 275 | padding: 0.35em 0.625em 0.75em; 276 | } 277 | legend { 278 | border: 0; 279 | padding: 0; 280 | } 281 | textarea { 282 | overflow: auto; 283 | } 284 | optgroup { 285 | font-weight: bold; 286 | } 287 | table { 288 | border-collapse: collapse; 289 | border-spacing: 0; 290 | } 291 | td, 292 | th { 293 | padding: 0; 294 | } 295 | * { 296 | -webkit-box-sizing: border-box; 297 | -moz-box-sizing: border-box; 298 | box-sizing: border-box; 299 | } 300 | *:before, 301 | *:after { 302 | -webkit-box-sizing: border-box; 303 | -moz-box-sizing: border-box; 304 | box-sizing: border-box; 305 | } 306 | html { 307 | font-size: 10px; 308 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 309 | } 310 | body { 311 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 312 | font-size: 14px; 313 | line-height: 1.42857143; 314 | color: #333333; 315 | background-color: #ffffff; 316 | } 317 | input, 318 | button, 319 | select, 320 | textarea { 321 | font-family: inherit; 322 | font-size: inherit; 323 | line-height: inherit; 324 | } 325 | a { 326 | color: #337ab7; 327 | text-decoration: none; 328 | } 329 | a:hover, 330 | a:focus { 331 | color: #23527c; 332 | text-decoration: underline; 333 | } 334 | a:focus { 335 | outline: thin dotted; 336 | outline: 5px auto -webkit-focus-ring-color; 337 | outline-offset: -2px; 338 | } 339 | figure { 340 | margin: 0; 341 | } 342 | img { 343 | vertical-align: middle; 344 | } 345 | .img-responsive { 346 | display: block; 347 | max-width: 100%; 348 | height: auto; 349 | } 350 | .img-rounded { 351 | border-radius: 6px; 352 | } 353 | .img-thumbnail { 354 | padding: 4px; 355 | line-height: 1.42857143; 356 | background-color: #ffffff; 357 | border: 1px solid #dddddd; 358 | border-radius: 4px; 359 | -webkit-transition: all 0.2s ease-in-out; 360 | -o-transition: all 0.2s ease-in-out; 361 | transition: all 0.2s ease-in-out; 362 | display: inline-block; 363 | max-width: 100%; 364 | height: auto; 365 | } 366 | .img-circle { 367 | border-radius: 50%; 368 | } 369 | hr { 370 | margin-top: 20px; 371 | margin-bottom: 20px; 372 | border: 0; 373 | border-top: 1px solid #eeeeee; 374 | } 375 | .sr-only { 376 | position: absolute; 377 | width: 1px; 378 | height: 1px; 379 | margin: -1px; 380 | padding: 0; 381 | overflow: hidden; 382 | clip: rect(0, 0, 0, 0); 383 | border: 0; 384 | } 385 | .sr-only-focusable:active, 386 | .sr-only-focusable:focus { 387 | position: static; 388 | width: auto; 389 | height: auto; 390 | margin: 0; 391 | overflow: visible; 392 | clip: auto; 393 | } 394 | [role="button"] { 395 | cursor: pointer; 396 | } 397 | .container { 398 | margin-right: auto; 399 | margin-left: auto; 400 | padding-left: 15px; 401 | padding-right: 15px; 402 | } 403 | @media (min-width: 768px) { 404 | .container { 405 | width: 750px; 406 | } 407 | } 408 | @media (min-width: 992px) { 409 | .container { 410 | width: 970px; 411 | } 412 | } 413 | @media (min-width: 1200px) { 414 | .container { 415 | width: 1170px; 416 | } 417 | } 418 | .container-fluid { 419 | margin-right: auto; 420 | margin-left: auto; 421 | padding-left: 15px; 422 | padding-right: 15px; 423 | } 424 | .row { 425 | margin-left: -15px; 426 | margin-right: -15px; 427 | } 428 | .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { 429 | position: relative; 430 | min-height: 1px; 431 | padding-left: 15px; 432 | padding-right: 15px; 433 | } 434 | .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { 435 | float: left; 436 | } 437 | .col-xs-12 { 438 | width: 100%; 439 | } 440 | .col-xs-11 { 441 | width: 91.66666667%; 442 | } 443 | .col-xs-10 { 444 | width: 83.33333333%; 445 | } 446 | .col-xs-9 { 447 | width: 75%; 448 | } 449 | .col-xs-8 { 450 | width: 66.66666667%; 451 | } 452 | .col-xs-7 { 453 | width: 58.33333333%; 454 | } 455 | .col-xs-6 { 456 | width: 50%; 457 | } 458 | .col-xs-5 { 459 | width: 41.66666667%; 460 | } 461 | .col-xs-4 { 462 | width: 33.33333333%; 463 | } 464 | .col-xs-3 { 465 | width: 25%; 466 | } 467 | .col-xs-2 { 468 | width: 16.66666667%; 469 | } 470 | .col-xs-1 { 471 | width: 8.33333333%; 472 | } 473 | .col-xs-pull-12 { 474 | right: 100%; 475 | } 476 | .col-xs-pull-11 { 477 | right: 91.66666667%; 478 | } 479 | .col-xs-pull-10 { 480 | right: 83.33333333%; 481 | } 482 | .col-xs-pull-9 { 483 | right: 75%; 484 | } 485 | .col-xs-pull-8 { 486 | right: 66.66666667%; 487 | } 488 | .col-xs-pull-7 { 489 | right: 58.33333333%; 490 | } 491 | .col-xs-pull-6 { 492 | right: 50%; 493 | } 494 | .col-xs-pull-5 { 495 | right: 41.66666667%; 496 | } 497 | .col-xs-pull-4 { 498 | right: 33.33333333%; 499 | } 500 | .col-xs-pull-3 { 501 | right: 25%; 502 | } 503 | .col-xs-pull-2 { 504 | right: 16.66666667%; 505 | } 506 | .col-xs-pull-1 { 507 | right: 8.33333333%; 508 | } 509 | .col-xs-pull-0 { 510 | right: auto; 511 | } 512 | .col-xs-push-12 { 513 | left: 100%; 514 | } 515 | .col-xs-push-11 { 516 | left: 91.66666667%; 517 | } 518 | .col-xs-push-10 { 519 | left: 83.33333333%; 520 | } 521 | .col-xs-push-9 { 522 | left: 75%; 523 | } 524 | .col-xs-push-8 { 525 | left: 66.66666667%; 526 | } 527 | .col-xs-push-7 { 528 | left: 58.33333333%; 529 | } 530 | .col-xs-push-6 { 531 | left: 50%; 532 | } 533 | .col-xs-push-5 { 534 | left: 41.66666667%; 535 | } 536 | .col-xs-push-4 { 537 | left: 33.33333333%; 538 | } 539 | .col-xs-push-3 { 540 | left: 25%; 541 | } 542 | .col-xs-push-2 { 543 | left: 16.66666667%; 544 | } 545 | .col-xs-push-1 { 546 | left: 8.33333333%; 547 | } 548 | .col-xs-push-0 { 549 | left: auto; 550 | } 551 | .col-xs-offset-12 { 552 | margin-left: 100%; 553 | } 554 | .col-xs-offset-11 { 555 | margin-left: 91.66666667%; 556 | } 557 | .col-xs-offset-10 { 558 | margin-left: 83.33333333%; 559 | } 560 | .col-xs-offset-9 { 561 | margin-left: 75%; 562 | } 563 | .col-xs-offset-8 { 564 | margin-left: 66.66666667%; 565 | } 566 | .col-xs-offset-7 { 567 | margin-left: 58.33333333%; 568 | } 569 | .col-xs-offset-6 { 570 | margin-left: 50%; 571 | } 572 | .col-xs-offset-5 { 573 | margin-left: 41.66666667%; 574 | } 575 | .col-xs-offset-4 { 576 | margin-left: 33.33333333%; 577 | } 578 | .col-xs-offset-3 { 579 | margin-left: 25%; 580 | } 581 | .col-xs-offset-2 { 582 | margin-left: 16.66666667%; 583 | } 584 | .col-xs-offset-1 { 585 | margin-left: 8.33333333%; 586 | } 587 | .col-xs-offset-0 { 588 | margin-left: 0%; 589 | } 590 | @media (min-width: 768px) { 591 | .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { 592 | float: left; 593 | } 594 | .col-sm-12 { 595 | width: 100%; 596 | } 597 | .col-sm-11 { 598 | width: 91.66666667%; 599 | } 600 | .col-sm-10 { 601 | width: 83.33333333%; 602 | } 603 | .col-sm-9 { 604 | width: 75%; 605 | } 606 | .col-sm-8 { 607 | width: 66.66666667%; 608 | } 609 | .col-sm-7 { 610 | width: 58.33333333%; 611 | } 612 | .col-sm-6 { 613 | width: 50%; 614 | } 615 | .col-sm-5 { 616 | width: 41.66666667%; 617 | } 618 | .col-sm-4 { 619 | width: 33.33333333%; 620 | } 621 | .col-sm-3 { 622 | width: 25%; 623 | } 624 | .col-sm-2 { 625 | width: 16.66666667%; 626 | } 627 | .col-sm-1 { 628 | width: 8.33333333%; 629 | } 630 | .col-sm-pull-12 { 631 | right: 100%; 632 | } 633 | .col-sm-pull-11 { 634 | right: 91.66666667%; 635 | } 636 | .col-sm-pull-10 { 637 | right: 83.33333333%; 638 | } 639 | .col-sm-pull-9 { 640 | right: 75%; 641 | } 642 | .col-sm-pull-8 { 643 | right: 66.66666667%; 644 | } 645 | .col-sm-pull-7 { 646 | right: 58.33333333%; 647 | } 648 | .col-sm-pull-6 { 649 | right: 50%; 650 | } 651 | .col-sm-pull-5 { 652 | right: 41.66666667%; 653 | } 654 | .col-sm-pull-4 { 655 | right: 33.33333333%; 656 | } 657 | .col-sm-pull-3 { 658 | right: 25%; 659 | } 660 | .col-sm-pull-2 { 661 | right: 16.66666667%; 662 | } 663 | .col-sm-pull-1 { 664 | right: 8.33333333%; 665 | } 666 | .col-sm-pull-0 { 667 | right: auto; 668 | } 669 | .col-sm-push-12 { 670 | left: 100%; 671 | } 672 | .col-sm-push-11 { 673 | left: 91.66666667%; 674 | } 675 | .col-sm-push-10 { 676 | left: 83.33333333%; 677 | } 678 | .col-sm-push-9 { 679 | left: 75%; 680 | } 681 | .col-sm-push-8 { 682 | left: 66.66666667%; 683 | } 684 | .col-sm-push-7 { 685 | left: 58.33333333%; 686 | } 687 | .col-sm-push-6 { 688 | left: 50%; 689 | } 690 | .col-sm-push-5 { 691 | left: 41.66666667%; 692 | } 693 | .col-sm-push-4 { 694 | left: 33.33333333%; 695 | } 696 | .col-sm-push-3 { 697 | left: 25%; 698 | } 699 | .col-sm-push-2 { 700 | left: 16.66666667%; 701 | } 702 | .col-sm-push-1 { 703 | left: 8.33333333%; 704 | } 705 | .col-sm-push-0 { 706 | left: auto; 707 | } 708 | .col-sm-offset-12 { 709 | margin-left: 100%; 710 | } 711 | .col-sm-offset-11 { 712 | margin-left: 91.66666667%; 713 | } 714 | .col-sm-offset-10 { 715 | margin-left: 83.33333333%; 716 | } 717 | .col-sm-offset-9 { 718 | margin-left: 75%; 719 | } 720 | .col-sm-offset-8 { 721 | margin-left: 66.66666667%; 722 | } 723 | .col-sm-offset-7 { 724 | margin-left: 58.33333333%; 725 | } 726 | .col-sm-offset-6 { 727 | margin-left: 50%; 728 | } 729 | .col-sm-offset-5 { 730 | margin-left: 41.66666667%; 731 | } 732 | .col-sm-offset-4 { 733 | margin-left: 33.33333333%; 734 | } 735 | .col-sm-offset-3 { 736 | margin-left: 25%; 737 | } 738 | .col-sm-offset-2 { 739 | margin-left: 16.66666667%; 740 | } 741 | .col-sm-offset-1 { 742 | margin-left: 8.33333333%; 743 | } 744 | .col-sm-offset-0 { 745 | margin-left: 0%; 746 | } 747 | } 748 | @media (min-width: 992px) { 749 | .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { 750 | float: left; 751 | } 752 | .col-md-12 { 753 | width: 100%; 754 | } 755 | .col-md-11 { 756 | width: 91.66666667%; 757 | } 758 | .col-md-10 { 759 | width: 83.33333333%; 760 | } 761 | .col-md-9 { 762 | width: 75%; 763 | } 764 | .col-md-8 { 765 | width: 66.66666667%; 766 | } 767 | .col-md-7 { 768 | width: 58.33333333%; 769 | } 770 | .col-md-6 { 771 | width: 50%; 772 | } 773 | .col-md-5 { 774 | width: 41.66666667%; 775 | } 776 | .col-md-4 { 777 | width: 33.33333333%; 778 | } 779 | .col-md-3 { 780 | width: 25%; 781 | } 782 | .col-md-2 { 783 | width: 16.66666667%; 784 | } 785 | .col-md-1 { 786 | width: 8.33333333%; 787 | } 788 | .col-md-pull-12 { 789 | right: 100%; 790 | } 791 | .col-md-pull-11 { 792 | right: 91.66666667%; 793 | } 794 | .col-md-pull-10 { 795 | right: 83.33333333%; 796 | } 797 | .col-md-pull-9 { 798 | right: 75%; 799 | } 800 | .col-md-pull-8 { 801 | right: 66.66666667%; 802 | } 803 | .col-md-pull-7 { 804 | right: 58.33333333%; 805 | } 806 | .col-md-pull-6 { 807 | right: 50%; 808 | } 809 | .col-md-pull-5 { 810 | right: 41.66666667%; 811 | } 812 | .col-md-pull-4 { 813 | right: 33.33333333%; 814 | } 815 | .col-md-pull-3 { 816 | right: 25%; 817 | } 818 | .col-md-pull-2 { 819 | right: 16.66666667%; 820 | } 821 | .col-md-pull-1 { 822 | right: 8.33333333%; 823 | } 824 | .col-md-pull-0 { 825 | right: auto; 826 | } 827 | .col-md-push-12 { 828 | left: 100%; 829 | } 830 | .col-md-push-11 { 831 | left: 91.66666667%; 832 | } 833 | .col-md-push-10 { 834 | left: 83.33333333%; 835 | } 836 | .col-md-push-9 { 837 | left: 75%; 838 | } 839 | .col-md-push-8 { 840 | left: 66.66666667%; 841 | } 842 | .col-md-push-7 { 843 | left: 58.33333333%; 844 | } 845 | .col-md-push-6 { 846 | left: 50%; 847 | } 848 | .col-md-push-5 { 849 | left: 41.66666667%; 850 | } 851 | .col-md-push-4 { 852 | left: 33.33333333%; 853 | } 854 | .col-md-push-3 { 855 | left: 25%; 856 | } 857 | .col-md-push-2 { 858 | left: 16.66666667%; 859 | } 860 | .col-md-push-1 { 861 | left: 8.33333333%; 862 | } 863 | .col-md-push-0 { 864 | left: auto; 865 | } 866 | .col-md-offset-12 { 867 | margin-left: 100%; 868 | } 869 | .col-md-offset-11 { 870 | margin-left: 91.66666667%; 871 | } 872 | .col-md-offset-10 { 873 | margin-left: 83.33333333%; 874 | } 875 | .col-md-offset-9 { 876 | margin-left: 75%; 877 | } 878 | .col-md-offset-8 { 879 | margin-left: 66.66666667%; 880 | } 881 | .col-md-offset-7 { 882 | margin-left: 58.33333333%; 883 | } 884 | .col-md-offset-6 { 885 | margin-left: 50%; 886 | } 887 | .col-md-offset-5 { 888 | margin-left: 41.66666667%; 889 | } 890 | .col-md-offset-4 { 891 | margin-left: 33.33333333%; 892 | } 893 | .col-md-offset-3 { 894 | margin-left: 25%; 895 | } 896 | .col-md-offset-2 { 897 | margin-left: 16.66666667%; 898 | } 899 | .col-md-offset-1 { 900 | margin-left: 8.33333333%; 901 | } 902 | .col-md-offset-0 { 903 | margin-left: 0%; 904 | } 905 | } 906 | @media (min-width: 1200px) { 907 | .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { 908 | float: left; 909 | } 910 | .col-lg-12 { 911 | width: 100%; 912 | } 913 | .col-lg-11 { 914 | width: 91.66666667%; 915 | } 916 | .col-lg-10 { 917 | width: 83.33333333%; 918 | } 919 | .col-lg-9 { 920 | width: 75%; 921 | } 922 | .col-lg-8 { 923 | width: 66.66666667%; 924 | } 925 | .col-lg-7 { 926 | width: 58.33333333%; 927 | } 928 | .col-lg-6 { 929 | width: 50%; 930 | } 931 | .col-lg-5 { 932 | width: 41.66666667%; 933 | } 934 | .col-lg-4 { 935 | width: 33.33333333%; 936 | } 937 | .col-lg-3 { 938 | width: 25%; 939 | } 940 | .col-lg-2 { 941 | width: 16.66666667%; 942 | } 943 | .col-lg-1 { 944 | width: 8.33333333%; 945 | } 946 | .col-lg-pull-12 { 947 | right: 100%; 948 | } 949 | .col-lg-pull-11 { 950 | right: 91.66666667%; 951 | } 952 | .col-lg-pull-10 { 953 | right: 83.33333333%; 954 | } 955 | .col-lg-pull-9 { 956 | right: 75%; 957 | } 958 | .col-lg-pull-8 { 959 | right: 66.66666667%; 960 | } 961 | .col-lg-pull-7 { 962 | right: 58.33333333%; 963 | } 964 | .col-lg-pull-6 { 965 | right: 50%; 966 | } 967 | .col-lg-pull-5 { 968 | right: 41.66666667%; 969 | } 970 | .col-lg-pull-4 { 971 | right: 33.33333333%; 972 | } 973 | .col-lg-pull-3 { 974 | right: 25%; 975 | } 976 | .col-lg-pull-2 { 977 | right: 16.66666667%; 978 | } 979 | .col-lg-pull-1 { 980 | right: 8.33333333%; 981 | } 982 | .col-lg-pull-0 { 983 | right: auto; 984 | } 985 | .col-lg-push-12 { 986 | left: 100%; 987 | } 988 | .col-lg-push-11 { 989 | left: 91.66666667%; 990 | } 991 | .col-lg-push-10 { 992 | left: 83.33333333%; 993 | } 994 | .col-lg-push-9 { 995 | left: 75%; 996 | } 997 | .col-lg-push-8 { 998 | left: 66.66666667%; 999 | } 1000 | .col-lg-push-7 { 1001 | left: 58.33333333%; 1002 | } 1003 | .col-lg-push-6 { 1004 | left: 50%; 1005 | } 1006 | .col-lg-push-5 { 1007 | left: 41.66666667%; 1008 | } 1009 | .col-lg-push-4 { 1010 | left: 33.33333333%; 1011 | } 1012 | .col-lg-push-3 { 1013 | left: 25%; 1014 | } 1015 | .col-lg-push-2 { 1016 | left: 16.66666667%; 1017 | } 1018 | .col-lg-push-1 { 1019 | left: 8.33333333%; 1020 | } 1021 | .col-lg-push-0 { 1022 | left: auto; 1023 | } 1024 | .col-lg-offset-12 { 1025 | margin-left: 100%; 1026 | } 1027 | .col-lg-offset-11 { 1028 | margin-left: 91.66666667%; 1029 | } 1030 | .col-lg-offset-10 { 1031 | margin-left: 83.33333333%; 1032 | } 1033 | .col-lg-offset-9 { 1034 | margin-left: 75%; 1035 | } 1036 | .col-lg-offset-8 { 1037 | margin-left: 66.66666667%; 1038 | } 1039 | .col-lg-offset-7 { 1040 | margin-left: 58.33333333%; 1041 | } 1042 | .col-lg-offset-6 { 1043 | margin-left: 50%; 1044 | } 1045 | .col-lg-offset-5 { 1046 | margin-left: 41.66666667%; 1047 | } 1048 | .col-lg-offset-4 { 1049 | margin-left: 33.33333333%; 1050 | } 1051 | .col-lg-offset-3 { 1052 | margin-left: 25%; 1053 | } 1054 | .col-lg-offset-2 { 1055 | margin-left: 16.66666667%; 1056 | } 1057 | .col-lg-offset-1 { 1058 | margin-left: 8.33333333%; 1059 | } 1060 | .col-lg-offset-0 { 1061 | margin-left: 0%; 1062 | } 1063 | } 1064 | .clearfix:before, 1065 | .clearfix:after, 1066 | .container:before, 1067 | .container:after, 1068 | .container-fluid:before, 1069 | .container-fluid:after, 1070 | .row:before, 1071 | .row:after { 1072 | content: " "; 1073 | display: table; 1074 | } 1075 | .clearfix:after, 1076 | .container:after, 1077 | .container-fluid:after, 1078 | .row:after { 1079 | clear: both; 1080 | } 1081 | .center-block { 1082 | display: block; 1083 | margin-left: auto; 1084 | margin-right: auto; 1085 | } 1086 | .pull-right { 1087 | float: right !important; 1088 | } 1089 | .pull-left { 1090 | float: left !important; 1091 | } 1092 | .hide { 1093 | display: none !important; 1094 | } 1095 | .show { 1096 | display: block !important; 1097 | } 1098 | .invisible { 1099 | visibility: hidden; 1100 | } 1101 | .text-hide { 1102 | font: 0/0 a; 1103 | color: transparent; 1104 | text-shadow: none; 1105 | background-color: transparent; 1106 | border: 0; 1107 | } 1108 | .hidden { 1109 | display: none !important; 1110 | } 1111 | .affix { 1112 | position: fixed; 1113 | } 1114 | -------------------------------------------------------------------------------- /src/utils/Dividends.js: -------------------------------------------------------------------------------- 1 | export function getDividends (number, arrSize) { 2 | var arr = [0]; 3 | var result = number / arrSize; 4 | 5 | while (arr.length < arrSize) { 6 | arr.push(Math.round(result * (arr.length + 1))); 7 | } 8 | return arr; 9 | } 10 | -------------------------------------------------------------------------------- /src/utils/DynamicScales.js: -------------------------------------------------------------------------------- 1 | var data2 = [ 2 | {x: 1999, y: 20}, 3 | {x: 2001, y: 0}, 4 | {x: 2002, y: 30}, 5 | {x: 2003, y: 45}, 6 | {x: 2004, y: 46}, 7 | {x: 2005, y: 37}, 8 | {x: 2006, y: 20}, 9 | {x: 2007, y: 15}, 10 | {x: 2008, y: 30}, 11 | {x: 2009, y: 11}, 12 | {x: 2010, y: 12}, 13 | {x: 2011, y: 22}, 14 | {x: 2012, y: 23}, 15 | {x: 2013, y: 33}, 16 | {x: 2014, y: 30}, 17 | {x: 2015, y: 44}, 18 | {x: 2016, y: 40}, 19 | {x: 2017, y: 55}, 20 | {x: 2018, y: 50}, 21 | {x: 2019, y: 66}, 22 | {x: 2020, y: 60}, 23 | {x: 2021, y: 75}, 24 | {x: 2022, y: 70}, 25 | {x: 2023, y: 80}, 26 | {x: 2024, y: 60}, 27 | {x: 2025, y: 40}, 28 | {x: 2026, y: 100}, 29 | {x: 2027, y: 92}, 30 | {x: 2028, y: 32}, 31 | {x: 2029, y: 72}, 32 | {x: 2030, y: 74}, 33 | ]; 34 | 35 | export function determineScales (data, xDataKey, yDataKey, defaultOrdinal) { 36 | var ix = [],iy = [], 37 | sx = [],sy = [], 38 | x,y; 39 | 40 | data.map((datum, key) => { 41 | if ((datum[xDataKey] === undefined || datum[xDataKey] === null )|| (datum[yDataKey] === null || datum[yDataKey] == undefined)) { 42 | console.error(`Some of your data contains 'null' or 'undefined' values at index ${key}`); 43 | } 44 | if (typeof datum[xDataKey] === 'string') { 45 | sx.push(datum[xDataKey]); 46 | } else { 47 | ix.push(datum[xDataKey]); 48 | } 49 | if (typeof datum[yDataKey] === 'string') { 50 | sy.push(datum[yDataKey]); 51 | } else { 52 | iy.push(datum[yDataKey]); 53 | } 54 | }); 55 | 56 | if (ix > sx) { 57 | x = 'linear'; 58 | } else { 59 | x = 'ordinal'; 60 | } 61 | 62 | if (iy > sy) { 63 | y = 'linear'; 64 | } else { 65 | y = 'ordinal'; 66 | } 67 | 68 | if (defaultOrdinal === 'x') { 69 | return {x: 'ordinal', y}; 70 | } else if (defaultOrdinal === 'y'){ 71 | return {x, y: 'ordinal'}; 72 | } else if (defaultOrdinal === 'xy') { 73 | return {x: 'ordinal', y: 'ordinal'}; 74 | } else { 75 | return {x, y}; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/visualization/AreaChart.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import d3 from 'd3'; 3 | import ReactFauxDOM from 'react-faux-dom'; 4 | 5 | class AreaChart extends React.Component { 6 | render () { 7 | const data = this.props.data, 8 | xDataKey = this.props.xDataKey, 9 | yDataKey = this.props.yDataKey, 10 | dataKey = this.props.dataKey || yDataKey, 11 | width= this.props.width || 350, 12 | height = this.props.height || 300, 13 | innerW = width - 60, 14 | innerH = height - 60, 15 | xScale = this.props.xScale, 16 | yScale = this.props.yScale, 17 | color = this.props.color || '#ff7473', 18 | colorOpacity = this.props.colorOpacity || 1; 19 | 20 | var area = d3.svg.area() 21 | .interpolate("monotone") 22 | .x((d) => xScale(d[xDataKey])) 23 | .y0(innerH) 24 | .y1((d) => yScale(d[dataKey])); 25 | 26 | var planeElement = ReactFauxDOM.createElement('svg') 27 | var plane = d3.select(planeElement) 28 | .attr('class', 'AreaChart') 29 | .attr('width', width) 30 | .attr('height', height) 31 | .style('z-index', this.props.zIndex) 32 | .style('position', 'absolute'); 33 | 34 | var g = plane.append('g') 35 | .attr('class', 'plane') 36 | .attr('width', innerW) 37 | .attr('height', innerH) 38 | .attr('transform', `translate(50, 20)`) 39 | .style('display', 'inline-block'); 40 | 41 | g.append('path') 42 | .datum(data) 43 | .attr('class', 'area') 44 | .attr('d', area) 45 | .style('fill', color) 46 | .style('stroke-linecap', 'round') 47 | .style('stroke-linehoin', 'round') 48 | .style('fill-opacity', colorOpacity); 49 | 50 | return plane.node().toReact(); 51 | } 52 | } 53 | 54 | AreaChart.propTypes = { 55 | width: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 56 | height: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 57 | data: React.PropTypes.array, 58 | dataKey: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).isRequired, 59 | color: React.PropTypes.string, 60 | colorOpacity: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]) 61 | } 62 | 63 | export default AreaChart; 64 | -------------------------------------------------------------------------------- /src/visualization/BarChart.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import d3 from 'd3'; 3 | import ReactFauxDOM from 'react-faux-dom'; 4 | 5 | class BarChart extends React.Component { 6 | render () { 7 | const data = this.props.data, 8 | xDataKey = this.props.xDataKey, 9 | yDataKey = this.props.yDataKey, 10 | dataKey = this.props.dataKey || yDataKey, 11 | width= this.props.width || 350, 12 | height = this.props.height || 300, 13 | innerW = width - 60, 14 | innerH = height - 60, 15 | xScale = this.props.xScale, 16 | yScale = this.props.yScale, 17 | scaleTypes = this.props.scaleTypes, 18 | color = this.props.color || 'rgb(136, 132, 216)', 19 | colorOpacity = this.props.colorOpacity || 0.6; 20 | 21 | var planeElement = ReactFauxDOM.createElement('svg') 22 | var plane = d3.select(planeElement) 23 | .attr('class', 'BarChart') 24 | .attr('width', width) 25 | .attr('height', height) 26 | .style('z-index', this.props.zIndex) 27 | .style('position', 'absolute'); 28 | 29 | var g = plane.append('g') 30 | .attr('class', 'plane') 31 | .attr('width', innerW) 32 | .attr('height', innerH) 33 | .attr('transform', `translate(50, 20)`) 34 | .style('display', 'inline-block'); 35 | 36 | if (scaleTypes.x === 'ordinal') { 37 | g.selectAll('.bar') 38 | .data(data) 39 | .enter().append('rect') 40 | .attr('class', 'bar') 41 | .attr('x', (d) => xScale(d[xDataKey])) 42 | .attr('y', (d) => yScale(d[dataKey])) 43 | .attr('height', (d) => innerH - yScale(d[dataKey])) 44 | .attr('width', xScale.rangeBand()) 45 | .style('fill', color) 46 | .style('fill-opacity', colorOpacity); 47 | } else { 48 | g.selectAll('.bar') 49 | .data(data) 50 | .enter().append('rect') 51 | .attr('class', 'bar') 52 | .style('fill', color) 53 | .style('fill-opacity', colorOpacity) 54 | .attr('x', (d) => xScale(d[xDataKey])) 55 | .attr('y', (d, i) => yScale.rangeBand(d[dataKey]) * i) 56 | .attr('height', (d, i) => innerH - yScale(d[dataKey])) 57 | .attr('width', '7'); 58 | } 59 | 60 | return plane.node().toReact(); 61 | } 62 | } 63 | 64 | BarChart.propTypes = { 65 | width: React.PropTypes.number, 66 | height: React.PropTypes.number, 67 | data: React.PropTypes.array, 68 | dataKey: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).isRequired, 69 | color: React.PropTypes.string, 70 | colorOpacity: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]) 71 | } 72 | 73 | export default BarChart; 74 | -------------------------------------------------------------------------------- /src/visualization/Legend.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import d3 from 'd3'; 3 | import ReactFauxDOM from 'react-faux-dom'; 4 | 5 | class Legend extends React.Component { 6 | render () { 7 | return ( 8 |

LEGEND UNDER CONSTRUCTION

9 | ); 10 | } 11 | } 12 | 13 | export default Legend; 14 | 15 | // var legend = g.selectAll('.legend') 16 | // .data(color.domain()) 17 | // .enter().append('g') 18 | // .attr('class', 'legend') 19 | // .attr('transform', (d, i) => `translate(0, ${i * 20})`); 20 | // 21 | // legend.append('rect') 22 | // .attr('x', innerW - 18) 23 | // .attr('width', 18) 24 | // .attr('height', 18) 25 | // .style('fill', color); 26 | // 27 | // legend.append('text') 28 | // .attr('x', width - 24) 29 | // .attr('y', 9) 30 | // .attr('dy', '.35em') 31 | // .style('text-anchor', 'end') 32 | // .text((d) => d.t); 33 | -------------------------------------------------------------------------------- /src/visualization/LineChart.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import d3 from 'd3'; 3 | import ReactFauxDOM from 'react-faux-dom'; 4 | 5 | class LineChart extends React.Component { 6 | render () { 7 | const data = this.props.data, 8 | xDataKey = this.props.xDataKey, 9 | yDataKey = this.props.yDataKey, 10 | dataKey = this.props.dataKey || yDataKey, 11 | width= this.props.width || 350, 12 | height = this.props.height || 300, 13 | innerW = width - 60, 14 | innerH = height - 60, 15 | xScale = this.props.xScale, 16 | yScale = this.props.yScale, 17 | color = this.props.color || '#47b8e0', 18 | pointBorderColor = this.props.pointBorderColor || '#ffc952', 19 | pointColor = this.props.pointColor || '#fff'; 20 | 21 | 22 | var line = d3.svg.line() 23 | .interpolate("monotone") 24 | .x((d) => xScale(d[xDataKey])) 25 | .y((d) => yScale(d[dataKey])); 26 | 27 | var planeElement = ReactFauxDOM.createElement('svg') 28 | var plane = d3.select(planeElement) 29 | .attr('class', 'LineChart') 30 | .attr('width', width) 31 | .attr('height', height) 32 | .style('z-index', this.props.zIndex) 33 | .style('position', 'absolute'); 34 | 35 | var g = plane.append('g') 36 | .attr('class', 'plane') 37 | .attr('width', innerW) 38 | .attr('height', innerH) 39 | .attr('transform', `translate(50, 20)`) 40 | .style('display', 'inline-block'); 41 | 42 | g.append('path') 43 | .datum(data) 44 | .attr('class', 'line') 45 | .attr('d', line) 46 | .style('fill', 'none') 47 | .style('stroke', color) 48 | .style('stroke-width', 2); 49 | 50 | g.selectAll('circle') 51 | .data(data) 52 | .enter().append('circle') 53 | .attr('class', 'circle') 54 | .attr('cx', (d) => xScale(d[xDataKey])) 55 | .attr('cy', (d) => yScale(d[dataKey])) 56 | .attr('r', 3) 57 | .style('fill', pointColor) 58 | .style('stroke', pointBorderColor); 59 | 60 | return plane.node().toReact(); 61 | } 62 | } 63 | 64 | LineChart.propTypes = { 65 | width: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 66 | height: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 67 | data: React.PropTypes.array, 68 | dataPoints: React.PropTypes.bool, 69 | dataKey: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).isRequired, 70 | color: React.PropTypes.string, 71 | pointColor: React.PropTypes.string, 72 | pointBorderColor: React.PropTypes.string 73 | } 74 | 75 | export default LineChart; 76 | -------------------------------------------------------------------------------- /src/visualization/PieChart.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import d3 from 'd3'; 3 | import ReactFauxDOM from 'react-faux-dom'; 4 | 5 | class PieChart extends React.Component { 6 | render () { 7 | const data = this.props.data, 8 | dataKey = this.props.dataKey || 'y', 9 | labelKey = this.props.labelKey || 'x', 10 | width= this.props.width || 350, 11 | height = this.props.height || 300, 12 | radius = Math.min(width, height) /2.1, 13 | donut = this.props.donut, 14 | colorFill = (donut) ? radius - radius / donut : 0, 15 | textColor = this.props.textColor || '#fff', 16 | colors = this.props.colors || ["#e1eef6","#ff5f2e","#fcbe32","#004e66", 17 | "#ff7473","#ffc952","#47b8e0","#34314c","#47b8e0","#47b8e0"], 18 | color = d3.scale.ordinal() 19 | .range(colors); 20 | 21 | var arc = d3.svg.arc() 22 | .outerRadius(radius - 10) 23 | .innerRadius(colorFill); 24 | 25 | var labelArc = d3.svg.arc() 26 | .outerRadius(radius - 40) 27 | .innerRadius(radius - 40); 28 | 29 | var pie = d3.layout.pie() 30 | .sort(null) 31 | .value((d) => d[dataKey]); 32 | 33 | var chart = d3.select(ReactFauxDOM.createElement('svg')) 34 | .attr('class', 'PieChart') 35 | .attr('width', width) 36 | .attr('height', height) 37 | .style('display', 'inline-block') 38 | 39 | var g = chart.append('g') 40 | .attr('transform', `translate(${width / 2}, ${height / 2})`) 41 | .style('display', 'inline-block'); 42 | 43 | var slice = g.selectAll('.arc') 44 | .data(pie(data)) 45 | .enter().append('g') 46 | .attr('class', 'arc'); 47 | 48 | slice.append('path') 49 | .attr('d', arc) 50 | .style('fill', (d) => color(d.data[labelKey])); 51 | 52 | slice.append('text') 53 | .attr('transform', (d) => `translate(${labelArc.centroid(d)})`) 54 | .attr('dy', '.35em') 55 | .text((d) => d.data[labelKey]) 56 | .style('font', '11px sans-serif') 57 | .style('fill', textColor) 58 | .style('text-anchor', 'middle'); 59 | 60 | return chart.node().toReact(); 61 | } 62 | } 63 | 64 | PieChart.propTypes = { 65 | width: React.PropTypes.number, 66 | height: React.PropTypes.number, 67 | colors: React.PropTypes.array, 68 | donut: React.PropTypes.number, 69 | data: React.PropTypes.array, 70 | dataKey: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).isRequired, 71 | labelKey: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).isRequired, 72 | textColor: React.PropTypes.string 73 | } 74 | 75 | export default PieChart; 76 | -------------------------------------------------------------------------------- /src/visualization/RadarArea.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import d3 from 'd3'; 3 | import ReactFauxDOM from 'react-faux-dom'; 4 | import { getDividends } from './../utils/Dividends.js'; 5 | 6 | class RadarArea extends React.Component { 7 | render () { 8 | const width = this.props.width || 350, 9 | height = this.props.height || 300, 10 | data = this.props.data, 11 | rangeKey = this.props.rangeKey, 12 | labelKey = this.props.labelKey, 13 | dataKey = this.props.dataKey || rangeKey, 14 | largestTick = this.props.largestTick, 15 | numBars = this.props.numBars, 16 | barHeight = this.props.barHeight, 17 | color = this.props.color, 18 | colorOpacity = this.props.colorOpacity || 0.7; 19 | 20 | var radius = d3.scale.linear() 21 | .domain([0,largestTick]) 22 | .range([0, barHeight]); 23 | 24 | var line = d3.svg.line.radial() 25 | .interpolate('linear-closed') 26 | .radius((d) => radius(d[dataKey])) 27 | .angle((d,i) => (i * 2 * Math.PI / numBars)); 28 | 29 | var area = d3.svg.area.radial() 30 | .interpolate(line.interpolate()) 31 | .innerRadius(radius(0)) 32 | .outerRadius(line.radius()) 33 | .angle(line.angle()); 34 | 35 | var plane = d3.select(ReactFauxDOM.createElement('svg')) 36 | .attr('class', 'RadarArea') 37 | .attr('width', width) 38 | .attr('height', height) 39 | .style('position', 'absolute'); 40 | 41 | var g = plane.append('g') 42 | .attr('transform', `translate(${width / 2}, ${height / 2} )`) 43 | .style('z-index', this.props.zIndex) 44 | .style('display', 'inline-block'); 45 | 46 | var layer = g.selectAll('.layer') 47 | .data([data]).enter() 48 | .append('path') 49 | .attr('class', 'layer') 50 | .attr('d', (d) => area(d)) 51 | .style('fill', color) 52 | .style('fill-opacity', colorOpacity) 53 | .style('stroke', '#CFCCCC') 54 | .style('stroke-width', '0.5px') 55 | .style('font-size', 12); 56 | 57 | return plane.node().toReact(); 58 | } 59 | } 60 | 61 | RadarArea.propTypes = { 62 | dataKey: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).isRequired, 63 | color: React.PropTypes.string, 64 | colorOpacity: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]) 65 | }; 66 | 67 | export default RadarArea; 68 | -------------------------------------------------------------------------------- /src/visualization/RadarChart.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import d3 from 'd3'; 3 | import ReactFauxDOM from 'react-faux-dom'; 4 | import { getDividends } from './../utils/Dividends.js'; 5 | 6 | class RadarChart extends React.Component { 7 | render () { 8 | const width = this.props.width || 350, 9 | height = this.props.height || 300, 10 | data = this.props.data, 11 | rangeKey = this.props.rangeKey, 12 | labelKey = this.props.labelKey, 13 | barHeight = height / 2 - 40, 14 | tickValues = data.map((d) => d[rangeKey]), 15 | largestTick = Math.max(...tickValues), 16 | tickSpace = getDividends(largestTick, 6); 17 | 18 | var plane = d3.select(ReactFauxDOM.createElement('svg')) 19 | .attr('class', 'RadarChart') 20 | .attr('width', width) 21 | .attr('height', height) 22 | .style('position', 'relative') 23 | .style('display', 'inline-block'); 24 | 25 | var g = plane.append('g') 26 | .attr('transform', `translate(${width / 2}, ${height / 2} )`); 27 | 28 | var numBars = data.length; 29 | 30 | var radius = d3.scale.linear() 31 | .domain([0,largestTick]) 32 | .range([0, barHeight]); 33 | 34 | var line = d3.svg.line.radial() 35 | .interpolate('linear-closed') 36 | .radius((d) => radius(d[rangeKey])) 37 | .angle((d,i) => (i * 2 * Math.PI / numBars)); 38 | 39 | var area = d3.svg.area.radial() 40 | .interpolate(line.interpolate()) 41 | .innerRadius(radius(0)) 42 | .outerRadius(line.radius()) 43 | .angle(line.angle()); 44 | 45 | tickValues.sort((a,b) => b - a); 46 | 47 | var tickPath = g.selectAll('.tickPath') 48 | .data(tickSpace).enter() 49 | 50 | tickPath.append('path') 51 | .attr('class', 'tickPath') 52 | .attr('d', function(d) { 53 | var tickArray = [], i; 54 | for (i = 0; i < numBars; i++) tickArray.push({[rangeKey]: d}); 55 | return area(tickArray); 56 | }) 57 | .style('fill', 'none') 58 | .style('stroke', (d,i) => (i === 0) ? 'rgb(102, 102, 102)' : 'rgb(102, 102, 102)') 59 | .style('stroke-width', (d,i) => (i === 0) ? '.8px' : '.5px'); 60 | 61 | g.selectAll('text') 62 | .data(tickSpace).enter() 63 | .append('text') 64 | .text((d) => d) 65 | .attr('y', (d) => radius(-d) + 20) 66 | .attr('x', + 3) 67 | .style('font-size', 12) 68 | .style('fill', '#CFCCCC'); 69 | 70 | var lines = g.selectAll('line') 71 | .data(data) 72 | .enter().append('g') 73 | .attr('class', 'lines'); 74 | 75 | lines.append('line') 76 | .attr('y2', - barHeight ) 77 | .style('stroke', '#5e5e5e') 78 | .style('stroke-width', '.5px') 79 | .attr('transform', (d, i) => `rotate(${(i * 360 / numBars)})`); 80 | 81 | lines.append('text') 82 | .attr('class', 'names') 83 | .attr('x', (d, i) => (barHeight + 13) * Math.sin((i * 2 * Math.PI / numBars))) 84 | .attr('y', (d, i) => -(barHeight + 13) * Math.cos((i * 2 * Math.PI / numBars))) 85 | .attr('text-anchor', function(d,i) { 86 | if (i === 0 || i === numBars / 2) { 87 | return 'middle'; 88 | }else if (i <= numBars / 2) { 89 | return 'begin'; 90 | }else { 91 | return 'end'; 92 | } 93 | }) 94 | .style('font-weight', 'bold') 95 | .style('fill', '#CFCCCC') 96 | .text((d) => d[labelKey]); 97 | 98 | return ( 99 |
100 | { 101 | (typeof this.props.children !== 'array') ? 102 | React.Children.map(this.props.children, (child, key) => { 103 | return React.cloneElement(child, { zIndex: key + 1, data, rangeKey, labelKey, width, height, largestTick, numBars, barHeight}); 104 | }) 105 | : 106 | React.cloneElement(this.props.children, { zIndex: 10 , data, rangeKey, labelKey, width, height, largestTick, numBars, barHeight}) 107 | } 108 | {plane.node().toReact()} 109 |
110 | ); 111 | } 112 | } 113 | 114 | RadarChart.propTypes = { 115 | width: React.PropTypes.number, 116 | height: React.PropTypes.number, 117 | data: React.PropTypes.array.isRequired, 118 | rangeKey: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).isRequired, 119 | labelKey: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).isRequired 120 | }; 121 | 122 | export default RadarChart; 123 | -------------------------------------------------------------------------------- /src/visualization/RadialBarChart.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import d3 from 'd3'; 3 | import ReactFauxDOM from 'react-faux-dom'; 4 | 5 | class RadialBarChart extends React.Component { 6 | render () { 7 | const {width, height, data, colors} = this.props, 8 | innerW = width - 0, 9 | innerH = height - 40, 10 | radiusMax = (height / 2.2), 11 | xColumn = "name", 12 | sliceSizeColumn = "population", 13 | colorColumn = "religion"; 14 | 15 | var xScale = d3.scale.ordinal().rangePoints([0, width]); 16 | 17 | var xAxis = d3.svg.axis().scale(xScale).orient("bottom") 18 | .outerTickSize(0); 19 | 20 | var colorScale = d3.scale.ordinal() 21 | .range(colors); 22 | 23 | var angleScale = d3.scale.linear(); 24 | 25 | var chart = d3.select(ReactFauxDOM.createElement('svg')) 26 | .attr('class', 'RadialBarChart') 27 | .attr('width', width) 28 | .attr('height', height); 29 | 30 | var g = chart.append("g") 31 | .attr('class', 'plane') 32 | .attr("transform", "translate(" + 11 + "," + 33 + ")"); 33 | 34 | var pieG = g.append("g"); 35 | 36 | var pie = d3.layout.pie(); 37 | var arc = d3.svg.arc(); 38 | 39 | xScale.domain(data.map((d) => d.name)); 40 | 41 | colorScale.domain(data.map((d) => d[colorColumn])); 42 | 43 | pie.value((d) => d[sliceSizeColumn]); 44 | 45 | angleScale.domain([0, d3.max(data, (d) => d[sliceSizeColumn])]) 46 | .range([0, Math.PI]); 47 | 48 | var pieData = pie(data); 49 | pieData.forEach(function (d){ 50 | d.startAngle = 0; 51 | d.endAngle = angleScale(d.value); 52 | }); 53 | 54 | pieG.attr("transform", `translate(${width / 2}, ${innerH}) rotate(-90)`) 55 | .attr('class', `pieSlice`); 56 | 57 | var slices = pieG.selectAll("path") 58 | .data(pieData); 59 | 60 | slices.append('text') 61 | .attr('dy', '.35em') 62 | .text((d) => d.population); 63 | 64 | slices.enter().append("path") 65 | .attr("d", function (d, i){ 66 | arc 67 | .innerRadius(function(d) { 68 | return i / (pieData.length - 1) * radiusMax; 69 | }) 70 | .outerRadius(function(d) { 71 | return (i + 1) / (pieData.length - 1) * radiusMax; 72 | }); 73 | return arc(d); 74 | }) 75 | .attr("fill", function (d){ return colorScale(d.data[colorColumn]); }); 76 | slices.exit().remove(); 77 | 78 | return chart.node().toReact(); 79 | } 80 | 81 | } 82 | 83 | RadialBarChart.propTypes = { 84 | data: React.PropTypes.array, 85 | width: React.PropTypes.number, 86 | height: React.PropTypes.number, 87 | colors: React.PropTypes.array 88 | }; 89 | 90 | export default RadialBarChart; 91 | -------------------------------------------------------------------------------- /src/visualization/Responsive.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { findDOMNode } from 'react-dom'; 3 | 4 | class Responsive extends React.Component{ 5 | constructor () { 6 | super(); 7 | this.state = { 8 | size: { 9 | w: 0, 10 | h: 0 11 | } 12 | } 13 | } 14 | 15 | componentDidMount () { 16 | window.addEventListener('resize', this.fitToParentSize.bind(this)); 17 | this.fitToParentSize(); 18 | } 19 | 20 | componentWillReceiveProps () { 21 | this.setState({ 22 | size: { 23 | w: this.props.width, 24 | h: this.props.height 25 | } 26 | }); 27 | this.fitToParentSize(); 28 | } 29 | 30 | componentWillUnmount() { 31 | window.removeEventListener('resize', this.fitToParentSize.bind(this)); 32 | } 33 | 34 | fitToParentSize () { 35 | let elem = findDOMNode(this); 36 | let w = elem.parentNode.offsetWidth; 37 | let h = elem.parentNode.offsetHeight; 38 | let currentSize = this.state.size; 39 | 40 | if (w !== currentSize.w || h !== currentSize.h) { 41 | this.setState({ 42 | size: { 43 | w: w, 44 | h: h 45 | } 46 | }); 47 | } 48 | } 49 | 50 | render () { 51 | 52 | let {width, height} = this.props; 53 | 54 | width = this.state.size.w; 55 | height = this.state.size.h; 56 | 57 | var Charts = React.cloneElement(this.props.children, { width, height}); 58 | 59 | return Charts; 60 | } 61 | }; 62 | 63 | export default Responsive; 64 | -------------------------------------------------------------------------------- /src/visualization/ScatterPlot.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import d3 from 'd3'; 3 | import ReactFauxDOM from 'react-faux-dom'; 4 | 5 | class ScatterPlot extends React.Component { 6 | render () { 7 | const data = this.props.data, 8 | xDataKey = this.props.xDataKey, 9 | yDataKey = this.props.yDataKey, 10 | dataKey = this.props.dataKey, 11 | scatterKey = this.props.scatterKey || yDataKey, 12 | width= this.props.width || 350, 13 | height = this.props.height || 300, 14 | innerW = width - 60, 15 | innerH = height - 60, 16 | xScale = this.props.xScale, 17 | yScale = this.props.yScale, 18 | pointRadius= this.props.pointRadius || 3.5, 19 | color = (this.props.colors) ? d3.scale.ordinal().range(this.props.colors) : d3.scale.category10(); 20 | 21 | var planeElement = ReactFauxDOM.createElement('svg') 22 | var plane = d3.select(planeElement) 23 | .attr('class', 'ScatterPlot') 24 | .attr('width', width) 25 | .attr('height', height) 26 | .style('position', 'absolute'); 27 | 28 | var g = plane.append('g') 29 | .attr('class', 'plane') 30 | .attr('width', innerW) 31 | .attr('height', innerH) 32 | .attr('transform', `translate(50, 20)`) 33 | .style('display', 'inline-block'); 34 | 35 | g.selectAll('.dot') 36 | .data(data) 37 | .enter().append('circle') 38 | .attr('class', 'dot') 39 | .attr('r', pointRadius) 40 | .attr('cx', (d) => xScale(d[xDataKey])) 41 | .attr('cy', (d) => yScale(d[dataKey])) 42 | .style('fill', (d) => color(d[scatterKey])); 43 | 44 | return plane.node().toReact(); 45 | } 46 | } 47 | 48 | ScatterPlot.propTypes = { 49 | width: React.PropTypes.number, 50 | height: React.PropTypes.number, 51 | data: React.PropTypes.array, 52 | colors: React.PropTypes.array, 53 | dataKey: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).isRequired, 54 | scatterKey: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 55 | pointRadius: React.PropTypes.number 56 | } 57 | 58 | export default ScatterPlot; 59 | -------------------------------------------------------------------------------- /src/visualization/TreeMap.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import d3 from 'd3'; 3 | import ReactFauxDOM from 'react-faux-dom'; 4 | 5 | class TreeMap extends React.Component { 6 | render () { 7 | const { root, width, height } = this.props; 8 | const innerW = width - 60, 9 | innerH = height - 60; 10 | 11 | var color = d3.scale.category20c(); 12 | 13 | var treemap = d3.layout.treemap() 14 | .size([width, height]) 15 | .sticky(true) 16 | .value((d) => d.size); 17 | 18 | var chart = d3.select(ReactFauxDOM.createElement('div')) 19 | .style('position', 'relative') 20 | .style('width', width) 21 | .style('height', height) 22 | .attr('class', 'TreeMap') 23 | .style('left', `10px`) 24 | .style('top', `40px`); 25 | 26 | var node = chart.datum(root) 27 | .selectAll('.node') 28 | .data(treemap.nodes) 29 | .enter().append('div') 30 | .attr('class', 'node') 31 | .style("left", (d) => d.x + "px") 32 | .style("top", (d) => d.y + "px") 33 | .style("width", (d) => Math.max(0, d.dx - 1) + "px") 34 | .style("height", (d) => Math.max(0, d.dy - 1) + "px") 35 | .style('background', (d) => (d.children) ? color (d.name) : null) 36 | .style('border', 'solid 1px white') 37 | .style('10px', 'sans-serif') 38 | .style('line-height', 12) 39 | .style('overflow', 'hidden') 40 | .style('position', 'absolute') 41 | .style('text-indent', 2) 42 | .text((d) => (d.children) ? null : d.name); 43 | 44 | return chart.node().toReact(); 45 | } 46 | } 47 | 48 | TreeMap.propTypes = { 49 | width: React.PropTypes.number, 50 | height: React.PropTypes.number, 51 | root: React.PropTypes.object 52 | } 53 | 54 | export default TreeMap; 55 | -------------------------------------------------------------------------------- /src/visualization/XYAxis.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import d3 from 'd3'; 3 | import ReactFauxDOM from 'react-faux-dom'; 4 | import { determineScales } from './../utils/DynamicScales.js'; 5 | 6 | class XYAxis extends React.Component { 7 | scales () { 8 | var xScale, yScale, 9 | xyConfig = this.props.xyConfig || {}, 10 | data = (xyConfig.data) ? xyConfig.data : this.props.data, 11 | xDataKey = (xyConfig.xDataKey) ? xyConfig.xDataKey : this.props.xDataKey || 'x', 12 | yDataKey = (xyConfig.yDataKey) ? xyConfig.yDataKey : this.props.yDataKey || 'y', 13 | width = (xyConfig.width) ? xyConfig.width : this.props.width || 350, 14 | height = (xyConfig.height) ? xyConfig.height : this.props.height || 300, 15 | innerW = width - 60, 16 | innerH = height - 60, 17 | defaultOrdinal = (xyConfig.defaultOrdinal) ? xyConfig.defaultOrdinal 18 | : this.props.defaultOrdinal, 19 | scaleTypes = (defaultOrdinal) ? determineScales(data, xDataKey, yDataKey, defaultOrdinal) 20 | : determineScales(data, xDataKey, yDataKey); 21 | 22 | if (scaleTypes.x === 'linear') { 23 | xScale = d3.scale.linear() 24 | .domain(d3.extent(data, (d) => d[xDataKey])) 25 | .range([0, innerW]); 26 | } else { 27 | xScale = d3.scale.ordinal() 28 | .domain(data.map((d) => d[xDataKey])) 29 | .rangeRoundBands([0, innerW], .2); 30 | } 31 | 32 | if (scaleTypes.y === 'linear') { 33 | yScale = d3.scale.linear() 34 | .domain([0, d3.max(data, (d) => d[yDataKey])]) 35 | .range([innerH, 0]); 36 | } else { 37 | yScale = d3.scale.ordinal() 38 | .domain(data.map((d) => d[yDataKey])) 39 | .rangeRoundBands([0, innerH], 0); 40 | } 41 | return {xScale, yScale, innerH, innerW, scaleTypes}; 42 | } 43 | 44 | makeGrid () { 45 | var xAxis, yAxis, 46 | scales = this.scales(), 47 | xScale = scales.xScale, 48 | yScale= scales.yScale, 49 | xyConfig = this.props.xyConfig || {}, 50 | xTicks = (xyConfig.xTicks) ? xyConfig.xTicks : this.props.xTicks || 4, 51 | yTicks = (xyConfig.yTicks) ? xyConfig.yTicks : this.props.yTicks || 4, 52 | grid = (xyConfig.grid) ? xyConfig.grid : this.props.grid || true; 53 | 54 | if (grid) { 55 | if (xTicks) { 56 | xAxis = d3.svg.axis() 57 | .scale(xScale) 58 | .ticks(xTicks) 59 | .orient('bottom') 60 | .innerTickSize(-scales.innerH) 61 | .outerTickSize(0) 62 | .tickPadding(3); 63 | 64 | yAxis = d3.svg.axis() 65 | .scale(yScale) 66 | .ticks(yTicks) 67 | .orient('left') 68 | .innerTickSize(-scales.innerW) 69 | .outerTickSize(0) 70 | .tickPadding(3); 71 | } else { 72 | xAxis = d3.svg.axis() 73 | .scale(xScale) 74 | .orient('bottom') 75 | .innerTickSize(-scales.innerH) 76 | .outerTickSize(0) 77 | .tickPadding(3); 78 | 79 | yAxis = d3.svg.axis() 80 | .scale(yScale) 81 | .orient('left') 82 | .innerTickSize(-scales.innerW) 83 | .outerTickSize(0) 84 | .tickPadding(3); 85 | } 86 | 87 | } else { 88 | if (yTicks) { 89 | xAxis = d3.svg.axis() 90 | .scale(xScale) 91 | .ticks(xTicks) 92 | .orient('bottom') 93 | .outerTickSize(0) 94 | .tickPadding(3); 95 | 96 | yAxis = d3.svg.axis() 97 | .scale(yScale) 98 | .ticks(yTicks) 99 | .orient('left') 100 | .outerTickSize(0) 101 | .tickPadding(3); 102 | } else { 103 | xAxis = d3.svg.axis() 104 | .scale(xScale) 105 | .orient('bottom') 106 | .outerTickSize(0) 107 | .tickPadding(3); 108 | 109 | yAxis = d3.svg.axis() 110 | .scale(yScale) 111 | .orient('left') 112 | .outerTickSize(0) 113 | .tickPadding(3); 114 | } 115 | } 116 | return {xAxis, yAxis, xScale, yScale, scaleTypes: scales.scaleTypes}; 117 | } 118 | 119 | render () { 120 | const xyConfig = this.props.xyConfig || {}, 121 | data = (xyConfig.data) ? xyConfig.data : this.props.data, 122 | xDataKey = (xyConfig.xDataKey) ? xyConfig.xDataKey : this.props.xDataKey || 'x', 123 | yDataKey = (xyConfig.yDataKey) ? xyConfig.yDataKey : this.props.yDataKey || 'y', 124 | width = (xyConfig.width) ? xyConfig.width : this.props.width || 350, 125 | height = (xyConfig.height) ? xyConfig.height : this.props.height || 300, 126 | innerW = width - 60, 127 | innerH = height - 60, 128 | xLabel = (xyConfig.xLabel) ? xyConfig.xLabel : this.props.xLabel || 'x-axis', 129 | yLabel = (xyConfig.yLabel) ? xyConfig.yLabel : this.props.yLabel || 'y-axis', 130 | gridLineType = (xyConfig.gridLines) ? (xyConfig.gridLines !== 'solid') ? '3,3' : '' : (this.props.gridLines !== 'solid') ? '3,3' : '', 131 | grid = this.makeGrid(), 132 | xScale = grid.xScale, 133 | yScale = grid.yScale, 134 | xAxis = grid.xAxis, 135 | yAxis = grid.yAxis, 136 | scaleTypes = grid.scaleTypes; 137 | 138 | var planeElement = ReactFauxDOM.createElement('svg') 139 | var plane = d3.select(planeElement) 140 | .attr('class', 'XYAxis') 141 | .attr('width', width) 142 | .attr('height', height) 143 | .style('position', 'relative') 144 | .style('z-index', 0); 145 | 146 | var g = plane.append('g') 147 | .attr('class', 'plane') 148 | .attr('transform', `translate(50, 20)`) 149 | .style('display', 'inline-block'); 150 | 151 | var xLines = g.append("g") 152 | .attr('class', 'x axis') 153 | .attr('transform', `translate(0, ${innerH})`) 154 | .call(xAxis) 155 | .style('fill', 'rgb(102, 102, 102)') 156 | .style('stroke', 'rgb(102, 102, 102)') 157 | .style('font-size', 12) 158 | .style('letter-spacing', 1.5) 159 | .style('font-weight', 100); 160 | 161 | xLines.selectAll('line') 162 | .style('stroke-width', '1') 163 | .style('stroke', 'rgb(102, 102, 102)') 164 | .style('opacity', 0.2) 165 | .style('stroke-dasharray', (gridLineType)) 166 | .style('fill', 'rgb(102, 102, 102)') 167 | .style('font-size', 12); 168 | 169 | xLines.append('text') 170 | .attr('class', 'label') 171 | .attr('x', innerW) 172 | .attr('y', -6) 173 | .style('text-anchor', 'end') 174 | .text(xLabel) 175 | .style('fill', 'rgb(102, 102, 102)') 176 | .style('font-size', 12); 177 | 178 | var yLines = g.append('g') 179 | .attr('class', 'y axis') 180 | .call(yAxis) 181 | .style('fill', 'rgb(102, 102, 102)') 182 | .style('stroke', 'rgb(102, 102, 102)') 183 | .style('font-size', 12) 184 | .style('letter-spacing', 1) 185 | .style('font-weight', 100); 186 | 187 | yLines.selectAll('line') 188 | .style('stroke-width', '1') 189 | .style('stroke', 'rgb(102, 102, 102)') 190 | .style('opacity', 0.2) 191 | .style('stroke-dasharray', (gridLineType)) 192 | .style('fill', 'rgb(102, 102, 102)') 193 | .style('font-size', 12); 194 | 195 | yLines.append('text') 196 | .attr('transform', 'rotate(-90)') 197 | .attr('y', 6) 198 | .attr('dy', '.71em') 199 | .style('text-anchor', 'end') 200 | .text(yLabel) 201 | .style('fill', 'rgb(102, 102, 102)') 202 | .style('font-size', 12); 203 | 204 | return ( 205 |
206 | { 207 | (typeof this.props.children !== 'array') ? 208 | React.Children.map(this.props.children, (child, key) => { 209 | return React.cloneElement(child, { zIndex: key + 1, data, xDataKey, yDataKey, width, height, xAxis, yAxis, xScale, yScale, scaleTypes}); 210 | }) 211 | : 212 | React.cloneElement(this.props.children, { zIndex: 10 , data, xDataKey, yDataKey, width, height, xAxis, yAxis, xScale, yScale, scaleTypes}) 213 | } 214 | {plane.node().toReact()} 215 |
216 | ); 217 | } 218 | } 219 | 220 | XYAxis.propTypes = { 221 | xyConfig: React.PropTypes.object, 222 | width: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 223 | height: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 224 | data: React.PropTypes.array, 225 | xdataKey: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 226 | ydataKey: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), 227 | defaultOrdinal: React.PropTypes.oneOf(['x', 'y', 'xy']), 228 | xTicks: React.PropTypes.number, 229 | yTicks: React.PropTypes.number, 230 | xLabel: React.PropTypes.string, 231 | yLabel: React.PropTypes.string, 232 | grid: React.PropTypes.bool, 233 | gridLines: React.PropTypes.oneOf(['solid', 'dashed']), 234 | } 235 | 236 | export default XYAxis; 237 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var env = process.env.NODE_ENV; 3 | 4 | var config = { 5 | 6 | output: { 7 | library: 'component-kit', 8 | libraryTarget: 'umd' 9 | }, 10 | 11 | externals: [ 12 | { 13 | react: { 14 | root: 'React', 15 | commonjs2: 'react', 16 | commonjs: 'react', 17 | amd: 'react' 18 | } 19 | } 20 | ], 21 | 22 | module: { 23 | loaders: [ 24 | { 25 | test: /\.js$/, 26 | exclude: /node_modules/, 27 | loader: 'babel' 28 | } 29 | ] 30 | }, 31 | 32 | node: { 33 | Buffer: false 34 | }, 35 | 36 | plugins: [ 37 | new webpack.optimize.OccurenceOrderPlugin(), 38 | new webpack.optimize.DedupePlugin(), 39 | new webpack.DefinePlugin({ 40 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) 41 | }) 42 | ] 43 | 44 | } 45 | 46 | if (env === 'production') { 47 | config.plugins.push( 48 | new webpack.optimize.UglifyJsPlugin({ 49 | compressor: { 50 | pure_getters: true, 51 | unsafe: true, 52 | unsafe_comps: true, 53 | screw_ie8: true, 54 | warnings: false 55 | } 56 | }) 57 | ) 58 | } 59 | 60 | module.exports = config; 61 | --------------------------------------------------------------------------------