Source: components/userComponents/monitoredArea/detail/PassDetail.js

  1. import React, { Component } from 'react';
  2. import * as am4core from "@amcharts/amcharts4/core";
  3. import * as am4charts from "@amcharts/amcharts4/charts";
  4. import am4themes_animated from "@amcharts/amcharts4/themes/animated";
  5. import { withNamespaces } from 'react-i18next';
  6. am4core.useTheme(am4themes_animated);
  7. /**
  8. * @extends Component
  9. * @hideconstructor
  10. */
  11. class PassDetail extends React.Component {
  12. /**
  13. * @constructs
  14. * @param props
  15. */
  16. constructor(props) {
  17. super(props);
  18. this.myRef = React.createRef();
  19. }
  20. // render() {
  21. // const { t } = this.props;
  22. // let table;
  23. //
  24. // table = <ReactTable
  25. // filterable
  26. // columns={[
  27. // {
  28. // Header: t('monitoredArea.info'),
  29. // accessor: "name",
  30. // width: 900,
  31. // Filter: ({filter, onChange}) => (
  32. // <div style={{position: 'relative'}}>
  33. // <input
  34. // onChange={event => onChange(event.target.value)}
  35. // value={filter ? filter.value : ''}
  36. // placeholder={t('monitoredArea.placeholderFilterByZone')}
  37. // style={{
  38. // width: '100%',
  39. // backgroundColor: 'transparent',
  40. // color: '#222222',
  41. // }}
  42. // />
  43. // <i className="fa fa-search" style={{position: 'absolute', right: '10px', lineHeight: '30px'}}>
  44. //
  45. // </i>
  46. // </div>
  47. // ),
  48. // },
  49. // {
  50. // Header: t('monitoredArea.passedVehicles'),
  51. // accessor: "count",
  52. // Filter: ({filter, onChange}) => (
  53. // <div style={{position: 'relative'}}>
  54. // <input
  55. // onChange={event => onChange(event.target.value)}
  56. // value={filter ? filter.value : ''}
  57. // placeholder={t('monitoredArea.placeholderFilterByValue')}
  58. // style={{
  59. // width: '100%',
  60. // backgroundColor: 'transparent',
  61. // color: '#222222',
  62. // }}
  63. // />
  64. // <i className="fa fa-search" style={{position: 'absolute', right: '10px', lineHeight: '30px'}}>
  65. //
  66. // </i>
  67. // </div>
  68. // ),
  69. // },
  70. // ]}
  71. // data={this.props.data.tableOfTransits}
  72. // defaultPageSize={7}
  73. // className="-striped -highlight"
  74. //
  75. // />;
  76. // return (
  77. // <div>
  78. // <div>{table}</div>
  79. // </div>
  80. // );
  81. /**
  82. *
  83. * @param data
  84. * @returns {XYChart}
  85. */
  86. createHistoGraph = (data) => {
  87. const { t } = this.props;
  88. // Create chart instance
  89. let chart = am4core.create("chartdiv", am4charts.XYChart);
  90. chart.data = data;
  91. chart.data.sort((a, b) => a.count - b.count);
  92. chart.seriesContainer.draggable = false;
  93. chart.seriesContainer.draggable = false;
  94. chart.seriesContainer.resizable = false;
  95. chart.maxZoomLevel = 1;
  96. // Create axes
  97. let categoryAxis = chart.yAxes.push(new am4charts.CategoryAxis());
  98. categoryAxis.dataFields.category = "name";
  99. categoryAxis.renderer.grid.template.location = 0;
  100. categoryAxis.renderer.minGridDistance = 30;
  101. //categoryAxis.renderer.labels.template.rotation = 50;
  102. categoryAxis.renderer.labels.template.disabled = true;
  103. let valueAxis = chart.xAxes.push(new am4charts.ValueAxis( ));
  104. valueAxis.title.text = t('graph.numberOfPassedVehicles');
  105. // Create series
  106. let series = chart.series.push(new am4charts.ColumnSeries());
  107. series.dataFields.valueX = "count";
  108. series.dataFields.categoryY = "name";
  109. series.columns.template.tooltipText = '{valueX}';
  110. var valueLabel = series.bullets.push(new am4charts.LabelBullet());
  111. valueLabel.label.text = "{categoryY}";
  112. valueLabel.label.fontSize = 10;
  113. valueLabel.label.truncate = false;
  114. valueLabel.label.hideOversized = false;
  115. valueLabel.locationX = 1;
  116. valueLabel.label.horizontalCenter = "left";
  117. valueLabel.label.dx = 10;
  118. valueLabel.tooltipText = '{categoryY}';
  119. /* Create a heat rule */
  120. series.heatRules.push({
  121. "target": series.columns.template,
  122. "property": "fill",
  123. "min": am4core.color("#adf58c"),
  124. "max": am4core.color("#ed8186"),
  125. "dataField": "valueX"
  126. });
  127. //Set cell size in pixels
  128. let cellSize = 40;
  129. //kicks in at the moment when chart has finished processing its data.
  130. chart.events.on("datavalidated", function(ev) {
  131. // Get objects of interest
  132. let chart = ev.target;
  133. let categoryAxis = chart.yAxes.getIndex(0);
  134. // Calculate how we need to adjust chart height
  135. let adjustHeight;
  136. if(chart.data.length < 2){
  137. adjustHeight = 2 * cellSize - categoryAxis.pixelHeight;
  138. } else {
  139. adjustHeight = chart.data.length * cellSize - categoryAxis.pixelHeight;
  140. }
  141. // get current chart height
  142. let targetHeight = chart.pixelHeight + adjustHeight;
  143. // Set it on chart's container
  144. // console.log("cell size: " + cellSize);
  145. // console.log("category pixel height: " + categoryAxis.pixelHeight);
  146. // console.log("pixel height: " + chart.pixelHeight);
  147. // console.log("adjustHeight: " + adjustHeight);
  148. // console.log("target: " + targetHeight);
  149. chart.svgContainer.htmlElement.style.height = targetHeight + "px";
  150. });
  151. return chart;
  152. }
  153. /**
  154. *
  155. */
  156. componentDidMount() {
  157. this.chart = this.createHistoGraph(this.props.data.tableOfTransits);
  158. window.addEventListener('resize', () => {
  159. if (this.props.data !== undefined && this.props.data.tableOfTransits !== undefined && this.props.data.tableOfTransits.length > 0) {
  160. //this.chart = this.createHistoGraph(this.props.data.tableOfTransits);
  161. this.reloadData(this.props.data.tableOfTransits)
  162. }
  163. });
  164. }
  165. /**
  166. *
  167. * @param prevProps
  168. */
  169. componentDidUpdate(prevProps) {
  170. if (this.props.data !== prevProps.data) {
  171. if (this.props.data !== undefined && this.props.data.tableOfTransits !== undefined && this.props.data.tableOfTransits.length > 0) {
  172. this.reloadData(this.props.data.tableOfTransits)
  173. }
  174. }
  175. }
  176. /**
  177. *
  178. * @param data
  179. */
  180. reloadData(data){
  181. if (this.chart !== undefined && this.chart !== null){
  182. this.chart.data = data;
  183. this.chart.data.sort((a, b) => a.count - b.count);
  184. //Updating the graph to show the new data
  185. this.chart.validateData();
  186. }else{
  187. this.chart = this.createHistoGraph(data);
  188. }
  189. }
  190. /**
  191. *
  192. */
  193. componentWillUnmount() {
  194. if (this.chart) {
  195. this.chart.dispose();
  196. }
  197. }
  198. /**
  199. *
  200. * @returns {*}
  201. */
  202. render() {
  203. const { t } = this.props;
  204. let name;
  205. if (this.props.data !== undefined && this.props.data.tableOfTransits !== undefined && this.props.data.tableOfTransits.length > 0)
  206. name = t("graph.transit") + ": " + this.props.data.name;
  207. else if (this.props.data !== undefined && this.props.data.name !== undefined)
  208. name = t("graph.zone") + ": " + this.props.data.name;
  209. else name = "";
  210. return(
  211. <div className="box">
  212. <div className="box-header">
  213. <div className="col-md-10">
  214. <h3 className="box-title">{name}</h3>
  215. </div>
  216. </div>
  217. <div ref={this.myRef} className="box-body">
  218. {<div id="chartdiv" style={{
  219. width: "100%",
  220. height: "100%"
  221. }}>
  222. </div>}
  223. <br/>
  224. </div>
  225. </div>
  226. )
  227. // if(this.props.data){
  228. // return (
  229. // <div>
  230. // <div className="box">
  231. // <div className="box-header">
  232. // <div className="col-md-6">
  233. // <h3 className="box-title text-right" >Chart of passed vehicles</h3>
  234. // </div>
  235. // </div>
  236. // <div className="box-body">
  237. // {<div id="chartdiv">
  238. // </div>}
  239. // </div>
  240. // </div>
  241. // </div>
  242. // );
  243. // }
  244. // else {
  245. // return (<div>Loading...</div>)
  246. // }
  247. }
  248. }
  249. export default withNamespaces()(PassDetail);