我正在开发可定制的仪表板,其中(除其他功能外)用户可以拖动仪表板磁贴(div
元素)并将这些磁贴重新定位在仪表板的任何位置。
HTML结构
html结构类似于下面的代码片段
<div class="dashboard">
<div class="tile"><canvas/></div>
<div class="tile"><canvas/></div>
<div class="tile empty"></div>
</div>
预期行为
这个想法是.dashboard
可以包含多个.tiles
,每个都.tile
包含一个报告(在canvas
元素上绘制的图形/图表)。其中一些.tiles
可以.empty
不包含任何报告。然后.tile
可以拖放到.empty
图块中。
因此,div.tile.empty
用作“dropzone”,同时div.tile
将是可拖动的元素。下面添加了一个提琴手片段,用于一个简单但功能齐全的示例。
使用的库
- jQuery
- ChartJs。一个在画布上绘制图表的开源 js 库
问题
一切似乎都很好,除了在放下.tile
画布后将其宽度/高度重置为零!!!而且我还没有找到在拖放事件之前将其重置回原始尺寸的方法。即使我手动设定宽度/高度,画布上也不会绘制任何内容。
问题
有什么方法可以保留(或恢复)画布的宽度/高度,同时还可以在拖放后重新绘制图形?
我尝试使用chartjs
'supdate
和函式无济于事render
。resize
这些函式的档案可以在下面的链接中找到(版本 3.5.0)...
https://www.chartjs.org/docs/3.5.0/developers/api.html
代码示例
这是一个示例代码片段,您可以在其中重现上述问题。这些按钮是我尝试在拖放后更新/调整大小/重新渲染图形。
显示代码片段
var $sourceTile = null;
var charts = [];
$(() => {
$(".buttons-container a").on("click", btnClickHandler);
renderChart("canvas1", 'doughnut');
renderChart("canvas2", "line");
attachDropHandlers();
});
attachDropHandlers = () => {
$(".tile").off("dragstart").off("dragover").off("drop");
$(".tile .report").on("dragstart", dragStartHandler);
$(".tile.empty").on("dragover", dragOverHandler);
$(".tile.empty").on("drop", dropHandler);
}
dragStartHandler = (e) => {
const $target = $(e.target);
const $report = $target.is(".report") ? $target : $target.parents(".report");
$sourceTile = $report.parents(".tile");
e.originalEvent.dataTransfer.setData("application/dashboard", $report[0].id);
e.originalEvent.dataTransfer.effectAllowed = "move";
e.originalEvent.dataTransfer.dropEffect = "move";
}
dragOverHandler = (e) => {
e.preventDefault();
e.originalEvent.dataTransfer.dropEffect = "move";
}
dropHandler = (e) => {
e.preventDefault();
const id = e.originalEvent.dataTransfer.getData("application/dashboard");
if (id) {
$("#" id).appendTo(".tile.empty");
$(".tile.empty").removeClass("empty");
if ($sourceTile) {
$sourceTile.addClass("empty");
attachDropHandlers();
}
}
}
renderChart = (canvasId, type) => {
const labels = ["Red", "Green", "Blue"];
const data = [30, 25, 42];
const colors = ['rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)'];
const canvas = document.getElementById(canvasId);
const ctx = canvas.getContext('2d');
const chart = new Chart(ctx, {
type: type,
data: {
labels: labels,
datasets: [{
data: data,
backgroundColor: colors,
borderColor: colors,
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
aspectRatio: 1,
plugins: {
legend: {
display: false
},
htmlLegend: {
tile: this.$tile,
maxItems: 8
}
}
}
});
chart.update();
charts.push(chart);
}
btnClickHandler = (e) => {
const button = e.target.id;
switch (button) {
case "btn1":
charts.forEach((chart) => chart.update());
break;
case "btn2":
charts.forEach((chart) => chart.update('resize'));
break;
case "btn3":
charts.forEach((chart) => chart.render());
break;
case "btn4":
charts.forEach((chart) => chart.resize());
break;
case "btn5":
charts.forEach((chart) => chart.resize(120, 120));
break;
}
}
html,
body {
background-color: #eee;
}
h3 {
margin: 0;
padding: 10px;
}
.dashboard {}
.dashboard .tile {
display: inline-block;
vertical-align: top;
margin: 5px;
height: 250px;
width: 250px;
}
.tile.empty {
border: 2px dashed #ccc;
}
.report {
height: 250px;
width: 250px;
background-color: #fff;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}
.buttons-container {
display: flex;
justify-content: space-between;
margin: 20px 0;
}
.buttons-container a {
background-color: #673AB7;
color: #EDE7F6;
cursor: pointer;
padding: 10px 15px;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}
.buttons-container a:hover {
background-color: #7E57C2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.6.0/dist/chart.min.js"></script>
<div class="dashboard">
<div class="tile">
<div id="report1" class="report" draggable="true">
<h3>
Report 1
</h3>
<div style="padding:10px;height:180px;width:180px">
<canvas id="canvas1"></canvas>
</div>
</div>
</div>
<div class="tile">
<div id="report2" class="report" draggable="true">
<h3>
Report 2
</h3>
<div style="padding:10px;height:180px;width:180px">
<canvas id="canvas2"></canvas>
</div>
</div>
</div>
<div class="tile empty">
</div>
</div>
<div class="buttons-container">
<a id="btn1">update()</a>
<a id="btn2">update('resize')</a>
<a id="btn3">render()</a>
<a id="btn4">resize()</a>
<a id="btn5">resize(120,120)</a>
</div>
uj5u.com热心网友回复:
这是3.6.0 版的 Chart.js问题,已在3.6.1版中修复。下面的例子:
显示代码片段
var $sourceTile = null;
var charts = [];
$(() => {
$(".buttons-container a").on("click", btnClickHandler);
renderChart("canvas1", 'doughnut');
renderChart("canvas2", "line");
attachDropHandlers();
});
attachDropHandlers = () => {
$(".tile").off("dragstart").off("dragover").off("drop");
$(".tile .report").on("dragstart", dragStartHandler);
$(".tile.empty").on("dragover", dragOverHandler);
$(".tile.empty").on("drop", dropHandler);
}
dragStartHandler = (e) => {
const $target = $(e.target);
const $report = $target.is(".report") ? $target : $target.parents(".report");
$sourceTile = $report.parents(".tile");
e.originalEvent.dataTransfer.setData("application/dashboard", $report[0].id);
e.originalEvent.dataTransfer.effectAllowed = "move";
e.originalEvent.dataTransfer.dropEffect = "move";
}
dragOverHandler = (e) => {
e.preventDefault();
e.originalEvent.dataTransfer.dropEffect = "move";
}
dropHandler = (e) => {
e.preventDefault();
const id = e.originalEvent.dataTransfer.getData("application/dashboard");
if (id) {
$("#" id).appendTo(".tile.empty");
$(".tile.empty").removeClass("empty");
if ($sourceTile) {
$sourceTile.addClass("empty");
attachDropHandlers();
}
}
}
renderChart = (canvasId, type) => {
const labels = ["Red", "Green", "Blue"];
const data = [30, 25, 42];
const colors = ['rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)'];
const canvas = document.getElementById(canvasId);
const ctx = canvas.getContext('2d');
const chart = new Chart(ctx, {
type: type,
data: {
labels: labels,
datasets: [{
data: data,
backgroundColor: colors,
borderColor: colors,
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
aspectRatio: 1,
plugins: {
legend: {
display: false
},
htmlLegend: {
tile: this.$tile,
maxItems: 8
}
}
}
});
chart.update();
charts.push(chart);
}
btnClickHandler = (e) => {
const button = e.target.id;
switch (button) {
case "btn1":
charts.forEach((chart) => chart.update());
break;
case "btn2":
charts.forEach((chart) => chart.update('resize'));
break;
case "btn3":
charts.forEach((chart) => chart.render());
break;
case "btn4":
charts.forEach((chart) => chart.resize());
break;
case "btn5":
charts.forEach((chart) => chart.resize(120, 120));
break;
}
}
html,
body {
background-color: #eee;
}
h3 {
margin: 0;
padding: 10px;
}
.dashboard {}
.dashboard .tile {
display: inline-block;
vertical-align: top;
margin: 5px;
height: 250px;
width: 250px;
}
.tile.empty {
border: 2px dashed #ccc;
}
.report {
height: 250px;
width: 250px;
background-color: #fff;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}
.buttons-container {
display: flex;
justify-content: space-between;
margin: 20px 0;
}
.buttons-container a {
background-color: #673AB7;
color: #EDE7F6;
cursor: pointer;
padding: 10px 15px;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}
.buttons-container a:hover {
background-color: #7E57C2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.6.1/dist/chart.min.js"></script>
<div class="dashboard">
<div class="tile">
<div id="report1" class="report" draggable="true">
<h3>
Report 1
</h3>
<div style="padding:10px;height:180px;width:180px">
<canvas id="canvas1"></canvas>
</div>
</div>
</div>
<div class="tile">
<div id="report2" class="report" draggable="true">
<h3>
Report 2
</h3>
<div style="padding:10px;height:180px;width:180px">
<canvas id="canvas2"></canvas>
</div>
</div>
</div>
<div class="tile empty">
</div>
</div>
<div class="buttons-container">
<a id="btn1">update()</a>
<a id="btn2">update('resize')</a>
<a id="btn3">render()</a>
<a id="btn4">resize()</a>
<a id="btn5">resize(120,120)</a>
</div>
0 评论