简体   繁体   English

如何在reactjs中将文件路径转换为URL

[英]how to convert filepath to url in reactjs

I'm trying to modify my code to load a Json file from an URL rather than to use from a local file. 我正在尝试修改代码以从URL加载Json文件,而不是从本地文件使用。 Can anyone please explain me how to resolve this issue 谁能解释一下如何解决这个问题

const TAXONOMY_DATA = require(../../assets/chord.json);

//for filters**
class AddRemoveSelection extends Component {
    constructor(props) {
        super(props);

        this.state = {
            selectedOptions: []
        }
    }

    handleDeselect = (deselectedOptions) => {
        var selectedOptions = this.state.selectedOptions.slice()
        deselectedOptions.forEach(option => {
            selectedOptions.splice(selectedOptions.indexOf(option), 1)
        })
        this.setState({ selectedOptions })
        this.props.onChange(selectedOptions)
    }

    handleSelect = (selectedOptions) => {
        selectedOptions.sort((a, b) => a.id - b.id)
        this.setState({ selectedOptions })
        this.props.onChange(selectedOptions)
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.options !== this.props.options) {
            this.setState({ selectedOptions: nextProps.options });
        }
    }

    render() {
        const { selectedOptions } = this.state
        const { options, type } = this.props

        return <div className="row mt-20">
            <div className="col-sm-6">
                <FilteredMultiSelect
                    placeholder={`Select ${type}`}
                    buttonText="Add"
                    classNames={{
                        filter: 'form-control',
                        select: 'form-control',
                        button: 'btn btn btn-block btn-default',
                        buttonActive: 'btn btn btn-block btn-primary',
                    }}
                    onChange={this.handleSelect}
                    options={options}
                    selectedOptions={selectedOptions}
                    textProp="name"
                    valueProp="id"
                />
            </div>
            <div className="col-sm-6">
                <FilteredMultiSelect
                    placeholder={`Visible ${type}`}
                    buttonText="Delete"
                    classNames={{
                        filter: 'form-control',
                        select: 'form-control',
                        button: 'btn btn btn-block btn-default',
                        buttonActive: 'btn btn btn-block btn-danger'
                    }}
                    onChange={this.handleDeselect}
                    options={selectedOptions}
                    textProp="name"
                    valueProp="id"
                />
            </div>
        </div>
    }
}


export default class ChordFinal extends Component {
    constructor(props) {
        super(props);
        this.state = {
            master: {},
            filterKeyword: {},
            filterTaxonomy: {},
            tooltip: {},
            pFormat: d3.format(".1%"),
            qFormat: d3.format(",.0f"),

            rankList: [],
            categoryList: [],
            selectedRank: "",
            selectedCategory: "",

            keywordsOptions: [],
            selectedKeywordsOptions: [],
            taxonomyOptions: [],
            selectedTaxonomyOptions: [],
        };

        this.importJSON = this.importJSON.bind(this);
        this.addFilter = this.addFilter.bind(this);
        this.updateChart = this.updateChart.bind(this);
        this.updateTooltip = this.updateTooltip.bind(this);
        this.reset = this.reset.bind(this);
        this.setFilters = this.setFilters.bind(this);
    }

    toggleVisibility = () => this.setState({ visible: !this.state.visible })

    updateTooltip = (data) => {
        console.log(data);

        this.setState({
            tooltip: data
        });
    };



    addFilter = (name) => {
        let filters = this.state.filters;
        filters[name] = {
            name: name,
            hide: true
        };
        this.setState({
            hasFilters: true,
            filters: filters
        });
        this.update()
    };

    // 1 - parse the data to get the list of ranks and categories
    importJSON() {

        // temporary dictionaries
        const ranks = {}
        const categories = {}
        const master = {}
        const rankList = []
        const categoryList = []

        TAXONOMY_DATA.fulldata.forEach(d => {
            const rank = d.taxonomyRank;
            const keyword = d.keywordCategory;

            ranks[rank] = true;
            categories[keyword] = true;
            if (!master[rank]) {
                master[rank] = {}
            }
            if (!master[rank][keyword]) {
                master[rank][keyword] = []
            }
            master[rank][keyword].push(d);
        })

        // add ranks/categories to list
        for (let key in ranks) {
            if (ranks.hasOwnProperty(key)) {
                rankList.push(key);
            }
        }

        for (let key in categories) {
            if (categories.hasOwnProperty(key)) {
                categoryList.push(key);
            }
        }
        console.log('rankList', rankList)
        console.log('categoryList', categoryList)
        console.log('master', master)

        this.setState({
            rankList,
            categoryList,
            master,

            selectedRank: "superfamily",
            selectedCategory: "Biological process",
        }, () => {
            this.updateList()
        });
    }

    // create taxonomy/keyword list
    updateList() {
        // temporary dictionary
        const keywords = {}
        const taxonomies = {}
        const { master, selectedRank, selectedCategory } = this.state
        console.log(`master[${selectedRank}][${selectedCategory}]`)

        if (master && master[selectedRank] && master[selectedRank][selectedCategory]) {
            console.log(`master[${selectedRank}][${selectedCategory}]`, master[selectedRank][selectedCategory])
            master[selectedRank][selectedCategory].forEach(d => {
                keywords[d.keywordId] = d.keywordName;
                taxonomies[d.taxId] = d.taxonomyName;
            })

            const keywordsOptions = [];
            const taxonomyOptions = [];

            // creates keyword list
            for (let key in keywords) {
                if (keywords.hasOwnProperty(key)) {
                    keywordsOptions.push({ id: key, name: keywords[key] });
                }
            }

            // creates taxonomy list
            for (let key in taxonomies) {
                if (taxonomies.hasOwnProperty(key)) {
                    taxonomyOptions.push({ id: key, name: taxonomies[key] });
                }
            }

            const selectedKeywordsOptions = keywordsOptions.slice();
            const selectedTaxonomyOptions = taxonomyOptions.slice();

            this.setState({
                keywordsOptions,
                selectedKeywordsOptions,
                taxonomyOptions,
                selectedTaxonomyOptions,

                filterKeyword: keywords,
                filterTaxonomy: taxonomies,
            }, () => {
                this.updateChart();
            });
        }
    }

    updateChart() {
        const { master, selectedRank, selectedCategory, filterKeyword, filterTaxonomy } = this.state;
        const data = master[selectedRank][selectedCategory];
        if (data) {
            this.child.drawChords(data.filter(d => (filterKeyword[d.keywordId] && filterTaxonomy[d.taxId])));
        }
    };

    setFilters(item, input) {
        let state = this.state;
        state.filters[item.name] = {
            name: item.name,
            hide: input.target.checked
        }
        this.setState({
            filters: state.filters
        });
        this.update(state);
    }

    reset() {
        let state = this.state;
        if (Object.keys(state.filters).length > 0 && state.hasFilters {
            state.filters = {};
            state.hasFilters = false;
            this.setState({
                filters: {},
                hasFilters: false
            });
            this.updateChart();
        }
    }

    componentDidMount() {
        this.setState({ isComponentMount: true });

        this.importJSON();
    }

    render =() => {
        let state = this.state;
        const { visible, rankList, categoryList, selectedRank, selectedCategory } = this.state

        return <div>
            <Sidebar.Pushable as={Segment}>
              <Button onClick={this.toggleVisibility} icon className="navbar-toggle">
                <Icon name="align justify"/>
              </Button>
              <Sidebar as={Menu} animation="overlay" width="very wide" direction="right" visible={visible} icon="labeled" vertical inverted>
                <Icon className="close" size="large" onClick={this.toggleVisibility} />
                <div className="row mt-50" />
                <div className="row mt-20">
                  <div className="col-sm-6">
                    <Dropdown placeholder="Select Rank" selection value={selectedRank} options={rankList.map(
                        item => ({ key: item, text: item, value: item })
                      )} onChange={(e, data) => {
                        this.setState(
                          { selectedRank: data.value },
                          () => {
                            this.updateList();
                          }
                        );
                      }} />
                  </div>
                  <div className="col-sm-6">
                    <Dropdown placeholder="Select Category" selection value={selectedCategory} options={categoryList.map(
                        item => ({ key: item, text: item, value: item })
                      )} onChange={(e, data) => {
                        this.setState(
                          { selectedCategory: data.value },
                          () => {
                            this.updateList();
                          }
                        );
                      }} />
                  </div>
                </div>
                <AddRemoveSelection type="Taxonomy" options={this.state.taxonomyOptions} onChange={selectedTaxonomyOptions
{
                    this.setState({ selectedTaxonomyOptions });
                  }} />
                <br />
                <AddRemoveSelection type="Keywords" options={this.state.keywordsOptions} onChange={selectedKeywordsOptions
{
                    this.setState({ selectedKeywordsOptions });
                  }} />
                <div className="row mt-20">
                  <div className="col-sm-12 text-left">
                    <button className="btn btn-primary" id="submit" onClick={this.toggleVisibility}>
                      Submit
                    </button>
                    <button className="btn btn-danger"  id="reset" onClick={this.reset}>
                      Reset
                    </button>
                  </div>
                </div>
              </Sidebar>
              <Sidebar.Pusher>
                <Segment basic>
                  <div className="row" style={{ position: "relative" }}>
                    <div className="large-8 small-12" role="content">
                      <article style={{ width: 800, height: 800 }} id="chord">
                        {state.isComponentMount ? 
                            <Chord updateTooltip={this.updateTooltip} addFilter={this.addFilter} onRef={ref => (this.child = ref)} filters={state.filters} />
                        : null}
                      </article>
                    </div>
                    <fieldset id="tooltip" placement="top" className="row">
                      <div className="small-6 small-12 ">
                        <h6>
                          Taxonomy Name: {state.tooltip.tname} <br /> Keyword Name: {state.tooltip.kname} <br /> Taxonomy ID: {state.tooltip.tid} <br /> Keyword Visibility: {state.tooltip.kwVizState} <br /> Taxonomy Visibility: {state.tooltip.taxVizState} <br /> Keyword ID: {state.tooltip.kid} <br /> Spect Count: {state.tooltip.tvalue}{" "}
                        </h6>
                      </div>
                    </fieldset>
                  </div>
                </Segment>
              </Sidebar.Pusher>
            </Sidebar.Pushable>
          </div>;
    }
}




    // 1 - parse the data to get the list of ranks and categories
    importJSON() {

        // temporary dictionaries
        const ranks = {}
        const categories = {}

        const master = {}
        const rankList = []
        const categoryList = []


          //to be placed for fullDataChord API fetch once it'S available
        //    d3.json('https://bitbucket.org/rohitkalva/viz/raw/11e7059eceaf571b12bf97d348cc157e5bf11fa3/fulldata.json')


        TAXONOMY_DATA.fulldata.forEach(d => {
            const rank = d.taxonomyRank;
            const keyword = d.keywordCategory;

            ranks[rank] = true;
            categories[keyword] = true;
            if (!master[rank]) {
                master[rank] = {}
            }
            if (!master[rank][keyword]) {
                master[rank][keyword] = []
            }
            master[rank][keyword].push(d);
        })


        // add ranks/categories to list
        for (let key in ranks) {
            if (ranks.hasOwnProperty(key)) {
                rankList.push(key);
            }
        }

        for (let key in categories) {
            if (categories.hasOwnProperty(key)) {
                categoryList.push(key);
            }
        }
        console.log('rankList', rankList)
        console.log('categoryList', categoryList)
        console.log('master', master)

        this.setState({
            rankList,
            categoryList,
            master,
            // selectedRank: rankList[0],
            // selectedCategory: categoryList[0],
            selectedRank: "superfamily",
            selectedCategory: "Biological process",
        }, () => {
            this.updateList()
        });
    }

    // create taxonomy/keyword list
    updateList() {
        // temporary dictionary
        const keywords = {}
        const taxonomies = {}
        const { master, selectedRank, selectedCategory } = this.state
        console.log(`master[${selectedRank}][${selectedCategory}]`)

        if (master && master[selectedRank] && master[selectedRank][selectedCategory]) {
            console.log(`master[${selectedRank}][${selectedCategory}]`, master[selectedRank][selectedCategory])
            master[selectedRank][selectedCategory].forEach(d => {
                keywords[d.keywordId] = d.keywordName;
                taxonomies[d.taxId] = d.taxonomyName;
            })

            const keywordsOptions = [];
            const taxonomyOptions = [];

            // creates keyword list
            for (let key in keywords) {
                if (keywords.hasOwnProperty(key)) {
                    keywordsOptions.push({ id: key, name: keywords[key] });
                }
            }

            // creates taxonomy list
            for (let key in taxonomies) {
                if (taxonomies.hasOwnProperty(key)) {
                    taxonomyOptions.push({ id: key, name: taxonomies[key] });
                }
            }

            const selectedKeywordsOptions = keywordsOptions.slice();
            const selectedTaxonomyOptions = taxonomyOptions.slice();

            this.setState({
                keywordsOptions,
                selectedKeywordsOptions,
                taxonomyOptions,
                selectedTaxonomyOptions,

                filterKeyword: keywords,
                filterTaxonomy: taxonomies,
            }, () => {
                this.updateChart();
            });
        }

    }




