首先让我分享一个代码示例,它将非常清楚,轻松地突出我目前遇到的问题:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
oppDiv: 'none',
oppTeam: 'none'
}
this.chartProps = {
myLightGrey: '#EEE',
myMidGrey: '#999',
myDarkGrey: '#333',
}
}
updateButtonColors(button, parent, self) {
const { myLightGrey, myDarkGrey } = self.chartProps;
parent.selectAll("rect")
.attr("fill", myLightGrey)
parent.selectAll("text")
.attr("fill", myDarkGrey)
button.select("rect")
.attr("fill", myDarkGrey)
button.select("text")
.attr("fill", myLightGrey)
}
grabTeamInfo() {
var data = [{"teamid":"ARI","division":"NL West"},{"teamid":"ATL","division":"NL East"},{"teamid":"BAL","division":"AL East"},{"teamid":"BOS","division":"AL East"},{"teamid":"CHC","division":"NL Central"},{"teamid":"CWS","division":"AL Central"},{"teamid":"CIN","division":"NL Central"},{"teamid":"CLE","division":"AL Central"},{"teamid":"COL","division":"NL West"},{"teamid":"DET","division":"AL Central"},{"teamid":"HOU","division":"AL West"},{"teamid":"KC","division":"AL Central"},{"teamid":"LAA","division":"AL West"},{"teamid":"LAD","division":"NL West"},{"teamid":"MIA","division":"NL East"},{"teamid":"MIL","division":"NL Central"},{"teamid":"MIN","division":"AL Central"},{"teamid":"NYM","division":"NL East"},{"teamid":"NYY","division":"AL East"},{"teamid":"OAK","division":"AL West"},{"teamid":"PHI","division":"NL East"},{"teamid":"PIT","division":"NL Central"},{"teamid":"STL","division":"NL Central"},{"teamid":"SD","division":"NL West"},{"teamid":"SF","division":"NL West"},{"teamid":"SEA","division":"AL West"},{"teamid":"TB","division":"AL East"},{"teamid":"TEX","division":"AL West"},{"teamid":"TOR","division":"AL East"},{"teamid":"WAS","division":"NL East"}];
return data;
}
drawOppDivision() {
const teamInfo = this.grabTeamInfo();
const { myLightGrey, myMidGrey, myDarkGrey } = this.chartProps;
const { updateButtonColors } = this;
const divs = ["NL East", "NL Central", "NL West", "AL East", "AL Central", "AL West"];
d3.select('g.oppDivision')
.attr("transform", "translate(" + 585 + "," + 135 + ")")
// Draw Button Group For 6 Divisions
// ==================================
const oppDivision = d3.select('g.oppDivision')
.selectAll('.divisions')
.data(divs)
.enter()
.append("g")
.attr("class", "divisions")
.attr("cursor", "pointer")
oppDivision.append("rect")
.attr("x", (d,i) => (i % 3)*67)
.attr("y", (d,i) => i > 2 ? 27 : 0)
.attr("rx", 4).attr("ry", 4)
.attr("width", 65).attr("height", 25)
.attr("stroke", "#BBB")
.attr("fill", "#EEE")
oppDivision.append("text")
.attr("x", (d,i) => 32 + (i % 3)*67)
.attr("y", (d,i) => i > 2 ? 15 + 27 : 15 + 0)
.style("font-size", "0.7em")
.style("text-anchor", "middle")
.style("font-weight", "700")
.text(d => d)
const self = this;
oppDivision
.on("click", function(d,i) {
updateButtonColors(d3.select(this), d3.select(this.parentNode), self)
self.setState({oppDiv: divs[i]})
})
.on("mouseover", function() {
if (d3.select(this).select("rect").attr("fill") != myDarkGrey) {
d3.select(this)
.select("rect")
.attr("fill", myMidGrey); // lol almost here keep trying
}
})
.on("mouseout", function() {
if (d3.select(this).select("rect").attr("fill") != myDarkGrey) {
d3.select(this)
.select("rect")
.attr("fill", myLightGrey);
}
});
// Draw Title
d3.select('g.oppDivision').append("text")
.attr("x", -1).attr("y", -15)
.style("font-size", '1.25em')
.style("font-weight", '700')
.style("fill", myDarkGrey)
.text("Opposing Div / Team")
}
drawOppTeam() {
// Draw Button Group For 5 Teams In Selected Division
// ====================================================
// make an object with (team, division, abbrev) keys?
const teamInfo = this.grabTeamInfo();
const { myLightGrey, myMidGrey, myDarkGrey } = this.chartProps;
const { updateButtonColors } = this;
const { oppDiv } = this.state;
const oppTeamList = teamInfo
.filter(team => team.division == oppDiv)
.map(team => team.teamid)
// d3.select('g.oppTeam').selectAll('*').remove()
d3.select('g.oppTeam')
.attr("transform", "translate(" + 585 + "," + 135 + ")")
const oppTeam = d3.select('g.oppTeam')
.selectAll('.oppteams')
.data(oppTeamList)
oppTeam
.enter()
.append("g")
.attr("class", "oppteams")
.attr("cursor", "pointer")
oppTeam.append("rect")
.attr("x", (d,i) => i * 40)
.attr("y", 65)
.attr("rx", 4).attr("ry", 4)
.attr("width", 38).attr("height", 20)
.attr("stroke", myMidGrey)
.attr("fill", myLightGrey)
oppTeam.append("text")
.attr("x", (d,i) => (i * 40)+20)
.attr("y", 79)
.style("font-size", "0.7em")
.style("font-weight", "700")
.style("text-anchor", "middle")
.text(d => d)
oppTeam // not wanting to work like it should (need D3 GUP)
.exit()
.remove()
const self = this;
oppTeam
.on("click", function(d,i) {
updateButtonColors(d3.select(this), d3.select(this.parentNode), self)
self.setState({oppTeam: oppTeamList[i]})
})
.on("mouseover", function() {
if (d3.select(this).select("rect").attr("fill") != myDarkGrey) {
d3.select(this)
.select("rect")
.attr("fill", myMidGrey); // lol almost here keep trying
}
})
.on("mouseout", function() {
if (d3.select(this).select("rect").attr("fill") != myDarkGrey) {
d3.select(this)
.select("rect")
.attr("fill", myLightGrey);
}
});
// ======
}
componentDidUpdate() {
this.drawOppTeam()
}
componentDidMount() {
d3.select('#my-button-svg')
.attr('width', '100%')
.attr('height', '100%')
.attr('viewBox', "0 0 " + (800) + " " + 600)
.attr('preserveAspectRatio', "xMaxYMax")
this.drawOppDivision();
}
render() {
return(
<div>
<svg id='my-button-svg'>
<g className="oppDivision" />
<g className="oppTeam" />
</svg>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script>
<div id='root'>
Come On Work!
</div>
我正在努力让2个D3收音机在这里与他人携手合作。应该发生的是:
我面临的当前问题是:
我认为这是React中整洁,干净的单选按钮代码,在按钮组之间具有简单而有用的交互性(特别是在团队和部门中,我需要一个棒球应用程序)。修复按钮无法正常工作(以及知道我的代码有什么问题)的原因,对我有所帮助!在此先感谢您的帮助。
答案 0 :(得分:1)
快速修复它,现在似乎对我有用,请告诉我你是否正在寻找它!
从长远来看,我建议保持状态完全在React中(其中componentDidUpdate()
负责更新样式)或完全在d3中(意味着你只是渲染SVG和React并不是&#39 ;之后触摸它,分割按钮单击处理程序调用{{1}}而不是drawOppTeam()
)。我认为这个问题很棘手的原因是两个库共享了状态处理。
componentDidUpdate()
&#13;
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
oppDiv: 'none',
oppTeam: 'none'
}
this.chartProps = {
myLightGrey: '#EEE',
myMidGrey: '#999',
myDarkGrey: '#333',
}
}
updateButtonColors(button, parent, self) {
const { myLightGrey, myDarkGrey } = self.chartProps;
parent.selectAll("rect")
.attr("fill", myLightGrey)
parent.selectAll("text")
.attr("fill", myDarkGrey)
button.select("rect")
.attr("fill", myDarkGrey)
button.select("text")
.attr("fill", myLightGrey)
}
grabTeamInfo() {
var data = [{"teamid":"ARI","division":"NL West"},{"teamid":"ATL","division":"NL East"},{"teamid":"BAL","division":"AL East"},{"teamid":"BOS","division":"AL East"},{"teamid":"CHC","division":"NL Central"},{"teamid":"CWS","division":"AL Central"},{"teamid":"CIN","division":"NL Central"},{"teamid":"CLE","division":"AL Central"},{"teamid":"COL","division":"NL West"},{"teamid":"DET","division":"AL Central"},{"teamid":"HOU","division":"AL West"},{"teamid":"KC","division":"AL Central"},{"teamid":"LAA","division":"AL West"},{"teamid":"LAD","division":"NL West"},{"teamid":"MIA","division":"NL East"},{"teamid":"MIL","division":"NL Central"},{"teamid":"MIN","division":"AL Central"},{"teamid":"NYM","division":"NL East"},{"teamid":"NYY","division":"AL East"},{"teamid":"OAK","division":"AL West"},{"teamid":"PHI","division":"NL East"},{"teamid":"PIT","division":"NL Central"},{"teamid":"STL","division":"NL Central"},{"teamid":"SD","division":"NL West"},{"teamid":"SF","division":"NL West"},{"teamid":"SEA","division":"AL West"},{"teamid":"TB","division":"AL East"},{"teamid":"TEX","division":"AL West"},{"teamid":"TOR","division":"AL East"},{"teamid":"WAS","division":"NL East"}];
return data;
}
drawOppDivision() {
const teamInfo = this.grabTeamInfo();
const { myLightGrey, myMidGrey, myDarkGrey } = this.chartProps;
const { updateButtonColors } = this;
const divs = ["NL East", "NL Central", "NL West", "AL East", "AL Central", "AL West"];
d3.select('g.oppDivision')
.attr("transform", "translate(" + 585 + "," + 135 + ")")
// Draw Button Group For 6 Divisions
// ==================================
const oppDivision = d3.select('g.oppDivision')
.selectAll('.divisions')
.data(divs)
.enter()
.append("g")
.attr("class", "divisions")
.attr("cursor", "pointer")
oppDivision.append("rect")
.attr("x", (d,i) => (i % 3)*67)
.attr("y", (d,i) => i > 2 ? 27 : 0)
.attr("rx", 4).attr("ry", 4)
.attr("width", 65).attr("height", 25)
.attr("stroke", "#BBB")
.attr("fill", "#EEE")
oppDivision.append("text")
.attr("x", (d,i) => 32 + (i % 3)*67)
.attr("y", (d,i) => i > 2 ? 15 + 27 : 15 + 0)
.style("font-size", "0.7em")
.style("text-anchor", "middle")
.style("font-weight", "700")
.text(d => d)
const self = this;
oppDivision
.on("click", function(d,i) {
updateButtonColors(d3.select(this), d3.select(this.parentNode), self)
self.setState({oppDiv: divs[i]})
})
.on("mouseover", function() {
if (d3.select(this).select("rect").attr("fill") != myDarkGrey) {
d3.select(this)
.select("rect")
.attr("fill", myMidGrey); // lol almost here keep trying
}
})
.on("mouseout", function() {
if (d3.select(this).select("rect").attr("fill") != myDarkGrey) {
d3.select(this)
.select("rect")
.attr("fill", myLightGrey);
}
});
// Draw Title
d3.select('g.oppDivision').append("text")
.attr("x", -1).attr("y", -15)
.style("font-size", '1.25em')
.style("font-weight", '700')
.style("fill", myDarkGrey)
.text("Opposing Div / Team")
}
drawOppTeam() {
// Draw Button Group For 5 Teams In Selected Division
// ====================================================
// make an object with (team, division, abbrev) keys?
const teamInfo = this.grabTeamInfo();
const { myLightGrey, myMidGrey, myDarkGrey } = this.chartProps;
const { updateButtonColors } = this;
const { oppDiv } = this.state;
const oppTeamList = teamInfo
.filter(team => team.division == oppDiv)
.map(team => team.teamid)
d3.select('g.oppTeam').selectAll('*').remove()
d3.select('g.oppTeam')
.attr("transform", "translate(" + 585 + "," + 135 + ")")
.attr("cursor", "pointer")
const oppTeam = d3.select('g.oppTeam')
.selectAll('.oppteams')
.data(oppTeamList)
const teams = oppTeam
.enter()
.append("g")
.attr("class", "oppteams")
teams.append("rect")
.attr("x", (d,i) => i * 40)
.attr("y", 65)
.attr("rx", 4).attr("ry", 4)
.attr("width", 38).attr("height", 20)
.attr("stroke", (d) => this.state.oppTeam === d ? myLightGrey : myMidGrey)
.attr("fill", (d) => this.state.oppTeam === d ? myDarkGrey : myLightGrey)
teams.append("text")
.attr("x", (d,i) => (i * 40)+20)
.attr("y", 79)
.attr("fill", (d) => this.state.oppTeam === d ? myLightGrey : myDarkGrey)
.style("font-size", "0.7em")
.style("font-weight", "700")
.style("text-anchor", "middle")
.text(d => d)
//oppTeam // not wanting to work like it should (need D3 GUP)
//.exit()
//.remove()
const self = this;
teams
.on("click", function(d,i) {
updateButtonColors(d3.select(this), d3.select(this.parentNode), self)
self.setState({oppTeam: oppTeamList[i]})
})
.on("mouseover", function() {
if (d3.select(this).select("rect").attr("fill") != myDarkGrey) {
d3.select(this)
.select("rect")
.attr("fill", myMidGrey); // lol almost here keep trying
}
})
.on("mouseout", function() {
if (d3.select(this).select("rect").attr("fill") != myDarkGrey) {
d3.select(this)
.select("rect")
.attr("fill", myLightGrey);
}
});
// ======
}
componentDidUpdate() {
this.drawOppTeam()
}
componentDidMount() {
d3.select('#my-button-svg')
.attr('width', '100%')
.attr('height', '100%')
.attr('viewBox', "0 0 " + (800) + " " + 600)
.attr('preserveAspectRatio', "xMaxYMax")
this.drawOppDivision();
}
render() {
return(
<div>
<svg id='my-button-svg'>
<g className="oppDivision" />
<g className="oppTeam" />
</svg>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
&#13;