首页 > 解决方案 > 可刷的水平条形图不起作用

问题描述

我正在使用 d3 制作可刷的水平条形图。我将此示例作为 d3 旧版本中的参考。所以我正在尝试转换为 d3 最新版本。我已经根据我的知识改变了一切,但不知何故它不起作用。所以,这是我的codepen链接的链接

这是示例代码:

var zoomer = d3.zoom()
  .on("zoom",null)

var main_margin = {top: 10, right: 10, bottom: 30, left: 100},
        main_width = 500 - main_margin.left - main_margin.right,
        main_height = 400 - main_margin.top - main_margin.bottom;

    var mini_margin = {top: 10, right: 10, bottom: 30, left: 10},
        mini_height = 400 - mini_margin.top - mini_margin.bottom;
    mini_width = 100 - mini_margin.left - mini_margin.right;

svg = d3.select("#chart").append("svg")
        .attr("class", "svgWrapper")
        .attr("width", main_width + main_margin.left + main_margin.right + mini_width + mini_margin.left + mini_margin.right)
        .attr("height", main_height + main_margin.top + main_margin.bottom)
        .call(zoomer)
        .on("wheel.zoom", scroll)
        //.on("mousewheel.zoom", scroll)
        //.on("DOMMouseScroll.zoom", scroll)
        //.on("MozMousePixelScroll.zoom", scroll)
        //Is this needed?
        .on("mousedown.zoom", null)
        .on("touchstart.zoom", null)
        .on("touchmove.zoom", null)
        .on("touchend.zoom", null);

var mainGroup = svg.append("g")
            .attr("class","mainGroupWrapper")
            .attr("transform","translate(" + main_margin.left + "," + main_margin.top + ")")
            .append("g") //another one for the clip path - due to not wanting to clip the labels
            .attr("clip-path", "url(#clip)")
            .style("clip-path", "url(#clip)")
            .attr("class","mainGroup");

var miniGroup = svg.append("g")
            .attr("class","miniGroup")
            .attr("transform","translate(" + (main_margin.left + main_width + main_margin.right + mini_margin.left) + "," + mini_margin.top + ")");

    var brushGroup = svg.append("g")
            .attr("class","brushGroup")
            .attr("transform","translate(" + (main_margin.left + main_width + main_margin.right + mini_margin.left) + "," + mini_margin.top + ")");

                                              main_xScale = d3.scaleLinear().range([0, main_width]);
    mini_xScale = d3.scaleLinear().range([0, mini_width]);

    main_yScale = d3.scaleBand().rangeRound([0, main_height], 0.4, 0);
    mini_yScale = d3.scaleBand().rangeRound([0, mini_height], 0.4, 0);

    //Based on the idea from: http://stackoverflow.com/questions/21485339/d3-brushing-on-grouped-bar-chart
    main_yZoom = d3.scaleLinear()
        .range([0, main_height])
        .domain([0, main_height]);
     main_xAxis = d3.axisBottom(main_xScale)
      .scale(main_xScale)
      .ticks(4)
      .tickSize(0);

    //Add group for the x axis
    d3.select(".mainGroupWrapper")
        .append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(" + 0 + "," + (main_height + 5) + ")");
  main_yAxis = d3.axisLeft()
      .scale(main_yScale);

    //Add group for the y axis
    mainGroup.append("g")
        .attr("class", "y axis")
        .attr("transform", "translate(-5,0)");
    main_xScale.domain([0, d3.max(data, function(d) { return d.value; })]);
    mini_xScale.domain([0, d3.max(data, function(d) { return d.value; })]);
    main_yScale.domain(data.map(function(d) { return d.country; }));
    mini_yScale.domain(data.map(function(d) { return d.country; }));
    d3.select(".mainGroup").select(".y.axis").call(main_yAxis);
    textScale = d3.scaleLinear()
      .domain([15,50])
      .range([12,6])
      .clamp(true);
    var brushExtent = Math.max( 1, Math.min( 20, Math.round(data.length*0.2) ) );
    brush = d3.brushY()
        // .y(mini_yScale)
        .extent([mini_yScale(data[0].country), mini_yScale(data[brushExtent].country)])
        .on("brush", brushmove)
    gBrush = d3.select(".brushGroup").append("g")
      .attr("class", "brush")
      .call(brush);
    
    gBrush.selectAll(".resize")
      .append("line")
      .attr("x2", mini_width);
        //.on("brushend", brushend); symbolTriangle
    gBrush.selectAll(".resize")
      .append("path")
      .attr("d", d3.symbolTriangle)
      .attr("transform", function(d,i) { 
        return i ? "translate(" + (mini_width/2) + "," + 4 + ") rotate(180)" : "translate(" + (mini_width/2) + "," + -4 + ") rotate(0)"; 
      });

    gBrush.selectAll("rect")
      .attr("width", mini_width);

    //On a click recenter the brush window
    gBrush.select(".background")
      .on("mousedown.brush", brushcenter)
      .on("touchstart.brush", brushcenter);
    defs = svg.append("defs")

    //Create two separate gradients for the main and mini bar - just because it looks fun
    createGradient("gradient-rainbow-main", "60%");
    createGradient("gradient-rainbow-mini", "13%");

    //Add the clip path for the main bar chart
    defs.append("clipPath")
      .attr("id", "clip")
      .append("rect")
        .attr("x", -main_margin.left)
      .attr("width", main_width + main_margin.left)
      .attr("height", main_height);
    var mini_bar = d3.select(".miniGroup").selectAll(".bar")
      .data(data, function(d) { return d.key; });

    //UDPATE
    mini_bar
      .attr("width", function(d) { return mini_xScale(d.value); })
      .attr("y", function(d,i) { return mini_yScale(d.country); })
      .attr("height", mini_yScale.rangeRound());

    //ENTER
    mini_bar.enter().append("rect")
      .attr("class", "bar")
      .attr("x", 0)
      .attr("width", function(d) { return mini_xScale(d.value); })
      .attr("y", function(d,i) { return mini_yScale(d.country); })
      .attr("height", mini_yScale.rangeRound())
      .style("fill", "url(#gradient-rainbow-mini)");
    mini_bar.exit()
      .remove();

    //Start the brush
    gBrush.call(brush.event);

任何帮助将不胜感激。

标签: javascriptd3.jsbar-chart

解决方案


推荐阅读