fill = { scale = "color", field = "series" },
}
}
}
if type(symShape) == "string" then
symbolmarks.properties.enter.shape = { value = symShape }
end
if type(symShape) == "table" then
symbolmarks.properties.enter.shape = { scale = "symShape", field = "series" }
end
if type(symSize) == "number" then
symbolmarks.properties.enter.size = { value = symSize }
end
if type(symSize) == "table" then
symbolmarks.properties.enter.size = { scale = "symSize", field = "series" }
end
if noFill then
symbolmarks.properties.enter.fill = nil
end
if alphaScale then
symbolmarks.properties.enter.fillOpacity =
{ scale = "transparency", field = "series" }
symbolmarks.properties.enter.strokeOpacity =
{ scale = "transparency", field = "series" }
end
if chartvis.from then symbolmarks.from = copy(chartvis.from) end  
return symbolmarks
end  
local function getAnnoMarks(chartvis, stroke, fill, opacity)  
local vannolines, hannolines, vannoLabels, vannoLabels
vannolines =
{
type = "rule",
from = { data = "v_anno" },
properties =
{
update =
{
x = { scale = "x", field = "x" },
y = { value = 0 },
y2 = { field = { group = "height" } },
strokeWidth = { value = stroke },
stroke = { value = persistentGrey },
opacity = { value = opacity }
}
}
}
vannolabels =
{
type = "text",
from = { data = "v_anno" },
properties =
{
update =
{
x = { scale = "x", field = "x", offset = 3 },
y = { field = { group = "height" }, offset = -3 },
text = { field = "label" },
baseline = { value = "top" },
angle = { value = -90 },
fill = { value = persistentGrey },
opacity = { value = opacity }
}
}
}
hannolines =
{
type = "rule",
from = { data = "h_anno" },
properties =
{
update =
{
y = { scale = "y", field = "y" },
x = { value = 0 },
x2 = { field = { group = "width" } },
strokeWidth = { value = stroke },
stroke = { value = persistentGrey },
opacity = { value = opacity }
}
}
}
hannolabels =
{
type = "text",
from = { data = "h_anno" },
properties =
{
update =
{
y = { scale = "y", field = "y", offset = 3 },
x = { value = 0 , offset = 3 },
text = { field = "label" },
baseline = { value = "top" },
angle = { value = 0 },
fill = { value = persistentGrey },
opacity = { value = opacity }
}
}
}
return vannolines, vannolabels, hannolines, hannolabels
end  
local function getAxes(xTitle, xAxisFormat, xAxisAngle, xType, xGrid, yTitle, yAxisFormat, yType, yGrid, chartType)
local xAxis, yAxis
if chartType ~= "pie" then
if xType == "integer" and not xAxisFormat then xAxisFormat = "d" end
xAxis =
{
type = "x",
scale = "x",
title = xTitle,
format = xAxisFormat,
grid = xGrid
}
if xAxisAngle then
local xAxisAlign
if xAxisAngle < 0 then xAxis else xAxis end
xAxis.properties =
{
title =
{
fill = { value = persistentGrey }
},
labels =
{
angle = { value = xAxisAngle },
align = { value = xAxisAlign },
fill = { value = persistentGrey }
},
ticks =
{
stroke = { value = persistentGrey }
},
axis =
{
stroke = { value = persistentGrey },
strokeWidth = { value = 2 }
},
grid =
{
stroke = { value = persistentGrey }
}
}
else
xAxis.properties =
{
title =
{
fill = { value = persistentGrey }
},
labels =
{
fill = { value = persistentGrey }
},
ticks =
{
stroke = { value = persistentGrey }
},
axis =
{
stroke = { value = persistentGrey },
strokeWidth = { value = 2 }
},
grid =
{
stroke = { value = persistentGrey }
}
}
end  
if yType == "integer" and not yAxisFormat then yAxisFormat = "d" end
yAxis =
{
type = "y",
scale = "y",
title = yTitle,
format = yAxisFormat,
grid = yGrid
}
yAxis.properties =
{
title =
{
fill = { value = persistentGrey }
},
labels =
{
fill = { value = persistentGrey }
},
ticks =
{
stroke = { value = persistentGrey }
},
axis =
{
stroke = { value = persistentGrey },
strokeWidth = { value = 2 }
},
grid =
{
stroke = { value = persistentGrey }
}
}  
end  
return xAxis, yAxis
end  
local function getLegend(legendTitle, chartType, outerRadius)
local legend =
{
fill = "color",
stroke = "color",
title = legendTitle,
}
legend.properties = {
title = {
fill = { value = persistentGrey },
},
labels = {
fill = { value = persistentGrey },
},
}
if chartType == "pie" then
legend.properties = {
-- move legend from position to top
legend = {
y = { value = -outerRadius },
},
title = {
fill = { value = persistentGrey }
},
labels = {
fill = { value = persistentGrey },
},
}
end
return legend
end  
function p.chart
-- chart width and height
local graphwidth = tonumber(.args.width) or 200
local graphheight = tonumber(.args.height) or 200
-- chart type
local chartType = .args.type or "line"
-- interpolation mode for line and area charts: linear, step-before, step-after, basis, basis-open, basis-closed (type=line only), bundle (type=line only), cardinal, cardinal-open, cardinal-closed (type=line only), monotone
local interpolate = .args.interpolate
-- mark colors (if no colors are given, the default 10 color palette is used)
local colorString = .args.colors
if colorString then colorString = string.lower(colorString) end
local colors = stringArray(colorString)
-- for line charts, the thickness of the line; for pie charts the gap between each slice
local linewidth = tonumber(.args.linewidth)
local linewidthsString = .args.linewidths
local linewidths
if linewidthsString and linewidthsString ~= "" then linewidths = numericArray(linewidthsString) or false end
-- x and y axis caption
local xTitle = .args.xAxisTitle or .args.xaxistitle
local yTitle = .args.yAxisTitle or .args.yaxistitle
-- x and y value types
local xType = .args.xType or .args.xtype
local yType = .args.yType or .args.ytype
-- override x and y axis minimum and maximum
local xMin = .args.xAxisMin or .args.xaxismin
local xMax = .args.xAxisMax or .args.xaxismax
local yMin = .args.yAxisMin or .args.yaxismin
local yMax = .args.yAxisMax or .args.yaxismax
-- override x and y axis label formatting
local xAxisFormat = .args.xAxisFormat or .args.xaxisformat
local yAxisFormat = .args.yAxisFormat or .args.yaxisformat
local xAxisAngle = tonumber(.args.xAxisAngle) or tonumber(.args.xaxisangle)
-- x and y scale types
local xScaleType = .args.xScaleType or .args.xscaletype
local yScaleType = .args.yScaleType or .args.yscaletype
-- log scale require minimum > 0, for now it's no possible to plot negative values on log - TODO see: https://www.mathworks.com/matlabcentral/answers/1792-log-scale-graphic-with-negative-value
-- if xScaleType == "log" then
-- if (not xMin or tonumber(xMin) <= 0) then xMin = 0.1 end
-- if not xType then xType = "number" end
-- end
-- if yScaleType == "log" then
-- if (not yMin or tonumber(yMin) <= 0) then yMin = 0.1 end
-- if not yType then yType = "number" end
-- end  
-- show grid
local xGrid = .args.xGrid or .args.xgrid or false
local yGrid = .args.yGrid or .args.ygrid or false
-- for line chart, show a symbol at each data point
local showSymbols = .args.showSymbols or .args.showsymbols
local symbolsShape = .args.symbolsShape or .args.symbolsshape
local symbolsNoFill = .args.symbolsNoFill or .args.symbolsnofill
local symbolsStroke = tonumber(.args.symbolsStroke or .args.symbolsstroke)
-- show legend with given title
local legendTitle = .args.legend
-- show values as text
local showValues = .args.showValues or .args.showvalues
-- show v- and h-line annotations
local v_annoLineString = .args.vAnnotatonsLine or .args.vannotatonsline
local h_annoLineString = .args.hAnnotatonsLine or .args.hannotatonsline
local v_annoLabelString = .args.vAnnotatonsLabel or .args.vannotatonslabel
local h_annoLabelString = .args.hAnnotatonsLabel or .args.hannotatonslabel  
-- decode annotations cvs
local v_annoLine, v_annoLabel, h_annoLine, h_annoLabel
if v_annoLineString and v_annoLineString ~= "" then  
if xType == "number" or xType == "integer" then
v_annoLine = numericArray(v_annoLineString)  
else
v_annoLine = stringArray(v_annoLineString)  
end
v_annoLabel = stringArray(v_annoLabelString)
end
if h_annoLineString and h_annoLineString ~= "" then  
if yType == "number" or yType == "integer" then
h_annoLine = numericArray(h_annoLineString)  
else
h_annoLine = stringArray(h_annoLineString)  
end