响应式dc.js图表占据了整个窗口 [英] responsive dc.js chart is taking over the whole window
问题描述
我在使图表响应时遇到麻烦,我试图通过以下链接对DC.js和Crossfilter应用相同的示例:
当我用 Console
分开屏幕时,图形将响应性地呈现,因为当我更改屏幕尺寸时,图形的大小也会改变,但是,如果我离开 Console
图表仍会占据整个屏幕,并且不会返回第一张图片中显示的默认初始大小.
有人知道如何告诉我如何解决这些错误吗?我不明白为什么会这样.
提前考虑
var复合= dc.compositeChart('#composite');var vendedorTable = dc.dataTable(#vendedores");var citysTable = dc.dataTable(#cities");函数remove_empty_bins(source_group){返回 {顶部:function(N){返回source_group.all().filter(function(d){返回d.value.totalAno>1e-3 ||d.value.totalHomologo>1e-3;}).slice(0,N);}};}var url ='https://gist.githubusercontent.com/bernalvinicius/3cece295bc37de1697e7f83418e7fcc9/raw/a5820379ec6eae76ee792495cc5dd1685c977a73/vendedores.json';d3.json(url).then(function(data){data.forEach(d =>Object.assign(d,{邮件:d.Month,单位:d.Vendas_Ano,passado:d.Vendas_Ant}));var cf = crossfilter(data);vendedorDim = cf.dimension(function(d){返回d.vendnm;});var vendedorGroup = vendedorDim.group().reduce(reduceAdd,reduceRemove,reduceInitial);cityDim = cf.dimension(function(d){返回d.zona;});var cityGroup = cityDim.group().reduce(reduceAdd,reduceRemove,reduceInitial);var dim = cf.dimension(dc.pluck('mes')),grp1 = dim.group().reduceSum(dc.pluck('atual')),grp2 = dim.group().reduceSum(dc.pluck('passado'));var minMonth = dim.bottom(1)[0] .mes;var maxMonth = dim.top(1)[0] .mes;var all = cf.groupAll();dc.dataCount(.dc-data-count").dimension(cf).group(all);函数reduceAdd(p,v){p.totalAno + = + v.Vendas_Ano;p.totalHomologo + = + v.Vendas_Ant;返回p;}函数reduceRemove(p,v){p.totalAno-= v.Vendas_Ano;p.totalHomologo-= v.Vendas_Ant;返回p;}函数reduceInitial(){返回 {totalAno:0,totalHomologo:0,};}//伪尺寸等级=函数(p){返回 ""};//每月图表合成的.width(600).height(300).x(d3.scaleLinear().domain([1,12])).yAxisLabel(").xAxisLabel(月").legend(dc.legend().x(500).y(0).itemHeight(13).gap(5)).renderHorizontalGridLines(true).撰写([dc.lineChart(复合).dimension(dim).colors('steelblue').group(grp1,当前年份"),dc.lineChart(复合).dimension(dim).colors('darkorange').group(grp2,去年")]).brushOn(true);Composite.brush().extent([-0.5,data.length + 1.5])Composite.extendBrush = function(brushSelection){如果(brushSelection){vendedorTable.filter(null);vendedorDim.filter(null);cityTable.filter(null);cityDim.filter(null);const point = Math.round((brushSelection [0] + brushSelection [1])/2);返回 [点-0.5,点+ 0.5];}};//销售表vendedorTable.width(500).height(480).dimension(remove_empty_bins(vendedorGroup)).group(等级).columns([function(d){返回d.key;},功能(d){返回Number(Math.round(d.value.totalAno * 100)/100).toLocaleString("es-ES",{minimumFractionDigits:2})+'€';},功能(d){返回Number(Math.round(d.value.totalHomologo * 100)/100).toLocaleString("es-ES",{minimumFractionDigits:2})+'€';}]).sortBy(function(d){返回d.value.totalAno}).order(d3.descending)//城市表citysTable.width(500).height(480).dimension(remove_empty_bins(citiesGroup)).group(等级).columns([function(d){返回d.key;},功能(d){返回Number(Math.round(d.value.totalAno * 100)/100).toLocaleString("es-ES",{minimumFractionDigits:2})+'€';},功能(d){返回Number(Math.round(d.value.totalHomologo * 100)/100).toLocaleString("es-ES",{minimumFractionDigits:2})+'€';}]).sortBy(function(d){返回d.value.totalAno}).order(d3.descending)//销售点击事件vendedorTable.on('pretransition',function(table){table.selectAll('td.dc-table-column').on('click',function(d){让滤镜= table.filters().slice();如果(filters.indexOf(d.key)=== -1)filter.push(d.key);别的过滤器= filters.filter(k => k!= d.key);如果(filters.length === 0)vendedorDim.filter(null);别的vendedorDim.filterFunction(function(d){返回filters.indexOf(d)!== -1;})table.replaceFilter([filters]);cityTable.filter(null);cityDim.filter(null);Composite.filter(null);dc.redrawAll();});让滤镜= table.filters();table.selectAll('tr.dc-table-row').classed('sel-rows',d => filters.indexOf(d.key)!== -1);});//城市点击事件cityTable.on('pretransition',function(table){table.selectAll('td.dc-table-column').on('click',function(d){让滤镜= table.filters().slice();如果(filters.indexOf(d.key)=== -1)filter.push(d.key);别的过滤器= filters.filter(k => k!= d.key);如果(filters.length === 0)cityDim.filter(null);别的cityDim.filterFunction(function(d){返回filters.indexOf(d)!== -1;})table.replaceFilter([filters]);vendedorTable.filter(null);vendedorDim.filter(null);Composite.filter(null);dc.redrawAll();});让滤镜= table.filters();table.selectAll('tr.dc-table-row').classed('sel-rows,d => filters.indexOf(d.key)!== -1);});dc.renderAll();//重置功能$('#reset').on('click',function(){vendedorTable.filter(null);vendedorDim.filter(null);cityTable.filter(null);cityDim.filter(null);Composite.filter(null);dc.redrawAll();});$('#resetTable').on('click',function(){vendedorTable.filter(null);vendedorDim.filter(null);cityTable.filter(null);cityDim.filter(null);Composite.filter(null);dc.redrawAll();});$('#resetTable2').on('click',function(){vendedorTable.filter(null);vendedorDim.filter(null);cityTable.filter(null);cityDim.filter(null);Composite.filter(null);dc.redrawAll();});/*********************************************************************************///处理响应的函数var AdjustX = 10,AdjustY = 40;apply_resizing(composite,adjustX,adjustY,function(composite){Composite.legend().x(window.innerWidth-200);});var find_query = function(){var _map = window.location.search.substr(1).split('&').map(function(a){返回a.split('=');}).reduce(function(p,v){如果(v.length> 1)p [v [0]] = encodeURIComponent(v [1] .replace(/\ +/g,"));别的p [v [0]] = true;返回p;},{});返回函数(字段){返回_map [field] ||空值;};}();var resizeMode = find_query('resize')||'widhei';函数apply_resizing(composite,adjustX,adjustY,onresize){如果(resizeMode ==='viewbox'){合成的.width(300).height(200).useViewBoxResizing(true);d3.select(composite.anchor()).classed('fullsize',false);} 别的 {AdjustX = AdjustX ||0;AdjustY = AdjustY ||AdjustX ||0;合成的.width(window.innerWidth-AdjustX).height(window.innerHeight-AdjustY);window.onresize = function(){如果(调整大小){onresize(composite);}合成的.width(window.innerWidth-AdjustX).height(window.innerHeight-AdjustY);如果(composite.rescale){Composite.rescale();}Composite.redraw();};}}});
#composite {内边距:10px;}.dc-table-group {能见度:崩溃;}tr.dc-table-row.sel-rows {背景颜色:浅蓝色;}.brush .custom-brush-handle {显示:无;}
<!-网站图标->< link rel =快捷方式图标" href ="https://img.icons8.com/nolan/64/puzzle.png"><!-bootstrap.css->< link rel ="stylesheet" href ="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"完整性="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va + PmSTszz/K68vbdE4><!-bootstrap-theme.css->< link rel ="stylesheet" href ="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"完整性="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPpQbGYginan"><!-dc.css->< link rel ="stylesheet" href ="https://cdnjs.cloudflare.com/ajax/libs/dc/2.1.8/dc.css"><!-jquery.js->< script src ="https://code.jquery.com/jquery-3.4.1.js"完整性="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU =" crossorigin ="anonymous"</script>< ;!-bootstrap.js->< script src ="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"完整性="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7T< ous"<!-d3.v5.js->< script src ="https://d3js.org/d3.v5.js"></script><!-crossfilter.js->< script src ="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"</script><!-dc.js->< script src ="https://cdnjs.cloudflare.com/ajax/libs/dc/3.1.8/dc.js"</script>< title> 12</title></head><身体>< div class ="container-fluid">< div class ="row content">< div class ="col-md-10">< div class ="col-md-4">< div id ="composite"></div></div></div></div>< div class ="row content">< div class ="col-md-10">< div style ="padding:20px ;;"class ="row marginClass">< h4 class ="pull-left" id =简介">< small>虚拟公司数据|向下钻取示例|</small></h4>< h6 class ="dc-data-count" style ="float:left; margin-left:5px;">< span>< span class ="filter-count"></span>从中选择< span class ="total-count"></span>记录|< a id =重置">重置</a></span></h6></div>< div class ="col-md-4">< table class ="table" id ="vendedores">< thead>< tr>< th; Sales</th><当前年</th>< th>去年</th></tr></thead></table></div>< div class ="col-md-4">< table class ="table" id ="cities">< thead>< tr>< th> City< th><当前年</th>< th>去年</th></tr></thead></table></div></div></div></div></body>
感谢您发布示例!除非您进入整页模式,否则该错误不会显示在SO代码段功能中.我发现您的小提琴更易于使用.
注意:这是我以前的答案的完整重写,尚不清楚.
1.使用 ResizeObserver
更新4/28/20
从Safari 13.1(于2020年3月24日发布)开始,所有现代浏览器均支持 ResizeObserver .这是检测图表大小的最干净的方法.
我推荐
- 使用自上而下的布局(例如flexbox或网格)来放置图表的div
- 使用
ResizeObserver
确定div何时更改大小 - 告诉图表以使用
.width(null).height(null)
来检测图表div大小
当前有一个调整大小的示例就是这样做的.
特殊值 null
告诉图表使SVG节点的大小与其父div相同:
chart1.width(空).height(空)
回调函数使用辅助函数来禁用过渡,因为过渡只会减慢调整大小并使其显得笨拙:
const回调=图表=>条目=>{redraw_chart_no_transitions(图表.width(null).height(空).rescale());};
设置观察者的样子
new ResizeObserver(callback(chart1)).observe(d3.select('#test1').node());
有关更多详细信息,请参见示例.
2.使用 window.onresize
其他调整大小示例注意 window.onresize
,因为直到最近,这是检测更改的唯一有效,可靠的跨浏览器方式.
他们根据窗口大小计算图表大小,如果您的布局是自下而上的,例如使用默认的 float:left
布局.
以下是设置此功能的功能:
function apply_resizing(图表,adjustX,adjustY,onresize){if(!Array.isArray(chart))图表= [图表];if(!isNaN(adjustX))AdjustX =(dx => x => x-dx)(adjustX);AdjustX = AdjustX ||(x => x);if(!isNaN(adjustY))AdjustY =(dy => y => y-dy)(adjustY);AdjustY = AdjustY ||AdjustX ||(y => y);chart.forEach(c => c.width(adjustX(window.innerWidth)).height(adjustY(window.innerHeight)));window.onresize = function(){如果(调整大小){chart.forEach(onresize);}chart.forEach(c => {c.width(adjustX(window.innerWidth)).height(adjustY(window.innerHeight));如果(c.rescale){c.rescale();}});redraw_chart_no_transitions(chart);};}
可以像这样初始化单个图表:
apply_resizing(图20);
这会填满窗口,但会使图表的宽度减少20个像素.
该函数还可以在一个数组中获取多个图表,并且可以使用调整函数来支持复杂的布局,例如其中两个图表应垂直拆分窗口的情况:
apply_resizing([heatmapChart,barChart],20,y => y/2-fudge);
I'm having trouble making my chart responsive, I'm trying to apply the same example with DC.js and Crossfilter that is at this link: resizing-series.
The chart is responsive, however, there are some bugs when interacting with the tables I have. For example, when I click on either the graph or any of the tables, the graph becomes very large, occupying the entire screen. As shown in the image below:
When I leave the screen split with Console
, the graph is rendered responsively, as I change the screen size the size of the graph is also changed, however, if I leaveConsole
the graph remains occupying the entire the screen and does not return to the default initial size shown in the first image.
Does anyone know how to tell me how to fix these bugs? I couldn't understand why this is happening.
Thnaks in advance.
var composite = dc.compositeChart('#composite');
var vendedorTable = dc.dataTable("#vendedores");
var citiesTable = dc.dataTable("#cities");
function remove_empty_bins(source_group) {
return {
top: function(N) {
return source_group.all().filter(function(d) {
return d.value.totalAno > 1e-3 ||
d.value.totalHomologo > 1e-3;
}).slice(0, N);
}
};
}
var url = 'https://gist.githubusercontent.com/bernalvinicius/3cece295bc37de1697e7f83418e7fcc9/raw/a5820379ec6eae76ee792495cc5dd1685c977a73/vendedores.json';
d3.json(url).then(function(data) {
data.forEach(d =>
Object.assign(d, {
mes: d.Month,
atual: d.Vendas_Ano,
passado: d.Vendas_Ant
})
);
var cf = crossfilter(data);
vendedorDim = cf.dimension(function(d) {
return d.vendnm;
});
var vendedorGroup = vendedorDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);
citiesDim = cf.dimension(function(d) {
return d.zona;
});
var citiesGroup = citiesDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);
var dim = cf.dimension(dc.pluck('mes')),
grp1 = dim.group().reduceSum(dc.pluck('atual')),
grp2 = dim.group().reduceSum(dc.pluck('passado'));
var minMonth = dim.bottom(1)[0].mes;
var maxMonth = dim.top(1)[0].mes;
var all = cf.groupAll();
dc.dataCount(".dc-data-count")
.dimension(cf)
.group(all);
function reduceAdd(p, v) {
p.totalAno += +v.Vendas_Ano;
p.totalHomologo += +v.Vendas_Ant;
return p;
}
function reduceRemove(p, v) {
p.totalAno -= v.Vendas_Ano;
p.totalHomologo -= v.Vendas_Ant;
return p;
}
function reduceInitial() {
return {
totalAno: 0,
totalHomologo: 0,
};
}
// Fake Dimension
rank = function(p) {
return ""
};
// Chart by months
composite
.width(600)
.height(300)
.x(d3.scaleLinear().domain([1, 12]))
.yAxisLabel("")
.xAxisLabel("Month")
.legend(dc.legend().x(500).y(0).itemHeight(13).gap(5))
.renderHorizontalGridLines(true)
.compose([
dc.lineChart(composite)
.dimension(dim)
.colors('steelblue')
.group(grp1, "Currently Year"),
dc.lineChart(composite)
.dimension(dim)
.colors('darkorange')
.group(grp2, "Last Year")
])
.brushOn(true);
composite.brush().extent([-0.5, data.length + 1.5])
composite.extendBrush = function(brushSelection) {
if (brushSelection) {
vendedorTable.filter(null);
vendedorDim.filter(null);
citiesTable.filter(null);
citiesDim.filter(null);
const point = Math.round((brushSelection[0] + brushSelection[1]) / 2);
return [
point - 0.5,
point + 0.5
];
}
};
// Sales Table
vendedorTable.width(500)
.height(480)
.dimension(remove_empty_bins(vendedorGroup))
.group(rank)
.columns([function(d) {
return d.key;
},
function(d) {
return Number(Math.round(d.value.totalAno * 100) / 100).toLocaleString("es-ES", {
minimumFractionDigits: 2
}) + '€';
},
function(d) {
return Number(Math.round(d.value.totalHomologo * 100) / 100).toLocaleString("es-ES", {
minimumFractionDigits: 2
}) + '€';
}
])
.sortBy(function(d) {
return d.value.totalAno
})
.order(d3.descending)
// Cities Table
citiesTable.width(500)
.height(480)
.dimension(remove_empty_bins(citiesGroup))
.group(rank)
.columns([function(d) {
return d.key;
},
function(d) {
return Number(Math.round(d.value.totalAno * 100) / 100).toLocaleString("es-ES", {
minimumFractionDigits: 2
}) + '€';
},
function(d) {
return Number(Math.round(d.value.totalHomologo * 100) / 100).toLocaleString("es-ES", {
minimumFractionDigits: 2
}) + '€';
}
])
.sortBy(function(d) {
return d.value.totalAno
})
.order(d3.descending)
// Sales click events
vendedorTable.on('pretransition', function(table) {
table.selectAll('td.dc-table-column')
.on('click', function(d) {
let filters = table.filters().slice();
if (filters.indexOf(d.key) === -1)
filters.push(d.key);
else
filters = filters.filter(k => k != d.key);
if (filters.length === 0)
vendedorDim.filter(null);
else
vendedorDim.filterFunction(function(d) {
return filters.indexOf(d) !== -1;
})
table.replaceFilter([filters]);
citiesTable.filter(null);
citiesDim.filter(null);
composite.filter(null);
dc.redrawAll();
});
let filters = table.filters();
table.selectAll('tr.dc-table-row')
.classed('sel-rows', d => filters.indexOf(d.key) !== -1);
});
// Cities click events
citiesTable.on('pretransition', function(table) {
table.selectAll('td.dc-table-column')
.on('click', function(d) {
let filters = table.filters().slice();
if (filters.indexOf(d.key) === -1)
filters.push(d.key);
else
filters = filters.filter(k => k != d.key);
if (filters.length === 0)
citiesDim.filter(null);
else
citiesDim.filterFunction(function(d) {
return filters.indexOf(d) !== -1;
})
table.replaceFilter([filters]);
vendedorTable.filter(null);
vendedorDim.filter(null);
composite.filter(null);
dc.redrawAll();
});
let filters = table.filters();
table.selectAll('tr.dc-table-row')
.classed('sel-rows', d => filters.indexOf(d.key) !== -1);
});
dc.renderAll();
// reset functions
$('#reset').on('click', function() {
vendedorTable.filter(null);
vendedorDim.filter(null);
citiesTable.filter(null);
citiesDim.filter(null);
composite.filter(null);
dc.redrawAll();
});
$('#resetTable').on('click', function() {
vendedorTable.filter(null);
vendedorDim.filter(null);
citiesTable.filter(null);
citiesDim.filter(null);
composite.filter(null);
dc.redrawAll();
});
$('#resetTable2').on('click', function() {
vendedorTable.filter(null);
vendedorDim.filter(null);
citiesTable.filter(null);
citiesDim.filter(null);
composite.filter(null);
dc.redrawAll();
});
/****************************************************************************/
// Functions to handle responsive
var adjustX = 10,
adjustY = 40;
apply_resizing(composite, adjustX, adjustY, function(composite) {
composite.legend().x(window.innerWidth - 200);
});
var find_query = function() {
var _map = window.location.search.substr(1).split('&').map(function(a) {
return a.split('=');
}).reduce(function(p, v) {
if (v.length > 1)
p[v[0]] = decodeURIComponent(v[1].replace(/\+/g, " "));
else
p[v[0]] = true;
return p;
}, {});
return function(field) {
return _map[field] || null;
};
}();
var resizeMode = find_query('resize') || 'widhei';
function apply_resizing(composite, adjustX, adjustY, onresize) {
if (resizeMode === 'viewbox') {
composite
.width(300)
.height(200)
.useViewBoxResizing(true);
d3.select(composite.anchor()).classed('fullsize', false);
} else {
adjustX = adjustX || 0;
adjustY = adjustY || adjustX || 0;
composite
.width(window.innerWidth - adjustX)
.height(window.innerHeight - adjustY);
window.onresize = function() {
if (onresize) {
onresize(composite);
}
composite
.width(window.innerWidth - adjustX)
.height(window.innerHeight - adjustY);
if (composite.rescale) {
composite.rescale();
}
composite.redraw();
};
}
}
});
#composite {
padding: 10px;
}
.dc-table-group {
visibility: collapse;
}
tr.dc-table-row.sel-rows {
background-color: lightblue;
}
.brush .custom-brush-handle {
display: none;
}
<!-- favicon -->
<link rel="shortcut icon" href="https://img.icons8.com/nolan/64/puzzle.png">
<!-- bootstrap.css -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- bootstrap-theme.css -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- dc.css -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dc/2.1.8/dc.css">
<!-- jquery.js -->
<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
<!-- bootstrap.js -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<!-- d3.v5.js -->
<script src="https://d3js.org/d3.v5.js"></script>
<!-- crossfilter.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<!-- dc.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/dc/3.1.8/dc.js"></script>
<title>12</title>
</head>
<body>
<div class="container-fluid">
<div class="row content">
<div class="col-md-10">
<div class="col-md-4">
<div id="composite"></div>
</div>
</div>
</div>
<div class="row content">
<div class="col-md-10">
<div style="padding: 20px;;" class="row marginClass">
<h4 class="pull-left" id="Introduction">
<small>Fictitious company data | Drilldown Example |</small>
</h4>
<h6 class="dc-data-count" style="float: left;margin-left:5px;">
<span>
<span class="filter-count"></span> selected from
<span class="total-count"></span> records |
<a id="reset"> Reset </a>
</span>
</h6>
</div>
<div class="col-md-4">
<table class="table" id="vendedores">
<thead>
<tr>
<th>Sales</th>
<th>Current Year</th>
<th>Last Year</th>
</tr>
</thead>
</table>
</div>
<div class="col-md-4">
<table class="table" id="cities">
<thead>
<tr>
<th>City</th>
<th>Current Year</th>
<th>Last Year</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</body>
Thanks for posting an example! The bug doesn't show up in the SO code snippet feature unless you go to full page mode. I found your fiddle easier to work with.
Note: this is a complete rewrite of my previous answer, which was not clear.
1. Using ResizeObserver
updated 4/28/20
As of Safari 13.1 (released March 24 2020) all modern browsers support ResizeObserver. This is the cleanest way to detect chart resizing.
I recommend
- Use a top-down layout such as flexbox or grid to position the divs for your charts
- Use
ResizeObserver
to determine when the div has changed size - Tell the charts to detect the chart div size using
.width(null).height(null)
There is currently one resizing example that does this.
The special value null
tells the chart to make the SVG node the same size as its parent div:
chart1.width(null)
.height(null)
The callback uses a helper function to disable transitions, because transitions just slow resizing down and make it look clunky:
const callback = chart => entries => {
redraw_chart_no_transitions(
chart
.width(null)
.height(null)
.rescale());
};
Setting up the observer looks like
new ResizeObserver(callback(chart1)).observe(d3.select('#test1').node());
Please see the example for more details.
2. Using window.onresize
The other resizing examples watch for window.onresize
because until recently that was the only efficient, reliable cross-browser way to detect changes.
They calculate chart sizes based on the window size, which works well if your layout is bottom-up, e.g. using the default float: left
layout.
Here is the function which sets this up:
function apply_resizing(chart, adjustX, adjustY, onresize) {
if(!Array.isArray(chart))
chart = [chart];
if(!isNaN(adjustX))
adjustX = (dx => x => x-dx)(adjustX);
adjustX = adjustX || (x => x);
if(!isNaN(adjustY))
adjustY = (dy => y => y-dy)(adjustY);
adjustY = adjustY || adjustX || (y => y);
chart.forEach(c => c.width(adjustX(window.innerWidth))
.height(adjustY(window.innerHeight)));
window.onresize = function () {
if (onresize) {
chart.forEach(onresize);
}
chart.forEach(c => {
c.width(adjustX(window.innerWidth))
.height(adjustY(window.innerHeight));
if (c.rescale) {
c.rescale();
}
});
redraw_chart_no_transitions(chart);
};
}
A single chart can be initialized like so:
apply_resizing(chart, 20);
This fills the window but makes the chart 20 pixels less wide.
The function can also take multiple charts in an array, and adjustment functions to support complicated layouts, like one where two charts should split the window vertically:
apply_resizing([heatmapChart, barChart], 20, y => y/2-fudge);
这篇关于响应式dc.js图表占据了整个窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!