Skip to content

Instantly share code, notes, and snippets.

@spatney
Created May 10, 2016 21:27
Show Gist options
  • Save spatney/0b21c9cce08524057c8c804ad14c8503 to your computer and use it in GitHub Desktop.
Save spatney/0b21c9cce08524057c8c804ad14c8503 to your computer and use it in GitHub Desktop.
module powerbi.visuals {
export interface LineDataPoint {
date;
temperature: number
}
export interface SeriesViewModel {
name: string;
values: LineDataPoint[];
}
export interface LineChartViewModel {
series: SeriesViewModel[];
}
var parseDate = d3.time.format("%Y%m%d").parse;
function fakeData(): LineChartViewModel {
return {
series: [{
name: 'New York',
values: [{
date: parseDate('20120827'),
temperature: 74.6
}, {
date: parseDate('20120828'),
temperature: 79.4
}, {
date: parseDate('20120829'),
temperature: 74.7
}]
},
{
name: 'San Francisco',
values: [{
date: parseDate('20120827'),
temperature: 58.3
}, {
date: parseDate('20120828'),
temperature: 58.7
}, {
date: parseDate('20120829'),
temperature: 57.5
},
]
},
{
name: 'Austin',
values: [{
date: parseDate('20120827'),
temperature: 82.1
}, {
date: parseDate('20120828'),
temperature: 84
}, {
date: parseDate('20120829'),
temperature: 85.7
},
]
}]
}
}
export class OurLineChart implements IVisual {
private svg: D3.Selection;
private mainG: D3.Selection;
private xaxis: D3.Selection;
private yaxis: D3.Selection;
public static capabilities: VisualCapabilities = {
dataRoles: [
{
name: 'T',
kind: VisualDataRoleKind.Measure,
displayName: 'Temperature'
},
{
name: 'D',
kind: VisualDataRoleKind.Grouping,
displayName: 'Date'
}
],
dataViewMappings: [
{
categorical: {
categories: { for: { in: 'D' } },
values: { select: [{ for: { in: 'T' } }] },
}
}
]
};
public static converter(dataViews: DataView[]): LineChartViewModel {
var dataView = dataViews[0];
var categories = dataView.categorical.categories[0].values;
var lineVM: LineChartViewModel = { series: [] };
var values = dataView.categorical.values;
for (var i = 0; i < values.length; i++) {
lineVM.series.push({ name: values[i].source.displayName, values: [] })
}
for (var s = 0; s < lineVM.series.length; s++) {
var v = values[s].values;
for (var i = 0; i < v.length; i++) {
lineVM.series[s].values.push({
date: categories[i],
temperature: v[i]
});
}
}
return lineVM;
}
public init(options: VisualInitOptions) {
options.element.addClass('ourline');
this.svg = d3.select(options.element.get(0)).append("svg");
this.mainG = this.svg.append("g");
this.xaxis = this.mainG.append("g")
.attr("class", "x axis");
this.yaxis = this.mainG.append("g")
.attr("class", "y axis");
this.yaxis.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Temperature (ºF)");
}
public update(options: VisualUpdateOptions) {
window.console.log('data', options.dataViews)
var viewport = options.viewport;
var width = viewport.width
var height = viewport.height;
var margin = { top: 20, right: 80, bottom: 30, left: 50 };
width = width - margin.left - margin.right;
height = height - margin.top - margin.bottom;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("basis")
.x(d => x(d.date))
.y(d => y(d.temperature));
this.svg
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var g = this.mainG.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var cities = OurLineChart.converter(options.dataViews).series//fakeData().series;
console.log('cities', cities)
x.domain(d3.extent(cities[0].values, d=> d.date));
y.domain([
d3.min(cities, c => d3.min(c.values, v=> v.temperature)),
d3.max(cities, c => d3.max(c.values, v=> v.temperature))
]);
this.xaxis
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
this.yaxis.call(yAxis);
var cityUpdate = g.selectAll(".city")
.data(cities);
var cityEnter = cityUpdate.enter();
var city = cityEnter.append("g")
.attr("class", "city");
var color = d3.scale.category10();
color.domain(cities.map(d=> d.name));
city
.append("path")
.attr("class", "line");
cityUpdate
.selectAll('.line')
.attr("d", d => line(d.values))
.style("stroke", d => color(d.name));
city.append("text")
.datum(function (d) { return { name: d.name, value: d.values[d.values.length - 1] }; });
cityUpdate
.selectAll('text')
.attr("transform", d => "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")")
.attr("x", 3)
.attr("dy", ".35em")
.text(d => d.name);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment