[export] export to svg working

This commit is contained in:
Prateeksha Singh 2018-04-17 01:08:32 +05:30
parent e28c564639
commit 8e45278303
19 changed files with 8784 additions and 79 deletions

View File

@ -1276,6 +1276,8 @@ function runSMILAnimation(parent, svgElement, elementsToAnimate) {
}, REPLACE_ALL_NEW_DUR); }, 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 { class BaseChart {
constructor(parent, options) { constructor(parent, options) {
@ -1599,6 +1601,42 @@ class BaseChart {
window.removeEventListener('resize', () => this.draw(true)); window.removeEventListener('resize', () => this.draw(true));
window.removeEventListener('orientationchange', () => 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 { class AggregationChart extends BaseChart {
@ -3594,6 +3632,8 @@ class AxisChart extends BaseChart {
} }
const chartTypes = { const chartTypes = {
bar: AxisChart,
line: AxisChart,
// multiaxis: MultiAxisChart, // multiaxis: MultiAxisChart,
percentage: PercentageChart, percentage: PercentageChart,
heatmap: Heatmap, heatmap: Heatmap,
@ -3601,13 +3641,7 @@ const chartTypes = {
}; };
function getChartByType(chartType = 'line', parent, options) { function getChartByType(chartType = 'line', parent, options) {
if(chartType === 'line') { if (chartType === 'axis-mixed') {
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') {
options.type = 'line'; options.type = 'line';
return new AxisChart(parent, options); return new AxisChart(parent, options);
} }

File diff suppressed because one or more lines are too long

View File

@ -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}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -88,6 +88,8 @@ Array.prototype.slice.call(
}); });
}); });
aggrChart.export();
// Update values chart // Update values chart
// ================================================================================ // ================================================================================
let updateDataAllLabels = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", 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]); return indices.map((index) => source_array[index]);
}; };
let update_data = { let updateData = {
labels: getUpdateData(updateDataAllLabels), labels: getUpdateData(updateDataAllLabels),
datasets: [{ datasets: [{
"values": getUpdateData(updateDataAllValues) "values": getUpdateData(updateDataAllValues)
@ -126,8 +128,8 @@ let update_data = {
], ],
}; };
let update_chart = new Chart("#chart-update", { let updateChart = new Chart("#chart-update", {
data: update_data, data: updateData,
type: 'line', type: 'line',
height: 250, height: 250,
colors: ['#ff6c03'], 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); shuffle(updateDataAllIndices);
let value = getRandom(); let value = getRandom();
let start = 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", () => { chartUpdateButtons.querySelector('[data-update="add"]').addEventListener("click", () => {
let index = update_chart.state.datasetLength; // last index to add let index = updateChart.state.datasetLength; // last index to add
if(index >= updateDataAllIndices.length) return; if(index >= updateDataAllIndices.length) return;
update_chart.addDataPoint( updateChart.addDataPoint(
updateDataAllLabels[index], [updateDataAllValues[index]] updateDataAllLabels[index], [updateDataAllValues[index]]
); );
}); });
chart_update_buttons.querySelector('[data-update="remove"]').addEventListener("click", () => { chartUpdateButtons.querySelector('[data-update="remove"]').addEventListener("click", () => {
update_chart.removeDataPoint(); updateChart.removeDataPoint();
}); });
// Trends Chart // Trends Chart

View File

@ -49,12 +49,6 @@ var HEATMAP_COLORS_YELLOW = ['#ebedf0', '#fdf436', '#ffc700', '#ff9100', '#06001
// Universal constants // 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. * Returns whether or not two given arrays are equal.
* @param {Array} arr1 First array * @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) { function clone(date) {
@ -164,8 +159,6 @@ function addDays(date, numberOfDays) {
date.setDate(date.getDate() + numberOfDays); date.setDate(date.getDate() + numberOfDays);
} }
// Composite Chart
// ================================================================================
var reportCountList = [152, 222, 199, 287, 534, 709, 1179, 1256, 1632, 1856, 1850]; var reportCountList = [152, 222, 199, 287, 534, 709, 1179, 1256, 1632, 1856, 1850];
var lineCompositeData = { var lineCompositeData = {
@ -385,6 +378,8 @@ Array.prototype.slice.call(document.querySelectorAll('.aggr-type-buttons button'
}); });
}); });
aggrChart.export();
// Update values chart // 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"]; 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), labels: getUpdateData(updateDataAllLabels),
datasets: [{ datasets: [{
"values": getUpdateData(updateDataAllValues) "values": getUpdateData(updateDataAllValues)
@ -425,8 +420,8 @@ var update_data = {
}] }]
}; };
var update_chart = new Chart("#chart-update", { var updateChart = new Chart("#chart-update", {
data: update_data, data: updateData,
type: 'line', type: 'line',
height: 250, height: 250,
colors: ['#ff6c03'], 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); shuffle(updateDataAllIndices);
var value = getRandom(); var value = getRandom();
var start = getRandom(); var start = getRandom();
@ -457,17 +452,17 @@ chart_update_buttons.querySelector('[data-update="random"]').addEventListener("c
end: end end: end
}] }]
}; };
update_chart.update(data); updateChart.update(data);
}); });
chart_update_buttons.querySelector('[data-update="add"]').addEventListener("click", function () { chartUpdateButtons.querySelector('[data-update="add"]').addEventListener("click", function () {
var index = update_chart.state.datasetLength; // last index to add var index = updateChart.state.datasetLength; // last index to add
if (index >= updateDataAllIndices.length) return; 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 () { chartUpdateButtons.querySelector('[data-update="remove"]').addEventListener("click", function () {
update_chart.removeDataPoint(); updateChart.removeDataPoint();
}); });
// Trends Chart // Trends Chart

File diff suppressed because one or more lines are too long

View File

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

8615
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,17 +1,42 @@
import pkg from './package.json';
// Rollup plugins // Rollup plugins
import babel from 'rollup-plugin-babel'; import babel from 'rollup-plugin-babel';
import eslint from 'rollup-plugin-eslint'; import eslint from 'rollup-plugin-eslint';
import replace from 'rollup-plugin-replace'; import replace from 'rollup-plugin-replace';
import uglify from 'rollup-plugin-uglify-es'; import uglify from 'rollup-plugin-uglify-es';
import sass from 'node-sass'; import sass from 'node-sass';
import postcss from 'rollup-plugin-postcss';
// PostCSS plugins // PostCSS plugins
import postcssPlugin from 'rollup-plugin-postcss';
import nested from 'postcss-nested'; import nested from 'postcss-nested';
import cssnext from 'postcss-cssnext'; import cssnext from 'postcss-cssnext';
import cssnano from 'cssnano'; 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 [ export default [
{ {
@ -29,7 +54,7 @@ export default [
], ],
name: 'frappe', name: 'frappe',
plugins: [ plugins: [
postcss({ postcssPlugin({
preprocessor: (content, id) => new Promise((resolve, reject) => { preprocessor: (content, id) => new Promise((resolve, reject) => {
const result = sass.renderSync({ file: id }) const result = sass.renderSync({ file: id })
resolve({ code: result.css.toString() }) resolve({ code: result.css.toString() })
@ -43,7 +68,7 @@ export default [
}), }),
eslint({ eslint({
exclude: [ exclude: [
'src/scss/**' 'src/css/**'
] ]
}), }),
babel({ babel({
@ -67,7 +92,7 @@ export default [
], ],
name: 'frappe', name: 'frappe',
plugins: [ plugins: [
postcss({ postcssPlugin({
preprocessor: (content, id) => new Promise((resolve, reject) => { preprocessor: (content, id) => new Promise((resolve, reject) => {
const result = sass.renderSync({ file: id }) const result = sass.renderSync({ file: id })
resolve({ code: result.css.toString() }) resolve({ code: result.css.toString() })
@ -81,7 +106,7 @@ export default [
}), }),
eslint({ eslint({
exclude: [ exclude: [
'src/scss/**' 'src/css/**'
] ]
}), }),
babel({ babel({
@ -106,7 +131,7 @@ export default [
} }
], ],
plugins: [ plugins: [
postcss({ postcssPlugin({
preprocessor: (content, id) => new Promise((resolve, reject) => { preprocessor: (content, id) => new Promise((resolve, reject) => {
const result = sass.renderSync({ file: id }) const result = sass.renderSync({ file: id })
resolve({ code: result.css.toString() }) resolve({ code: result.css.toString() })
@ -120,7 +145,7 @@ export default [
}), }),
eslint({ eslint({
exclude: [ exclude: [
'src/scss/**', 'src/css/**',
] ]
}), }),
babel({ babel({
@ -142,7 +167,7 @@ export default [
} }
], ],
plugins: [ plugins: [
postcss({ postcssPlugin({
preprocessor: (content, id) => new Promise((resolve, reject) => { preprocessor: (content, id) => new Promise((resolve, reject) => {
const result = sass.renderSync({ file: id }) const result = sass.renderSync({ file: id })
resolve({ code: result.css.toString() }) resolve({ code: result.css.toString() })
@ -157,7 +182,7 @@ export default [
}), }),
eslint({ eslint({
exclude: [ exclude: [
'src/scss/**', 'src/css/**',
] ]
}), }),
replace({ replace({

View File

@ -1,10 +1,10 @@
.chart-container { .chart-container {
// https://www.smashingmagazine.com/2015/11/using-system-ui-fonts-practical-guide/ position: relative; /* for absolutely positioned tooltip */
font-family: -apple-system, BlinkMacSystemFont,
"Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell",
"Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
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 { .axis, .chart-label {
fill: #555b51; fill: #555b51;
@ -36,13 +36,9 @@
} }
} }
line.dashed { line.dashed {
stroke-dasharray: 5,3; stroke-dasharray: 5, 3;
} }
.axis-line { .axis-line {
// &.x-axis-label {
// display: block;
// }
// TODO: hack dy attr to be settable via styles
.specific-value { .specific-value {
text-anchor: start; text-anchor: start;
} }
@ -87,7 +83,7 @@
position: absolute; position: absolute;
height: 5px; height: 5px;
margin: 0 0 0 -5px; margin: 0 0 0 -5px;
content: " "; content: ' ';
border: 5px solid transparent; border: 5px solid transparent;
border-top-color: rgba(0, 0, 0, 0.8); border-top-color: rgba(0, 0, 0, 0.8);
} }

1
src/css/chartsCss.js Normal file
View File

@ -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}";

View File

@ -1,4 +1,4 @@
import '../scss/charts.scss'; import '../css/charts.scss';
// import MultiAxisChart from './charts/MultiAxisChart'; // import MultiAxisChart from './charts/MultiAxisChart';
import PercentageChart from './charts/PercentageChart'; import PercentageChart from './charts/PercentageChart';
@ -7,6 +7,8 @@ import Heatmap from './charts/Heatmap';
import AxisChart from './charts/AxisChart'; import AxisChart from './charts/AxisChart';
const chartTypes = { const chartTypes = {
bar: AxisChart,
line: AxisChart,
// multiaxis: MultiAxisChart, // multiaxis: MultiAxisChart,
percentage: PercentageChart, percentage: PercentageChart,
heatmap: Heatmap, heatmap: Heatmap,
@ -14,13 +16,7 @@ const chartTypes = {
}; };
function getChartByType(chartType = 'line', parent, options) { function getChartByType(chartType = 'line', parent, options) {
if(chartType === 'line') { if (chartType === 'axis-mixed') {
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') {
options.type = 'line'; options.type = 'line';
return new AxisChart(parent, options); return new AxisChart(parent, options);
} }

View File

@ -7,6 +7,7 @@ import { BASE_CHART_TOP_MARGIN, BASE_CHART_LEFT_MARGIN,
import { getColor, isValidColor } from '../utils/colors'; import { getColor, isValidColor } from '../utils/colors';
import { runSMILAnimation } from '../utils/animation'; import { runSMILAnimation } from '../utils/animation';
import { Chart } from '../chart'; import { Chart } from '../chart';
import { CSSTEXT } from '../../css/chartsCss';
export default class BaseChart { export default class BaseChart {
constructor(parent, options) { constructor(parent, options) {
@ -331,4 +332,40 @@ export default class BaseChart {
window.removeEventListener('resize', () => this.draw(true)); window.removeEventListener('resize', () => this.draw(true));
window.removeEventListener('orientationchange', () => 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;
}
} }