Advertisement
Guest User

Untitled

a guest
Feb 10th, 2017
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import _ from 'lodash'
  2. import React, { Component, PropTypes } from 'react'
  3. import moment from 'moment'
  4. import * as d3 from 'd3'
  5. import Paper from 'material-ui/Paper'
  6. import { RadioButton } from 'material-ui/RadioButton'
  7. import RadioButtonGroup from 'material-ui/RadioButton/RadioButtonGroup'
  8.  
  9. import { Row, Col } from '../../../../../components/Grid/Grid'
  10. import { DateRangeField } from '../../../../../components/FormComponents/FormComponents'
  11. import { FilterBlock } from '../../../../../components/FiltersDialog/FilterComponents'
  12.  
  13. import Chart from '../../../../../components/Chart/Chart'
  14. import Tooltip from '../../../../../components/Tooltip/Tooltip'
  15.  
  16. import { FacebookModable } from '../../../../../shared/icons/Facebook'
  17. import { TwitterModable } from '../../../../../shared/icons/Twitter'
  18.  
  19. import style from './KeywordInTimeIntervals.scss'
  20.  
  21. import { getSpheresParticularKeyword } from '../../../actions/analysis'
  22.  
  23. export const SocialMediaRadio = ({ selectedRadio, onChange }) => (
  24.   <div className={style.container}>
  25.       <RadioButtonGroup
  26.         className={style.radioButtonGroup}
  27.         name="postType"
  28.         defaultSelected={selectedRadio}
  29.         onChange={(e, v) => {
  30.           e.stopPropagation()
  31.           onChange(v)
  32.         }}
  33.       >
  34.         <RadioButton value="lastWeek" label="Last week" />
  35.         <RadioButton value="lastMonth" label="Last month" />
  36.         <RadioButton value="lastYear" label="Last year" />
  37.         <RadioButton value="dateRange" label="Date range" />
  38.       </RadioButtonGroup>
  39.   </div>
  40. )
  41.  
  42. SocialMediaRadio.propTypes = {
  43.   selectedRadio: PropTypes.string.isRequired,
  44.   onChange: PropTypes.func
  45. }
  46.  
  47. class KeywordInTimeIntervals extends Component {
  48.   constructor (props) {
  49.     super(props)
  50.  
  51.     this.state = {
  52.       selectedRadio: 'lastWeek',
  53.       dateRange: {
  54.         from: null,
  55.         to: null
  56.       },
  57.       dateErrorText: '',
  58.       tooltip: {
  59.         visible: false,
  60.         x: 0,
  61.         y: 0
  62.       }
  63.     }
  64.  
  65.     this.onDateChange = this.onDateChange.bind(this)
  66.     this.onRadioChange = this.onRadioChange.bind(this)
  67.     this.getNewData = this.getNewData.bind(this)
  68.     this.giveColor = this.giveColor.bind(this)
  69.     this.onMouseEnter = this.onMouseEnter.bind(this)
  70.     this.onMouseLeave = this.onMouseLeave.bind(this)
  71.   }
  72.  
  73.   componentWillMount () {
  74.     const {
  75.       props: { dispatch, id },
  76.       state: { selectedRadio, dateRange }
  77.     } = this
  78.     dispatch(getSpheresParticularKeyword(id, selectedRadio, dateRange))
  79.   }
  80.  
  81.   onDateChange (newState) {
  82.     const { dateRange: { from, to } } = this.state
  83.     const error = (newState.to || to) && (newState.from || from) &&
  84.     moment(newState.to || to).isBefore(moment(newState.from || from))
  85.       ? 'Incorrected date range'
  86.       : ''
  87.  
  88.     this.setState({
  89.       dateRange: {
  90.         from: newState.from || from,
  91.         to: newState.to || to
  92.       },
  93.       dateErrorText: error
  94.     }, () => this.getNewData())
  95.   }
  96.  
  97.   onRadioChange (v) {
  98.     this.setState({
  99.       selectedRadio: v
  100.     }, () => this.getNewData())
  101.   }
  102.  
  103.   getNewData () {
  104.     const {
  105.       props: { dispatch, id },
  106.       state: { selectedRadio, dateRange, dateErrorText }
  107.     } = this
  108.     !dateErrorText.length && dispatch(getSpheresParticularKeyword(id, selectedRadio, dateRange))
  109.   }
  110.  
  111.   giveColor (data) {
  112.     const color = d3.scaleOrdinal(d3.schemeCategory10)
  113.     return data
  114.       .map(v => ({
  115.           ...v,
  116.           color: color(v.word)
  117.         })
  118.       )
  119.   }
  120.  
  121.   onMouseEnter (e) {
  122.     e.stopPropagation()
  123.     // console.log('ivent onMouseEnter', this, window)
  124.     this.setState({
  125.       tooltip: {
  126.         visible: true,
  127.         x: e.clientX,
  128.         y: e.clientY
  129.       }
  130.     })
  131.   }
  132.  
  133.   onMouseLeave (e) {
  134.     e.stopPropagation()
  135.     // console.log('ivent onMouseLeave', this.state)
  136.     this.setState({
  137.       tooltip: {
  138.         visible: false,
  139.         x: 0,
  140.         y: 0
  141.       }
  142.     })
  143.   }
  144.  
  145.   render () {
  146.     const {
  147.       state: { selectedRadio, dateErrorText, tooltip },
  148.       props: { analysis }
  149.     } = this
  150.     const keywords = this.giveColor(
  151.       analysis.particularKeyword.data.reduce((prev, curr) => {
  152.       const prevBigger = prev.facebookPhraseActivityStats
  153.  
  154.       const currBigger = curr.facebookPhraseActivityStats.length > curr.twitterPhraseActivityStats.length
  155.         ? curr.facebookPhraseActivityStats
  156.         : curr.twitterPhraseActivityStats
  157.  
  158.       const prevCurrBigger = currBigger.length > prevBigger.length
  159.         ? currBigger
  160.         : prevBigger
  161.       return {
  162.         facebookPhraseActivityStats: prevCurrBigger
  163.       }
  164.       }, { facebookPhraseActivityStats: [], twitterPhraseActivityStats: [] }).facebookPhraseActivityStats
  165.     )
  166.     console.log(keywords, 'kejwords')
  167.     const { visibility, x: tooltipX, y: tooltipY } = tooltip
  168.     return (
  169.       <Paper className={style.keywordInTimeIntervals}>
  170.         <header className={style.title}>
  171.           Proportion of activities with particular keyword on FB vs on Twitter in time intervals
  172.         </header>
  173.         <Row>
  174.           <Col>
  175.             <SocialMediaRadio
  176.               name="date" selectedRadio={selectedRadio} onChange={this.onRadioChange} />
  177.           </Col>
  178.           <Col n={2}>
  179.             <FilterBlock title="Date range">
  180.               <DateRangeField
  181.                 onChange={this.onDateChange}
  182.                 errorText={dateErrorText}
  183.                 isDisabled={selectedRadio !== 'dateRange'}
  184.                 name="dateRange"
  185.                 reduxForm={false} />
  186.             </FilterBlock>
  187.           </Col>
  188.           <Col>
  189.             {
  190.               keywords.map((keyword, i) =>
  191.                 <div key={i} className={style.keyword}>
  192.                   <svg width="12" height="20" >
  193.                   <rect
  194.                     fill={keyword.color}
  195.                     width={12}
  196.                     height={20}
  197.                     rx={4}
  198.                     ry={4}
  199.                   >
  200.                   </rect>
  201.                   </svg>
  202.                   <span>{keyword.word}</span>
  203.                 </div>
  204.               )
  205.             }
  206.           </Col>
  207.         </Row>
  208.         <Row>
  209.           <Col n={4}>
  210.             <Chart
  211.               data={analysis.particularKeyword.data
  212.                 .map(v => ({ interval: Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5), ...v }))}
  213.               width={1200} height={500} padding={30}
  214.               wantedData={['facebookPhraseActivityStats', 'twitterPhraseActivityStats']}
  215.             >
  216.               <BarAnalysis
  217.                 keywords={keywords}
  218.                 onMouseEnter={this.onMouseEnter}
  219.                 onMouseLeave={this.onMouseLeave}
  220.               />
  221.             </Chart>
  222.           </Col>
  223.         </Row>
  224.         <Tooltip
  225.           tooltipVisibility={visibility}
  226.           tooltipY={tooltipY}
  227.           tooltipX={tooltipX}
  228.           color={'red'}
  229.           label={'qwe'}
  230.           categoryValue={'60'}
  231.           percent={60}
  232.         />
  233.       </Paper>
  234.     )
  235.   }
  236. }
  237. KeywordInTimeIntervals.propTypes = {
  238.   id: PropTypes.string,
  239.   analysis: PropTypes.object,
  240.   monitoringStartDate: PropTypes.number
  241. }
  242.  
  243. export default KeywordInTimeIntervals
  244.  
  245.  
  246. const BarAnalysis = ({
  247.   key, x, height, width, onMouseEnter, onMouseLeave, scaleY, bottom, keywords,
  248.   data: { facebookPhraseActivityStats, twitterPhraseActivityStats },
  249.   ...rest
  250. }) => {
  251.   const fPAS = facebookPhraseActivityStats.reduce((prev, curr, i) => {
  252.       const previousHeights = prev.reduce((fprev, fcurr) => fprev + fcurr.props.height, 0)
  253.     const minHeight = height - scaleY(curr.count) > 10 ? height - scaleY(curr.count) : 10
  254.     const newY = i > 0
  255.         ? bottom - minHeight - previousHeights
  256.         : bottom - minHeight
  257.     return [
  258.         ...prev,
  259.         (
  260.           <rect key={i} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}
  261.                 fill={keywords.find(v => v.word === curr.word).color} x={x - 11}
  262.                 y={newY} height={minHeight} width={width} />
  263.         )
  264.       ]
  265.     }, []
  266.   )
  267.  
  268.   const tPAS = twitterPhraseActivityStats.reduce((prev, curr, i) => {
  269.     const previousHeights = prev.reduce((tprev, tcurr) => tprev + tcurr.props.height, 0)
  270.     const minHeight = height - scaleY(curr.count) > 10 ? height - scaleY(curr.count) : 10
  271.     const newY = i > 0
  272.       ? bottom - minHeight - previousHeights
  273.       : bottom - minHeight
  274.     return [
  275.       ...prev,
  276.       (
  277.         <rect key={i} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}
  278.               fill={keywords.find(v => v.word === curr.word).color} x={x + 11}
  279.               y={newY} height={minHeight} width={width} />
  280.       )
  281.     ]
  282.     }, []
  283.   )
  284.  
  285.   return (
  286.   <g key={key}>
  287.     <g>
  288.     {
  289.       fPAS.length > 0
  290.         ? (fPAS.concat(<FacebookModable className={style.icon}
  291.             width={20} height={20}
  292.             x={fPAS[fPAS.length - 1].props.x} y={fPAS[fPAS.length - 1].props.y - 25} />))
  293.         : fPAS
  294.     }
  295.     </g>
  296.     <g>
  297.     {
  298.       tPAS.length > 0
  299.         ? (tPAS.concat(<TwitterModable className={style.icon}
  300.             width={20} height={20}
  301.             x={tPAS[tPAS.length - 1].props.x} y={tPAS[tPAS.length - 1].props.y - 25} />))
  302.         : tPAS
  303.     }
  304.     </g>
  305.   </g>
  306. )
  307. }
  308.  
  309. BarAnalysis.propTypes = {
  310.   key: PropTypes.string.isRequired,
  311.   data: PropTypes.object.isRequired,
  312.   keywords: PropTypes.array.isRequired,
  313.   x: PropTypes.number,
  314.   height: PropTypes.number,
  315.   width: PropTypes.number,
  316.   bottom: PropTypes.number,
  317.   scaleY: PropTypes.func,
  318.   onMouseEnter: PropTypes.func,
  319.   onMouseLeave: PropTypes.func
  320. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement