import Highcharts from 'highcharts'
import mxGraphFactory from 'mxgraph'
import { getmethod, showModalWindow } from './dependencies'
const {
mxEvent
} = new mxGraphFactory()
export const graphSigbuilder = ''
export let sigbuilderGraph = ''
let wind = ''
// Function to create a chart with responsive points for Sigbuilder
function createDraggablePointsChartSigbuilder (graphParameters, pointsHistory, xmin, xmax, ymin, ymax, chartType, points, method, xmaxtitle, step, stepname) {
graphParameters.mtd = method
const subtitle = updateSubtitleForSigbuilderGraph(points, graphParameters.mtd, xmaxtitle, graphParameters.PeriodicOption)
pointsHistory.push(graphParameters.graphPoints.slice())
sigbuilderGraph = Highcharts.chart('drag_sig_chart', {
chart: {
type: chartType,
animation: false,
events: {
click: function (e) {
const xValue = e.xAxis[0].value
const yValue = e.yAxis[0].value
addPointsOnChart(graphParameters, pointsHistory, xValue, yValue)
}
}
},
tooltip: {
enabled: false
},
title: {
text: ''
},
subtitle: {
text: subtitle
},
yAxis: {
title: {
text: 'Output'
},
min: parseFloat(ymin),
max: parseFloat(ymax),
gridLineWidth: 1,
gridLineDashStyle: 'dash'
},
xAxis: {
title: {
text: 'time'
},
min: parseFloat(xmin),
max: parseFloat(xmax),
gridLineWidth: 1,
gridLineDashStyle: 'dash'
},
plotOptions: {
series: {
point: {
events: {
drag: function (e) {
if (e.y >= ymax) {
this.y = ymax
return false
}
if (e.y <= ymin) {
this.y = ymin
return false
}
if (e.x >= xmax) {
this.x = xmax
return false
}
if (e.x <= xmin) {
this.x = xmin
return false
}
},
drop: function () {
pointsHistory.push(graphParameters.graphPoints.slice())
},
dblclick: function (e) {
const graphObject = e
editPointsValue(graphObject, graphParameters, pointsHistory)
},
contextmenu: function (e) {
const graphObject = e
removePointsFromChart(graphObject, graphParameters, pointsHistory)
}
},
stickyTracking: false
},
column: {
stacking: 'normal'
},
marker: {
enabled: true,
symbol: 'url(../images/plus-icon.png)'
}
}
},
series: [{
draggableX: true,
draggableY: true,
showInLegend: false,
data: graphParameters.graphPoints,
step,
name: stepname
}]
})
}
export function updateSubtitleForSigbuilderGraph (points, method, xmaxtitle, periodicFlag) {
let subTitle = ''
if (periodicFlag === 'y') {
subTitle = '' + points + ' points, Method: ' + getmethod(method) + ', periodic, T = ' + xmaxtitle + ''
} else {
subTitle = '' + points + ' points, Method: ' + getmethod(method) + ', aperiodic'
}
return subTitle
}
function autoscaleFunctionalityForGraph (graphParameters, pointsHistory) {
// Added for postive/maximum value autoscale functionality
const maxXValueNew = sigbuilderGraph.xAxis[0].getExtremes().dataMax // get max x point's value
const minXValueNew = sigbuilderGraph.xAxis[0].getExtremes().dataMin // get min x point's value
const maxYValueNew = sigbuilderGraph.yAxis[0].getExtremes().dataMax // get max y point's value
let minYValueNew = sigbuilderGraph.yAxis[0].getExtremes().dataMin // get min y point's value
const diffX = ((Math.abs(maxXValueNew - minXValueNew)) / 100) * 10
const diffY = ((Math.abs(maxYValueNew - minYValueNew)) / 100) * 10
graphParameters.xmin = 0 // set min x axis value
graphParameters.xmax = maxXValueNew + diffX // set max x axis value
if (minYValueNew > 0) {
minYValueNew = 0
}
graphParameters.ymin = minYValueNew - diffY // set min y axis value
graphParameters.ymax = maxYValueNew + diffY // set max y axis value
graphParameters.points = graphParameters.graphPoints.length
createDraggablePointsChartSigbuilder(graphParameters, pointsHistory, graphParameters.xmin, graphParameters.xmax, graphParameters.ymin, graphParameters.ymax, graphParameters.chartType, graphParameters.points, graphParameters.mtd, graphParameters.xmaxTitle, graphParameters.step, graphParameters.stepname)
}
export function editPointsValue (graphObject, graphParameters, pointsHistory) {
document.getElementById('messageLabel').innerHTML = ''
// Making graph window inaccessible
const graphWind = document.getElementById('graphcontentwind')
graphWind.style.pointerEvents = 'none'
// Create basic structure for the form
const content = document.createElement('div')
content.setAttribute('id', 'editCoordinates')
// Add Form
const myform = document.createElement('form')
myform.method = 'post'
myform.id = 'formEditCoordinate'
myform.style.padding = '10px'
const titlelabel = document.createElement('span')
titlelabel.innerHTML = 'Enter new x and y'
myform.appendChild(titlelabel)
// Line break
const linebreak = document.createElement('br')
myform.appendChild(linebreak)
myform.appendChild(linebreak)
const keys = Object.keys(graphObject.point.options)
const len = keys.length
for (let i = 0; i < len; i++) {
// Input Title
const namelabel = document.createElement('label')
namelabel.innerHTML = keys[i].toString()
namelabel.style.marginLeft = '30px'
myform.appendChild(namelabel)
let value = 0
if (((graphObject.point.options[keys[i]]).toString()).includes('.')) {
value = (graphObject.point.options[keys[i]]).toFixed(6)
} else {
value = (graphObject.point.options[keys[i]])
}
// Input
const input = document.createElement('input')
input.name = 'edit_' + keys[i]
input.value = value
input.setAttribute('id', 'edit_' + keys[i])
input.setAttribute('class', 'fieldInput')
myform.appendChild(input)
myform.appendChild(linebreak)
myform.appendChild(linebreak)
}
myform.appendChild(linebreak)
// Button - Cancel
const cancelBtn = document.createElement('button')
cancelBtn.style.cssFloat = 'right'
cancelBtn.innerHTML = 'Cancel'
cancelBtn.type = 'button'
cancelBtn.name = 'Cancel'
myform.appendChild(cancelBtn)
// Button - OK
const okBtn = document.createElement('button')
okBtn.style.cssFloat = 'right'
okBtn.style.marginRight = '20px'
okBtn.innerHTML = 'OK'
okBtn.type = 'button'
okBtn.name = 'OK'
myform.appendChild(okBtn)
content.appendChild(myform)
const height = 150
wind = showModalWindow(graphSigbuilder, 'Scilab Multiple Values Request', content, 200, height)
wind.addListener(mxEvent.DESTROY, function () {
graphWind.style.pointerEvents = 'auto'
})
// Executes when button 'cancelBtn' is clicked
cancelBtn.onclick = function () {
document.getElementById('messageLabel').innerHTML = ''
graphWind.style.pointerEvents = 'auto'
wind.destroy()
}
// Executes when button 'okBtn' is clicked
okBtn.onclick = function () {
let xValue = parseFloat(document.getElementById('edit_x').value)
if (xValue < 0) {
xValue = 0
}
const yValue = parseFloat(document.getElementById('edit_y').value)
const points = graphParameters.graphPoints
const xArry = []
for (let i = 0; i < points.length; i++) {
xArry[i] = points[i][0]
}
xArry[points.length] = xValue
const result = checkDuplicateXValues(xArry)
const mtdCheck = [0, 1, 2].includes(graphParameters.mtd)
if (result) {
removePointsFromChart(graphObject, graphParameters, pointsHistory)
addPointsOnChart(graphParameters, pointsHistory, xValue, yValue)
autoscaleFunctionalityForGraph(graphParameters, pointsHistory)
document.getElementById('messageLabel').innerHTML = ''
graphWind.style.pointerEvents = 'auto'
wind.destroy()
} else {
if (mtdCheck) {
removePointsFromChart(graphObject, graphParameters, pointsHistory)
addPointsOnChart(graphParameters, pointsHistory, xValue, yValue)
autoscaleFunctionalityForGraph(graphParameters, pointsHistory)
document.getElementById('messageLabel').innerHTML = ''
graphWind.style.pointerEvents = 'auto'
wind.destroy()
} else {
document.getElementById('messageLabel').innerHTML = 'ERROR IN SPLINE : ' + getmethod(graphParameters.mtd)
wind.destroy()
graphWind.style.pointerEvents = 'auto'
throw new Error('incorrect')
}
}
}
}
export function removePointsFromChart (graphObject, graphParameters, pointsHistory) {
const counter = graphObject.point.index
sigbuilderGraph.series[0].data[counter].remove()
pointsHistory.push(graphParameters.graphPoints.slice())
graphParameters.points = sigbuilderGraph.series[0].data.length
graphParameters.xmaxTitle = sigbuilderGraph.xAxis[0].getExtremes().dataMax.toFixed(6)
sigbuilderGraph.setTitle(null, { text: updateSubtitleForSigbuilderGraph(graphParameters.points, graphParameters.mtd, graphParameters.xmaxTitle, graphParameters.PeriodicOption) })
}
export function addPointsOnChart (graphParameters, pointsHistory, xValue, yValue) {
document.getElementById('messageLabel').innerHTML = ''
if (xValue === 0 && yValue === 0) {
graphParameters.flag_for_zeros = true
}
const points = graphParameters.graphPoints
const xArry = []
for (let i = 0; i < points.length; i++) {
xArry[i] = points[i][0]
}
xArry[points.length] = xValue
const result = checkDuplicateXValues(xArry)
const mtdCheck = [0, 1, 2].includes(graphParameters.mtd)
if (result) {
sigbuilderGraph.series[0].addPoint([xValue, yValue])
pointsHistory.push(graphParameters.graphPoints.slice())
graphParameters.points = sigbuilderGraph.series[0].data.length
graphParameters.xmaxTitle = sigbuilderGraph.xAxis[0].getExtremes().dataMax.toFixed(6)
sigbuilderGraph.setTitle(null, { text: updateSubtitleForSigbuilderGraph(graphParameters.points, graphParameters.mtd, graphParameters.xmaxTitle, graphParameters.PeriodicOption) })
} else {
if (mtdCheck) {
sigbuilderGraph.series[0].addPoint([xValue, yValue])
pointsHistory.push(graphParameters.graphPoints.slice())
graphParameters.points = sigbuilderGraph.series[0].data.length
graphParameters.xmaxTitle = sigbuilderGraph.xAxis[0].getExtremes().dataMax.toFixed(6)
sigbuilderGraph.setTitle(null, { text: updateSubtitleForSigbuilderGraph(graphParameters.points, graphParameters.mtd, graphParameters.xmaxTitle, graphParameters.PeriodicOption) })
} else {
document.getElementById('messageLabel').innerHTML = 'ERROR IN SPLINE : ' + getmethod(graphParameters.mtd)
throw new Error('incorrect')
}
}
}
function checkDuplicateXValues (xxArry) {
const arrayForCompare = []
const result = xxArry.slice(0).every(function (item, index, array) {
if (arrayForCompare.indexOf(item) > -1) {
array.length = 0
return false
} else {
arrayForCompare.push(item)
return true
}
})
return result
}