Created
February 28, 2017 19:37
-
-
Save YoungElPaso/e1ac3e0c4db62a806a0fbfb63109c816 to your computer and use it in GitHub Desktop.
D3 Demos // source https://jsbin.com/quwokus
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>D3 Demos</title> | |
<script src="https://fb.me/react-15.1.0.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script> | |
<script src="https://fb.me/react-dom-15.1.0.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.string/3.3.4/underscore.string.js"></script> | |
<link rel="stylesheet" href="https://unpkg.com/[email protected]/css/tachyons.min.css"/> | |
<style id="jsbin-css"> | |
h1, h2, h3, h4, h5, h6, p { | |
font-family: sans-serif; | |
} | |
h1, h2, h3, h4, h5, h6, div, p, nav, section, hr { | |
/* margin: 0 0 1em 0; */ | |
margin: 0 0 10px 0; | |
} | |
nav, section, div, p { | |
/* padding: 0.3em; */ | |
padding: 10px; | |
} | |
/* Stealing from Tachyon, for svg */ | |
.bg-blue-svg { | |
fill: #357EDD; | |
} | |
svg path:hover, | |
svg path.selected { | |
opacity: 1; | |
stroke: white; | |
stroke-width: 2px; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>D3 Demos</h1> | |
<div id="app"> Here was pie </div> | |
<script id="jsbin-javascript"> | |
// Some default data. | |
'use strict'; | |
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | |
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | |
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | |
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | |
var data = { | |
title: 'Some Data', | |
desc: 'Maps values to color on \'magma \' scale and maps values to a font-size on a linear scale.', | |
values: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] | |
}; | |
var textNumData = { | |
title: 'Text & Number', | |
desc: 'This illustrates how numbers and basic text can go together.', | |
values: [50, 100, 500], | |
label: 'we\'ve grown in leaps and bounds!' | |
}; | |
var donationData = { | |
title: 'Donations 2016', | |
desc: 'Shows donation totals in a dynamic way, with the total highlighted along with a basic label or description that can support HTML.', | |
values: [1000], | |
label: 'in <b>donations</b> raised by McGill U in 2016.<br/ > More on the way!', | |
symbol: '$', | |
// TODO: have a CTA available? | |
cta: null | |
}; | |
var stepCountData = { | |
title: 'Step Count Today', | |
desc: 'Shows a simple step counter.', | |
values: [1700, 1000] | |
}; | |
var pieData = { | |
title: 'Academic Community', | |
desc: 'A pie chart that shows the demographic breakdown of the academic community at McGill', | |
values: [{ 'label': 'Undergraduate', 'number': 10000 }, { 'label': 'Post-graduate', 'number': 3000 }, { 'label': 'Graduate', 'number': 8000 }, { 'label': 'Other', 'number': 800 }, { 'label': 'Faculty', 'number': 1500 }, { 'label': 'TA\'s', 'number': 7000 }] | |
}; | |
var percentageData = { | |
title: 'Advanced preparation!', | |
label: '55% of McGill undergraduates will go on to get a PhD. More than any other Canadian university.', | |
values: [55], | |
desc: 'Number of undergraduate students who later in a PhD' | |
}; | |
// TODO : style this component (text to the left or right or bottom of % and big label, see one of those xample websites Joyce sent.) | |
// TODO: put this stuff in a document and put that in the ticket. | |
var Charts = (function (_React$Component) { | |
_inherits(Charts, _React$Component); | |
function Charts(props) { | |
_classCallCheck(this, Charts); | |
_get(Object.getPrototypeOf(Charts.prototype), 'constructor', this).call(this, props); | |
this.state = { | |
data: data | |
}; | |
} | |
// A generic text based infographic class. | |
// Renders some text w/ d3js in a fun way. | |
// Takes data, colors text based on values. | |
// This component doesn't even need to use SVG | |
// But it could! | |
// Handles loading the data and viz. | |
_createClass(Charts, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() {} | |
}, { | |
key: 'render', | |
value: function render() { | |
return React.createElement( | |
'div', | |
{ className: 'all-charts-render' }, | |
React.createElement(StepCount, { type: 'Text Number svg infographic', data: stepCountData }), | |
React.createElement(Percentage, { type: 'Percentage', data: percentageData }), | |
React.createElement(Pie, { type: 'Pie', data: pieData }), | |
React.createElement(Bar, { type: 'Bar', data: this.state.data }), | |
React.createElement(GenText, { type: 'Text infographic', data: this.state.data }), | |
React.createElement(TextNumber, { type: 'Text Number infographic', data: textNumData }), | |
React.createElement(Donation, { type: 'Donation', data: donationData }) | |
); | |
} | |
}]); | |
return Charts; | |
})(React.Component); | |
var GenText = (function (_React$Component2) { | |
_inherits(GenText, _React$Component2); | |
function GenText(props) { | |
_classCallCheck(this, GenText); | |
_get(Object.getPrototypeOf(GenText.prototype), 'constructor', this).call(this, props); | |
// Set up a font scale for all text components ot have. | |
var scale = d3.scaleLinear(); | |
scale.domain([this.props.data.values[0], this.props.data.values[this.props.data.values.length - 1]]); | |
// A reasonable font-size scale range. | |
scale.range([16, 60]); | |
this.fontScale = scale; | |
} | |
// A generic chart class. | |
// Handles loading the data and viz. | |
_createClass(GenText, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() { | |
var fontScale = this.fontScale; | |
// TODO: get a pie-chart or some other graph going. | |
// console.log(this.props.type); | |
// Fire up d3. | |
var selector = '.' + s.slugify(this.props.type) + ' .text-info'; | |
var textBox = d3.select(selector); | |
textBox.selectAll('div').data(this.props.data.values).enter().append('div').text(function (d) { | |
return d; | |
}) | |
// Enhance the font-size based on value. | |
.style('font-size', function (d) { | |
// Run the values through scale, any number will be between scale.range value. | |
return fontScale(d) + "px"; | |
}) // Enhance the color based on value. | |
.style('background-color', function (d) { | |
// Try out D3 color interpolation... | |
var color = d3.interpolateInferno(100); | |
return color; | |
}).style('color', function (d) { | |
// Try out D3 color interpolation... | |
// Need rainbow to offset inferno. | |
var color = d3.interpolateRainbow(d / 100); | |
return color; | |
}).classed('value', true); | |
} | |
// Renders the basic markup | |
}, { | |
key: 'render', | |
value: function render() { | |
var scale = d3.scaleLinear(); | |
scale.domain([this.props.data.values[0], this.props.data.values[this.props.data.values.length - 1]]); | |
// A reasonable font-size scale range. | |
scale.range([16, 60]); | |
return React.createElement( | |
'div', | |
{ className: 'gen-text-render bg-mid-gray ' + s.slugify(this.props.type) }, | |
React.createElement( | |
'h2', | |
{ className: 'hot-pink' }, | |
this.props.type, | |
' Text: ', | |
React.createElement( | |
'span', | |
{ className: 'dark-pink' }, | |
this.props.data.title | |
), | |
' ' | |
), | |
React.createElement('div', { className: 'text-info light-gray' }), | |
React.createElement( | |
'div', | |
null, | |
this.props.data.desc || this.props.data.label | |
) | |
); | |
} | |
}]); | |
return GenText; | |
})(React.Component); | |
var GenChart = (function (_React$Component3) { | |
_inherits(GenChart, _React$Component3); | |
function GenChart(props) { | |
_classCallCheck(this, GenChart); | |
_get(Object.getPrototypeOf(GenChart.prototype), 'constructor', this).call(this, props); | |
// Set up a basic scale for chart. | |
var scale = d3.scaleLinear(); | |
scale.domain([0, 10000]); | |
// A reasonable font-size scale range. | |
scale.range([0, 100]); | |
this.scale = scale; | |
} | |
// A pie chart. | |
// Handles loading the data and viz. | |
_createClass(GenChart, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() {} | |
// Renders the basic markup | |
}, { | |
key: 'render', | |
value: function render() { | |
return React.createElement( | |
'div', | |
{ className: 'gen-chart-render bg-mid-gray ' + s.slugify(this.props.type) }, | |
React.createElement( | |
'h2', | |
null, | |
this.props.type, | |
' Chart: ', | |
this.props.data.title, | |
' ' | |
), | |
React.createElement('div', { className: 'chart' }) | |
); | |
} | |
}]); | |
return GenChart; | |
})(React.Component); | |
var Pie = (function (_GenChart) { | |
_inherits(Pie, _GenChart); | |
function Pie() { | |
_classCallCheck(this, Pie); | |
_get(Object.getPrototypeOf(Pie.prototype), 'constructor', this).apply(this, arguments); | |
} | |
// A bar chart. | |
_createClass(Pie, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() { | |
var scale = this.scale; | |
// Need to convert number to scale on 0-1. | |
var fillScale = d3.scaleLinear(); | |
fillScale.domain([0, 15000]);true; | |
fillScale.range([0, 1]); | |
var selector = '.' + s.slugify(this.props.type) + ' .chart'; | |
var chart = d3.select(selector); | |
chart.classed(' tc bg-light-blue cf', true); | |
var svg = chart.append('svg').attr('width', 200).attr('height', 200); | |
// .classed('cf', true); | |
svg.selectAll('path').data(this.props.data.values).enter(); | |
// Use d3 pie utility to construct an arc made of pie segments. | |
var pie = d3.pie(); | |
var arcs = pie.value(function (d) { | |
return d.number; | |
})(this.props.data.values); | |
var arc = d3.arc().outerRadius(100).padAngle(0.03).innerRadius(50); | |
arcs.forEach(function (d, i) { | |
var data = d.data; | |
svg.append('path').attr('d', arc(d)).classed('centersvg ' + s.slugify(data.label), true).attr('transform', 'translate(100, 100)').attr('opacity', 0.85).attr('fill', function (data) { | |
var newD = fillScale(d.value); | |
var color = d3.interpolatePlasma(newD); | |
return color; | |
}); | |
}); | |
// Sort the labels according to biggest number value. | |
var sorted = this.props.data.values.sort(function (a, b) { | |
return a.number < b.number; | |
}); | |
// TODO: need to add some labels or a legend! | |
svg.exit(); | |
// Lets try a legend! | |
chart.append('div').classed('cf w-100', true); | |
chart.selectAll('div').select('.w-100').data(sorted).enter().append('div').classed('f6 dib mr1 white b grow', true).text(function (d) { | |
return d.label; | |
}).style('background-color', function (d) { | |
return d3.interpolatePlasma(fillScale(d.number)); | |
}).on('mouseover', function (e) { | |
var pathC = s.slugify(this.__data__.label); | |
var p = chart.select('path.' + pathC) | |
// .attr('opacity', 1) | |
// .attr('stroke', 'white') | |
// .attr('stroke-width', 2); | |
.classed('selected', true); | |
}).on('mouseout', function (e) { | |
var pathC = s.slugify(this.__data__.label); | |
var p = chart.select('path.' + pathC) | |
// .attr('opacity', 0.8) | |
// .attr('stroke-width', 0); | |
.classed('selected', false); | |
}); | |
} | |
}]); | |
return Pie; | |
})(GenChart); | |
var Bar = (function (_GenChart2) { | |
_inherits(Bar, _GenChart2); | |
function Bar() { | |
_classCallCheck(this, Bar); | |
_get(Object.getPrototypeOf(Bar.prototype), 'constructor', this).apply(this, arguments); | |
} | |
// A special statement type of text-based viz. | |
_createClass(Bar, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() {} | |
}]); | |
return Bar; | |
})(GenChart); | |
var TextNumber = (function (_GenText) { | |
_inherits(TextNumber, _GenText); | |
function TextNumber() { | |
_classCallCheck(this, TextNumber); | |
_get(Object.getPrototypeOf(TextNumber.prototype), 'constructor', this).apply(this, arguments); | |
} | |
// A special donation centric text viz. | |
_createClass(TextNumber, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() { | |
// Load the generic fontScale. | |
var fontScale = this.fontScale; | |
// Change the range a bit. | |
fontScale.range([24, 100]); | |
var selector = '.' + s.slugify(this.props.type) + ' .text-info'; | |
var textBox = d3.select(selector); | |
textBox.classed('tc bg-blue white pt3 br3 hide-child hover-bg-dark-blue', true); | |
textBox.selectAll('div').data(this.props.data.values).enter().append('div').text(function (d) { | |
return d; | |
}) | |
// Enhance the font-size based on value. | |
.style('font-size', function (d) { | |
// var d = d > 100 ? 80 : d; // replace this with scale. | |
var d = fontScale(d); | |
return d + "px"; | |
}).style('color', function (d) { | |
// Need to convert number to scale on 0-1. | |
var d = Math.log(d) / 10; | |
// Try out D3 color interpolation... | |
var color = d3.interpolateWarm(d); | |
return color; | |
}).classed('garamond fw9 underline', true); | |
// Add the description. | |
textBox.append('div').text(this.props.data.label || this.props.data.desc).classed('child f2', true); | |
} | |
}]); | |
return TextNumber; | |
})(GenText); | |
var Donation = (function (_GenText2) { | |
_inherits(Donation, _GenText2); | |
function Donation() { | |
_classCallCheck(this, Donation); | |
_get(Object.getPrototypeOf(Donation.prototype), 'constructor', this).apply(this, arguments); | |
} | |
// A big fat juicy percentage! | |
_createClass(Donation, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() { | |
// Load the symbol from the data. | |
var sym = this.props.data.symbol; | |
// Load the generic fontScale. | |
var fontScale = this.fontScale; | |
// Changing default range, want bigger fonts, not as much variation. | |
fontScale.range([80, 100]); | |
var selector = '.' + s.slugify(this.props.type) + ' .text-info'; | |
var textBox = d3.select(selector); | |
textBox.classed(' tc bg-dark-gray hover-bg-dark-green', true); | |
textBox.selectAll('div').data(this.props.data.values).enter().append('div').text(function (d) { | |
return sym + d; | |
}) | |
// Enhance the font-size based on value. | |
.style('font-size', function (d) { | |
var d = fontScale(d); | |
return d + "px"; | |
}).style('color', function (d) { | |
// Need to convert number to scale on 0-1. | |
var d = Math.log(d) / 10; | |
// Try out D3 color interpolation... | |
var color = d3.interpolateMagma(d); | |
return color; | |
}).classed('garamond fw9', true); | |
// Add the description. | |
textBox.append('div').html(this.props.data.label || this.props.data.desc).classed('f3 garamond', true); | |
} | |
}]); | |
return Donation; | |
})(GenText); | |
var Percentage = (function (_GenText3) { | |
_inherits(Percentage, _GenText3); | |
function Percentage() { | |
_classCallCheck(this, Percentage); | |
_get(Object.getPrototypeOf(Percentage.prototype), 'constructor', this).apply(this, arguments); | |
} | |
// A common example of a more complex text-based viz. | |
_createClass(Percentage, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() {} | |
}]); | |
return Percentage; | |
})(GenText); | |
var StepCount = (function (_GenText4) { | |
_inherits(StepCount, _GenText4); | |
function StepCount() { | |
_classCallCheck(this, StepCount); | |
_get(Object.getPrototypeOf(StepCount.prototype), 'constructor', this).apply(this, arguments); | |
} | |
// TODO: | |
// What other types do we want? | |
// Pie Chart (svg) -- done | |
// Big fancy percentage! | |
// Bar Chart (svg) | |
// Donations (css/html) -- kinda done | |
// Student body Martlett thing? (css/html?) | |
// Earthquake? (css/html?) | |
// Text pyramid? (css/html?) | |
// (See notes in Google photos sketch) | |
_createClass(StepCount, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() { | |
// Create a good scale for the circles. | |
var scale = d3.scaleLinear(); | |
scale.domain([0, 2000]); | |
// A reasonable font-size scale range. | |
scale.range([10, 100]); | |
var radialScale = d3.scaleLinear(); | |
radialScale.domain([0, 2000]); | |
radialScale.range([0, 8]); | |
var selector = '.' + s.slugify(this.props.type) + ' .text-info'; | |
var textBox = d3.select(selector); | |
textBox.classed(' tc bg-light-blue', true); | |
var svg = textBox.append('svg').attr('width', 200).attr('height', 200); | |
svg.selectAll('path').data(this.props.data.values).enter() | |
// Add a circle that scales well. | |
.append('path') | |
// 'd' attribute is the SVtrueG attr. for the shape of path. | |
.attr('d', function (d) { | |
// Lets try an arc. | |
var arc = d3.arc(); | |
var arcPath = arc({ | |
innerRadius: 0, | |
// Need a nice scale for d... | |
outerRadius: scale(d), | |
startAngle: 0, | |
endAngle: radialScale(d) | |
}); | |
return arcPath; | |
}).attr('transform', 'translate(100, 100)').attr('opacity', 0.8).attr('fill', function (d) { | |
// Need to convert number to scale on 0-1. | |
var fillScale = d3.scaleLinear(); | |
fillScale.domain([0, 2000]);true; | |
fillScale.range([0, 1]); | |
var newD = fillScale(d); | |
var color = d3.interpolatePlasma(newD); | |
return color; | |
}); | |
// Add a label? | |
var doSvgtext = false; | |
// Do the text in the svg. | |
if (doSvgtext == true) { | |
svg.selectAll('text').data(this.props.data.values).enter().append('text').text(function (d) { | |
return d; | |
}).attr('class', 'f4 Helvetica').attr('text-anchor', 'middle').attr('fill', 'white').attr('opacity', 0.75).attr('transform', function (d) { | |
y = scale(d); | |
return 'translate(100,' + (130 - y) + ')'; | |
}); | |
} else { | |
// Doing text in html/css. | |
textBox.selectAll('div'); | |
textBox.append('div').text(this.props.data.values[1] + ' out of ' + this.props.data.values[0] + ' steps today!').classed('f5 Helvetica blue', true); | |
} | |
} | |
}]); | |
return StepCount; | |
})(GenText); | |
ReactDOM.render(React.createElement(Charts), document.getElementById('app')); | |
</script> | |
<script id="jsbin-source-css" type="text/css">h1,h2,h3,h4,h5,h6, p { | |
font-family: sans-serif; | |
} | |
h1,h2,h3,h4,h5,h6,div,p,nav,section,hr { | |
/* margin: 0 0 1em 0; */ | |
margin: 0 0 10px 0; | |
} | |
nav, section, div, p { | |
/* padding: 0.3em; */ | |
padding: 10px; | |
} | |
/* Stealing from Tachyon, for svg */ | |
.bg-blue-svg { | |
fill: #357EDD; | |
} | |
svg path:hover, | |
svg path.selected { | |
opacity: 1; | |
stroke: white; | |
stroke-width: 2px; | |
} | |
svg .centersvg { | |
}</script> | |
<script id="jsbin-source-javascript" type="text/javascript">// Some default data. | |
var data = { | |
title: 'Some Data', | |
desc: 'Maps values to color on \'magma \' scale and maps values to a font-size on a linear scale.', | |
values: [10,20,30,40,50, 60, 70, 80, 90, 100] | |
} | |
var textNumData = { | |
title: 'Text & Number', | |
desc: 'This illustrates how numbers and basic text can go together.', | |
values: [50, 100, 500], | |
label: 'we\'ve grown in leaps and bounds!' | |
} | |
var donationData = { | |
title: 'Donations 2016', | |
desc: 'Shows donation totals in a dynamic way, with the total highlighted along with a basic label or description that can support HTML.', | |
values: [1000], | |
label: 'in <b>donations</b> raised by McGill U in 2016.<br/ > More on the way!', | |
symbol: '$', | |
// TODO: have a CTA available? | |
cta: null | |
} | |
var stepCountData = { | |
title: 'Step Count Today', | |
desc: 'Shows a simple step counter.', | |
values: [1700, 1000] | |
} | |
var pieData = { | |
title: 'Academic Community', | |
desc: 'A pie chart that shows the demographic breakdown of the academic community at McGill', | |
values: [ | |
{'label':'Undergraduate', 'number': 10000}, | |
{'label':'Post-graduate', 'number': 3000}, | |
{'label':'Graduate', 'number': 8000}, | |
{'label':'Other', 'number': 800}, | |
{'label':'Faculty', 'number': 1500}, | |
{'label':'TA\'s', 'number': 7000} | |
] | |
} | |
var percentageData = { | |
title: 'Advanced preparation!', | |
label: '55% of McGill undergraduates will go on to get a PhD. More than any other Canadian university.', | |
values: [55], | |
desc: 'Number of undergraduate students who later in a PhD' | |
} | |
// TODO : style this component (text to the left or right or bottom of % and big label, see one of those xample websites Joyce sent.) | |
// TODO: put this stuff in a document and put that in the ticket. | |
class Charts extends React.Component { | |
constructor(props) { | |
super(props) | |
this.state = { | |
data: data | |
} | |
} | |
// Handles loading the data and viz. | |
componentDidMount() { | |
} | |
render() { | |
return ( | |
<div className="all-charts-render"> | |
<StepCount type="Text Number svg infographic" data={stepCountData} /> | |
<Percentage type="Percentage" data={percentageData} /> | |
<Pie type="Pie" data={pieData} /> | |
<Bar type="Bar" data={this.state.data} /> | |
<GenText type="Text infographic" data={this.state.data} /> | |
<TextNumber type="Text Number infographic" data={textNumData} /> | |
<Donation type="Donation" data={donationData} /> | |
</div> | |
) | |
} | |
} | |
// A generic text based infographic class. | |
// Renders some text w/ d3js in a fun way. | |
// Takes data, colors text based on values. | |
// This component doesn't even need to use SVG | |
// But it could! | |
class GenText extends React.Component { | |
constructor(props) { | |
super(props); | |
// Set up a font scale for all text components ot have. | |
var scale = d3.scaleLinear(); | |
scale.domain([this.props.data.values[0], this.props.data.values[this.props.data.values.length-1]]); | |
// A reasonable font-size scale range. | |
scale.range([16, 60]); | |
this.fontScale = scale; | |
} | |
// Handles loading the data and viz. | |
componentDidMount() { | |
var fontScale = this.fontScale; | |
// TODO: get a pie-chart or some other graph going. | |
// console.log(this.props.type); | |
// Fire up d3. | |
var selector = '.' + s.slugify(this.props.type) + ' .text-info'; | |
var textBox = d3.select(selector); | |
textBox.selectAll('div') | |
.data(this.props.data.values) | |
.enter() | |
.append('div') | |
.text(function(d){ | |
return d; | |
}) | |
// Enhance the font-size based on value. | |
.style('font-size', function(d) { | |
// Run the values through scale, any number will be between scale.range value. | |
return fontScale(d) + "px" | |
})// Enhance the color based on value. | |
.style('background-color', function(d) { | |
// Try out D3 color interpolation... | |
var color = d3.interpolateInferno(100) | |
return color; | |
}) | |
.style('color', function(d) { | |
// Try out D3 color interpolation... | |
// Need rainbow to offset inferno. | |
var color = d3.interpolateRainbow(d/100) | |
return color; | |
}) | |
.classed('value', true); | |
} | |
// Renders the basic markup | |
render() {var scale = d3.scaleLinear(); | |
scale.domain([this.props.data.values[0], this.props.data.values[this.props.data.values.length-1]]); | |
// A reasonable font-size scale range. | |
scale.range([16, 60]); | |
return ( | |
<div className={'gen-text-render bg-mid-gray ' + s.slugify(this.props.type)}> | |
<h2 className="hot-pink">{this.props.type} Text: <span className="dark-pink">{this.props.data.title}</span> </h2> | |
<div className="text-info light-gray"> | |
</div> | |
<div> | |
{this.props.data.desc || this.props.data.label} | |
</div> | |
</div> | |
) | |
} | |
} | |
// A generic chart class. | |
class GenChart extends React.Component { | |
constructor(props) { | |
super(props); | |
// Set up a basic scale for chart. | |
var scale = d3.scaleLinear(); | |
scale.domain([0, 10000]); | |
// A reasonable font-size scale range. | |
scale.range([0, 100]); | |
this.scale = scale; | |
} | |
// Handles loading the data and viz. | |
componentDidMount() { | |
} | |
// Renders the basic markup | |
render() { | |
return ( | |
<div className={'gen-chart-render bg-mid-gray ' + s.slugify(this.props.type)}> | |
<h2>{this.props.type} Chart: {this.props.data.title} </h2> | |
<div className="chart"></div> | |
</div> | |
) | |
} | |
} | |
// A pie chart. | |
class Pie extends GenChart { | |
componentDidMount() { | |
let scale = this.scale; | |
// Need to convert number to scale on 0-1. | |
let fillScale = d3.scaleLinear(); | |
fillScale.domain([0, 15000]);true | |
fillScale.range([0,1]); | |
var selector = '.' + s.slugify(this.props.type) + ' .chart'; | |
var chart = d3.select(selector); | |
chart.classed(' tc bg-light-blue cf', true); | |
var svg = chart.append('svg') | |
.attr('width', 200) | |
.attr('height', 200); | |
// .classed('cf', true); | |
svg.selectAll('path') | |
.data(this.props.data.values) | |
.enter(); | |
// Use d3 pie utility to construct an arc made of pie segments. | |
var pie = d3.pie(); | |
var arcs = pie.value(function(d){ | |
return d.number; | |
})(this.props.data.values); | |
var arc = d3.arc() | |
.outerRadius(100) | |
.padAngle(0.03) | |
.innerRadius(50); | |
arcs.forEach(function(d, i){ | |
var data = d.data; | |
svg.append('path') | |
.attr('d', arc(d)) | |
.classed('centersvg ' + s.slugify(data.label) , true) | |
.attr('transform', 'translate(100, 100)') | |
.attr('opacity', 0.85) | |
.attr('fill', function(data){ | |
var newD = fillScale(d.value); | |
var color = d3.interpolatePlasma(newD); | |
return color; | |
}); | |
}); | |
// Sort the labels according to biggest number value. | |
var sorted = this.props.data.values.sort(function(a,b){ | |
return a.number < b.number; | |
}) | |
// TODO: need to add some labels or a legend! | |
svg.exit(); | |
// Lets try a legend! | |
chart.append('div').classed('cf w-100', true) | |
; | |
chart.selectAll('div').select('.w-100') | |
.data(sorted) | |
.enter() | |
.append('div') | |
.classed('f6 dib mr1 white b grow', true) | |
.text(function(d){ | |
return d.label; | |
}) | |
.style('background-color', function(d){ | |
return d3.interpolatePlasma(fillScale(d.number)); | |
}) | |
.on('mouseover', function(e){ | |
var pathC = s.slugify(this.__data__.label); | |
var p = chart.select('path.'+pathC) | |
// .attr('opacity', 1) | |
// .attr('stroke', 'white') | |
// .attr('stroke-width', 2); | |
.classed('selected', true); | |
}) | |
.on('mouseout', function(e){ | |
var pathC = s.slugify(this.__data__.label); | |
var p = chart.select('path.'+pathC) | |
// .attr('opacity', 0.8) | |
// .attr('stroke-width', 0); | |
.classed('selected', false); | |
}) | |
; | |
} | |
} | |
// A bar chart. | |
class Bar extends GenChart { | |
componentDidMount() { | |
} | |
} | |
// A special statement type of text-based viz. | |
class TextNumber extends GenText { | |
componentDidMount() { | |
// Load the generic fontScale. | |
var fontScale = this.fontScale; | |
// Change the range a bit. | |
fontScale.range([24, 100]); | |
var selector = '.' + s.slugify(this.props.type) + ' .text-info'; | |
var textBox = d3.select(selector); | |
textBox.classed('tc bg-blue white pt3 br3 hide-child hover-bg-dark-blue', true); | |
textBox.selectAll('div') | |
.data(this.props.data.values) | |
.enter() | |
.append('div') | |
.text(function(d){ | |
return d; | |
}) | |
// Enhance the font-size based on value. | |
.style('font-size', function(d) { | |
// var d = d > 100 ? 80 : d; // replace this with scale. | |
var d = fontScale(d); | |
return d + "px" | |
}) | |
.style('color', function(d) { | |
// Need to convert number to scale on 0-1. | |
var d = Math.log(d) / 10; | |
// Try out D3 color interpolation... | |
var color = d3.interpolateWarm(d) | |
return color; | |
}) | |
.classed('garamond fw9 underline', true); | |
// Add the description. | |
textBox | |
.append('div') | |
.text(this.props.data.label || this.props.data.desc) | |
.classed('child f2', true) | |
; | |
} | |
} | |
// A special donation centric text viz. | |
class Donation extends GenText { | |
componentDidMount() { | |
// Load the symbol from the data. | |
var sym = this.props.data.symbol; | |
// Load the generic fontScale. | |
var fontScale = this.fontScale; | |
// Changing default range, want bigger fonts, not as much variation. | |
fontScale.range([80, 100]); | |
var selector = '.' + s.slugify(this.props.type) + ' .text-info'; | |
var textBox = d3.select(selector); | |
textBox.classed(' tc bg-dark-gray hover-bg-dark-green', true); | |
textBox.selectAll('div') | |
.data(this.props.data.values) | |
.enter() | |
.append('div') | |
.text(function(d){ | |
return sym + d; | |
}) | |
// Enhance the font-size based on value. | |
.style('font-size', function(d) { | |
var d = fontScale(d); | |
return d + "px" | |
}) | |
.style('color', function(d) { | |
// Need to convert number to scale on 0-1. | |
var d = Math.log(d) / 10; | |
// Try out D3 color interpolation... | |
var color = d3.interpolateMagma(d) | |
return color; | |
}) | |
.classed('garamond fw9', true); | |
// Add the description. | |
textBox | |
.append('div') | |
.html(this.props.data.label || this.props.data.desc) | |
.classed('f3 garamond', true) | |
; | |
} | |
} | |
// A big fat juicy percentage! | |
class Percentage extends GenText { | |
componentDidMount() { | |
} | |
} | |
// A common example of a more complex text-based viz. | |
class StepCount extends GenText { | |
componentDidMount() { | |
// Create a good scale for the circles. | |
var scale = d3.scaleLinear(); | |
scale.domain([0, 2000]); | |
// A reasonable font-size scale range. | |
scale.range([10, 100]); | |
var radialScale = d3.scaleLinear(); | |
radialScale.domain([0,2000]); | |
radialScale.range([0, 8]); | |
var selector = '.' + s.slugify(this.props.type) + ' .text-info'; | |
var textBox = d3.select(selector); | |
textBox.classed(' tc bg-light-blue', true); | |
var svg = textBox.append('svg') | |
.attr('width', 200) | |
.attr('height', 200); | |
svg.selectAll('path') | |
.data(this.props.data.values) | |
.enter() | |
// Add a circle that scales well. | |
.append('path') | |
// 'd' attribute is the SVtrueG attr. for the shape of path. | |
.attr('d', function(d){ | |
// Lets try an arc. | |
var arc = d3.arc(); | |
var arcPath = arc({ | |
innerRadius: 0, | |
// Need a nice scale for d... | |
outerRadius: scale(d), | |
startAngle: 0, | |
endAngle: radialScale(d) | |
}); | |
return arcPath; | |
}) | |
.attr('transform', 'translate(100, 100)') | |
.attr('opacity', 0.8) | |
.attr('fill', function(d){ | |
// Need to convert number to scale on 0-1. | |
var fillScale = d3.scaleLinear(); | |
fillScale.domain([0, 2000]);true | |
fillScale.range([0,1]); | |
var newD = fillScale(d); | |
var color = d3.interpolatePlasma(newD); | |
return color; | |
}); | |
// Add a label? | |
var doSvgtext = false; | |
// Do the text in the svg. | |
if (doSvgtext== true) { | |
svg.selectAll('text') | |
.data(this.props.data.values) | |
.enter() | |
.append('text') | |
.text(function(d){return d}) | |
.attr('class', 'f4 Helvetica') | |
.attr('text-anchor', 'middle') | |
.attr('fill', 'white') | |
.attr('opacity', 0.75) | |
.attr('transform', function(d){ | |
y = scale(d); | |
return 'translate(100,' + (130 - y) + ')'; | |
}); | |
} else { | |
// Doing text in html/css. | |
textBox.selectAll('div') | |
textBox.append('div').text(this.props.data.values[1] + ' out of ' + this.props.data.values[0] + ' steps today!').classed('f5 Helvetica blue', true) | |
} | |
} | |
} | |
// TODO: | |
// What other types do we want? | |
// Pie Chart (svg) -- done | |
// Big fancy percentage! | |
// Bar Chart (svg) | |
// Donations (css/html) -- kinda done | |
// Student body Martlett thing? (css/html?) | |
// Earthquake? (css/html?) | |
// Text pyramid? (css/html?) | |
// (See notes in Google photos sketch) | |
ReactDOM.render( | |
React.createElement(Charts), | |
document.getElementById('app') | |
);</script></body> | |
</html> |
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
h1, h2, h3, h4, h5, h6, p { | |
font-family: sans-serif; | |
} | |
h1, h2, h3, h4, h5, h6, div, p, nav, section, hr { | |
/* margin: 0 0 1em 0; */ | |
margin: 0 0 10px 0; | |
} | |
nav, section, div, p { | |
/* padding: 0.3em; */ | |
padding: 10px; | |
} | |
/* Stealing from Tachyon, for svg */ | |
.bg-blue-svg { | |
fill: #357EDD; | |
} | |
svg path:hover, | |
svg path.selected { | |
opacity: 1; | |
stroke: white; | |
stroke-width: 2px; | |
} |
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
// Some default data. | |
'use strict'; | |
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | |
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | |
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | |
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | |
var data = { | |
title: 'Some Data', | |
desc: 'Maps values to color on \'magma \' scale and maps values to a font-size on a linear scale.', | |
values: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] | |
}; | |
var textNumData = { | |
title: 'Text & Number', | |
desc: 'This illustrates how numbers and basic text can go together.', | |
values: [50, 100, 500], | |
label: 'we\'ve grown in leaps and bounds!' | |
}; | |
var donationData = { | |
title: 'Donations 2016', | |
desc: 'Shows donation totals in a dynamic way, with the total highlighted along with a basic label or description that can support HTML.', | |
values: [1000], | |
label: 'in <b>donations</b> raised by McGill U in 2016.<br/ > More on the way!', | |
symbol: '$', | |
// TODO: have a CTA available? | |
cta: null | |
}; | |
var stepCountData = { | |
title: 'Step Count Today', | |
desc: 'Shows a simple step counter.', | |
values: [1700, 1000] | |
}; | |
var pieData = { | |
title: 'Academic Community', | |
desc: 'A pie chart that shows the demographic breakdown of the academic community at McGill', | |
values: [{ 'label': 'Undergraduate', 'number': 10000 }, { 'label': 'Post-graduate', 'number': 3000 }, { 'label': 'Graduate', 'number': 8000 }, { 'label': 'Other', 'number': 800 }, { 'label': 'Faculty', 'number': 1500 }, { 'label': 'TA\'s', 'number': 7000 }] | |
}; | |
var percentageData = { | |
title: 'Advanced preparation!', | |
label: '55% of McGill undergraduates will go on to get a PhD. More than any other Canadian university.', | |
values: [55], | |
desc: 'Number of undergraduate students who later in a PhD' | |
}; | |
// TODO : style this component (text to the left or right or bottom of % and big label, see one of those xample websites Joyce sent.) | |
// TODO: put this stuff in a document and put that in the ticket. | |
var Charts = (function (_React$Component) { | |
_inherits(Charts, _React$Component); | |
function Charts(props) { | |
_classCallCheck(this, Charts); | |
_get(Object.getPrototypeOf(Charts.prototype), 'constructor', this).call(this, props); | |
this.state = { | |
data: data | |
}; | |
} | |
// A generic text based infographic class. | |
// Renders some text w/ d3js in a fun way. | |
// Takes data, colors text based on values. | |
// This component doesn't even need to use SVG | |
// But it could! | |
// Handles loading the data and viz. | |
_createClass(Charts, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() {} | |
}, { | |
key: 'render', | |
value: function render() { | |
return React.createElement( | |
'div', | |
{ className: 'all-charts-render' }, | |
React.createElement(StepCount, { type: 'Text Number svg infographic', data: stepCountData }), | |
React.createElement(Percentage, { type: 'Percentage', data: percentageData }), | |
React.createElement(Pie, { type: 'Pie', data: pieData }), | |
React.createElement(Bar, { type: 'Bar', data: this.state.data }), | |
React.createElement(GenText, { type: 'Text infographic', data: this.state.data }), | |
React.createElement(TextNumber, { type: 'Text Number infographic', data: textNumData }), | |
React.createElement(Donation, { type: 'Donation', data: donationData }) | |
); | |
} | |
}]); | |
return Charts; | |
})(React.Component); | |
var GenText = (function (_React$Component2) { | |
_inherits(GenText, _React$Component2); | |
function GenText(props) { | |
_classCallCheck(this, GenText); | |
_get(Object.getPrototypeOf(GenText.prototype), 'constructor', this).call(this, props); | |
// Set up a font scale for all text components ot have. | |
var scale = d3.scaleLinear(); | |
scale.domain([this.props.data.values[0], this.props.data.values[this.props.data.values.length - 1]]); | |
// A reasonable font-size scale range. | |
scale.range([16, 60]); | |
this.fontScale = scale; | |
} | |
// A generic chart class. | |
// Handles loading the data and viz. | |
_createClass(GenText, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() { | |
var fontScale = this.fontScale; | |
// TODO: get a pie-chart or some other graph going. | |
// console.log(this.props.type); | |
// Fire up d3. | |
var selector = '.' + s.slugify(this.props.type) + ' .text-info'; | |
var textBox = d3.select(selector); | |
textBox.selectAll('div').data(this.props.data.values).enter().append('div').text(function (d) { | |
return d; | |
}) | |
// Enhance the font-size based on value. | |
.style('font-size', function (d) { | |
// Run the values through scale, any number will be between scale.range value. | |
return fontScale(d) + "px"; | |
}) // Enhance the color based on value. | |
.style('background-color', function (d) { | |
// Try out D3 color interpolation... | |
var color = d3.interpolateInferno(100); | |
return color; | |
}).style('color', function (d) { | |
// Try out D3 color interpolation... | |
// Need rainbow to offset inferno. | |
var color = d3.interpolateRainbow(d / 100); | |
return color; | |
}).classed('value', true); | |
} | |
// Renders the basic markup | |
}, { | |
key: 'render', | |
value: function render() { | |
var scale = d3.scaleLinear(); | |
scale.domain([this.props.data.values[0], this.props.data.values[this.props.data.values.length - 1]]); | |
// A reasonable font-size scale range. | |
scale.range([16, 60]); | |
return React.createElement( | |
'div', | |
{ className: 'gen-text-render bg-mid-gray ' + s.slugify(this.props.type) }, | |
React.createElement( | |
'h2', | |
{ className: 'hot-pink' }, | |
this.props.type, | |
' Text: ', | |
React.createElement( | |
'span', | |
{ className: 'dark-pink' }, | |
this.props.data.title | |
), | |
' ' | |
), | |
React.createElement('div', { className: 'text-info light-gray' }), | |
React.createElement( | |
'div', | |
null, | |
this.props.data.desc || this.props.data.label | |
) | |
); | |
} | |
}]); | |
return GenText; | |
})(React.Component); | |
var GenChart = (function (_React$Component3) { | |
_inherits(GenChart, _React$Component3); | |
function GenChart(props) { | |
_classCallCheck(this, GenChart); | |
_get(Object.getPrototypeOf(GenChart.prototype), 'constructor', this).call(this, props); | |
// Set up a basic scale for chart. | |
var scale = d3.scaleLinear(); | |
scale.domain([0, 10000]); | |
// A reasonable font-size scale range. | |
scale.range([0, 100]); | |
this.scale = scale; | |
} | |
// A pie chart. | |
// Handles loading the data and viz. | |
_createClass(GenChart, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() {} | |
// Renders the basic markup | |
}, { | |
key: 'render', | |
value: function render() { | |
return React.createElement( | |
'div', | |
{ className: 'gen-chart-render bg-mid-gray ' + s.slugify(this.props.type) }, | |
React.createElement( | |
'h2', | |
null, | |
this.props.type, | |
' Chart: ', | |
this.props.data.title, | |
' ' | |
), | |
React.createElement('div', { className: 'chart' }) | |
); | |
} | |
}]); | |
return GenChart; | |
})(React.Component); | |
var Pie = (function (_GenChart) { | |
_inherits(Pie, _GenChart); | |
function Pie() { | |
_classCallCheck(this, Pie); | |
_get(Object.getPrototypeOf(Pie.prototype), 'constructor', this).apply(this, arguments); | |
} | |
// A bar chart. | |
_createClass(Pie, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() { | |
var scale = this.scale; | |
// Need to convert number to scale on 0-1. | |
var fillScale = d3.scaleLinear(); | |
fillScale.domain([0, 15000]);true; | |
fillScale.range([0, 1]); | |
var selector = '.' + s.slugify(this.props.type) + ' .chart'; | |
var chart = d3.select(selector); | |
chart.classed(' tc bg-light-blue cf', true); | |
var svg = chart.append('svg').attr('width', 200).attr('height', 200); | |
// .classed('cf', true); | |
svg.selectAll('path').data(this.props.data.values).enter(); | |
// Use d3 pie utility to construct an arc made of pie segments. | |
var pie = d3.pie(); | |
var arcs = pie.value(function (d) { | |
return d.number; | |
})(this.props.data.values); | |
var arc = d3.arc().outerRadius(100).padAngle(0.03).innerRadius(50); | |
arcs.forEach(function (d, i) { | |
var data = d.data; | |
svg.append('path').attr('d', arc(d)).classed('centersvg ' + s.slugify(data.label), true).attr('transform', 'translate(100, 100)').attr('opacity', 0.85).attr('fill', function (data) { | |
var newD = fillScale(d.value); | |
var color = d3.interpolatePlasma(newD); | |
return color; | |
}); | |
}); | |
// Sort the labels according to biggest number value. | |
var sorted = this.props.data.values.sort(function (a, b) { | |
return a.number < b.number; | |
}); | |
// TODO: need to add some labels or a legend! | |
svg.exit(); | |
// Lets try a legend! | |
chart.append('div').classed('cf w-100', true); | |
chart.selectAll('div').select('.w-100').data(sorted).enter().append('div').classed('f6 dib mr1 white b grow', true).text(function (d) { | |
return d.label; | |
}).style('background-color', function (d) { | |
return d3.interpolatePlasma(fillScale(d.number)); | |
}).on('mouseover', function (e) { | |
var pathC = s.slugify(this.__data__.label); | |
var p = chart.select('path.' + pathC) | |
// .attr('opacity', 1) | |
// .attr('stroke', 'white') | |
// .attr('stroke-width', 2); | |
.classed('selected', true); | |
}).on('mouseout', function (e) { | |
var pathC = s.slugify(this.__data__.label); | |
var p = chart.select('path.' + pathC) | |
// .attr('opacity', 0.8) | |
// .attr('stroke-width', 0); | |
.classed('selected', false); | |
}); | |
} | |
}]); | |
return Pie; | |
})(GenChart); | |
var Bar = (function (_GenChart2) { | |
_inherits(Bar, _GenChart2); | |
function Bar() { | |
_classCallCheck(this, Bar); | |
_get(Object.getPrototypeOf(Bar.prototype), 'constructor', this).apply(this, arguments); | |
} | |
// A special statement type of text-based viz. | |
_createClass(Bar, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() {} | |
}]); | |
return Bar; | |
})(GenChart); | |
var TextNumber = (function (_GenText) { | |
_inherits(TextNumber, _GenText); | |
function TextNumber() { | |
_classCallCheck(this, TextNumber); | |
_get(Object.getPrototypeOf(TextNumber.prototype), 'constructor', this).apply(this, arguments); | |
} | |
// A special donation centric text viz. | |
_createClass(TextNumber, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() { | |
// Load the generic fontScale. | |
var fontScale = this.fontScale; | |
// Change the range a bit. | |
fontScale.range([24, 100]); | |
var selector = '.' + s.slugify(this.props.type) + ' .text-info'; | |
var textBox = d3.select(selector); | |
textBox.classed('tc bg-blue white pt3 br3 hide-child hover-bg-dark-blue', true); | |
textBox.selectAll('div').data(this.props.data.values).enter().append('div').text(function (d) { | |
return d; | |
}) | |
// Enhance the font-size based on value. | |
.style('font-size', function (d) { | |
// var d = d > 100 ? 80 : d; // replace this with scale. | |
var d = fontScale(d); | |
return d + "px"; | |
}).style('color', function (d) { | |
// Need to convert number to scale on 0-1. | |
var d = Math.log(d) / 10; | |
// Try out D3 color interpolation... | |
var color = d3.interpolateWarm(d); | |
return color; | |
}).classed('garamond fw9 underline', true); | |
// Add the description. | |
textBox.append('div').text(this.props.data.label || this.props.data.desc).classed('child f2', true); | |
} | |
}]); | |
return TextNumber; | |
})(GenText); | |
var Donation = (function (_GenText2) { | |
_inherits(Donation, _GenText2); | |
function Donation() { | |
_classCallCheck(this, Donation); | |
_get(Object.getPrototypeOf(Donation.prototype), 'constructor', this).apply(this, arguments); | |
} | |
// A big fat juicy percentage! | |
_createClass(Donation, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() { | |
// Load the symbol from the data. | |
var sym = this.props.data.symbol; | |
// Load the generic fontScale. | |
var fontScale = this.fontScale; | |
// Changing default range, want bigger fonts, not as much variation. | |
fontScale.range([80, 100]); | |
var selector = '.' + s.slugify(this.props.type) + ' .text-info'; | |
var textBox = d3.select(selector); | |
textBox.classed(' tc bg-dark-gray hover-bg-dark-green', true); | |
textBox.selectAll('div').data(this.props.data.values).enter().append('div').text(function (d) { | |
return sym + d; | |
}) | |
// Enhance the font-size based on value. | |
.style('font-size', function (d) { | |
var d = fontScale(d); | |
return d + "px"; | |
}).style('color', function (d) { | |
// Need to convert number to scale on 0-1. | |
var d = Math.log(d) / 10; | |
// Try out D3 color interpolation... | |
var color = d3.interpolateMagma(d); | |
return color; | |
}).classed('garamond fw9', true); | |
// Add the description. | |
textBox.append('div').html(this.props.data.label || this.props.data.desc).classed('f3 garamond', true); | |
} | |
}]); | |
return Donation; | |
})(GenText); | |
var Percentage = (function (_GenText3) { | |
_inherits(Percentage, _GenText3); | |
function Percentage() { | |
_classCallCheck(this, Percentage); | |
_get(Object.getPrototypeOf(Percentage.prototype), 'constructor', this).apply(this, arguments); | |
} | |
// A common example of a more complex text-based viz. | |
_createClass(Percentage, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() {} | |
}]); | |
return Percentage; | |
})(GenText); | |
var StepCount = (function (_GenText4) { | |
_inherits(StepCount, _GenText4); | |
function StepCount() { | |
_classCallCheck(this, StepCount); | |
_get(Object.getPrototypeOf(StepCount.prototype), 'constructor', this).apply(this, arguments); | |
} | |
// TODO: | |
// What other types do we want? | |
// Pie Chart (svg) -- done | |
// Big fancy percentage! | |
// Bar Chart (svg) | |
// Donations (css/html) -- kinda done | |
// Student body Martlett thing? (css/html?) | |
// Earthquake? (css/html?) | |
// Text pyramid? (css/html?) | |
// (See notes in Google photos sketch) | |
_createClass(StepCount, [{ | |
key: 'componentDidMount', | |
value: function componentDidMount() { | |
// Create a good scale for the circles. | |
var scale = d3.scaleLinear(); | |
scale.domain([0, 2000]); | |
// A reasonable font-size scale range. | |
scale.range([10, 100]); | |
var radialScale = d3.scaleLinear(); | |
radialScale.domain([0, 2000]); | |
radialScale.range([0, 8]); | |
var selector = '.' + s.slugify(this.props.type) + ' .text-info'; | |
var textBox = d3.select(selector); | |
textBox.classed(' tc bg-light-blue', true); | |
var svg = textBox.append('svg').attr('width', 200).attr('height', 200); | |
svg.selectAll('path').data(this.props.data.values).enter() | |
// Add a circle that scales well. | |
.append('path') | |
// 'd' attribute is the SVtrueG attr. for the shape of path. | |
.attr('d', function (d) { | |
// Lets try an arc. | |
var arc = d3.arc(); | |
var arcPath = arc({ | |
innerRadius: 0, | |
// Need a nice scale for d... | |
outerRadius: scale(d), | |
startAngle: 0, | |
endAngle: radialScale(d) | |
}); | |
return arcPath; | |
}).attr('transform', 'translate(100, 100)').attr('opacity', 0.8).attr('fill', function (d) { | |
// Need to convert number to scale on 0-1. | |
var fillScale = d3.scaleLinear(); | |
fillScale.domain([0, 2000]);true; | |
fillScale.range([0, 1]); | |
var newD = fillScale(d); | |
var color = d3.interpolatePlasma(newD); | |
return color; | |
}); | |
// Add a label? | |
var doSvgtext = false; | |
// Do the text in the svg. | |
if (doSvgtext == true) { | |
svg.selectAll('text').data(this.props.data.values).enter().append('text').text(function (d) { | |
return d; | |
}).attr('class', 'f4 Helvetica').attr('text-anchor', 'middle').attr('fill', 'white').attr('opacity', 0.75).attr('transform', function (d) { | |
y = scale(d); | |
return 'translate(100,' + (130 - y) + ')'; | |
}); | |
} else { | |
// Doing text in html/css. | |
textBox.selectAll('div'); | |
textBox.append('div').text(this.props.data.values[1] + ' out of ' + this.props.data.values[0] + ' steps today!').classed('f5 Helvetica blue', true); | |
} | |
} | |
}]); | |
return StepCount; | |
})(GenText); | |
ReactDOM.render(React.createElement(Charts), document.getElementById('app')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment