Skip to content

Commit d68dbad

Browse files
authored
Calendar input (#61)
* cleaning up * fix handle errors * clean checks
1 parent 4a29942 commit d68dbad

File tree

2 files changed

+68
-54
lines changed

2 files changed

+68
-54
lines changed

examples/calendar/calendar.js

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,36 +26,52 @@ looker.plugins.visualizations.add({
2626

2727
// [{x.name: value, y.name: value}, ]
2828
let series = []
29-
data.forEach(function(datum) {
29+
data.filter(function(d) {
30+
return d3v4.timeParse("%Y-%m-%d")(d[x.name]["value"])
31+
}).forEach(function(d) {
3032
let point = {}
31-
point[x.name] = datum[x.name]["value"]
32-
point[y.name] = datum[y.name]["value"]
33+
point[x.name] = d[x.name]["value"]
34+
point[y.name] = d[y.name]["value"]
3335
series.push(point)
3436
})
3537

3638
// {date: value, }
3739
let formattedData = d3v4.nest()
38-
.key(function(d) { return d[x.name]; })
39-
.rollup(function(d) { return d[0][y.name]; })
40-
.map(series);
40+
.key(function(d) { return d[x.name] })
41+
.rollup(function(d) { return d[0][y.name] })
42+
.map(series)
4143

42-
let formatter = formatType(y.value_format);
44+
let formatter = formatType(y.value_format)
4345

4446
return {
4547
data: formattedData,
4648
formatter: formatter,
4749
}
4850
},
49-
51+
handleErrors(queryResponse) {
52+
if (!(queryResponse.fields.dimensions[0].is_timeframe &&
53+
queryResponse.fields.dimensions[0].time_interval.name === "day")) {
54+
this.addError({
55+
group: "date-req",
56+
title: "Incompatible Data",
57+
message: "Calendar Visualization Requires a Date Dimension",
58+
})
59+
return false
60+
} else {
61+
this.clearErrors("date-req")
62+
}
63+
return true
64+
},
5065
// Render in response to the data or settings changing
5166
update: function(data, element, config, queryResponse) {
5267
if (!handleErrors(this, queryResponse, {
5368
min_pivots: 0, max_pivots: 0,
5469
min_dimensions: 1, max_dimensions: 1,
5570
min_measures: 1, max_measures: 1,
56-
})) return;
57-
this.create(element, config);
58-
let formattedData = this.prepare(data, queryResponse);
59-
return calendarView(element, formattedData, config.color_range);
71+
})) return
72+
if (!this.handleErrors(queryResponse)) return
73+
this.create(element, config)
74+
let formattedData = this.prepare(data, queryResponse)
75+
return calendarView(element, formattedData, config.color_range)
6076
}
61-
});
77+
})

