From d5db175abaa34aead79de97ed9b17131f36a7b8b Mon Sep 17 00:00:00 2001 From: kadevgraaf Date: Mon, 29 Oct 2018 10:35:24 +0100 Subject: [PATCH] Reintroduce nv3-d support --- assets/css/nv.d3.min.css | 2 + .../SlideEditPanel/SlideContentEditor.js | 54 +++--- .../SlideViewPanel/SlideContentView.js | 5 + .../Deck/ContentPanel/util/ChartRender.js | 172 ++++++++++++++++++ components/Deck/Presentation/Presentation.js | 5 +- components/DefaultHTMLLayout.js | 1 + custom_modules/reveal.js | 2 +- package.json | 2 + server.js | 2 + webpack/dev.config.js | 5 +- webpack/prod.config.js | 4 + 11 files changed, 230 insertions(+), 24 deletions(-) create mode 100644 assets/css/nv.d3.min.css create mode 100644 components/Deck/ContentPanel/util/ChartRender.js diff --git a/assets/css/nv.d3.min.css b/assets/css/nv.d3.min.css new file mode 100644 index 000000000..3af35bd38 --- /dev/null +++ b/assets/css/nv.d3.min.css @@ -0,0 +1,2 @@ +.nvd3 .nv-axis line,.nvd3 .nv-axis path{fill:none;shape-rendering:crispEdges}.nv-brush .extent,.nvd3 .background path,.nvd3 .nv-axis line,.nvd3 .nv-axis path{shape-rendering:crispEdges}.nv-distx,.nv-disty,.nv-noninteractive,.nvd3 .nv-axis,.nvd3.nv-pie .nv-label,.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3 .nv-axis{opacity:1}.nvd3 .nv-axis.nv-disabled,.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3 .nv-axis path{stroke:#000;stroke-opacity:.75}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{stroke:#e5e5e5}.nvd3 .nv-axis .zero line, .nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:transparent}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-discretebar .nv-groups rect,.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick,.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover,.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:transparent}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover,.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-markerLine{stroke:#000;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nv-force-node{stroke:#fff;stroke-width:1.5px}.nv-force-link{stroke:#999;stroke-opacity:.6}.nv-force-node text{stroke-width:0}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.nvd3 .nv-groups .nv-point.hover,.nvd3.nv-scatter .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{box-shadow:0 5px 10px rgba(0,0,0,.2);border-radius:5px}.nvd3 text{font:400 12px Arial,sans-serif}.nvd3 .title{font:700 14px Arial,sans-serif}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}@media print{.nvd3 text{stroke-width:0;fill-opacity:1}}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;stroke:#fff;stroke-width:1px;stroke-opacity:1;fill-opacity:.7}.nvd3.nv-pie .hover path{fill-opacity:1}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-interactiveGuideLine,.nvtooltip{pointer-events:none}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvtooltip h3,.nvtooltip table td.key{font-weight:400}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;color:rgba(0,0,0,1);padding:1px;z-index:10000;display:block;font-family:Arial,sans-serif;font-size:13px;text-align:left;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip h3,.nvtooltip p{margin:0;text-align:center}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{padding:4px 14px;line-height:18px;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.nvtooltip p{padding:5px 14px}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key.total{font-weight:700}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table td.percent{color:#a9a9a9}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{vertical-align:middle;width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 line.nv-guideline{stroke:#ccc} +/*# sourceMappingURL=nv.d3.min.css.map */ diff --git a/components/Deck/ContentPanel/SlideModes/SlideEditPanel/SlideContentEditor.js b/components/Deck/ContentPanel/SlideModes/SlideEditPanel/SlideContentEditor.js index fd46574ba..1fb8f1ee5 100644 --- a/components/Deck/ContentPanel/SlideModes/SlideEditPanel/SlideContentEditor.js +++ b/components/Deck/ContentPanel/SlideModes/SlideEditPanel/SlideContentEditor.js @@ -1,32 +1,35 @@ +import {connectToStores} from 'fluxible-addons-react'; +import {NavLink, navigateAction} from 'fluxible-router'; import PropTypes from 'prop-types'; import React from 'react'; -import {NavLink, navigateAction} from 'fluxible-router'; -import {connectToStores} from 'fluxible-addons-react'; -import SlideEditStore from '../../../../../stores/SlideEditStore'; +let ReactDOM = require('react-dom'); + +import ChartRender from '../../util/ChartRender'; import DataSourceStore from '../../../../../stores/DataSourceStore'; -import SlideViewStore from '../../../../../stores/SlideViewStore'; +import DeckTreeStore from '../../../../../stores/DeckTreeStore'; +import { findDOMNode } from 'react-dom'; +import {FormattedMessage, defineMessages} from 'react-intl'; +import handleDroppedFile from '../../../../../actions/media/handleDroppedFile'; +import {HotKeys} from 'react-hotkeys'; import MediaStore from '../../../../../stores/MediaStore'; +import {Microservices} from '../../../../../configs/microservices'; import PaintModalStore from '../../../../../stores/PaintModalStore'; -import addSlide from '../../../../../actions/slide/addSlide'; import saveSlide from '../../../../../actions/slide/saveSlide'; import editImageWithSrc from '../../../../../actions/paint/editImageWithSrc'; import editSVGwithSVG from '../../../../../actions/paint/editSVGwithSVG'; import loadSlideAll from '../../../../../actions/slide/loadSlideAll'; -import handleDroppedFile from '../../../../../actions/media/handleDroppedFile'; import contentEditorClick from '../../../../../actions/slide/contentEditorClick'; //import ResizeAware from 'react-resize-aware'; -import { findDOMNode } from 'react-dom'; -import UserProfileStore from '../../../../../stores/UserProfileStore'; -import {Microservices} from '../../../../../configs/microservices'; -import DeckTreeStore from '../../../../../stores/DeckTreeStore'; +import SlideEditStore from '../../../../../stores/SlideEditStore'; +import SlideViewStore from '../../../../../stores/SlideViewStore'; //import TemplateDropdown from '../../../../common/TemplateDropdown'; -import {HotKeys} from 'react-hotkeys'; import UploadMediaModal from '../../../../common/UploadMediaModal'; +import UserProfileStore from '../../../../../stores/UserProfileStore'; import Util from '../../../../common/Util'; -import {FormattedMessage, defineMessages} from 'react-intl'; import changeSlideSizeText from '../../../../../actions/slide/changeSlideSizeText'; -let ReactDOM = require('react-dom'); + + class SlideContentEditor extends React.Component { constructor(props) { @@ -252,7 +255,7 @@ class SlideContentEditor extends React.Component { $('.swal2-confirm').focus(); }, 500); } - + } rewriteTemplate(template, keepExistingContent, pptx2htmlStartDiv, pptx2htmlcontent, pptx2htmlCloseDiv){ if(keepExistingContent){ @@ -957,7 +960,7 @@ class SlideContentEditor extends React.Component { } handleEmbedQuestionsClick(content){ - let title = content.options.title; + let title = content.options.title; let titleDiv = '

'+title+'

'; let questionhtml = '
'; @@ -966,7 +969,7 @@ class SlideContentEditor extends React.Component { let showNumbers = content.options.showNumbers; let showAnsExp = content.options.showAnsExp; - + for (let i = 0; i < questionsList.length; i++){ let currentQuestion = questionsList[i]; let currentAnswers = currentQuestion.answers; @@ -1010,16 +1013,16 @@ class SlideContentEditor extends React.Component { //let iframe = '
'; //let pptx2htmlDiv = '
'+titleDiv + iframe+'
'; let pptx2htmlDiv = '
'+titleDiv + questionhtml+'
'; - + if($('.pptx2html').length) //if slide is in canvas mode { /*$('.pptx2html').append('
'+iframe+'
'); this.hasChanges = true; //this.correctDimensionsBoxes('iframe'); */ this.refs.inlineContent.innerHTML = pptx2htmlDiv; - + } else { //if slide is in non-canvas mode - this.refs.inlineContent.innerHTML = scrolldiv; + this.refs.inlineContent.innerHTML = scrolldiv; } //console.log(pptx2htmlDiv); @@ -1100,7 +1103,7 @@ class SlideContentEditor extends React.Component { //CKEDITOR.instances.inlineContent.on('blur',(evt) => { // return false; //}); - + CKEDITOR.instances.inlineContent.on('focus',(evt) => { this.context.executeAction(contentEditorClick, { focus: true @@ -1207,6 +1210,11 @@ class SlideContentEditor extends React.Component { this.correctDimensionsBoxesImg(); this.resetZIndexSpeakerNotes(); + //('img'); + + // WARNING: Since this function is affected by the usage of contextMenuAll I decided to put it here right after of it... + ChartRender.renderCharts(true); + let slideSizeTextTemp; if (this.refs.inlineContent.innerHTML.includes('pptx2html')) { @@ -1227,6 +1235,10 @@ class SlideContentEditor extends React.Component { // add to the mathjax rendering queue the command to type-set the inlineContent //MathJax.Hub.Queue(['Typeset',MathJax.Hub,'inlineContent']); this.resize(); + + // WARNING: Since this function is affected by the usage of contextMenuAll I decided to put it here right after of it... + ChartRender.renderCharts(false); + } correctDimensionsBoxesIframe() @@ -2525,7 +2537,7 @@ class SlideContentEditor extends React.Component { const buttonColorBlack = { color: 'black' }; - + // //
SLIDE ' + this.props.selector.sid + ' TITLE'}}>
/* diff --git a/components/Deck/ContentPanel/SlideModes/SlideViewPanel/SlideContentView.js b/components/Deck/ContentPanel/SlideModes/SlideViewPanel/SlideContentView.js index 794972946..88b2587c2 100644 --- a/components/Deck/ContentPanel/SlideModes/SlideViewPanel/SlideContentView.js +++ b/components/Deck/ContentPanel/SlideModes/SlideViewPanel/SlideContentView.js @@ -1,6 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {findDOMNode} from 'react-dom'; +import ChartRender from '../../util/ChartRender'; import {connectToStores} from 'fluxible-addons-react'; import SlideViewStore from '../../../../../stores/SlideViewStore'; const ReactDOM = require('react-dom'); @@ -33,9 +34,13 @@ class SlideContentView extends React.Component { //window.addEventListener('resize', this.handleResize); } this.forceUpdate(); + + // Resize of charts only necessary here. + ChartRender.renderCharts(true); } componentDidUpdate() { + ChartRender.renderCharts(false); // update mathjax rendering // add to the mathjax rendering queue the command to type-set the inlineContent MathJax.Hub.Queue(['Typeset',MathJax.Hub,'inlineContent']); diff --git a/components/Deck/ContentPanel/util/ChartRender.js b/components/Deck/ContentPanel/util/ChartRender.js new file mode 100644 index 000000000..c1716348e --- /dev/null +++ b/components/Deck/ContentPanel/util/ChartRender.js @@ -0,0 +1,172 @@ +import d3 from 'd3'; +import nv from 'nvd3'; + +class ChartRender { + + static renderCharts(resize){ + + let charts = $('div[id^=chart]'); + + if (charts.length === 0 ) { + return 0; + } + + for (let i = 0; i < charts.length; i++){ + + let id = charts[i].getAttribute('id'); + + if ($('#' + id).has('svg').length) { // case when some svg is already created inside the chart. + $('#' + id).children('svg').remove(); // re-render just in case for resizing. + } + + let data = null; + let chart = null; + + let jsonChart = JSON.parse( charts[i].getAttribute('datum')); + + if (jsonChart === null) return; + let chartID = jsonChart.chartID; + let chartType = jsonChart.chartType; + let chartData = jsonChart.chartData; + let title = null; + + switch (chartType) { + case 'areaChart': + case 'area3DChart': + data = chartData; + chart = nv.models.stackedAreaChart() + .clipEdge(true) + .useInteractiveGuideline(true); + chart.xAxis.tickFormat( (d) => { return chartData[0].xlabels[d] || d; }); + break; + case 'barChart': + case 'bar3DChart': + case 'radarChart': + case 'surface3DChart': + data = chartData; + chart = nv.models.multiBarChart(); + chart.xAxis.tickFormat( (d) => { return chartData[0].xlabels[d] || d; }); + break; + case 'doughnutChart': + title = chartData[0].key; + let data = []; + for (let k = 0; k < chartData[0].values.length; k++) { + data.push({ + label: chartData[0].xlabels[k][0], + value: chartData[0].values[k].y + }); + } + chartData = data; + chart = nv.models.pieChart() + .x((d) => { return d.label; }) + .y((d) => { return d.value; }) + .showLabels(true) + .labelThreshold(.05) + .labelType('percent') + .donut(true) + .donutRatio(0.35); + break; + case 'lineChart': + case 'line3DChart': + data = chartData; + chart = nv.models.lineChart() + .useInteractiveGuideline(true); + chart.xAxis.tickFormat( (d) => { return chartData[0].xlabels[d] || d; }); + break; + case 'pie3DChart': + data = []; + for (let k = 0; k < chartData[0].values.length; k++) { + data.push({ + label: chartData[0].xlabels[k][0], + value: chartData[0].values[k].y + }); + } + chart = nv.models.pieChart() + .x((d) => { return d.label; }) + .y((d) => { return d.value; }) + .showLabels(true); + chartData = data; + break; + case 'pieChart': + case 'ofPieChart': + data = []; + for (let k = 0; k < chartData[0].values.length; k++) { + data.push({ + label: chartData[0].xlabels[k][0], + value: chartData[0].values[k].y + }); + } + chart = nv.models.pieChart() + .x((d) => { return d.label; }) + .y((d) => { return d.value; }) + .showLabels(true); + chartData = data; + break; + case 'scatterChart': + data = []; + for (let k = 0; k < chartData.length; k++) { + data.push({ + key: chartData[k].key, + values: [] + }); + + for (let h = 0; h < chartData[k].values.length; h++) { + data[k].values.push({ + x: chartData[k].values[h].x, + y: chartData[k].values[h].y + }); + } + } + + chart = nv.models.scatterChart() + .showDistX(true) + .showDistY(true) + .color(d3.scale.category10().range()); + + chart.xAxis.axisLabel('X').tickFormat(d3.format('.02f')); + chart.yAxis.axisLabel('Y').tickFormat(d3.format('.02f')); + chartData = data; + break; + default: + break; + } + + if (chart !== null) { + let h = $('#' + chartID).height(); + let w = $('#' + chartID).width(); + // Auxiliar sleep function for the asynchronous rendering. + let sleep = (ms) => { + return new Promise((resolve) => setTimeout(resolve,ms)); + }; + // Async function that waits one second to render the charts, so that the component mounts properly all + // its components. + let renderChart = async () => { + // Black Magic Trick to avoid multiple rendering of charts due to multiple updates in the component. + let ghostDiv = ''; + let ghostDivExists = $('#' + chartID + 'ghost').length; + if (ghostDivExists) return; + // Black Magic Ends here. + $('#' + chartID).append(ghostDiv); + await sleep(1000); + let titleExists = $('#' + chartID + 'title').length; + if (title && !titleExists) { + let $chartDiv = $('#' + chartID); + $chartDiv.append('
' + title + '
'); + } + d3.select('#' + chartID) + .append('svg') + .datum(chartData) + .call(chart) + .style({'width': w, 'height': h}); + }; + renderChart(); + } + } + + if (resize) { + window.dispatchEvent(new Event('resize')); + } + } +} + +export default ChartRender; diff --git a/components/Deck/Presentation/Presentation.js b/components/Deck/Presentation/Presentation.js index 6cf89303d..4765fbb82 100644 --- a/components/Deck/Presentation/Presentation.js +++ b/components/Deck/Presentation/Presentation.js @@ -5,7 +5,8 @@ import PresentationSlide from './PresentationSlide'; import { connectToStores } from 'fluxible-addons-react'; import { Microservices } from '../../../configs/microservices'; import PresentationStore from '../../../stores/PresentationStore'; - +import loadPresentation from '../../../actions/loadPresentation'; +import ChartRender from '../ContentPanel/util/ChartRender'; // if(process.env.BROWSER){ // require('../../../assets/css/PresentationDefaults.css'); // } @@ -146,6 +147,7 @@ class Presentation extends React.Component{ //$('.present > .accessibilityWrapper > .pptx2html div:first-child').focus(); //console.log($('.present > .accessibilityWrapper > .pptx2html div:first').html()); // event.currentSlide, event.indexh, event.indexv + ChartRender.renderCharts(false); this.resize(); } ); @@ -153,6 +155,7 @@ class Presentation extends React.Component{ //console.log('slidechanged: ' + $('.present > .accessibilityWrapper > .pptx2html div:first').html()); //$('.present > .accessibilityWrapper > .pptx2html div:first-child').focus(); //console.log('resize non-pptx2html slide content - presentwidth: ' + presentwidth + ' and height: ' + presentheight); + ChartRender.renderCharts(true); this.resize(); } ); diff --git a/components/DefaultHTMLLayout.js b/components/DefaultHTMLLayout.js index 61f2f9deb..46a4afa4c 100644 --- a/components/DefaultHTMLLayout.js +++ b/components/DefaultHTMLLayout.js @@ -25,6 +25,7 @@ class DefaultHTMLLayout extends React.Component { + { user ? : diff --git a/custom_modules/reveal.js b/custom_modules/reveal.js index 16089caa3..94cbb6cf3 160000 --- a/custom_modules/reveal.js +++ b/custom_modules/reveal.js @@ -1 +1 @@ -Subproject commit 16089caa3e0fd9a56f7ebf5d47b482f32922217f +Subproject commit 94cbb6cf334540ae2058dff4516f16498732b06b diff --git a/package.json b/package.json index db2ab4eab..584b319e0 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,7 @@ "css-loader": "^0.28.7", "css-modules-require-hook": "^4.0.6", "csurf": "^1.9.0", + "d3": "3", "debug": "^3.1.0", "diff": "3.4.0", "es5-shim": "^4.5.9", @@ -126,6 +127,7 @@ "moment": "^2.22.2", "napa": "^2.3.0", "npm": "^5.5.1", + "nvd3": "^1.8.6", "pre-commit": "^1.2.2", "prop-types": "^15.6.2", "react": "^15.4.2", diff --git a/server.js b/server.js index 4b5d953cf..208f3c944 100644 --- a/server.js +++ b/server.js @@ -59,6 +59,8 @@ server.use('/jquery', express.static(path.join(__dirname, '/node_modules/jquery' server.use('/sweetalert2', express.static(path.join(__dirname, '/node_modules/sweetalert2'))); server.use('/headjs', express.static(path.join(__dirname, '/node_modules/headjs'))); server.use('/glidejs', express.static(path.join(__dirname, '/node_modules/glidejs'))); +server.use('/d3', express.static(path.join(__dirname, '/node_modules/d3'))); +server.use('/nvd3', express.static(path.join(__dirname, '/node_modules/nvd3'))); server.use('/ckeditor', express.static(path.join(__dirname, 'node_modules/ckeditor'))); server.use('/ckeditor-plugins/youtube', express.static(path.join(__dirname, 'node_modules/ckeditor-youtube-plugin/youtube'))); diff --git a/webpack/dev.config.js b/webpack/dev.config.js index ca86b3391..dc593abfe 100644 --- a/webpack/dev.config.js +++ b/webpack/dev.config.js @@ -78,7 +78,10 @@ let webpackConfig = { BROWSER: JSON.stringify(true) } }), - + new webpack.ProvidePlugin({ + d3: 'd3', + nvd3: 'nvd3' + }) ], devtool: 'source-map' }; diff --git a/webpack/prod.config.js b/webpack/prod.config.js index e78984836..db75e7e44 100644 --- a/webpack/prod.config.js +++ b/webpack/prod.config.js @@ -104,6 +104,10 @@ let webpackConfig = { return JSON.stringify(data, null, 2); } }), + new webpack.ProvidePlugin({ + d3: 'd3', + nvd3: 'nvd3' + }), new Visualizer() ], devtool: 'source-map',