作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试根据用户点击的按钮更改 Lollipop 图表中圆圈的填充以及顺序(从大到小排序)。我已经根据值成功更改了我的 y 轴,但我在尝试更改其他参数时遇到了问题。
这是我正在使用的 csv:
media_outlet,positive,negative,balanced,informational,total
La Opinión,149,296,142,101,688
Wall Street Journal,137,118,125,79,459
Univision,226,484,225,159,1094
San Diego Union Tribune,60,24,18,17,119
Fox News,73,102,58,60,293
Washington Post,52,97,56,50,255
CNN,127,160,102,88,477
USA Today,32,23,14,22,91
The Daily Beast,9,50,13,10,82
Bloomberg,251,183,158,119,711
Fusion,48,86,54,49,237
NPR,20,30,12,14,76
Dallas Morning News,40,34,24,31,129
TIME,26,30,17,17,90
Forbes,97,56,72,37,262
Christian Science Monitor,19,15,21,7,62
NBC News,23,34,19,22,98
Huffington Post,232,344,219,85,880
New York TImes,90,129,74,62,355
Houston Chronicle,40,32,31,24,127
Los Angeles Times,66,75,45,45,231
San Antonio Express News,28,22,14,16,80
Arizona Daily Star,32,15,6,8,61
Vice News,17,169,44,12,242
我的 Javascript 代码开始可视化,用总数对图表进行排序(我还没有弄清楚当单击按钮时如何或在代码中应用排序的位置):
const svg = d3
.select('#outlets-viz')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// Initialize the X axis
const x = d3
.scaleBand()
.range([0, width])
.padding(1);
const xAxis = svg.append('g').attr('transform', 'translate(0,' + height + ')');
// Initialize the Y axis
const y = d3.scaleLinear().range([height, 0]);
const yAxis = svg.append('g').attr('class', 'myYaxis');
// A function that create / update the plot for a given variable:
function update(selectedVar) {
// Parse the Data
d3.csv('../data/media_tendency.csv').then(function(data) {
data.forEach(function(d) {
d.positive = +d.positive;
d.negative = +d.negative;
d.balanced = +d.balanced;
d.informational = +d.informational;
d.total = +d.total;
});
console.log(data);
data = data.sort(function(a, b) {
if (a.total < b.total) {
return 1;
} else {
return -1;
}
});
// X axis
x.domain(
data.map(function(d) {
return d.media_outlet;
})
);
xAxis
.transition()
.duration(1000)
.call(d3.axisBottom(x))
.selectAll('text')
.attr('transform', 'translate(-10,0)rotate(-40)')
.style('text-anchor', 'end');
// Add Y axis
y.domain([
0,
d3.max(data, function(d) {
return +d[selectedVar];
}),
]);
yAxis
.transition()
.duration(1000)
.call(d3.axisLeft(y));
// variable u: map data to existing circle
const j = svg.selectAll('.myLine').data(data);
// update lines
j.enter()
.append('line')
.attr('class', 'myLine')
.merge(j)
.transition()
.duration(1000)
.attr('x1', function(d) {
//console.log(x(d.media_outlet));
return x(d.media_outlet);
})
.attr('x2', function(d) {
return x(d.media_outlet);
})
.attr('y1', y(0))
.attr('y2', function(d) {
return y(d[selectedVar]);
})
.attr('stroke', 'grey');
// variable u: map data to existing circle
const u = svg.selectAll('circle').data(data);
// update bars
u.enter()
.append('circle')
.merge(u)
.transition()
.duration(1000)
.attr('cx', function(d) {
return x(d.media_outlet);
})
.attr('cy', function(d) {
return y(d[selectedVar]);
})
.attr('r', 5)
.attr('fill', function(d) {
if (d[selectedVar] === 'total') {
return '#bfc0c1';
} else if (d[selectedVar] === 'positive') {
return '#5cdacc';
} else if (d[selectedVar] === 'negative') {
return '#ff1d34';
} else if (d[selectedVar] === 'balanced') {
return '#ffc750';
} else {
return '#ff8c50';
}
});
});
}
update('total');
我的 html:
<div class="container">
<div class="row justify-content-md-center">
<div class="col-auto">
<button class="positive p-2" onclick="update('positive')">
Positive
</button>
</div>
<div class="col-auto">
<button class="negative p-2" onclick="update('negative')">
Negative
</button>
</div>
<div class="col-auto">
<button class="balanced p-2" onclick="update('balanced')">
Balanced
</button>
</div>
<div class="col-auto">
<button class="informational p-2" onclick="update('informational')">
Informational
</button>
</div>
<div class="col-auto">
<button class="p-2" id="total-button" onclick="update('total')">
Total
</button>
</div>
</div>
</div>
我是 d3 的新手,我几个月前就开始编码了,任何关于如何改进或更改代码的指导都会对我有很大帮助!感谢您的宝贵帮助 :)!
最佳答案
关于颜色:
你的if
条件...
.attr('fill', function(d) {
if (d[selectedVar] === 'total') {
return '#bfc0c1';
} else if (d[selectedVar] === 'positive') {
return '#5cdacc';
} else if (d[selectedVar] === 'negative') {
return '#ff1d34';
} else if (d[selectedVar] === 'balanced') {
return '#ffc750';
} else {
return '#ff8c50';
}
});
... 是不正确的,因为 total
、positive
、negative
等...都是 property 名称,不是值(value)观。它应该只是 if(selectedVar === "total")
等
最重要的是,您不需要那一堆if
。只需使用秤:
const colorScale = d3.scaleOrdinal()
.domain(["positive", "negative", "balanced", "informational", "total"])
.range(['#5cdacc', '#ff1d34', '#ffc750', '#ff8c50', '#bfc0c1']);
然后就这么简单了:
.attr('fill', colorScale(selectedVar));
关于排序问题:
使用属性本身进行排序:
data.sort(function(a, b) {
return b[selectedVar] - a[selectedVar];
});
此外,sort
就地排序,您不需要重新分配data
。
这是您更新后的代码:
const csv = `media_outlet,positive,negative,balanced,informational,total
La Opinión,149,296,142,101,688
Wall Street Journal,137,118,125,79,459
Univision,226,484,225,159,1094
San Diego Union Tribune,60,24,18,17,119
Fox News,73,102,58,60,293
Washington Post,52,97,56,50,255
CNN,127,160,102,88,477
USA Today,32,23,14,22,91
The Daily Beast,9,50,13,10,82
Bloomberg,251,183,158,119,711
Fusion,48,86,54,49,237
NPR,20,30,12,14,76
Dallas Morning News,40,34,24,31,129
TIME,26,30,17,17,90
Forbes,97,56,72,37,262
Christian Science Monitor,19,15,21,7,62
NBC News,23,34,19,22,98
Huffington Post,232,344,219,85,880
New York TImes,90,129,74,62,355
Houston Chronicle,40,32,31,24,127
Los Angeles Times,66,75,45,45,231
San Antonio Express News,28,22,14,16,80
Arizona Daily Star,32,15,6,8,61
Vice News,17,169,44,12,242`;
const data = d3.csvParse(csv, function(d) {
d.positive = +d.positive;
d.negative = +d.negative;
d.balanced = +d.balanced;
d.informational = +d.informational;
d.total = +d.total;
return d;
});
const width = 500,
height = 300;
const margin = {
left: 30,
right: 10,
top: 10,
bottom: 70
};
const svg = d3
.select("body")
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// Initialize the X axis
const x = d3
.scaleBand()
.range([0, width])
.padding(1);
const xAxis = svg.append('g').attr('transform', 'translate(0,' + height + ')');
// Initialize the Y axis
const y = d3.scaleLinear().range([height, 0]);
const yAxis = svg.append('g').attr('class', 'myYaxis');
const colorScale = d3.scaleOrdinal()
.domain(["positive", "negative", "balanced", "informational", "total"])
.range(['#5cdacc', '#ff1d34', '#ffc750', '#ff8c50', '#bfc0c1']);
// A function that create / update the plot for a given variable:
function update(selectedVar) {
// Parse the Data
data.sort(function(a, b) {
return b[selectedVar] - a[selectedVar];
});
// X axis
x.domain(
data.map(function(d) {
return d.media_outlet;
})
);
xAxis
.transition()
.duration(1000)
.call(d3.axisBottom(x))
.selectAll('text')
.attr('transform', 'translate(-10,0)rotate(-40)')
.style('text-anchor', 'end');
// Add Y axis
y.domain([
0,
d3.max(data, function(d) {
return +d[selectedVar];
}),
]);
yAxis
.transition()
.duration(1000)
.call(d3.axisLeft(y));
// variable u: map data to existing circle
const j = svg.selectAll('.myLine').data(data);
// update lines
j.enter()
.append('line')
.attr('class', 'myLine')
.merge(j)
.transition()
.duration(1000)
.attr('x1', function(d) {
//console.log(x(d.media_outlet));
return x(d.media_outlet);
})
.attr('x2', function(d) {
return x(d.media_outlet);
})
.attr('y1', y(0))
.attr('y2', function(d) {
return y(d[selectedVar]);
})
.attr('stroke', 'grey');
// variable u: map data to existing circle
const u = svg.selectAll('circle').data(data);
// update bars
u.enter()
.append('circle')
.merge(u)
.transition()
.duration(1000)
.attr('cx', function(d) {
return x(d.media_outlet);
})
.attr('cy', function(d) {
return y(d[selectedVar]);
})
.attr('r', 5)
.attr('fill', colorScale(selectedVar));
}
update('total');
<script src="https://d3js.org/d3.v5.min.js"></script>
<div class="container">
<div class="row justify-content-md-center">
<div class="col-auto">
<button class="positive p-2" onclick="update('positive')">
Positive
</button>
</div>
<div class="col-auto">
<button class="negative p-2" onclick="update('negative')">
Negative
</button>
</div>
<div class="col-auto">
<button class="balanced p-2" onclick="update('balanced')">
Balanced
</button>
</div>
<div class="col-auto">
<button class="informational p-2" onclick="update('informational')">
Informational
</button>
</div>
<div class="col-auto">
<button class="p-2" id="total-button" onclick="update('total')">
Total
</button>
</div>
</div>
</div>
关于javascript - 如何更新 Lollipop 图表的填充和排序值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56050159/
我是一名优秀的程序员,十分优秀!