Created
May 10, 2016 21:27
-
-
Save spatney/0b21c9cce08524057c8c804ad14c8503 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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