[英]How to show the value of each element when hovering
I am new to D3.js and have created a graph that shows the sales history of some sellers.我是 D3.js 的新手,并创建了一个图表来显示一些卖家的销售历史。
In the table below shows the total sales result in the year, in the graph shows the monthly evolution of sales, when I hover under each circle I want to show the amount that sold in the respective month.下表显示了当年的总销售结果,图中显示了每月的销售额演变,当我将鼠标悬停在每个圆圈下方时,我想显示相应月份的销售量。
But it is always showing the same values (the values are being shown at the top of the chart).但它总是显示相同的值(这些值显示在图表的顶部)。
//#region Criando Tabela de Vendedores var newMapVendedores = [ { "vendnm": "CHARNECA", "Vendas_Ano": 236009.2299999998, "Vendas_Ant": 282753.77999999997 }, { "vendnm": "JOÃO LUIS", "Vendas_Ano": 257733.04999999996, "Vendas_Ant": 332119.31 }, ] $(document).ready(function () { $("#tableVendedores").append('<tfoot><th></th><th></th><th></th></tfoot>'); var table = $('#tableVendedores').DataTable({ "data": newMapVendedores, "columns": [ { "data": "vendnm", title: 'Vendedor' }, { "data": "Vendas_Ano", title: 'Vendas Ano' }, { "data": "Vendas_Ant", title: 'Vendas Ant' }, ], "bLengthChange": false, "bPaginate": false, "bFilter": false, "info": false, }); $('#tableVendedores').on('click', 'tr', function () { var data = table.row(this).data(); }); }); //#endregion //#region GRÁFICO var codes = ["VENDAS_ANO", "VENDAS_ANT"]; $('span.values').html(codes.join(', ')); modalitySelected = document.querySelector('input[name=modality-selector]:checked').value; var data = null; var filtered_data = null; var margin = { top: 30, right: 20, bottom: 50, left: 50 }; var width = 600 - margin.left - margin.right; var height = 350 - margin.top - margin.bottom; var duration = 250; var lineOpacity = "0.25"; var lineOpacityHover = "0.85"; var otherLinesOpacityHover = "0.1"; var lineStroke = "1.5px"; var lineStrokeHover = "2.5px"; var circleOpacity = '0.85'; var circleOpacityOnLineHover = "0.25"; var circleRadius = 3; var circleRadiusHover = 6; var month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; var x = d3.scaleBand().range([0, width]).domain(month).padding(1); var y = d3.scaleLinear().range([height, 0]).domain([0, 65000]); var color = d3.scaleOrdinal(d3.schemeCategory10); var xAxis = d3.axisBottom(x).ticks(12); var yAxis = d3.axisLeft(y); var svg = d3.select("#line-chart-container") .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 + ")"); var g = null; var line = d3.line() .x(function (d) { return x(d.month); }) .y(function (d) { return y(d.value); }); // .curve(d3.curveBasis); let lines = svg.append('g') .attr('class', 'lines'); var mouseG = svg.append("g") // this the black vertical line to folow mouse .attr("class", "mouse-over-effects"); mouseG.append("path") .attr("class", "mouse-line") .style("stroke", "black") .style("stroke-width", "1px") .style("opacity", "0"); // get data d3.queue() .defer(d3.json, 'http://www.json-generator.com/api/json/get/cjsmAgXIVu?indent=2') .await(makeLineChart); function makeLineChart(error, data) { if (error) { console.log(error); } color.domain(d3.keys(data[0]) .filter(function (key) { return key == "CODE"; }) ); createAxis(); updateChart(data); // radio button change d3.selectAll("input[name='modality-selector']") .on("change", function () { modalitySelected = document.querySelector('input[name=modality-selector]:checked').value; clearChart(); createAxis(); updateChart(data); }); } // end makeLineChart function /** * Create (if is the firts time) or updates the line chart, * based on radio button selection. */ function updateChart(data) { // filter data filtered_data = data.filter(function (d) { return d.MODALITY == modalitySelected && codes.includes(d.CODE); }); // first we need to corerce the data into the right formats filtered_data = filtered_data.map(function (d) { return { code: d.CODE, month: d.MONTH, modality: d.MODALITY, value: +d.VALUE }; }); filtered_data = d3.nest() .key(function (d) { return d.code; }) .entries(filtered_data); var codesArray = svg.selectAll(".code") .data(filtered_data, function (d) { return d.key; }) .enter() .append("g") .attr("class", "code") .on("mouseover", function (d, i) { codesArray.append("text") .attr("class", "title-text") .style("fill", color(d.key)) .text('') .attr("text-anchor", "middle") .attr("x", 200) .attr("y", 20); }) .on("mouseout", function (d) { codesArray.select(".title-text").remove(); }) codesArray.append("path") .attr("class", "line") .attr("d", function (d) { // console.log(d) return line(d.values); }) .style("stroke", function (d) { return color(d.key); }) .style('opacity', lineOpacity) .on("mouseover", function (d) { d3.selectAll('.line') .style('opacity', otherLinesOpacityHover); d3.selectAll('.circle') .style('opacity', circleOpacityOnLineHover); d3.select(this) .style('opacity', lineOpacityHover) .style("stroke-width", lineStrokeHover) .style("cursor", "pointer"); }) .on("mouseout", function (d) { d3.selectAll(".line") .style('opacity', lineOpacity); d3.selectAll('.circle') .style('opacity', circleOpacity); d3.select(this) .style("stroke-width", lineStroke) .style("cursor", "none"); }); /* Add circles in the line */ codesArray.selectAll("circle-group") .data(filtered_data, function (d) { return d.key; }) .enter() .append("g") .style("fill", function (d, i) { return color(d.key); }) .on("mouseover", function (d, i) { d3.select(this) .style("cursor", "pointer") .append("text") .attr("class", "text") .text(d.values[i].value) .attr("x", d => x(d.key) + 5) .attr("y", d => y(d.value) + 10); }) .on("mouseout", function (d) { codesArray.select(".text").remove(); }) .selectAll("circle") .data(d => d.values).enter() .append("g") .attr("class", "circle") .append("circle") .attr("cx", function (d) { return x(d.month) }) .attr("cy", d => y(d.value)) .attr("r", circleRadius) .style('opacity', circleOpacity) .on("mouseover", function (d) { d3.select(this) .transition() .duration(duration) .attr("r", circleRadiusHover); }) .on("mouseout", function (d) { d3.select(this) .transition() .duration(duration) .attr("r", circleRadius); }); } function createAxis() { g = svg.append("g") .attr("class", "chartGroup") g.append("g") .attr("class", "axis x") .attr("transform", "translate(0, " + height + ")") .call(xAxis); g.append("g") .attr("class", "axis y") .call(yAxis); } /** * Remove old chart (axis and lines). */ function clearChart() { d3.select(".chartGroup").remove(); d3.selectAll(".code").remove(); } //#endregion
<head> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.css"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script> <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script> <script src="https://d3js.org/topojson.v2.min.js"></script> <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.js"></script> <title>Index 9</title> </head> <style> svg { font-family: Sans-Serif, Arial; } .line { stroke-width: 1.5; fill: none; } .axis path { stroke: black; } .text { font-size: 12px; } .title-text { font-size: 12px; } table { font-family: Arial, Helvetica, sans-serif; border-collapse: collapse; font-size: 12px !important; margin-left: 10px; margin-top: 10px; /* width: 300px !important; */ } .table td { padding: .0rem; } tr { line-height: 25px; } .axis path, .axis line { fill: none; stroke: grey; stroke-width: 1; shape-rendering: crispEdges; } th, td { border: 1px solid #cccccc; padding: 0px; text-align: center; } input { visibility: hidden; } label { cursor: pointer; margin-bottom: .0rem; } hr { margin-top: -5px; border-width: 1px; border-color: black; } </style> <body> <div style="width: 600px; margin-left: 10px;"> <div id="line-chart-container"></div> <hr> <div style="width: 600px;" id="modality-selector-container"> <form id="modality-selector"> <div class="row table"> <div class="col-6"> <h7 style="margin-left: 10px;">Sales</h7> <table id="tableSales" class="table table-hover"> <thead> <tr> <th>Sale</th> <th>Current Year</th> <th>Last Year</th> </tr> </thead> <tbody> <tr> <td> <input type="radio" name="modality-selector" id="rb-charneca" value="charneca" checked /> <label for="rb-charneca">CHARNECA</label> </td> <td>236.009,23</td> <td>282.753,78</td> </tr> <tr> <td> <input type="radio" name="modality-selector" id="rb-joaoluis" value="joaoluis" /> <label for="rb-joaoluis">JOÃO LUIS</label> </td> <td>257.733,05</td> <td>332.119,31</td> </tr> </tbody> </table> </div> </div> </form> </div> </div> </div> </body>
As you can see, hovering over circles always shows the same values.如您所见,将鼠标悬停在圆圈上始终显示相同的值。 Can you help me fix this?
你能帮我解决这个问题吗?
Thank you very much in advance.非常感谢您提前。
You are attaching the mouseover
listener to the groups, hoping that the index i
could give you the circle:您正在将
mouseover
侦听器附加到组中,希望索引i
可以为您提供圆圈:
.on("mouseover", function (d, i) {
d3.select(this)
.append("text")
.text(d.values[i].value)
//etc...
However, that i
is the index of the groups , not of the circles, and you have just two groups, with indices 0 and 1.然而,
i
在该组的未圆的指数,和你刚才两组,指数在0和1。
The simplest solution is attaching the listener to the circles themselves.最简单的解决方案是将侦听器附加到圆圈本身。 Here is your code with that change:
这是带有该更改的代码:
//#region Criando Tabela de Vendedores var newMapVendedores = [{ "vendnm": "CHARNECA", "Vendas_Ano": 236009.2299999998, "Vendas_Ant": 282753.77999999997 }, { "vendnm": "JOÃO LUIS", "Vendas_Ano": 257733.04999999996, "Vendas_Ant": 332119.31 }, ] $(document).ready(function() { $("#tableVendedores").append('<tfoot><th></th><th></th><th></th></tfoot>'); var table = $('#tableVendedores').DataTable({ "data": newMapVendedores, "columns": [{ "data": "vendnm", title: 'Vendedor' }, { "data": "Vendas_Ano", title: 'Vendas Ano' }, { "data": "Vendas_Ant", title: 'Vendas Ant' }, ], "bLengthChange": false, "bPaginate": false, "bFilter": false, "info": false, }); $('#tableVendedores').on('click', 'tr', function() { var data = table.row(this).data(); }); }); //#endregion //#region GRÁFICO var codes = ["VENDAS_ANO", "VENDAS_ANT"]; $('span.values').html(codes.join(', ')); modalitySelected = document.querySelector('input[name=modality-selector]:checked').value; var data = null; var filtered_data = null; var margin = { top: 30, right: 20, bottom: 50, left: 50 }; var width = 600 - margin.left - margin.right; var height = 350 - margin.top - margin.bottom; var duration = 250; var lineOpacity = "0.25"; var lineOpacityHover = "0.85"; var otherLinesOpacityHover = "0.1"; var lineStroke = "1.5px"; var lineStrokeHover = "2.5px"; var circleOpacity = '0.85'; var circleOpacityOnLineHover = "0.25"; var circleRadius = 3; var circleRadiusHover = 6; var month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; var x = d3.scaleBand().range([0, width]).domain(month).padding(1); var y = d3.scaleLinear().range([height, 0]).domain([0, 65000]); var color = d3.scaleOrdinal(d3.schemeCategory10); var xAxis = d3.axisBottom(x).ticks(12); var yAxis = d3.axisLeft(y); var svg = d3.select("#line-chart-container") .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 + ")"); var g = null; var line = d3.line() .x(function(d) { return x(d.month); }) .y(function(d) { return y(d.value); }); // .curve(d3.curveBasis); let lines = svg.append('g') .attr('class', 'lines'); var mouseG = svg.append("g") // this the black vertical line to folow mouse .attr("class", "mouse-over-effects"); mouseG.append("path") .attr("class", "mouse-line") .style("stroke", "black") .style("stroke-width", "1px") .style("opacity", "0"); // get data d3.queue() .defer(d3.json, 'http://www.json-generator.com/api/json/get/cjsmAgXIVu?indent=2') .await(makeLineChart); function makeLineChart(error, data) { if (error) { console.log(error); } color.domain(d3.keys(data[0]) .filter(function(key) { return key == "CODE"; }) ); createAxis(); updateChart(data); // radio button change d3.selectAll("input[name='modality-selector']") .on("change", function() { modalitySelected = document.querySelector('input[name=modality-selector]:checked').value; clearChart(); createAxis(); updateChart(data); }); } // end makeLineChart function /** * Create (if is the firts time) or updates the line chart, * based on radio button selection. */ function updateChart(data) { // filter data filtered_data = data.filter(function(d) { return d.MODALITY == modalitySelected && codes.includes(d.CODE); }); // first we need to corerce the data into the right formats filtered_data = filtered_data.map(function(d) { return { code: d.CODE, month: d.MONTH, modality: d.MODALITY, value: +d.VALUE }; }); filtered_data = d3.nest() .key(function(d) { return d.code; }) .entries(filtered_data); var codesArray = svg.selectAll(".code") .data(filtered_data, function(d) { return d.key; }) .enter() .append("g") .attr("class", "code") .on("mouseover", function(d, i) { codesArray.append("text") .attr("class", "title-text") .style("fill", color(d.key)) .text('') .attr("text-anchor", "middle") .attr("x", 200) .attr("y", 20); }) .on("mouseout", function(d) { codesArray.select(".title-text").remove(); }) codesArray.append("path") .attr("class", "line") .attr("d", function(d) { // console.log(d) return line(d.values); }) .style("stroke", function(d) { return color(d.key); }) .style('opacity', lineOpacity) .on("mouseover", function(d) { d3.selectAll('.line') .style('opacity', otherLinesOpacityHover); d3.selectAll('.circle') .style('opacity', circleOpacityOnLineHover); d3.select(this) .style('opacity', lineOpacityHover) .style("stroke-width", lineStrokeHover) .style("cursor", "pointer"); }) .on("mouseout", function(d) { d3.selectAll(".line") .style('opacity', lineOpacity); d3.selectAll('.circle') .style('opacity', circleOpacity); d3.select(this) .style("stroke-width", lineStroke) .style("cursor", "none"); }); /* Add circles in the line */ codesArray.selectAll("circle-group") .data(filtered_data, function(d) { return d.key; }) .enter() .append("g") .style("fill", function(d, i) { return color(d.key); }) .selectAll("circle") .data(d => d.values).enter() .append("g") .attr("class", "circle") .append("circle") .attr("cx", function(d) { return x(d.month) }) .attr("cy", d => y(d.value)) .attr("r", circleRadius) .style('opacity', circleOpacity) .on("mouseover", function(d) { d3.select(this.parentNode) .style("cursor", "pointer") .append("text") .attr("class", "text") .text(d.value) .attr("x", d => x(d.month) + 10) .attr("y", d => y(d.value) - 10); d3.select(this) .transition() .duration(duration) .attr("r", circleRadiusHover); }) .on("mouseout", function(d) { codesArray.select(".text").remove(); d3.select(this) .transition() .duration(duration) .attr("r", circleRadius); }); } function createAxis() { g = svg.append("g") .attr("class", "chartGroup") g.append("g") .attr("class", "axis x") .attr("transform", "translate(0, " + height + ")") .call(xAxis); g.append("g") .attr("class", "axis y") .call(yAxis); } /** * Remove old chart (axis and lines). */ function clearChart() { d3.select(".chartGroup").remove(); d3.selectAll(".code").remove(); } //#endregion
<head> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.css"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script> <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script> <script src="https://d3js.org/topojson.v2.min.js"></script> <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.js"></script> <title>Index 9</title> </head> <style> svg { font-family: Sans-Serif, Arial; } .line { stroke-width: 1.5; fill: none; } .axis path { stroke: black; } .text { font-size: 12px; } .title-text { font-size: 12px; } table { font-family: Arial, Helvetica, sans-serif; border-collapse: collapse; font-size: 12px !important; margin-left: 10px; margin-top: 10px; /* width: 300px !important; */ } .table td { padding: .0rem; } tr { line-height: 25px; } .axis path, .axis line { fill: none; stroke: grey; stroke-width: 1; shape-rendering: crispEdges; } th, td { border: 1px solid #cccccc; padding: 0px; text-align: center; } input { visibility: hidden; } label { cursor: pointer; margin-bottom: .0rem; } hr { margin-top: -5px; border-width: 1px; border-color: black; } </style> <body> <div style="width: 600px; margin-left: 10px;"> <div id="line-chart-container"></div> <hr> <div style="width: 600px;" id="modality-selector-container"> <form id="modality-selector"> <div class="row table"> <div class="col-6"> <h7 style="margin-left: 10px;">Sales</h7> <table id="tableSales" class="table table-hover"> <thead> <tr> <th>Sale</th> <th>Current Year</th> <th>Last Year</th> </tr> </thead> <tbody> <tr> <td> <input type="radio" name="modality-selector" id="rb-charneca" value="charneca" checked /> <label for="rb-charneca">CHARNECA</label> </td> <td>236.009,23</td> <td>282.753,78</td> </tr> <tr> <td> <input type="radio" name="modality-selector" id="rb-joaoluis" value="joaoluis" /> <label for="rb-joaoluis">JOÃO LUIS</label> </td> <td>257.733,05</td> <td>332.119,31</td> </tr> </tbody> </table> </div> </div> </form> </div> </div> </div> </body>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.