123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- //© 2019 Dublin City University, Trinity College Dublin. All rights reserved. This material may not be reproduced, displayed, modified or distributed without the express prior written permission of the copyright holder.
- import React, { Component} from 'react';
- import { Bar } from 'react-chartjs-2';
- import {
- Card,
- CardBody,
- CardHeader,
- ButtonDropdown,
- ButtonGroup,
- DropdownItem,
- DropdownMenu,
- DropdownToggle,
- Media,
- Modal,
- ModalHeader,
- ModalBody,
- ModalFooter,
- Button,
- FormGroup,
- Form,
- Label,
- Input,
- } from 'reactstrap';
- import { connect } from 'react-redux';
- import { CustomTooltips } from '@coreui/coreui-plugin-chartjs-custom-tooltips';
- import { getAllAssessmentDates } from '../../services/tripleStoreAPIs/sparql/getAllAssessmentDates';
- import { getAssessmentQuality } from '../../services/tripleStoreAPIs/sparql/getAssessmentQuality';
- import { read } from '../../services/tripleStoreAPIs/readFromTripleStore';
- import LoadingSpinner from './loading';
- import LoadingFailed from './loadingFailed';
- const options = {
- tooltips: {
- enabled: false,
- custom: CustomTooltips
- },
- scales: {
- xAxes: [{
- barThickness: 40,
- scaleLabel: {
- display: true,
- labelString: "Date/Time"
- }
- }],
- yAxes:[
- {
- ticks :{
- max: 100,
- min: 0,
- stepSize: 20
- },
- scaleLabel: {
- display: true,
- labelString: "Data Quality"
- }
- }
- ]
- },
- legend: {
- display: false
- },
- maintainAspectRatio: false
- }
- class DataQualityOverTime extends Component{
- constructor(props) {
- super(props);
- this.state = {
- assessmentDates:[],
- assessmentQualities:[],
- qualityStatus :[],
- isloading : false,
- loadFailed : false,
- dropdownOpen: false,
- popupOpen: false,
- tempLimit: sessionStorage.getItem("LIMIT")
- };
- }
- togglePopup = () => {
- this.setState(prevState => ({
- popupOpen: !prevState.popupOpen
- }));
- }
- onChangeLimit = (event) =>
- {
- this.setState(
- { tempLimit: event.target.value }
- );
- }
- saveLimit = () =>
- {
- //console.log(this.state.tempLimit);
- sessionStorage.setItem("LIMIT",this.state.tempLimit );
- this.togglePopup();
- }
- componentDidMount(){
- //console.log("componentDidMount");
- //console.log(this.props)
- var linkedDataset = this.props.datasetDetailsCache[0]
- if(this.props.is1Spatial){
- var sessionStore = JSON.parse(sessionStorage.getItem("PIPELINECACHE"));
- var index = 0
- sessionStore.forEach((store, index)=>{
- if(this.props.datasetID === store.datasetID)
- index = index
- })
- console.log(index)
- linkedDataset = sessionStore[index]
- }
- this.setState({is1Spatial: this.props.is1Spatial})
- if (this.props.is1Spatial || this.props.datasetDetailsCache.length>0) {
- this.setState({ isloading: true }, () => {
- this.setup(linkedDataset)
- .then(()=>{
- let assessmentDate =[];
- let assessmentQuality = [];
- let assessmentColor =[];
- if(typeof linkedDataset.historicAssessmentData!=="undefined")
- {
- if(linkedDataset.historicAssessmentData.length>0)
- {
- assessmentDate = linkedDataset.historicAssessmentData.map((result,index) => {
- return ({index: index, result:Object.keys(result)[0]});
- });
- }
- }
- assessmentDate.forEach((date)=>{
- //console.log(date.result);
- let quality=0;
- let status="rgba(255,99,132,0.2)";
- let tempTotal=[];
- var cache = linkedDataset.historicAssessmentData[date.index][date.result]
- tempTotal = cache.map((metricDetails) => {
- let metricValueType = (metricDetails.Value.datatype).split("#")[1]
- let metricValue = 0.0;
- if (metricValueType === "boolean") {
- let metricValueTemp = metricDetails.Value.value
- if (metricValueTemp === "true") {
- metricValue = 1.0;
- }
- }
- else {
- metricValue = Number.parseFloat(metricDetails.Value.value).toFixed(2)
- }
- tempTotal.push(
- {
- /* metric: (metricDetails.Metric.value).split("#")[1], */
- metric: metricDetails.Metric.value,
- value: metricValue
- }
- );
- if(!this.state.is1Spatial)
- return (linkedDataset.assessmentMetrics.filter((metric) => { if (metric.assess === true & metric.metric === metricDetails.Metric.value) { return true; } return false }).map((metric) => {if (metricValueType === "boolean") { if(metricValue===metric.target){return parseFloat(1.0, 10);}else{return parseFloat(0.0, 10);}}else{return parseFloat(metricValue, 10);}}));
- else{
- if(metricValue != -Infinity){
- return parseFloat(metricValue, 10)
- }
- else{
- return 0
- }
- }
- });
- if (tempTotal.length > 0) {
- let filteredArray = tempTotal.flat();
- if(filteredArray.length>1)
- {
- quality = filteredArray.reduce((previous, current) => current += previous) / filteredArray.length;
- }
- else {
- quality = filteredArray[0];
- }
- if (quality >= linkedDataset.expectedProgress) {
- status="rgba(0,255,0,0.2)";
- }
- quality = Number(parseFloat(quality).toFixed(4))*100;
- }
- assessmentQuality.push(
- {
- index : date.index,
- quality : Number.parseFloat(quality).toFixed(2)
- }
- );
- assessmentColor.push(
- {
- index : date.index,
- status : status
- }
- );
- });
- this.setState(
- {
- assessmentDates : assessmentDate,
- assessmentQualities : assessmentQuality,
- qualityStatus : assessmentColor,
- isloading: false
- }
- );
- });
- });
- }
- }
- setup = async (props) =>
- {
- return;
- }
- fetchHistoricDateFromCache = (historicAssessmentDataFromCache)=>
- {
- return new Promise((resolve)=>{
- let cachedHistoricDates = [];
- if (typeof historicAssessmentDataFromCache!=="undefined")
- {
- historicAssessmentDataFromCache.forEach((assessmentData)=>{
- cachedHistoricDates.push(Object.keys(assessmentData));
- });
- }
- //console.log(cachedHistoricDates.flat());
- resolve(cachedHistoricDates.flat());
- });
- }
- fetchHistoricDateFromTripleStore = (datasetPLD) =>
- {
- return new Promise((resolve)=>{
- let historicDates = [];
- read(getAllAssessmentDates(datasetPLD))
- .then((response) => {
- //console.log(response);
- if (response) {
- if (response.results.bindings.length > 0) {
- historicDates = response.results.bindings.map((result,index) => {
- return ({result:result.TimePeriod.value});
- });
- }
- }
- //console.log(historicDates);
- resolve(historicDates);
- });
- });
- }
- refreshCacheWithHistoricAssessmentData = (cachedHistoricDates, date, datasetID,datasetPLD) =>
- {
- return new Promise((resolve)=>{
- //console.log(cachedHistoricDates.indexOf(date.result));
- if(cachedHistoricDates.indexOf(date.result) >= 0)
- {
- //console.log("Yes");
- resolve();
- }
- else
- {
- //console.log("No");
- read(getAssessmentQuality(datasetPLD,date.result)).then((response) => {
- let assessmentResult = {
- [date.result] : [...response.results.bindings]
- }
- //console.log(assessmentResult);
- this.props.updateHistoricAssessmentDetailsToCache(assessmentResult,datasetID);
- resolve();
- }
- );
- }
- });
- }
- toggleAlertModel = () => {
- this.setState({
- loadFailed: false
- });
- }
- toggle = () => {
- this.setState({
- dropdownOpen: !this.state.dropdownOpen,
- });
- }
- render ()
- {
- //console.log(this.props.datasetDetailsCache[0]);
- console.log(this.state.assessmentDates)
- let assessmentCount = this.state.assessmentDates.length;
- var dateTime = ''
- var dates = ''
- var time = ''
- if(this.state.is1Spatial){
- dateTime = this.state.assessmentDates.map((date)=>{return((date.result));});
- dates = dateTime.map((date)=>{return((date).split(" ")[0]);});
- time = dateTime.map((date)=>{return((date).split(" ")[1]);});
- }else{
- dateTime = this.state.assessmentDates.map((date)=>{return((date.result).split(".")[0]);});
- dates = dateTime.map((date)=>{return((date).split("T")[0]);});
- time = dateTime.map((date)=>{return((date).split("T")[1]);});
- }
- let backgroundColour = this.state.qualityStatus.sort((a, b) => parseInt(a.index) - parseInt(b.index));
- let assessData = this.state.assessmentQualities.sort((a, b) => parseInt(a.index) - parseInt(b.index));
- if(assessmentCount>sessionStorage.getItem("LIMIT"))
- {
- let startIndex=assessmentCount-sessionStorage.getItem("LIMIT");
- dateTime=dateTime.slice(startIndex);
- backgroundColour=backgroundColour.slice(startIndex);
- assessData=assessData.slice(startIndex);
- }
- let mergedDateTime=[];
- let size = dateTime.length;
- let index=0;
- for (index=0; index<size;index++)
- {
- mergedDateTime.push([dates[index],time[index]]);
- }
- const bar = {
- labels: [...mergedDateTime],
- datasets: [
- {
- label: this.state.datasetPLD,
- backgroundColor: backgroundColour.map((status)=> {return(status.status)}),
- data: assessData.map((data)=>{return(data.quality)}) ,
- },
- ],
- };
- let model = (<Modal isOpen={true} className="modal-dialog-centered">
- <ModalHeader style={{ margin: 'auto' }}>Configure Settings</ModalHeader>
- <ModalBody>
- <Form>
- <FormGroup>
- <Label>Dataset Name:</Label>
- <Input type="text" name="limitInput" id="limitInput" ref="limitInput" value={this.state.tempLimit} onChange={this.onChangeLimit} />
- </FormGroup>
- </Form>
- </ModalBody>
- <ModalFooter>
- <Button color="secondary" onClick={this.togglePopup}>Close</Button>
- <Button color="primary" onClick={this.saveLimit}>Save</Button>{' '}
- </ModalFooter>
- </Modal>
- );
- return(
- <Card className="w-75">
- {this.state.popupOpen?model:null}
- <CardHeader>
- Data Quality over Time
- <ButtonGroup className="float-right">
- <ButtonDropdown id='card1' isOpen={this.state.dropdownOpen} toggle={this.toggle}>
- <DropdownToggle caret className="p-0" color="black">
- <Media className="icon-settings"></Media>
- </DropdownToggle>
- <DropdownMenu right>
- <DropdownItem onClick={this.togglePopup}>Config</DropdownItem>
- </DropdownMenu>
- </ButtonDropdown>
- </ButtonGroup>
- </CardHeader>
- <CardBody>
- {this.state.isloading ? <LoadingSpinner /> : null}
- {this.state.loadFailed ? <LoadingFailed clickHandler={this.toggleAlertModel} /> : null}
- <Bar data={bar} options={options} />
- </CardBody>
- </Card>
- );
- }
- }
- const mapStateToProps = (state,ownProps) => {
- let datasetID = ownProps.datasetID;
- let datasetDetails = null
- if(ownProps.is1Spatial && state.pipelineCache){
- datasetDetails = state.pipelineCache.filter((dataset)=>{if(dataset.datasetID===datasetID){return dataset;} return null; });
- }else{
- datasetDetails = state.datasetDetailsCache.filter((dataset)=>{if(dataset.datasetID===datasetID){return dataset;} return null; });
- }
- return (
- {
- datasetDetailsCache: datasetDetails
- }
- );
- }
- const mapDispatchToProps = (dispatch) => {
- return ({
- updateHistoricAssessmentDetailsToCache: (historicAssessmentData,datasetID) => { return dispatch({ type: 'UPDATE_HISTORIC_ASSESSMENT_DETAILS_CACHE', payLoad: {historicAssessmentData:historicAssessmentData, datasetID:datasetID} }); }
- }
- );
- }
- export default connect(mapStateToProps, mapDispatchToProps)(DataQualityOverTime);
|