plotly_renderers.coffee
5.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
callWithJQuery = (pivotModule) ->
if typeof exports is "object" and typeof module is "object" # CommonJS
pivotModule require("jquery"), require("plotly.js")
else if typeof define is "function" and define.amd # AMD
define ["jquery", "plotly.js"], pivotModule
# Plain browser env
else
pivotModule jQuery, Plotly
callWithJQuery ($, Plotly) ->
makePlotlyChart = (traceOptions = {}, layoutOptions = {}, transpose = false) ->
(pivotData, opts) ->
defaults =
localeStrings: {vs: "vs", by: "by"}
plotly: {}
plotlyConfig: {}
opts = $.extend(true, {}, defaults, opts)
rowKeys = pivotData.getRowKeys()
colKeys = pivotData.getColKeys()
traceKeys = if transpose then colKeys else rowKeys
traceKeys.push([]) if traceKeys.length == 0
datumKeys = if transpose then rowKeys else colKeys
datumKeys.push([]) if datumKeys.length == 0
fullAggName = pivotData.aggregatorName
if pivotData.valAttrs.length
fullAggName += "(#{pivotData.valAttrs.join(", ")})"
data = traceKeys.map (traceKey) ->
values = []
labels = []
for datumKey in datumKeys
val = parseFloat(pivotData.getAggregator(
if transpose then datumKey else traceKey,
if transpose then traceKey else datumKey
).value())
values.push(if isFinite(val) then val else null)
labels.push(datumKey.join('-') || ' ')
trace = {name: traceKey.join('-') || fullAggName}
if traceOptions.type == "pie"
trace.values = values
trace.labels = if labels.length > 1 then labels else [fullAggName]
else
trace.x = if transpose then values else labels
trace.y = if transpose then labels else values
return $.extend(trace, traceOptions)
if transpose
hAxisTitle = pivotData.rowAttrs.join("-")
groupByTitle = pivotData.colAttrs.join("-")
else
hAxisTitle = pivotData.colAttrs.join("-")
groupByTitle = pivotData.rowAttrs.join("-")
titleText = fullAggName
titleText += " #{opts.localeStrings.vs} #{hAxisTitle}" if hAxisTitle != ""
titleText += " #{opts.localeStrings.by} #{groupByTitle}" if groupByTitle != ""
layout =
title: titleText
hovermode: 'closest'
width: window.innerWidth / 1.4
height: window.innerHeight / 1.4 - 50
if traceOptions.type == 'pie'
columns = Math.ceil(Math.sqrt(data.length))
rows = Math.ceil(data.length / columns)
layout.grid = {columns, rows}
for i, d of data
d.domain = {
row: Math.floor(i / columns),
column: i - columns * Math.floor(i / columns),
}
if data.length > 1
d.title = d.name
layout.showlegend = false if data[0].labels.length == 1
else
layout.xaxis =
title: if transpose then fullAggName else null
automargin: true
layout.yaxis =
title: if transpose then null else fullAggName
automargin: true
result = $("<div>").appendTo $("body")
Plotly.newPlot(result[0], data, $.extend(layout, layoutOptions, opts.plotly), opts.plotlyConfig)
return result.detach()
makePlotlyScatterChart = -> (pivotData, opts) ->
defaults =
localeStrings: {vs: "vs", by: "by"}
plotly: {}
plotlyConfig: {}
opts = $.extend(true, {}, defaults, opts)
rowKeys = pivotData.getRowKeys()
rowKeys.push [] if rowKeys.length == 0
colKeys = pivotData.getColKeys()
colKeys.push [] if colKeys.length == 0
data = {x: [], y: [], text: [], type: 'scatter', mode: 'markers'}
for rowKey in rowKeys
for colKey in colKeys
v = pivotData.getAggregator(rowKey, colKey).value()
if v?
data.x.push(colKey.join('-'))
data.y.push(rowKey.join('-'))
data.text.push(v)
layout = {
title: pivotData.rowAttrs.join("-") + ' vs ' + pivotData.colAttrs.join("-")
hovermode: 'closest',
xaxis: {title: pivotData.colAttrs.join('-'), automargin: true},
yaxis: {title: pivotData.rowAttrs.join('-'), automargin: true},
width: window.innerWidth / 1.5,
height: window.innerHeight / 1.4 - 50
}
renderArea = $("<div>", style: "display:none;").appendTo $("body")
result = $("<div>").appendTo renderArea
Plotly.newPlot(result[0], [data], $.extend(layout, opts.plotly), opts.plotlyConfig)
result.detach()
renderArea.remove()
return result
$.pivotUtilities.plotly_renderers =
"Horizontal Bar Chart": makePlotlyChart({type: 'bar', orientation: 'h'},
{barmode: 'group'}, true)
"Horizontal Stacked Bar Chart": makePlotlyChart({type: 'bar', orientation: 'h'},
{barmode: 'relative'}, true)
"Bar Chart": makePlotlyChart({type: 'bar'}, {barmode: 'group'})
"Stacked Bar Chart": makePlotlyChart({type: 'bar'}, {barmode: 'relative'})
"Line Chart": makePlotlyChart()
"Area Chart": makePlotlyChart({stackgroup: 1})
"Scatter Chart": makePlotlyScatterChart()
'Multiple Pie Chart': makePlotlyChart(
{type: 'pie', scalegroup: 1, hoverinfo: 'label+value', textinfo: 'none'},
{}, true)