examples/calendar/calendar_view.js

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,104 @@
11
function calendarView(element, formattedData, colorRange) {
2-
let d3 = d3v4;
3-
4-
let data = formattedData.data;
2+
let data = formattedData.data
53

64
function monthPath(t0) {
75
let t1 = new Date(t0.getFullYear(), t0.getMonth() + 1, 0),
8-
d0 = t0.getDay(), w0 = d3.timeWeek.count(d3.timeYear(t0), t0)
9-
d1 = t1.getDay(), w1 = d3.timeWeek.count(d3.timeYear(t1), t1);
6+
d0 = t0.getDay(), w0 = d3v4.timeWeek.count(d3v4.timeYear(t0), t0)
7+
d1 = t1.getDay(), w1 = d3v4.timeWeek.count(d3v4.timeYear(t1), t1)
108
return "M" + (w0 + 1) * cellSize + "," + d0 * cellSize
119
+ "H" + w0 * cellSize + "V" + 7 * cellSize
1210
+ "H" + w1 * cellSize + "V" + (d1 + 1) * cellSize
1311
+ "H" + (w1 + 1) * cellSize + "V" + 0
14-
+ "H" + (w0 + 1) * cellSize + "Z";
12+
+ "H" + (w0 + 1) * cellSize + "Z"
1513
}
1614

17-
let format = d3.timeFormat("%Y-%m-%d");
18-
let parseDate = d3.timeParse("%Y-%m-%d");
15+
let format = d3v4.timeFormat("%Y-%m-%d")
16+
let parseDate = d3v4.timeParse("%Y-%m-%d")
1917

20-
let minYear = d3.min(data.keys(), function(d) { return parseDate(d).getFullYear(); })
21-
let maxYear = d3.max(data.keys(), function(d) { return parseDate(d).getFullYear(); })
18+
let minYear = d3v4.min(data.keys(), function(d) { return parseDate(d).getFullYear() })
19+
let maxYear = d3v4.max(data.keys(), function(d) { return parseDate(d).getFullYear() })
2220

2321
let yearLength = maxYear - minYear + 1
2422

25-
let minY = d3.min(data.values(), function(d) { return d; })
26-
let maxY = d3.max(data.values(), function(d) { return d; })
23+
let minY = d3v4.min(data.values(), function(d) { return d })
24+
let maxY = d3v4.max(data.values(), function(d) { return d })
2725

2826
let heightCellRatio = 9
29-
widthCellRatio = 55;
27+
widthCellRatio = 55
3028

31-
let cellSize = d3.max([d3.min([(element.offsetWidth - 20) / widthCellRatio, element.offsetHeight / yearLength / heightCellRatio]), 1])
29+
let cellSize = d3v4.max([d3v4.min([(element.offsetWidth - 20) / widthCellRatio, element.offsetHeight / yearLength / heightCellRatio]), 1])
3230
width = cellSize * widthCellRatio
3331
yearHeight = cellSize * heightCellRatio
34-
height = yearHeight * yearLength;
32+
height = yearHeight * yearLength
3533

36-
let color = d3.scaleQuantize()
34+
let color = d3v4.scaleQuantize()
3735
.domain([minY, maxY])
38-
.range(colorRange);
36+
.range(colorRange)
3937

40-
let svg = d3.select(element)
38+
let svg = d3v4.select(element)
4139
.selectAll("svg")
42-
.data(d3.range(minYear, maxYear + 1))
40+
.data(d3v4.range(minYear, maxYear + 1))
4341
.enter().append("svg")
4442
.style("display", "block")
4543
.style("margin", "0 auto")
4644
.attr("width", width)
4745
.attr("height", yearHeight)
48-
.attr("year", function(d) { return d; })
46+
.attr("year", function(d) { return d })
4947
.append("g")
50-
.attr("transform", "translate(" + ((width - cellSize * 53) / 2) + ",0)");
48+
.attr("transform", "translate(" + ((width - cellSize * 53) / 2) + ",0)")
5149

5250
svg.append("text")
5351
.attr("transform", "translate(-6," + cellSize * 3.5 + ")rotate(-90)")
5452
.style("font-family", "sans-serif")
5553
.style("font-size", 10)
5654
.style("text-anchor", "middle")
57-
.text(function(d) { return d; });
55+
.text(function(d) { return d })
5856

5957
let rect = svg.append("g")
6058
.attr("fill", "none")
6159
.attr("stroke", "#ccc")
6260
.selectAll("rect")
63-
.data(function(d) { return d3.timeDays(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
61+
.data(function(d) { return d3v4.timeDays(new Date(d, 0, 1), new Date(d + 1, 0, 1)) })
6462
.enter().append("rect")
6563
.attr("width", cellSize)
6664
.attr("height", cellSize)
67-
.attr("x", function(d) { return d3.timeWeek.count(d3.timeYear(d), d) * cellSize; })
68-
.attr("y", function(d) { return d.getDay() * cellSize; })
69-
.datum(format);
65+
.attr("x", function(d) { return d3v4.timeWeek.count(d3v4.timeYear(d), d) * cellSize })
66+
.attr("y", function(d) { return d.getDay() * cellSize })
67+
.datum(format)
7068

7169
svg.append("g")
7270
.attr("fill", "none")
7371
.attr("stroke", "#000")
7472
.selectAll("path")
75-
.data(function(d) { return d3.timeMonths(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
73+
.data(function(d) { return d3v4.timeMonths(new Date(d, 0, 1), new Date(d + 1, 0, 1)) })
7674
.enter().append("path")
77-
.attr("d", monthPath);
75+
.attr("d", monthPath)
7876

79-
let tooltip = d3.select(element)
77+
let tooltip = d3v4.select(element)
8078
.append("div").attr("id", "tooltip")
8179
.style("position", "absolute")
8280
.style("z-index", "10")
8381
.style("visibility", "hidden")
8482

85-
rect.filter(function(d) { return data.has(d); })
86-
.attr("fill", function(d) { return color(data.get(d)); })
83+
rect.filter(function(d) { return data.has(d) })
84+
.attr("fill", function(d) { return color(data.get(d)) })
8785
.append("title")
88-
.text(function(d) { return d + ": " + formattedData.formatter(data.get(d)); })
86+
.text(function(d) { return d + ": " + formattedData.formatter(data.get(d)) })
8987
.on("mouseenter", function(d) {
90-
tooltip.style("visibility", "visible");
91-
d.style("fill-opacity", .15);
88+
tooltip.style("visibility", "visible")
89+
d.style("fill-opacity", .15)
9290
tooltip.transition()
9391
.duration(10)
9492
.style("opacity", .9)
95-
.style("visibility", "visible");
96-
tooltip.text(function(d) { return d + ": " + formattedData.formatter(data.get(d)); })
97-
.style("left", (d3.event.pageX)+30 + "px")
98-
.style("top", (d3.event.pageY) + "px");
93+
.style("visibility", "visible")
94+
tooltip.text(function(d) { return d + ": " + formattedData.formatter(data.get(d)) })
95+
.style("left", (d3v4.event.pageX)+30 + "px")
96+
.style("top", (d3v4.event.pageY) + "px")
9997
})
10098
.on("mouseleave", function(d) {
10199
console.log("leave")
102100
tooltip.text("")
103-
.style("visibility", "hidden");
104-
d.style("fill-opacity", 1);
105-
});
101+
.style("visibility", "hidden")
102+
d.style("fill-opacity", 1)
103+
})
106104
}

0 commit comments

Comments
 (0)