拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 拖放后Html画布元素将宽度和高度重置为零

拖放后Html画布元素将宽度和高度重置为零

白鹭 - 2022-02-02 2145 0 0

我正在开发可定制的仪表板,其中(除其他功能外)用户可以拖动仪表板磁贴(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函式无济于事renderresize这些函式的档案可以在下面的链接中找到(版本 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 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *