Переглянути джерело

[export] export to svg working

tags/1.2.0
Prateeksha Singh 7 роки тому
джерело
коміт
8e45278303
19 змінених файлів з 8784 додано та 79 видалено
  1. +41
    -7
      dist/frappe-charts.esm.js
  2. +1
    -1
      dist/frappe-charts.min.cjs.js
  3. +1
    -1
      dist/frappe-charts.min.css
  4. +1
    -1
      dist/frappe-charts.min.esm.js
  5. +1
    -1
      dist/frappe-charts.min.iife.js
  6. +1
    -1
      dist/frappe-charts.min.iife.js.map
  7. +1
    -1
      docs/assets/js/frappe-charts.min.js
  8. +1
    -1
      docs/assets/js/frappe-charts.min.js.map
  9. +13
    -11
      docs/assets/js/index.js
  10. +14
    -19
      docs/assets/js/index.min.js
  11. +1
    -1
      docs/assets/js/index.min.js.map
  12. +1
    -0
      docs/index.html
  13. +8615
    -0
      package-lock.json
  14. +8
    -5
      package.json
  15. +35
    -10
      rollup.config.js
  16. +7
    -11
      src/css/charts.scss
  17. +1
    -0
      src/css/chartsCss.js
  18. +4
    -8
      src/js/chart.js
  19. +37
    -0
      src/js/charts/BaseChart.js

+ 41
- 7
dist/frappe-charts.esm.js Переглянути файл

@@ -1276,6 +1276,8 @@ function runSMILAnimation(parent, svgElement, elementsToAnimate) {
}, REPLACE_ALL_NEW_DUR);
}

const CSSTEXT = ".chart-container{position:relative;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','Roboto','Oxygen','Ubuntu','Cantarell','Fira Sans','Droid Sans','Helvetica Neue',sans-serif}.chart-container .axis,.chart-container .chart-label{fill:#555b51}.chart-container .axis line,.chart-container .chart-label line{stroke:#dadada}.chart-container .dataset-units circle{stroke:#fff;stroke-width:2}.chart-container .dataset-units path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container .dataset-path{stroke-width:2px}.chart-container .path-group path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container line.dashed{stroke-dasharray:5,3}.chart-container .axis-line .specific-value{text-anchor:start}.chart-container .axis-line .y-line{text-anchor:end}.chart-container .axis-line .x-line{text-anchor:middle}.graph-svg-tip{position:absolute;z-index:99999;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,.8);border-radius:3px}.graph-svg-tip ul{padding-left:0;display:flex}.graph-svg-tip ol{padding-left:0;display:flex}.graph-svg-tip ul.data-point-list li{min-width:90px;flex:1;font-weight:600}.graph-svg-tip strong{color:#dfe2e5;font-weight:600}.graph-svg-tip .svg-pointer{position:absolute;height:5px;margin:0 0 0 -5px;content:' ';border:5px solid transparent;border-top-color:rgba(0,0,0,.8)}.graph-svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.graph-svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.graph-svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.graph-svg-tip.comparison li{display:inline-block;padding:5px 10px}";

