D3.js d3图表重画无法调整窗口大小

D3.js d3图表重画无法调整窗口大小,d3.js,D3.js,我正在使用d3显示几个等效的折线图,我正在使用一个chart()函数构建这些折线图,该函数接受所有图表数据 此chart()函数是根据draw()函数的要求调用的,该函数循环遍历页面上的所有占位符图表元素 我想在调整视口大小时重新绘制所有图表。为此,我使用d3.select(“svg”).remove()删除现有的图表,然后再次调用mydraw()函数 不幸的是,当图表重新绘制时,并非所有元素都正确-我的路径不会显示(尽管它出现在标记中),其他一些圆对象也不会显示)。我不知道这是为什么 请查看我

我正在使用d3显示几个等效的折线图,我正在使用一个
chart()
函数构建这些折线图,该函数接受所有图表数据

chart()
函数是根据
draw()
函数的要求调用的,该函数循环遍历页面上的所有占位符图表元素

我想在调整视口大小时重新绘制所有图表。为此,我使用d3.select(“svg”).remove()删除现有的图表,然后再次调用my
draw()
函数

不幸的是,当图表重新绘制时,并非所有元素都正确-我的路径不会显示(尽管它出现在标记中),其他一些圆对象也不会显示)。我不知道这是为什么

请查看我创建的。此外,以下是相关代码:

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
}

var data = [], promos = [], stocks = [], start = [], end = [];

data['chart-7114'] = [{"date":"2017-08-14","value":"5.0000"},{"date":"2017-08-16","value":"5.0000"},{"date":"2017-08-17","value":"5.0000"},{"date":"2017-08-24","value":"5.0000"},{"date":"2017-08-31","value":"5.0000"},{"date":"2017-09-13","value":"5.0000"},{"date":"2017-09-14","value":"5.0000"},{"date":"2017-09-25","value":"6.4500"},{"date":"2017-09-26","value":"6.4500"},{"date":"2017-09-27","value":"6.4500"},{"date":"2017-09-28","value":"6.4500"}];
                promos['chart-7114'] = [{"start_date":"2017-08-14","end_date":"2017-08-16"},{"start_date":"2017-08-24","end_date":"2017-08-24"},{"start_date":"2017-09-13","end_date":"2017-09-14"}];
                stocks['chart-7114'] = [{"start_date":"2017-08-16","end_date":"2017-08-16"},{"start_date":"2017-09-14","end_date":"2017-09-14"},{"start_date":"2017-09-26","end_date":"2017-09-26"}];
                start['chart-7114'] = "2017-08-14";
                end['chart-7114'] = "2017-09-28";


