Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/vue UI waffle #2

Merged
merged 3 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refacto to one pdf method, last steps waffle wip
  • Loading branch information
graphieros committed Jul 31, 2023
commit 3a29f79965986368ac4142b02061977ddc04abd9
68 changes: 9 additions & 59 deletions src/components/vue-ui-donut.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<script setup>
import { ref, computed, nextTick, onMounted, onBeforeUnmount } from "vue";
import { treeShake, makeDonut, palette, convertColorToHex } from '../lib';
import html2canvas from 'html2canvas';
import JsPDF from "jspdf";
import pdf from "../pdf";
import * as XLSX from 'xlsx';

const props = defineProps({
Expand Down Expand Up @@ -329,62 +328,13 @@ function useTooltip(arc, i, showTooltip = true) {
}

function generatePdf(){
const chart = document.getElementById(`donut__${uid.value}`);
console.log(chart)
if(chart) {
isPrinting.value = true;
const a4 = {
height: 851.89,
width: 595.28,
};
const pdf = new JsPDF("", "pt", "a4");
let contentWidth, contentHeight, imgWidth, imgHeight, pageData;
html2canvas(chart)
.then((canvasChart) => {
contentWidth = canvasChart.width;
contentHeight = canvasChart.height;
let leftHeight = contentHeight;
const pageHeight = (contentWidth / a4.width) * a4.height;
let position = 0;

imgWidth = a4.width;
imgHeight = (582.28 / contentWidth) * contentHeight;
pageData = canvasChart.toDataURL("image/png", 1.0);
if (leftHeight < pageHeight) {
pdf.addImage(
pageData,
"PNG",
33,
24,
imgWidth * 0.9,
imgHeight * 0.9,
"",
"FAST"
);
} else {
while (leftHeight > 0) {
pdf.addImage(
pageData,
"PNG",
33,
position,
imgWidth * 0.9,
imgHeight * 0.9,
"",
"FAST"
);
leftHeight -= pageHeight;
position -= a4.height - 24;
if (leftHeight > 0) {
pdf.addPage();
}
}
}
pdf.save(`${donutConfig.value.style.chart.title.text || 'vue-ui-donut'}.pdf`);
}).finally(() => {
isPrinting.value = false;
})
}
isPrinting.value = true;
pdf({
domElement: document.getElementById(`donut__${uid.value}`),
fileName: donutConfig.value.style.chart.title.text || 'vue-ui-donut'
}).finally(() => {
isPrinting.value = false;
});
}

const table = computed(() => {
Expand Down Expand Up @@ -481,7 +431,7 @@ function generateXls() {
</div>
</details>

<svg :viewBox="`0 0 ${svg.width} ${svg.height}`" :style="`max-width:100%; overflow: visible; padding: 0 24px;background:${donutConfig.style.chart.backgroundColor};color:${donutConfig.style.chart.color}`" @click="closeDetails">
<svg :viewBox="`0 0 ${svg.width} ${svg.height}`" :style="`max-width:100%; overflow: visible; background:${donutConfig.style.chart.backgroundColor};color:${donutConfig.style.chart.color}`" @click="closeDetails">

<!-- DEFS -->
<defs>
Expand Down
123 changes: 117 additions & 6 deletions src/components/vue-ui-waffle.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<script setup>
import { ref, onMounted, onBeforeUnmount, computed } from "vue";
import { treeShake, palette, convertColorToHex, shiftHue } from "../lib";
import { ref, onMounted, onBeforeUnmount, computed, nextTick } from "vue";
import { treeShake, palette, shiftHue } from "../lib";
import pdf from "../pdf";
import * as XLSX from 'xlsx';

// TODO: accept color formats

const props = defineProps({
config: {
Expand All @@ -18,7 +22,6 @@ const props = defineProps({
});

const uid = ref(`vue-ui-waffle-${Math.random()}`);

const defaultConfig = ref({
style: {
fontFamily: "inherit",
Expand Down Expand Up @@ -81,6 +84,21 @@ const defaultConfig = ref({
showTable: "Show table"
}
},
table: {
show: false,
th: {
backgroundColor: "#FAFAFA",
color: "#2D353C",
outline: "1px solid #e1e5e8"
},
td: {
backgroundColor: "#FFFFFF",
color: "#2D353C",
outline: "1px solid #e1e5e8",
roundingValue: 0,
roundingPercentage: 0
}
}
});

const isPrinting = ref(false);
Expand Down Expand Up @@ -320,6 +338,59 @@ function segregate(uid) {
segregated.value.push(uid);
}
}

const table = computed(() => {
const head = waffleSet.value.map(ds => {
return {
name: ds.name,
color: ds.color
}
});
const body = waffleSet.value.map(ds => ds.value);
return { head, body };
});

function generatePdf(){
isPrinting.value = true;
pdf({
domElement: document.getElementById(`vue-ui-waffle_${uid.value}`),
fileName: waffleConfig.value.style.chart.title.text || 'vue-ui-waffle'
}).finally(() => {
isPrinting.value = false;
});
}

function generateXls() {
nextTick(() => {
const labels = table.value.head.map((h,i) => {
return [[
h.name
],[table.value.body[i]], [isNaN(table.value.body[i] / total.value) ? '-' : table.value.body[i] / total.value * 100]]
});
const tableXls = [[waffleConfig.value.style.chart.title.text],[waffleConfig.value.style.chart.title.subtitle.text],[[""],["val"],["%"]]].concat(labels);

function s2ab(s) {
let buf = new ArrayBuffer(s.length);
let view = new Uint8Array(buf);
for (let i = 0; i < s.length; i++) {
view[i] = s.charCodeAt(i) & 0xff;
}
return buf;
}

const workbook = XLSX.utils.book_new();
const worksheet = XLSX.utils.aoa_to_sheet(tableXls);
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
const excelFile = XLSX.write(workbook, { bookType: 'xlsx', type: 'binary' });
const blob = new Blob([s2ab(excelFile)], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = `${waffleConfig.value.style.chart.title.text.replaceAll(" ", "_") || 'vue-ui-waffle'}.xlsx`;
link.click();
window.URL.revokeObjectURL(link.href);
});
}

</script>

<template>
Expand Down Expand Up @@ -371,7 +442,7 @@ function segregate(uid) {
</details>

<!-- CHART -->
<svg :viewBox="`0 0 ${svg.width} ${svg.height}`" :style="`max-width:100%;overflow:visible;padding:24px;background:${waffleConfig.style.chart.backgroundColor};color:${waffleConfig.style.chart.color}`" @click="closeDetails">
<svg :viewBox="`0 0 ${svg.width} ${svg.height}`" :style="`max-width:100%;overflow:visible;background:${waffleConfig.style.chart.backgroundColor};color:${waffleConfig.style.chart.color}`" @click="closeDetails">

<!-- DEFS -->
<defs>
Expand Down Expand Up @@ -406,8 +477,7 @@ function segregate(uid) {
</text>
</g>

<!-- SQUARES // COULD BE CUSTOM SHAPES TOO -->

<!-- RECTS -->
<rect
v-for="(position, i) in positions"
@mouseover="useTooltip(i)"
Expand Down Expand Up @@ -463,6 +533,47 @@ function segregate(uid) {
/>

<!-- DATA TABLE -->
<div @click="closeDetails" class="vue-ui-waffle-table" :style="`width:100%;margin-top:${mutableConfig.inside ? '48px' : ''}`" v-if="mutableConfig.showTable">
<table>
<thead>
<tr v-if="waffleConfig.style.chart.title.text">
<th colspan="3" :style="`background:${waffleConfig.table.th.backgroundColor};color:${waffleConfig.table.th.color};outline:${waffleConfig.table.th.outline}`">
<span>{{ waffleConfig.style.chart.title.text }}</span>
<span v-if="waffleConfig.style.chart.title.subtitle.text">
: {{ waffleConfig.style.chart.title.subtitle.text }}
</span>
</th>
</tr>
<tr>
<th align="right" :style="`background:${waffleConfig.table.th.backgroundColor};color:${waffleConfig.table.th.color};outline:${waffleConfig.table.th.outline};padding-right:6px`">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M18 16v2a1 1 0 0 1 -1 1h-11l6 -7l-6 -7h11a1 1 0 0 1 1 1v2" /></svg>
</th>
<th :style="`background:${waffleConfig.table.th.backgroundColor};color:${waffleConfig.table.th.color};outline:${waffleConfig.table.th.outline};text-align:right;padding-right:6px`">
{{ total.toFixed(waffleConfig.table.td.roundingValue) }}
</th>
<th :style="`background:${waffleConfig.table.th.backgroundColor};color:${waffleConfig.table.th.color};outline:${waffleConfig.table.th.outline};text-align:right;padding-right:6px`">
100%
</th>
</tr>
</thead>
<tbody>
<tr v-for="(th, i) in table.head">
<td :style="`background:${waffleConfig.table.td.backgroundColor};color:${waffleConfig.table.td.color};outline:${waffleConfig.table.td.outline}`">
<div style="max-width: 200px margin:0 auto">
<span :style="`color:${th.color};margin-right:6px;`">◼</span>
<span>{{ th.name }}</span>
</div>
</td>
<td :style="`background:${waffleConfig.table.td.backgroundColor};color:${waffleConfig.table.td.color};outline:${waffleConfig.table.td.outline}`">
{{ table.body[i].toFixed(waffleConfig.table.td.roundingValue) }}
</td>
<td :style="`background:${waffleConfig.table.td.backgroundColor};color:${waffleConfig.table.td.color};outline:${waffleConfig.table.td.outline}`">
{{ isNaN(table.body[i] / total) ? "-" : (table.body[i] / total * 100).toFixed(waffleConfig.table.td.roundingPercentage) }}%
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>

Expand Down
71 changes: 10 additions & 61 deletions src/components/vue-ui-xy.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

<template>
<div class="vue-ui-xy" ref="chart" :style="`background:${chartConfig.chart.backgroundColor}; color:${chartConfig.chart.color};width:100%`">
<div :id="`vue-ui-xy_${uniqueId}`" class="vue-ui-xy" ref="chart" :style="`background:${chartConfig.chart.backgroundColor}; color:${chartConfig.chart.color};width:100%`">
<!-- TITLE AS OUTSIDE DIV -->
<div class="vue-ui-xy-title" v-if="chartConfig.chart.title.show && (!mutableConfig.titleInside || isPrinting)" :style="`font-family:${chartConfig.chart.fontFamily}`">
<div class="vue-ui-xy-title-main" :style="`font-size:${chartConfig.chart.title.fontSize}px; color:${chartConfig.chart.title.color}; font-weight:${chartConfig.chart.title.bold ? 'bold': '400'}`">
Expand Down Expand Up @@ -401,8 +401,7 @@
</template>

<script>
import html2canvas from 'html2canvas';
import JsPDF from "jspdf";
import pdf from '../pdf';
import * as XLSX from 'xlsx';
import { treeShake, isSafeValue, checkNaN, palette, shiftHue } from '../lib';

Expand Down Expand Up @@ -860,6 +859,7 @@ export default {
isSafeValue,
treeShake,
shiftHue,
pdf,

// specific
calcRectHeight(plot) {
Expand Down Expand Up @@ -979,65 +979,14 @@ export default {
this.selectedSerieIndex = null;
}
},

generatePdf(){
const chart = this.$refs.chart;
if(chart) {
this.isPrinting = true;
this.$nextTick(() => {
const a4 = {
height: 851.89,
width: 595.28,
};
const pdf = new JsPDF("", "pt", "a4");
let contentWidth, contentHeight, imgWidth, imgHeight, pageData;
html2canvas(chart)
.then((canvasChart) => {
contentWidth = canvasChart.width;
contentHeight = canvasChart.height;
let leftHeight = contentHeight;
const pageHeight = (contentWidth / a4.width) * a4.height;
let position = 0;

imgWidth = a4.width;
imgHeight = (582.28 / contentWidth) * contentHeight;
pageData = canvasChart.toDataURL("image/png", 1.0);
if (leftHeight < pageHeight) {
pdf.addImage(
pageData,
"PNG",
33,
24,
imgWidth * 0.9,
imgHeight * 0.9,
"",
"FAST"
);
} else {
while (leftHeight > 0) {
pdf.addImage(
pageData,
"PNG",
33,
position,
imgWidth * 0.9,
imgHeight * 0.9,
"",
"FAST"
);
leftHeight -= pageHeight;
position -= a4.height - 24;
if (leftHeight > 0) {
pdf.addPage();
}
}
}
pdf.save(`${this.chartConfig.chart.title.text || 'vue-ui-xy'}.pdf`);
}).finally(() => {
this.isPrinting = false;
})
})
}
this.isPrinting = true;
this.pdf({
domElement: document.getElementById(`vue-ui-xy_${this.uniqueId}`),
fileName: this.chartConfig.chart.title.text || 'vue-ui-xy'
}).finally(() => {
this.isPrinting = false;
});
},
generateXls() {
const title = [[this.chartConfig.chart.title.text], [this.chartConfig.chart.title.subtitle.text], [""]];
Expand Down
Loading