class BaseChart {
constructor(parent, options) {

@@ -1599,6 +1601,42 @@ class BaseChart {
window.removeEventListener('resize', () => this.draw(true));
window.removeEventListener('orientationchange', () => this.draw(true));
}

export() {
let chartSvg = this.prepareForExport();
this.downloadFile(this.title || 'Chart', [chartSvg]);
}

downloadFile(filename, data) {
var a = document.createElement('a');
a.style = "display: none";
var blob = new Blob(data, {type: "image/svg+xml; charset=utf-8"});
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function(){
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 300);
}

prepareForExport() {
let clone = this.svg.cloneNode(true);
clone.classList.add('chart-container');
clone.setAttribute('xmlns', "http://www.w3.org/2000/svg");
clone.setAttribute('xmlns:xlink', "http://www.w3.org/1999/xlink");
let styleEl = $.create('style', {
'innerHTML': CSSTEXT
});
clone.insertBefore(styleEl, clone.firstChild);

let container = $.create('div');
container.appendChild(clone);

return container.innerHTML;
}
}

class AggregationChart extends BaseChart {
@@ -3594,6 +3632,8 @@ class AxisChart extends BaseChart {
}

const chartTypes = {
bar: AxisChart,
line: AxisChart,
// multiaxis: MultiAxisChart,
percentage: PercentageChart,
heatmap: Heatmap,
@@ -3601,13 +3641,7 @@ const chartTypes = {
};

function getChartByType(chartType = 'line', parent, options) {
if(chartType === 'line') {
options.type = 'line';
return new AxisChart(parent, options);
} else if (chartType === 'bar') {
options.type = 'bar';
return new AxisChart(parent, options);
} else if (chartType === 'axis-mixed') {
if (chartType === 'axis-mixed') {
options.type = 'line';
return new AxisChart(parent, options);
}


+ 1
- 1
dist/frappe-charts.min.cjs.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 1
dist/frappe-charts.min.css Переглянути файл

@@ -1 +1 @@
.chart-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;position:relative}.chart-container .axis,.chart-container .chart-label{fill:#555b51}.chart-container .axis line,.chart-container .chart-label line{stroke:#dadada}.chart-container .dataset-units circle{stroke:#fff;stroke-width:2}.chart-container .dataset-units path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container .dataset-path{stroke-width:2px}.chart-container .path-group path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container line.dashed{stroke-dasharray:5,3}.chart-container .axis-line .specific-value{text-anchor:start}.chart-container .axis-line .y-line{text-anchor:end}.chart-container .axis-line .x-line{text-anchor:middle}.graph-svg-tip{position:absolute;z-index:1;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,.8);border-radius:3px}.graph-svg-tip ol,.graph-svg-tip ul{padding-left:0;display:-webkit-box;display:-ms-flexbox;display:flex}.graph-svg-tip ul.data-point-list li{min-width:90px;-webkit-box-flex:1;-ms-flex:1;flex:1;font-weight:600}.graph-svg-tip strong{color:#dfe2e5;font-weight:600}.graph-svg-tip .svg-pointer{position:absolute;height:5px;margin:0 0 0 -5px;content:" ";border:5px solid transparent;border-top-color:rgba(0,0,0,.8)}.graph-svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.graph-svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.graph-svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.graph-svg-tip.comparison li{display:inline-block;padding:5px 10px}
.chart-container{position:relative;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.chart-container .axis,.chart-container .chart-label{fill:#555b51}.chart-container .axis line,.chart-container .chart-label line{stroke:#dadada}.chart-container .dataset-units circle{stroke:#fff;stroke-width:2}.chart-container .dataset-units path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container .dataset-path{stroke-width:2px}.chart-container .path-group path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container line.dashed{stroke-dasharray:5,3}.chart-container .axis-line .specific-value{text-anchor:start}.chart-container .axis-line .y-line{text-anchor:end}.chart-container .axis-line .x-line{text-anchor:middle}.graph-svg-tip{position:absolute;z-index:1;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,.8);border-radius:3px}.graph-svg-tip ol,.graph-svg-tip ul{padding-left:0;display:-webkit-box;display:-ms-flexbox;display:flex}.graph-svg-tip ul.data-point-list li{min-width:90px;-webkit-box-flex:1;-ms-flex:1;flex:1;font-weight:600}.graph-svg-tip strong{color:#dfe2e5;font-weight:600}.graph-svg-tip .svg-pointer{position:absolute;height:5px;margin:0 0 0 -5px;content:" ";border:5px solid transparent;border-top-color:rgba(0,0,0,.8)}.graph-svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.graph-svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.graph-svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.graph-svg-tip.comparison li{display:inline-block;padding:5px 10px}

+ 1
- 1
dist/frappe-charts.min.esm.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 1
dist/frappe-charts.min.iife.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 1
dist/frappe-charts.min.iife.js.map
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 1
docs/assets/js/frappe-charts.min.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 1
docs/assets/js/frappe-charts.min.js.map
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 13
- 11
docs/assets/js/index.js Переглянути файл

@@ -88,6 +88,8 @@ Array.prototype.slice.call(
});
});

aggrChart.export();

// Update values chart
// ================================================================================
let updateDataAllLabels = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue",
@@ -105,7 +107,7 @@ let getUpdateData = (source_array, length=10) => {
return indices.map((index) => source_array[index]);
};

let update_data = {
let updateData = {
labels: getUpdateData(updateDataAllLabels),
datasets: [{
"values": getUpdateData(updateDataAllValues)
@@ -126,8 +128,8 @@ let update_data = {
],
};

let update_chart = new Chart("#chart-update", {
data: update_data,
let updateChart = new Chart("#chart-update", {
data: updateData,
type: 'line',
height: 250,
colors: ['#ff6c03'],
@@ -137,9 +139,9 @@ let update_chart = new Chart("#chart-update", {
},
});

let chart_update_buttons = document.querySelector('.chart-update-buttons');
let chartUpdateButtons = document.querySelector('.chart-update-buttons');

chart_update_buttons.querySelector('[data-update="random"]').addEventListener("click", () => {
chartUpdateButtons.querySelector('[data-update="random"]').addEventListener("click", () => {
shuffle(updateDataAllIndices);
let value = getRandom();
let start = getRandom();
@@ -162,19 +164,19 @@ chart_update_buttons.querySelector('[data-update="random"]').addEventListener("c
},
],
};
update_chart.update(data);
updateChart.update(data);
});

chart_update_buttons.querySelector('[data-update="add"]').addEventListener("click", () => {
let index = update_chart.state.datasetLength; // last index to add
chartUpdateButtons.querySelector('[data-update="add"]').addEventListener("click", () => {
let index = updateChart.state.datasetLength; // last index to add
if(index >= updateDataAllIndices.length) return;
update_chart.addDataPoint(
updateChart.addDataPoint(
updateDataAllLabels[index], [updateDataAllValues[index]]
);
});

chart_update_buttons.querySelector('[data-update="remove"]').addEventListener("click", () => {
update_chart.removeDataPoint();
chartUpdateButtons.querySelector('[data-update="remove"]').addEventListener("click", () => {
updateChart.removeDataPoint();
});

// Trends Chart


+ 14
- 19
docs/assets/js/index.min.js Переглянути файл

@@ -49,12 +49,6 @@ var HEATMAP_COLORS_YELLOW = ['#ebedf0', '#fdf436', '#ffc700', '#ff9100', '#06001

// Universal constants

/**
* Returns the value of a number upto 2 decimal places.
* @param {Number} d Any number
*/


/**
* Returns whether or not two given arrays are equal.
* @param {Array} arr1 First array
@@ -124,6 +118,7 @@ var MONTH_NAMES_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",



// https://stackoverflow.com/a/11252167/6495043


function clone(date) {
@@ -164,8 +159,6 @@ function addDays(date, numberOfDays) {
date.setDate(date.getDate() + numberOfDays);
}

// Composite Chart
// ================================================================================
var reportCountList = [152, 222, 199, 287, 534, 709, 1179, 1256, 1632, 1856, 1850];

var lineCompositeData = {
@@ -385,6 +378,8 @@ Array.prototype.slice.call(document.querySelectorAll('.aggr-type-buttons button'
});
});

aggrChart.export();

// Update values chart
// ================================================================================
var updateDataAllLabels = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon"];
@@ -408,7 +403,7 @@ var getUpdateData = function getUpdateData(source_array) {
});
};

var update_data = {
var updateData = {
labels: getUpdateData(updateDataAllLabels),
datasets: [{
"values": getUpdateData(updateDataAllValues)
@@ -425,8 +420,8 @@ var update_data = {
}]
};

var update_chart = new Chart("#chart-update", {
data: update_data,
var updateChart = new Chart("#chart-update", {
data: updateData,
type: 'line',
height: 250,
colors: ['#ff6c03'],
@@ -436,9 +431,9 @@ var update_chart = new Chart("#chart-update", {
}
});

var chart_update_buttons = document.querySelector('.chart-update-buttons');
var chartUpdateButtons = document.querySelector('.chart-update-buttons');

chart_update_buttons.querySelector('[data-update="random"]').addEventListener("click", function () {
chartUpdateButtons.querySelector('[data-update="random"]').addEventListener("click", function () {
shuffle(updateDataAllIndices);
var value = getRandom();
var start = getRandom();
@@ -457,17 +452,17 @@ chart_update_buttons.querySelector('[data-update="random"]').addEventListener("c
end: end
}]
};
update_chart.update(data);
updateChart.update(data);
});

chart_update_buttons.querySelector('[data-update="add"]').addEventListener("click", function () {
var index = update_chart.state.datasetLength; // last index to add
chartUpdateButtons.querySelector('[data-update="add"]').addEventListener("click", function () {
var index = updateChart.state.datasetLength; // last index to add
if (index >= updateDataAllIndices.length) return;
update_chart.addDataPoint(updateDataAllLabels[index], [updateDataAllValues[index]]);
updateChart.addDataPoint(updateDataAllLabels[index], [updateDataAllValues[index]]);
});

chart_update_buttons.querySelector('[data-update="remove"]').addEventListener("click", function () {
update_chart.removeDataPoint();
chartUpdateButtons.querySelector('[data-update="remove"]').addEventListener("click", function () {
updateChart.removeDataPoint();
});

// Trends Chart


+ 1
- 1
docs/assets/js/index.min.js.map
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 0
docs/index.html Переглянути файл

@@ -100,6 +100,7 @@
<button type="button" class="btn btn-sm btn-secondary" data-type='pie'>Pie Chart</button>
<button type="button" class="btn btn-sm btn-secondary" data-type='percentage'>Percentage Chart</button>
</div>
<button type="button" class="btn btn-sm btn-tertiary" data-type='export'>Export</button>
<!-- <p class="text-muted">
<a target="_blank" href="http://www.storytellingwithdata.com/blog/2011/07/death-to-pie-charts">Why Percentage?</a>
</p> -->


+ 8615
- 0
package-lock.json
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 8
- 5
package.json Переглянути файл

@@ -33,16 +33,22 @@
},
"homepage": "https://github.com/frappe/charts#readme",
"devDependencies": {
"autoprefixer": "^8.2.0",
"babel-core": "^6.26.0",
"babel-plugin-external-helpers": "^6.22.0",
"babel-preset-env": "^1.6.1",
"babel-preset-latest": "^6.24.1",
"clean-css": "^4.1.11",
"cssnano": "^3.10.0",
"eslint": "^4.18.2",
"fs": "0.0.1-security",
"livereload": "^0.6.3",
"node-sass": "^4.7.2",
"npm-run-all": "^4.1.1",
"postcss": "^6.0.21",
"postcss-cssnext": "^3.0.2",
"postcss-nested": "^2.1.2",
"precss": "^3.1.2",
"rollup": "^0.50.0",
"rollup-plugin-babel": "^3.0.2",
"rollup-plugin-eslint": "^4.0.0",
@@ -51,10 +57,7 @@
"rollup-plugin-replace": "^2.0.0",
"rollup-plugin-uglify": "^2.0.1",
"rollup-plugin-uglify-es": "0.0.1",
"rollup-watch": "^4.3.1",
"eslint": "^4.18.2"
"rollup-watch": "^4.3.1"
},
"dependencies": {
}
"dependencies": {}
}

+ 35
- 10
rollup.config.js Переглянути файл

@@ -1,17 +1,42 @@
import pkg from './package.json';

// Rollup plugins
import babel from 'rollup-plugin-babel';
import eslint from 'rollup-plugin-eslint';
import replace from 'rollup-plugin-replace';
import uglify from 'rollup-plugin-uglify-es';
import sass from 'node-sass';
import postcss from 'rollup-plugin-postcss';

// PostCSS plugins
import postcssPlugin from 'rollup-plugin-postcss';
import nested from 'postcss-nested';
import cssnext from 'postcss-cssnext';
import cssnano from 'cssnano';

import pkg from './package.json';
import postcss from 'postcss';
import precss from 'precss';
import CleanCSS from 'clean-css';
import autoprefixer from 'autoprefixer';
import fs from 'fs';
import { HEATMAP_LEFT_MARGIN } from './src/js/utils/constants';

fs.readFile('src/css/charts.scss', (err, css) => {
postcss([precss, autoprefixer])
.process(css, { from: 'src/css/charts.scss', to: 'src/css/charts.css' })
.then(result => {
let options = {
level: {
1: {
removeQuotes: false,
}
}
}
let output = new CleanCSS(options).minify(result.css);
let res = JSON.stringify(output.styles).replace(/"/g, "'");
let js = `export const CSSTEXT = "${res.slice(1, -1)}";`;
fs.writeFile('src/css/chartsCss.js', js);
});
});

export default [
{
@@ -29,7 +54,7 @@ export default [
],
name: 'frappe',
plugins: [
postcss({
postcssPlugin({
preprocessor: (content, id) => new Promise((resolve, reject) => {
const result = sass.renderSync({ file: id })
resolve({ code: result.css.toString() })
@@ -43,7 +68,7 @@ export default [
}),
eslint({
exclude: [
'src/scss/**'
'src/css/**'
]
}),
babel({
@@ -67,7 +92,7 @@ export default [
],
name: 'frappe',
plugins: [
postcss({
postcssPlugin({
preprocessor: (content, id) => new Promise((resolve, reject) => {
const result = sass.renderSync({ file: id })
resolve({ code: result.css.toString() })
@@ -81,7 +106,7 @@ export default [
}),
eslint({
exclude: [
'src/scss/**'
'src/css/**'
]
}),
babel({
@@ -106,7 +131,7 @@ export default [
}
],
plugins: [
postcss({
postcssPlugin({
preprocessor: (content, id) => new Promise((resolve, reject) => {
const result = sass.renderSync({ file: id })
resolve({ code: result.css.toString() })
@@ -120,7 +145,7 @@ export default [
}),
eslint({
exclude: [
'src/scss/**',
'src/css/**',
]
}),
babel({
@@ -142,7 +167,7 @@ export default [
}
],
plugins: [
postcss({
postcssPlugin({
preprocessor: (content, id) => new Promise((resolve, reject) => {
const result = sass.renderSync({ file: id })
resolve({ code: result.css.toString() })
@@ -157,7 +182,7 @@ export default [
}),
eslint({
exclude: [
'src/scss/**',
'src/css/**',
]
}),
replace({


src/scss/charts.scss → src/css/charts.scss Переглянути файл

@@ -1,10 +1,10 @@
.chart-container {
// https://www.smashingmagazine.com/2015/11/using-system-ui-fonts-practical-guide/
font-family: -apple-system, BlinkMacSystemFont,
"Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell",
"Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
position: relative; /* for absolutely positioned tooltip */

position: relative;
/* https://www.smashingmagazine.com/2015/11/using-system-ui-fonts-practical-guide/ */
font-family: -apple-system, BlinkMacSystemFont,
'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell',
'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;

.axis, .chart-label {
fill: #555b51;
@@ -36,13 +36,9 @@
}
}
line.dashed {
stroke-dasharray: 5,3;
stroke-dasharray: 5, 3;
}
.axis-line {
// &.x-axis-label {
// display: block;
// }
// TODO: hack dy attr to be settable via styles
.specific-value {
text-anchor: start;
}
@@ -87,7 +83,7 @@
position: absolute;
height: 5px;
margin: 0 0 0 -5px;
content: " ";
content: ' ';
border: 5px solid transparent;
border-top-color: rgba(0, 0, 0, 0.8);
}

+ 1
- 0
src/css/chartsCss.js Переглянути файл

@@ -0,0 +1 @@
export const CSSTEXT = ".chart-container{position:relative;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','Roboto','Oxygen','Ubuntu','Cantarell','Fira Sans','Droid Sans','Helvetica Neue',sans-serif}.chart-container .axis,.chart-container .chart-label{fill:#555b51}.chart-container .axis line,.chart-container .chart-label line{stroke:#dadada}.chart-container .dataset-units circle{stroke:#fff;stroke-width:2}.chart-container .dataset-units path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container .dataset-path{stroke-width:2px}.chart-container .path-group path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container line.dashed{stroke-dasharray:5,3}.chart-container .axis-line .specific-value{text-anchor:start}.chart-container .axis-line .y-line{text-anchor:end}.chart-container .axis-line .x-line{text-anchor:middle}.graph-svg-tip{position:absolute;z-index:99999;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,.8);border-radius:3px}.graph-svg-tip ul{padding-left:0;display:flex}.graph-svg-tip ol{padding-left:0;display:flex}.graph-svg-tip ul.data-point-list li{min-width:90px;flex:1;font-weight:600}.graph-svg-tip strong{color:#dfe2e5;font-weight:600}.graph-svg-tip .svg-pointer{position:absolute;height:5px;margin:0 0 0 -5px;content:' ';border:5px solid transparent;border-top-color:rgba(0,0,0,.8)}.graph-svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.graph-svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.graph-svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.graph-svg-tip.comparison li{display:inline-block;padding:5px 10px}";

+ 4
- 8
src/js/chart.js Переглянути файл

@@ -1,4 +1,4 @@
import '../scss/charts.scss';
import '../css/charts.scss';

// import MultiAxisChart from './charts/MultiAxisChart';
import PercentageChart from './charts/PercentageChart';
@@ -7,6 +7,8 @@ import Heatmap from './charts/Heatmap';
import AxisChart from './charts/AxisChart';

const chartTypes = {
bar: AxisChart,
line: AxisChart,
// multiaxis: MultiAxisChart,
percentage: PercentageChart,
heatmap: Heatmap,
@@ -14,13 +16,7 @@ const chartTypes = {
};

function getChartByType(chartType = 'line', parent, options) {
if(chartType === 'line') {
options.type = 'line';
return new AxisChart(parent, options);
} else if (chartType === 'bar') {
options.type = 'bar';
return new AxisChart(parent, options);
} else if (chartType === 'axis-mixed') {
if (chartType === 'axis-mixed') {
options.type = 'line';
return new AxisChart(parent, options);
}


+ 37
- 0
src/js/charts/BaseChart.js Переглянути файл

@@ -7,6 +7,7 @@ import { BASE_CHART_TOP_MARGIN, BASE_CHART_LEFT_MARGIN,
import { getColor, isValidColor } from '../utils/colors';
import { runSMILAnimation } from '../utils/animation';
import { Chart } from '../chart';
import { CSSTEXT } from '../../css/chartsCss';

export default class BaseChart {
constructor(parent, options) {
@@ -331,4 +332,40 @@ export default class BaseChart {
window.removeEventListener('resize', () => this.draw(true));
window.removeEventListener('orientationchange', () => this.draw(true));
}

export() {
let chartSvg = this.prepareForExport();
this.downloadFile(this.title || 'Chart', [chartSvg]);
}

downloadFile(filename, data) {
var a = document.createElement('a');
a.style = "display: none";
var blob = new Blob(data, {type: "image/svg+xml; charset=utf-8"});
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function(){
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 300);
}

prepareForExport() {
let clone = this.svg.cloneNode(true);
clone.classList.add('chart-container');
clone.setAttribute('xmlns', "http://www.w3.org/2000/svg");
clone.setAttribute('xmlns:xlink', "http://www.w3.org/1999/xlink");
let styleEl = $.create('style', {
'innerHTML': CSSTEXT
});
clone.insertBefore(styleEl, clone.firstChild);

let container = $.create('div');
container.appendChild(clone);

return container.innerHTML;
}
}

Завантаження…
Відмінити
Зберегти