- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个圆环图,当图例中的标签/类别被禁用时,它会重新计算每个类别的百分比和大小。我想做的是重新计算不包括残疾人类别的总数。每次用户启用或禁用图例中的类别时,我都想这样做。
代码如下:
// define data
var dataset = [
{label: "Venue", count: 16107},
{label: "Photographer", count: 2783},
{label: "Wedding/Event Planner", count: 2037},
{label: "Reception Band", count: 4156},
{label: "Reception DJ", count: 1245},
{label: "Florist/Decor", count: 2534},
{label: "Videographer", count: 1995},
{label: "Wedding Dress", count: 1564},
{label: "Groom's Attire", count: 280},
{label: "Wedding Cake", count: 582},
{label: "Ceremony Site", count: 2197},
{label: "Ceremony Musicians", count: 755},
{label: "Invitations", count: 2534},
{label: "Transportation", count: 1995},
{label: "Favors", count: 1564},
{label: "Rehearsal Dinner", count: 280},
{label: "Engagement Ring", count: 582},
{label: "Officiant", count: 2197}
];
// chart dimensions
var width = 800;
var height = 800;
// a circle chart needs a radius
var radius = Math.min(width, height) / 2;
var donutWidth = 100; // size of donut hole. not needed if doing pie chart
// legend dimensions
var legendRectSize = 25; // defines the size of the colored squares in legend
var legendSpacing = 6; // defines spacing between squares
// define color scale
var color = d3.scaleOrdinal(d3.schemeCategory20b);
// more color scales: https://bl.ocks.org/pstuffa/3393ff2711a53975040077b7453781a9
// calculate new total
var total = d3.sum(dataset, d => d.count);
// define new total section
var newTotal = d3.select('new-total-holder')
.append('span')
.attr('class', 'newTotal')
var svg = d3.select('#chart') // select element in the DOM with id 'chart'
.append('svg') // append an svg element to the element we've selected
.attr('width', width) // set the width of the svg element we just added
.attr('height', height) // set the height of the svg element we just added
.append('g') // append 'g' element to the svg element
.attr('transform', 'translate(' + (width / 2) + ',' + (height / 2) + ')'); // our reference is now to the 'g' element. centerting the 'g' element to the svg element
var arc = d3.arc()
.innerRadius(radius - donutWidth) // radius - donutWidth = size of donut hole. use 0 for pie chart
.outerRadius(radius); // size of overall chart
var pie = d3.pie() // start and end angles of the segments
.value(function(d) { return d.count; }) // how to extract the numerical data from each entry in our dataset
.sort(null); // by default, data sorts in oescending value. this will mess with our animation so we set it to null
// define tooltip
var tooltip = d3.select('#chart') // select element in the DOM with id 'chart'
.append('div') // append a div element to the element we've selected
.attr('class', 'tooltip'); // add class 'tooltip' on the divs we just selected
tooltip.append('div') // add divs to the tooltip defined above
.attr('class', 'label'); // add class 'label' on the selection
tooltip.append('div') // add divs to the tooltip defined above
.attr('class', 'count'); // add class 'count' on the selection
tooltip.append('div') // add divs to the tooltip defined above
.attr('class', 'percent'); // add class 'percent' on the selection
// Confused? see below:
// <div id="chart">
// <div class="tooltip">
// <div class="label">
// </div>
// <div class="count">
// </div>
// <div class="percent">
// </div>
// </div>
// </div>
dataset.forEach(function(d) {
d.count = +d.count; // calculate count as we iterate through the data
d.enabled = true; // add enabled property to track which entries are checked
});
// creating the chart
var path = svg.selectAll('path') // select all path elements inside the svg. specifically the 'g' element. they don't exist yet but they will be created below
.data(pie(dataset)) //associate dataset wit he path elements we're about to create. must pass through the pie function. it magically knows how to extract values and bakes it into the pie
.enter() //creates placeholder nodes for each of the values
.append('path') // replace placeholders with path elements
.attr('d', arc) // define d attribute with arc function above
.attr('fill', function(d) { return color(d.data.label); }) // use color scale to define fill of each label in dataset
.each(function(d) { this._current - d; }); // creates a smooth animation for each track
// mouse event handlers are attached to path so they need to come after its definition
path.on('mouseover', function(d) { // when mouse enters div
var total = d3.sum(dataset.map(function(d) { // calculate the total number of tickets in the dataset
return (d.enabled) ? d.count : 0; // checking to see if the entry is enabled. if it isn't, we return 0 and cause other percentages to increase
}));
var percent = Math.round(1000 * d.data.count / total) / 10; // calculate percent
tooltip.select('.label').html(d.data.label); // set current label
tooltip.select('.count').html('$' + d.data.count); // set current count
tooltip.select('.percent').html(percent + '%'); // set percent calculated above
tooltip.style('display', 'block'); // set display
});
path.on('mouseout', function() { // when mouse leaves div
tooltip.style('display', 'none'); // hide tooltip for that element
});
path.on('mousemove', function(d) { // when mouse moves
tooltip.style('top', (d3.event.layerY + 10) + 'px') // always 10px below the cursor
.style('left', (d3.event.layerX + 10) + 'px'); // always 10px to the right of the mouse
});
// define legend
var legend = svg.selectAll('.legend') // selecting elements with class 'legend'
.data(color.domain()) // refers to an array of labels from our dataset
.enter() // creates placeholder
.append('g') // replace placeholders with g elements
.attr('class', 'legend') // each g is given a legend class
.attr('transform', function(d, i) {
var height = legendRectSize + legendSpacing; // height of element is the height of the colored square plus the spacing
var offset = height * color.domain().length / 2; // vertical offset of the entire legend = height of a single element & half the total number of elements
var horz = -2 * legendRectSize; // the legend is shifted to the left to make room for the text
var vert = i * height - offset; // the top of the element is hifted up or down from the center using the offset defiend earlier and the index of the current element 'i'
return 'translate(' + horz + ',' + vert + ')'; //return translation
});
// adding colored squares to legend
legend.append('rect') // append rectangle squares to legend
.attr('width', legendRectSize) // width of rect size is defined above
.attr('height', legendRectSize) // height of rect size is defined above
.style('fill', color) // each fill is passed a color
.style('stroke', color) // each stroke is passed a color
.on('click', function(label) {
var rect = d3.select(this); // this refers to the colored squared just clicked
var enabled = true; // set enabled true to default
var totalEnabled = d3.sum(dataset.map(function(d) { // can't disable all options
return (d.enabled) ? 1 : 0; // return 1 for each enabled entry. and summing it up
}));
if (rect.attr('class') === 'disabled') { // if class is disabled
rect.attr('class', ''); // remove class disabled
} else { // else
if (totalEnabled < 2) return; // if less than two labels are flagged, exit
rect.attr('class', 'disabled'); // otherwise flag the square disabled
enabled = false; // set enabled to false
}
pie.value(function(d) {
if (d.label === label) d.enabled = enabled; // if entry label matches legend label
return (d.enabled) ? d.count : 0; // update enabled property and return count or 0 based on the entry's status
});
path = path.data(pie(dataset)); // update pie with new data
path.transition() // transition of redrawn pie
.duration(750) //
.attrTween('d', function(d) { // 'd' specifies the d attribute that we'll be animating
var interpolate = d3.interpolate(this._current, d); // this = current path element
this._current = interpolate(0); // interpolate between current value and the new value of 'd'
return function(t) {
return arc(interpolate(t));
};
});
// calculate new total
var newTotalCalc = d3.sum(dataset, d => d.count)
console.log(newTotalCalc);
// append newTotalCalc to newTotal which is defined above
newTotal.append("text")
.text(newTotalCalc);
});
// adding text to legend
legend.append('text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.text(function(d) { return d; }); // return label
body {
font-family: 'Open Sans Condensed', sans-serif;
}
.title-holder {
text-align: center;
}
.title {
font-family: 'Pacifico', cursive;
}
.font {
font-size: 20px;
}
/* legend */
.legend {
font-size: 14px;
}
rect {
cursor: pointer;
stroke-width: 2;
}
rect.disabled {
fill: transparent !important;
}
/* chart */
#chart {
height: 800px;
margin: 0 auto;
position: relative;
display: block;
width: 800px;
}
/* tooltip */
.tooltip {
background: #eee;
box-shadow: 0 0 5px #999999;
color: #333;
display: none;
font-size: 18px;
left: 130px;
padding: 10px;
position: absolute;
text-align: center;
top: 95px;
width: 80px;
z-index: 10;
}
.footer {
padding-top: 50px;
text-align: center;
list-style-type: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>D3.js Donut Chart</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300|Pacifico" rel="stylesheet">
<link href="styles.css" rel="stylesheet">
</head>
<body>
<div class="title-holder">
<h1 class="title">2016 Average Wedding Budget Breakdown</h1>
<p class="font">Uncheck categories to recalculate.</p>
<p class="font new-total-holder">New Total:</p>
</div>
<div id="chart"></div>
<footer>
<a href="https://xogroupinc.com/press-releases/theknot2016realweddings_costofweddingsus/?__hstc=131446032.9fd6826aa789a27bcd4899793f171195.1518035170660.1518035170660.1518035170660.1&__hssc=131446032.1.1518035170660&__hsfp=2080303699" target="_blank">Data Source</a></li>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
<script src="script.js"></script> <!-- remove if no javascript -->
</body>
</html>
最佳答案
这是一种方法:
当您切换 enabled
时标志基于图例点击,新 计数 可以根据这个标志计算如下:
var newTotalCalc = d3.sum(dataset.filter(function(d) { return d.enabled;}), d => d.count)
var newTotal = d3.select('.new-total-holder')
text
新元素总数<span>
,我只是在更改文本。newTotal.text(newTotalCalc);
// define data
var dataset = [
{label: "Venue", count: 16107},
{label: "Photographer", count: 2783},
{label: "Wedding/Event Planner", count: 2037},
{label: "Reception Band", count: 4156},
{label: "Reception DJ", count: 1245},
{label: "Florist/Decor", count: 2534},
{label: "Videographer", count: 1995},
{label: "Wedding Dress", count: 1564},
{label: "Groom's Attire", count: 280},
{label: "Wedding Cake", count: 582},
{label: "Ceremony Site", count: 2197},
{label: "Ceremony Musicians", count: 755},
{label: "Invitations", count: 2534},
{label: "Transportation", count: 1995},
{label: "Favors", count: 1564},
{label: "Rehearsal Dinner", count: 280},
{label: "Engagement Ring", count: 582},
{label: "Officiant", count: 2197}
];
// chart dimensions
var width = 800;
var height = 800;
// a circle chart needs a radius
var radius = Math.min(width, height) / 2;
var donutWidth = 100; // size of donut hole. not needed if doing pie chart
// legend dimensions
var legendRectSize = 25; // defines the size of the colored squares in legend
var legendSpacing = 6; // defines spacing between squares
// define color scale
var color = d3.scaleOrdinal(d3.schemeCategory20b);
// more color scales: https://bl.ocks.org/pstuffa/3393ff2711a53975040077b7453781a9
// calculate new total
var total = d3.sum(dataset, d => d.count);
// define new total section
var newTotal = d3.select('.new-total-holder')
.append('span')
.attr('class', 'newTotal').text(total);
var svg = d3.select('#chart') // select element in the DOM with id 'chart'
.append('svg') // append an svg element to the element we've selected
.attr('width', width) // set the width of the svg element we just added
.attr('height', height) // set the height of the svg element we just added
.append('g') // append 'g' element to the svg element
.attr('transform', 'translate(' + (width / 2) + ',' + (height / 2) + ')'); // our reference is now to the 'g' element. centerting the 'g' element to the svg element
var arc = d3.arc()
.innerRadius(radius - donutWidth) // radius - donutWidth = size of donut hole. use 0 for pie chart
.outerRadius(radius); // size of overall chart
var pie = d3.pie() // start and end angles of the segments
.value(function(d) { return d.count; }) // how to extract the numerical data from each entry in our dataset
.sort(null); // by default, data sorts in oescending value. this will mess with our animation so we set it to null
// define tooltip
var tooltip = d3.select('#chart') // select element in the DOM with id 'chart'
.append('div') // append a div element to the element we've selected
.attr('class', 'tooltip'); // add class 'tooltip' on the divs we just selected
tooltip.append('div') // add divs to the tooltip defined above
.attr('class', 'label'); // add class 'label' on the selection
tooltip.append('div') // add divs to the tooltip defined above
.attr('class', 'count'); // add class 'count' on the selection
tooltip.append('div') // add divs to the tooltip defined above
.attr('class', 'percent'); // add class 'percent' on the selection
// Confused? see below:
// <div id="chart">
// <div class="tooltip">
// <div class="label">
// </div>
// <div class="count">
// </div>
// <div class="percent">
// </div>
// </div>
// </div>
dataset.forEach(function(d) {
d.count = +d.count; // calculate count as we iterate through the data
d.enabled = true; // add enabled property to track which entries are checked
});
// creating the chart
var path = svg.selectAll('path') // select all path elements inside the svg. specifically the 'g' element. they don't exist yet but they will be created below
.data(pie(dataset)) //associate dataset wit he path elements we're about to create. must pass through the pie function. it magically knows how to extract values and bakes it into the pie
.enter() //creates placeholder nodes for each of the values
.append('path') // replace placeholders with path elements
.attr('d', arc) // define d attribute with arc function above
.attr('fill', function(d) { return color(d.data.label); }) // use color scale to define fill of each label in dataset
.each(function(d) { this._current - d; }); // creates a smooth animation for each track
// mouse event handlers are attached to path so they need to come after its definition
path.on('mouseover', function(d) { // when mouse enters div
var total = d3.sum(dataset.map(function(d) { // calculate the total number of tickets in the dataset
return (d.enabled) ? d.count : 0; // checking to see if the entry is enabled. if it isn't, we return 0 and cause other percentages to increase
}));
var percent = Math.round(1000 * d.data.count / total) / 10; // calculate percent
tooltip.select('.label').html(d.data.label); // set current label
tooltip.select('.count').html('$' + d.data.count); // set current count
tooltip.select('.percent').html(percent + '%'); // set percent calculated above
tooltip.style('display', 'block'); // set display
});
path.on('mouseout', function() { // when mouse leaves div
tooltip.style('display', 'none'); // hide tooltip for that element
});
path.on('mousemove', function(d) { // when mouse moves
tooltip.style('top', (d3.event.layerY + 10) + 'px') // always 10px below the cursor
.style('left', (d3.event.layerX + 10) + 'px'); // always 10px to the right of the mouse
});
// define legend
var legend = svg.selectAll('.legend') // selecting elements with class 'legend'
.data(color.domain()) // refers to an array of labels from our dataset
.enter() // creates placeholder
.append('g') // replace placeholders with g elements
.attr('class', 'legend') // each g is given a legend class
.attr('transform', function(d, i) {
var height = legendRectSize + legendSpacing; // height of element is the height of the colored square plus the spacing
var offset = height * color.domain().length / 2; // vertical offset of the entire legend = height of a single element & half the total number of elements
var horz = -2 * legendRectSize; // the legend is shifted to the left to make room for the text
var vert = i * height - offset; // the top of the element is hifted up or down from the center using the offset defiend earlier and the index of the current element 'i'
return 'translate(' + horz + ',' + vert + ')'; //return translation
});
// adding colored squares to legend
legend.append('rect') // append rectangle squares to legend
.attr('width', legendRectSize) // width of rect size is defined above
.attr('height', legendRectSize) // height of rect size is defined above
.style('fill', color) // each fill is passed a color
.style('stroke', color) // each stroke is passed a color
.on('click', function(label) {
var rect = d3.select(this); // this refers to the colored squared just clicked
var enabled = true; // set enabled true to default
var totalEnabled = d3.sum(dataset.map(function(d) { // can't disable all options
return (d.enabled) ? 1 : 0; // return 1 for each enabled entry. and summing it up
}));
if (rect.attr('class') === 'disabled') { // if class is disabled
rect.attr('class', ''); // remove class disabled
} else { // else
if (totalEnabled < 2) return; // if less than two labels are flagged, exit
rect.attr('class', 'disabled'); // otherwise flag the square disabled
enabled = false; // set enabled to false
}
pie.value(function(d) {
if (d.label === label) d.enabled = enabled; // if entry label matches legend label
return (d.enabled) ? d.count : 0; // update enabled property and return count or 0 based on the entry's status
});
path = path.data(pie(dataset)); // update pie with new data
path.transition() // transition of redrawn pie
.duration(750) //
.attrTween('d', function(d) { // 'd' specifies the d attribute that we'll be animating
var interpolate = d3.interpolate(this._current, d); // this = current path element
this._current = interpolate(0); // interpolate between current value and the new value of 'd'
return function(t) {
return arc(interpolate(t));
};
});
// calculate new total
var newTotalCalc = d3.sum(dataset.filter(function(d) { return d.enabled;}), d => d.count)
// console.log(newTotalCalc);
// append newTotalCalc to newTotal which is defined above
newTotal.text(newTotalCalc);
});
// adding text to legend
legend.append('text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.text(function(d) { return d; }); // return label
body {
font-family: 'Open Sans Condensed', sans-serif;
}
.title-holder {
text-align: center;
}
.title {
font-family: 'Pacifico', cursive;
}
.font {
font-size: 20px;
}
/* legend */
.legend {
font-size: 14px;
}
rect {
cursor: pointer;
stroke-width: 2;
}
rect.disabled {
fill: transparent !important;
}
/* chart */
#chart {
height: 800px;
margin: 0 auto;
position: relative;
display: block;
width: 800px;
}
/* tooltip */
.tooltip {
background: #eee;
box-shadow: 0 0 5px #999999;
color: #333;
display: none;
font-size: 18px;
left: 130px;
padding: 10px;
position: absolute;
text-align: center;
top: 95px;
width: 80px;
z-index: 10;
}
.footer {
padding-top: 50px;
text-align: center;
list-style-type: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>D3.js Donut Chart</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300|Pacifico" rel="stylesheet">
<link href="styles.css" rel="stylesheet">
</head>
<body>
<div class="title-holder">
<h1 class="title">2016 Average Wedding Budget Breakdown</h1>
<p class="font">Uncheck categories to recalculate.</p>
<p class="font new-total-holder">New Total:</p>
</div>
<div id="chart"></div>
<footer>
<a href="https://xogroupinc.com/press-releases/theknot2016realweddings_costofweddingsus/?__hstc=131446032.9fd6826aa789a27bcd4899793f171195.1518035170660.1518035170660.1518035170660.1&__hssc=131446032.1.1518035170660&__hsfp=2080303699" target="_blank">Data Source</a></li>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
<script src="script.js"></script> <!-- remove if no javascript -->
</body>
</html>
关于d3.js - 在 D3.js 圆环图中禁用类别后的新总数总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48711871/
我想知道有没有可能做 new PrintWriter(new BufferedWriter(new PrintWriter(s.getOutputStream, true))) 在 Java 中,s
我正在尝试使用 ConcurrentHashMap 初始化 ConcurrentHashMap private final ConcurrentHashMap > myMulitiConcurrent
我只是想知道两个不同的新对象初始化器之间是否有任何区别,还是仅仅是语法糖。 因此: Dim _StreamReader as New Streamreader(mystream) 与以下内容不同: D
在 C++ 中,以下两种动态对象创建之间的确切区别是什么: A* pA = new A; A* pA = new A(); 我做了一些测试,但似乎在这两种情况下,都调用了默认构造函数,并且只调用了它。
我已经阅读了其他帖子,但它们没有解决我的问题。环境为VB 2008(2.0 Framework)下面的代码在 xslt.Load 行导致 XSLT 编译错误下面是错误的输出。我将 XSLT 作为字符串
我想知道为什么alert(new Boolean(false))打印 false 而不是打印对象,因为 new Boolean 应该返回对象。如果我使用 console.log(new Boolean
本文实例讲述了Python装饰器用法。分享给大家供大家参考,具体如下: 写装饰器 装饰器只不过是一种函数,接收被装饰的可调用对象作为它的唯一参数,然后返回一个可调用对象(就像前面的简单例子) 注
我可以编写 YAML header 来使用 knit 为 R Markdown 文件生成多种输出格式吗?我无法重现 the original question with this title 的答案中
我可以编写一个YAML标头以使用knitr为R Markdown文件生成多种输出格式吗?我无法重现the original question with this title答案中描述的功能。 这个降价
我正在使用vars package可视化脉冲响应。示例: library(vars) Canada % names ir % `$`(irf) %>% `[[`(variables[e])) %>%
我有一个容器类,它有一个通用参数,该参数被限制到某个基类。提供给泛型的类型是基类约束的子类。子类使用方法隐藏(新)来更改基类方法的行为(不,我不能将其设为虚拟,因为它不是我的代码)。我的问题是"new
Java 在提示! cannot find symbol symbol : constructor Bar() location: class Bar JPanel panel =
在我的应用程序中,一个新的 Activity 从触摸按钮(而不是点击)开始,而且我没有抬起手指并希望在新的 Activity 中跟踪触摸的 Action 。第二个 Activity 中的触摸监听器不响
已关闭。此问题旨在寻求有关书籍、工具、软件库等的建议。不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,
和我的last question ,我的程序无法检测到一个短语并将其与第一行以外的任何行匹配。但是,我已经解决并回答了。但现在我需要一个新的 def函数,它删除某个(给定 refName )联系人及其
这个问题在这里已经有了答案: Horizontal list items (7 个答案) 关闭 9 年前。
我想创建一个新的 float 类型,大小为 128 位,指数为 4 字节(32 位),小数为 12 字节(96 位),我该怎么做输入 C++,我将能够在其中进行输入、输出、+、-、*、/操作。 [我正
我在放置引用计数指针的实例时遇到问题 类到我的数组类中。使用调试器,似乎永远不会调用构造函数(这会扰乱引用计数并导致行中出现段错误)! 我的 push_back 函数是: void push_back
我在我们的代码库中发现了经典的新建/删除不匹配错误,如下所示: char *foo = new char[10]; // do something delete foo; // instead of
A *a = new A(); 这是创建一个指针还是一个对象? 我是一个 c++ 初学者,所以我想了解这个区别。 最佳答案 两者:您创建了一个新的 A 实例(一个对象),并创建了一个指向它的名为 a
我是一名优秀的程序员,十分优秀!