$(document).ready(function() {

function chart(selector, data, promos, stocks, start, end) {

    var margin = {top: 20, right: 20, bottom: 30, left: 60},
        width = $(selector).width() - margin.left - margin.right,
        height = $(selector).height() - margin.top - margin.bottom;

    var svg = d3.select(selector).append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom);

    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var parseDate = d3.timeParse("%Y-%m-%d"),
        formatDate = d3.timeFormat("%Y"),
        formatDate2 = d3.timeFormat("%d/%m/%Y");

    var x = d3.scaleTime()
        .domain([parseDate(start), parseDate(end)])
        .range([0, width]);

    var y = d3.scaleLinear()
        .range([height, 0]);

    var xAxis = d3.axisBottom(x);
    var yAxis = d3.axisLeft(y);

    var area = d3.line()
        .curve(d3.curveLinear)
        .y(function(d) { return y(d.value); });

    var areaPath = g.append("path")
        .attr('class', 'line')
        .attr("clip-path", "url(#clip)");

    var yGroup = g.append("g");

    var xGroup = g.append("g")
        .attr("transform", "translate(0," + height + ")");

    var tip = d3.tip()
        .attr('class', 'd3-tip')
        .offset([-10, 0])
        .html(function(d) {
            return "Date: " + formatDate2(d.date) + "<br>Price: &pound;" + d.value;
        });

    g.call(tip);

    var promoHighlights = g.selectAll('.promo')
        .data(promos)
        .enter().append("rect")
            .attr('class', 'promo' )
            .style("pointer-events","all")
            .attr("height", height);


    var stockHighlights = g.selectAll('.nostock')
        .data(stocks)
        .enter().append("rect")
            .attr('class', 'nostock' )
            .style("pointer-events","all")
            .attr("height", height);

    var zoom = d3.zoom()
        .scaleExtent([1 / 4, 8])
        .translateExtent([[-width, -Infinity], [2 * width, Infinity]])
        .on("zoom", zoomed);

    var zoomRect = g.append("rect")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .attr("fill", "none")
        .attr("pointer-events", "all")
        .call(zoom);

    var toolTips = g.selectAll("circle")
        .data(data).enter()
        .append("circle")
            .attr("r", 4)
            .style("pointer-events","all")
            .on('mouseover', function(d, e) {
                tip.show(d);
                d3.select(this).attr('r', 8);
            })
            .on('mouseout', function(d, e) {
                tip.hide(d);
                d3.select(this).attr('r', 4);
            });

    g.append("clipPath")
        .attr("id", "clip")
        .append("rect")
            .attr("width", width)
            .attr("height", height);

    data.forEach(function(d) {
        d.date = parseDate(d.date);
        d.value = +d.value;
    });

    var xExtent = d3.extent(data, function(d) { return d.date; });
    zoom.translateExtent([[x(xExtent[0]), -Infinity], [x(xExtent[1]), Infinity]]);
    y.domain([0, d3.max(data, function(d) { return d.value; })+1]);
    yGroup.call(yAxis).select(".domain").remove();
    areaPath.datum(data);
    zoomRect.call(zoom.transform, d3.zoomIdentity);
    toolTips.attr("cy", function(d) { return y(d.value); });

    function zoomed() {
        var xz = d3.event.transform.rescaleX(x);
        xGroup.call(xAxis.scale(xz));
        areaPath.attr("d", area.x(function(d) { return xz(d.date); }));
        toolTips.attr("cx", function(d) { return xz(d.date); });
        promoHighlights.attr("x", function(d) { return xz(parseDate(d.start_date)); })
            .attr("width", function(d) {
                if(d.end_date != d.start_date) {
                    //console.log(parseDate(d.end_date));
                    return xz(parseDate(d.end_date))-xz(parseDate(d.start_date));
                }
                else {
                    return xz(d3.timeDay.offset(parseDate(d.end_date)))-xz(parseDate(d.start_date));
                }
            });
        stockHighlights.attr("x", function(d) {
                return xz(parseDate(d.start_date));
            })
            .attr("width", function(d) {
                if(d.end_date != d.start_date) {
                    //console.log(parseDate(d.end_date));
                    return xz(parseDate(d.end_date))-xz(parseDate(d.start_date));
                }
                else {
                    return xz(d3.timeDay.offset(parseDate(d.end_date)))-xz(parseDate(d.start_date));
                }
            });
    }

}

function draw() {
    $('.chart').each(function() {
        chart_id = $(this).attr('id');
        chart('#'+$(this).attr('id'), data[chart_id], promos[chart_id], stocks[chart_id], start[chart_id], end[chart_id]);
    });
}

if($('.chart').length > 0) {
    draw();

    $(window).resize(debounce(function(){
        d3.select("svg").remove();
        draw();
    },100));
}

});
函数去盎司(func,wait,immediate){
var超时;
返回函数(){
var context=this,args=arguments;
var later=function(){
超时=空;
如果(!immediate)函数应用(上下文,参数);
};
var callNow=立即&&!超时;
clearTimeout(超时);
超时=设置超时(稍后,等待);
if(callNow)funct.apply(上下文,参数);
};
}
var数据=[]、促销=[]、股票=[]、开始=[]、结束=[];
数据['chart-7114']=[{“日期”:“2017-08-14”,“价值”:“5.0000”},{“日期”:“2017-08-16”,“价值”:“5.0000”},{“日期”:“2017-08-17”,“价值”:“5.0000”},{“日期”:“2017-08-31”,“价值”:“5.0000”},{“日期”:“2017-09-13”,“价值”:“5.0000”},{“日期”:“2017-09-14”,“价值”:“5.0000”},{“日期”:“2017-08-24”,“价值”:“5.0000”},{“2017-09-26”,“价值”:“6.4500”},{“日期”:“2017-09-27”,“价值”:“6.4500”},{“日期”:“2017-09-28”,“价值”:“6.4500”}];
宣传片['chart-7114']=[{“开始日期”:“2017-08-14”,“结束日期”:“2017-08-16”},{“开始日期”:“2017-08-24”,“结束日期”:“2017-08-24”},{“开始日期”:“2017-09-13”,“结束日期”:“2017-09-14”};
股票['chart-7114']=[{“开始日期”:“2017-08-16”,“结束日期”:“2017-08-16”},{“开始日期”:“2017-09-14”,“结束日期”:“2017-09-14”},{“开始日期”:“2017-09-26”,“结束日期”:“2017-09-26”};
开始['chart-7114']=“2017-08-14”;
结束['chart-7114']=“2017-09-28”;
$(文档).ready(函数(){
功能图(选择器、数据、促销、股票、开始、结束){
var margin={顶部:20,右侧:20,底部:30,左侧:60},
宽度=$(选择器).width()-margin.left-margin.right,
高度=$(选择器).height()-margin.top-margin.bottom;
var svg=d3.select(选择器).append(“svg”)
.attr(“宽度”,宽度+边距。左侧+边距。右侧)
.attr(“高度”,高度+边距。顶部+边距。底部);
g=svg.append(“g”).attr(“transform”、“translate”(+margin.left+)、“+margin.top+”);
var parseDate=d3.timeParse(“%Y-%m-%d”),
formatDate=d3.timeFormat(“%Y”),
formatDate2=d3.timeFormat(“%d/%m/%Y”);
var x=d3.scaleTime()
.domain([parseDate(开始),parseDate(结束)])
.范围([0,宽度]);
变量y=d3.scaleLinear()
.范围([高度,0]);
var xAxis=d3.axisBottom(x);
var yAxis=d3.轴左(y);
变量面积=d3.line()
.曲线(d3.曲线线)
.y(函数(d){返回y(d.value);});
var areaPath=g.append(“路径”)
.attr('类','行')
.attr(“剪辑路径”、“url(#剪辑)”);
var yGroup=g.append(“g”);
var xGroup=g.append(“g”)
.attr(“变换”、“平移(0)”、“高度+”);
var tip=d3.tip()
.attr('class','d3 tip')
.偏移量([-10,0])
.html(函数(d){
返回“日期:”+formatDate2(d.Date)+“
价格:£;”+d.value; }); g、 电话(tip); var promoHighlights=g.selectAll('.promo') .资料(宣传片) .enter().append(“rect”) .attr('class','promo') .style(“指针事件”、“全部”) .attr(“高度”,高度); var stockHighlights=g.selectAll(“.nostock”) .数据(库存) .enter().append(“rect”) .attr('class','nostock') .style(“指针事件”、“全部”) .attr(“高度”,高度); var zoom=d3.zoom() .scaleExtent([1/4,8]) .translateExtent([[-宽度,-无穷大],[2*宽度,无穷大]] 。打开(“缩放”,缩放); var zoomRect=g.append(“rect”) .attr(“宽度”,宽度+边距。左侧+边距。右侧) .attr(“高度”,高度+边距。顶部+边距。底部) .attr(“填充”、“无”) .attr(“指针事件”、“全部”) .呼叫(缩放); var toolTips=g.selectAll(“圆圈”) .data(data).enter() .附加(“圆圈”) .attr(“r”,4) .style(“指针事件”、“全部”) .on('mouseover',函数(d,e){ 提示:显示(d); d3.选择(this).attr('r',8); }) .on('mouseout',函数(d,e){ 提示:隐藏(d); d3.选择(this).attr('r',4); }); g、 附加(“clipPath”) .attr(“id”、“剪辑”) .append(“rect”) .attr(“宽度”,宽度) .attr(“高度”,高度); data.forEach(函数(d){ d、 日期=解析日期(d.date); d、 值=+d.值; }); var xExtent=d3.extent(数据,函数(d){return d.date;}); zoom.translateExtent([[x(xExtent[0]),-Infinity],[x(xExtent[1]),Infinity]]; y、 域([0,d3.max(数据,函数(d){返回d.value;})+1]); 调用(yAxis)。选择(“.domain”).remove(); 区域路径基准面(数据); zoomRect.call(zoom.transform,d3.zoomIdentity); attr(“cy”,函数(d){返回y(d.value);}); 函数缩放(){ var xz=d3.event.transform.rescaleX(x); xGroup.call(xAxis.scale(xz)); attr(“d”,area.x(函数(d){return xz(d.date);})); attr(“cx”,函数(d){returnxz(d.date);});
function render() {
    updateDimensions(window.innerWidth);   
    x.range([0, width]);
    y.range([height, 0]);
    svg
      .attr('width', '100%')
      .attr('height', height + margin.top + margin.bottom);
    fh = svg.style("height").replace("px", "");
    fw = svg.style("width").replace("px", "");
    chartWrapper
      .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');           
    xAxis.scale(x);
    yAxis.scale(y);
    if(window.innerWidth < wbreakPoint) {
      xAxis.ticks(d3.timeHour.every(12))
    }
    else {
      xAxis.ticks(d3.timeHour.every(5))
    };
    if(window.innerinnerHeight < hbreakPoint) {   
      yAxis.ticks(Math.max(height/50, 2))
    }
    else {
      yAxis.ticks(Math.max(height/50, 2));
    }; 
    svg.select('.x.axis')
        .attr('transform', 'translate(0,' + height + ')')
        .transition()
        .duration(200)
        .call(xAxis)
        .selectAll("text")  
            .style("text-anchor", "end")
            .attr("dx", "-.8em")
            .attr("dy", ".15em")
            .attr("transform", "rotate(-50)" ); 
    svg.select('.y.axis')
        .transition()
        .duration(200)
        .call(yAxis);
    chartWrapper.select("text")
        .attr("x", (fw / 2))             
        .attr("y", 0 - (margin.top / 2))
        .attr("text-anchor", "middle");     
    path
        .transition()
        .duration(1000)
        .attr('d',  d => lineGen(d.Data))
        .attr("stroke-width", 3)
        .attr("fill", "none")
        .attr("stroke", (d, i) => colors(i));
    groups.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
    groups
        .transition()
        .duration(1000);} 
function updateDimensions(winWidth) {
    margin.top = 40;
    margin.right = winWidth < wbreakPoint ? 50 : 80;
    margin.left = winWidth < wbreakPoint ? 30 : 50;
    margin.bottom = 100;
    width = winWidth - margin.left - margin.right;
    height = .1 * width;}
return {render : render}
})(window,d3);
window.addEventListener('resize', Chart.render);
var inter = setInterval(function() {
            updateData(jsont1);
data.forEach(function(d) {
    d.date = parseDate(d.date);
    d.value = +d.value;
});