    updateChart() {
        const { master, selectedRank, selectedCategory, filterKeyword, filterTaxonomy } = this.state;
        const data = master[selectedRank][selectedCategory];
        if (data) {
            this.child.drawChords(data.filter(d => (filterKeyword[d.keywordId] && filterTaxonomy[d.taxId])));
        }
    };

    setFilters(item, input) {
        let state = this.state;
        state.filters[item.name] = {
            name: item.name,
            hide: input.target.checked
        }
        this.setState({
            filters: state.filters
        });
        this.update(state);
    }

    reset() {
        let state = this.state;
        if (Object.keys(state.filters).length > 0 && state.hasFilters) {
            state.filters = {};
            state.hasFilters = false;
            this.setState({
                filters: {},
                hasFilters: false
            });
            this.updateChart();
        }
    }

    componentDidMount() {
        this.setState({ isComponentMount: true });

        this.importJSON();
    }

React doesn't mind how you do API(URL) call. React并不介意您如何进行API(URL)调用。 you can choose whatever kind of AJAX library you like for this task. 您可以为该任务选择喜欢的任何一种AJAX库。 The simplest way is this. 最简单的方法是这样。

  importJSON() {

        const ranks = {}
        const categories = {}
        const master = {}
        const rankList = []
        const categoryList = []

        var request = new XMLHttpRequest();
        request.open('GET', '/my/url', true);
        request.setRequestHeader('Content-Type', 'application/json');
        request.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {

          this.state({
                    TAXONOMY_DATA: xhttp.responseText
                }, ()=> {
                    this.state.TAXONOMY_DATA.fulldata.forEach(d => {
                    const rank = d.taxonomyRank;
                    const keyword = d.keywordCategory;

                    ranks[rank] = true;
                    categories[keyword] = true;
                    if (!master[rank]) {
                        master[rank] = {}
                    }
                    if (!master[rank][keyword]) {
                        master[rank][keyword] = []
                    }
                    master[rank][keyword].push(d);
                });
            });

        }
    };
        request.send();
 // add ranks/categories to list
        for (let key in ranks) {
            if (ranks.hasOwnProperty(key)) {
                rankList.push(key);
            }
        }

        for (let key in categories) {
            if (categories.hasOwnProperty(key)) {
                categoryList.push(key);
            }
        }
        console.log('rankList', rankList)
        console.log('categoryList', categoryList)
        console.log('master', master)

        this.setState({
            rankList,
            categoryList,
            master,

            selectedRank: "superfamily",
            selectedCategory: "Biological process",
        }, () => {
            this.updateList()
        });
    }

Instead of require at the beginning, 而不是一开始就require

const TAXONOMY_DATA = require(../../assets/chord.json);

Utilize fetch API : 利用提取API

constructor(props) {
    super(props);

    this.state = {
        selectedOptions: [],
        TAXONOMY_DATA: null 
    }
}


importJSON() {

    const ranks = {}
    const categories = {}
    const master = {}
    const rankList = []
    const categoryList = []

    fetch("https://.../chord.json")
        .then( (response) => {
            return response.json() 
        })   
        .then( (json) => {
            this.setState({
                TAXONOMY_DATA: json
            }, ()=> {
                this.state.TAXONOMY_DATA.fulldata.forEach(d => {
                    const rank = d.taxonomyRank;
                    const keyword = d.keywordCategory;

                    ranks[rank] = true;
                    categories[keyword] = true;
                    if (!master[rank]) {
                        master[rank] = {}
                    }
                    if (!master[rank][keyword]) {
                        master[rank][keyword] = []
                    }
                    master[rank][keyword].push(d);

                     ...

                    this.setState({
                        rankList,
                        categoryList,
                        master,
                        selectedRank: "superfamily",
                        selectedCategory: "Biological process",
                    }, () => {
                        this.updateList()
                    });
            });
        });

}

And because you deploy importJSON in componentDidMount() , which means you ask for data after all of the element have been rendered once. 并且因为您在componentDidMount()部署了importJSON ,这意味着您在所有元素都呈现一次之后就请求数据。 This would cause problem cause you have many value assignment in importJSON and you don't have those values when the first rendering, you need make sure this.state.TAXONOMY_DATA have been settled and then assigned value by 这会导致问题,因为您在importJSON有很多值分配,并且在第一次渲染时没有这些值,您需要确保this.state.TAXONOMY_DATA已结算,然后通过

render =() => {
    ...
    if(this.state.TAXONOMY_DATA) {
        const { visible, rankList, categoryList, selectedRank, selectedCategory } = this.state`
        return (<div>...</div>)
    } else {
        return null;
    }
    ...
}  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM