D3.JS和条形图代码中的奇怪错误

piv4azn7  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(154)

嗨,伙计们,我正在学习D3,我正在尝试制作动态图表,随着图表组的改变,图表组将显示相同的图表,让我用两张图片给你看:

我按照文档教程,这是工作!但我的代码的行为是奇怪的,当我应用过滤器选择组,它显示酒吧在随机位置或在其他顶部,也过滤器应用后,它从来没有显示数组的第一个酒吧这里是代码

var cereals;
    if (manufacturer === 'All')
        cereals = data.filter(d => d.manufacturer !== manufacturer);
    else cereals = data.filter(d => d.manufacturer === manufacturer);

    //****Draw and Update your chart here****
    var bars = chartG.selectAll('.bar')
        .data(cereals,function(d,i){
            return d.sugar;
        });

    var barsEnter = bars.enter()
        .append('g')
        .attr('class', 'bar');

    barsEnter.merge(bars)
        .attr('transform', function(d,i){
            return 'translate('+[i * barBand + 4,0]+')';
        });

    /*barsEnter.append('rect')
            .attr("class", "bar")
            .attr("width", barWidth)
            .attr("height", function(d) { return chartHeight - sugarScale(d.sugar); });
    */
    barsEnter.append('rect')
    .attr("class", "bar")
    .attr("y", function(d) { return sugarScale(d.sugar); })
    .attr("width", barWidth)
    .attr("height", function(d) { return chartHeight - sugarScale(d.sugar); });

    barsEnter.append('text')
        .attr('dy', '0.9em')
        .attr('dx', '0.6em')
        .attr('class','axis-label')
        .attr("transform", "translate(0," + chartHeight + ")")
        .text(function(d){
            console.log(d)
            return d.cerealName;
        }); 
    bars.exit().remove();

这里是完整的代码,如果你想检查!
main.js

// Global function called when select element is changed
function onCategoryChanged() {
    var select = d3.select('#categorySelect').node();
    var category = select.options[select.selectedIndex].value;
    // Update chart with the selected category of cereal
    updateChart(category);
}

// recall that when data is loaded into memory, numbers are loaded as strings
// this function helps convert numbers into string during data preprocessing
function dataPreprocessor(row) {
    return {
        cerealName: row['Cereal Name'],
        manufacturer: row['Manufacturer'],
        sugar: +row['Sugars']
    };
}

var svg = d3.select('svg');

// Get layout parameters
var svgWidth = +svg.attr('width');
var svgHeight = +svg.attr('height');

var padding = { t: 60, r: 20, b: 80, l: 60 };

// Compute chart dimensions
var chartWidth = svgWidth - padding.l - padding.r;
var chartHeight = svgHeight - padding.t - padding.b;

// Variable for the spacing of bar charts
var barBand;
var barWidth;

// scales
var sugarScale; // y axis
var xBandScale; // x axis

// Create a group element for appending chart elements
var chartG = svg.append('g')
    .attr('transform', `translate(${padding.l}, ${padding.t})`);

var data;

d3.csv('cereals.csv', dataPreprocessor).then(function(dataset) {
    // Create global variables here and intialize the chart
    data = dataset;

    // Compute the spacing for bar bands based on number of cereals
    barBand = chartWidth / data.length;
    barWidth = 0.7 * barBand;

    //****Your JavaScript code goes here****\
    dataset

    // Add axes to chart
    addAxes();

    // Main Part
    sugarScale.domain([0, d3.max(dataset, function(d) { return d.sugar; })]);0

    chartG.append("g").call(d3.axisLeft(sugarScale)).append("text").text("value");

    // Update the chart for All cereals to initialize
    updateChart('All');
});

function addAxes() {
    //****Draw the axes here****
    sugarScale = d3.scaleLinear().range ([chartHeight,0]),
    xBandScale = d3.scaleLinear().range([0, chartWidth])
}

function updateChart(manufacturer) {
    //  Create a filtered array of cereals based on the manufacturer
    var cereals;
    if (manufacturer === 'All')
        cereals = data.filter(d => d.manufacturer !== manufacturer);
    else cereals = data.filter(d => d.manufacturer === manufacturer);

    //****Draw and Update your chart here****
    var bars = chartG.selectAll('.bar')
        .data(cereals,function(d,i){
            return d.sugar;
        });

    var barsEnter = bars.enter()
        .append('g')
        .attr('class', 'bar');

    barsEnter.merge(bars)
        .attr('transform', function(d,i){
            return 'translate('+[i * barBand + 4,0]+')';
        });

    /*barsEnter.append('rect')
            .attr("class", "bar")
            .attr("width", barWidth)
            .attr("height", function(d) { return chartHeight - sugarScale(d.sugar); });
    */
    barsEnter.append('rect')
    .attr("class", "bar")
    .attr("y", function(d) { return sugarScale(d.sugar); })
    .attr("width", barWidth)
    .attr("height", function(d) { return chartHeight - sugarScale(d.sugar); });

    barsEnter.append('text')
        .attr('dy', '0.9em')
        .attr('dx', '0.6em')
        .attr('class','axis-label')
        .attr("transform", "translate(0," + chartHeight + ")")
        .text(function(d){
            console.log(d)
            return d.cerealName;
        }); 
    bars.exit().remove();
}

// Remember code outside of the data callback function will run before the data loads

index.html

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Lab 4 - ABCs of D3</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
    <link rel="stylesheet" href="./style.css">
</head>
<body>
    <div id="main">
        <svg width="600" height="330" style="border: 1px solid #777;">
        </svg>
        <div>
            <label for="categorySelect">Manufacturer: </label>
            <select class="custom-select" id="categorySelect" onchange="onCategoryChanged()">
              <option selected value="All">All</option>
              <option value="General Mills">General Mills</option>
              <option value="Quaker Oats">Quaker Oats</option>
              <option value="Ralston Purina">Ralston Purina</option>
              <option value="Kelloggs">Kelloggs</option>
              <option value="Nabisco">Nabisco</option>
              <option value="Post">Post</option>
            </select>
        </div>
    </div>
</body>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="./main.js"></script>
</html>

样式

.axis-label {
    text-anchor: middle;
    font-size: 12px;
    font-weight: semibold;
}

body {
    font-family: "Open Sans";
    margin: 0;
}

.bar {
    fill: #4571C9;
}

# main {

    margin: 20px;
}

cereals.csv

Cereal Name,Manufacturer,Sugars
Kix,General Mills,3
Life,Quaker Oats,6
Trix,General Mills,12
Smacks,Kelloggs,15
Basic 4,General Mills,8
Crispix,Kelloggs,3
All-Bran,Kelloggs,5
Cheerios,General Mills,1
Clusters,General Mills,7
Wheaties,General Mills,3
100% Bran,Nabisco,6
Bran Chex,Ralston Purina,6
Corn Chex,Ralston Purina,3
Corn Pops,Kelloggs,12
Rice Chex,Ralston Purina,2
Special K,Kelloggs,3
Grape-Nuts,Post,3
Honey-comb,Post,11
Wheat Chex,Ralston Purina,3
Apple Jacks,Kelloggs,14

这是一个奇怪的错误的例子:
第一次
x1c4d 1x指令集

ijnw1ujt

ijnw1ujt1#

我可以看到两种可能:
1.您正在将class bar添加到“g”元素以及“g”元素中的“rect”元素-我可以看到,当您在该类上选择All时,会导致问题
1.在合并新条形图和现有条形图后,您正在追加新的矩形和文本。这将向现有条形图中添加更多文本和矩形。您希望在合并前追加文本和矩形元素。
不是必须的,但可能很好:2a)您可能希望在合并操作后,“选择”矩形并在那里进行条形Y/宽度/高度计算,这样如果自上次操作以来值发生了变化,现有条形也会更新。尽管这看起来像是静态数据。

相关问题