(function () { var getDimensions = function (root) { var size = root.getBoundingClientRect(); return { width: size.width, height: 500 }; }; var host = document.body; var dims = getDimensions(host); var margins = { top: 80, right: 30, bottom: 30, left: 30 }; var chartSize = { width: dims.width - (margins.left + margins.right), height: dims.height - (margins.top + margins.bottom) }; var svg = d3.select("svg").attr("width", dims.width).attr("height", dims.height); var plot = createPlotArea(svg); function createChart(data, trades, map) { var keys = Object.keys(data); var dates = keys.map(function (key) { return new Date(key); }); var xScale = d3.scaleTime() .domain(getDateRange(dates)) .range([0, chartSize.width]); var totals = keys.map(function (key) { return data[key]; }); var maxCommissions = d3.max(totals, function (d) { return d.totalCommissions; }); var minCommissions = d3.min(totals, function (d) { return d.totalCommissions; }); var yScale = d3.scaleLinear() .domain([maxCommissions, minCommissions]) .range([0, chartSize.height]); var xAxis = d3.axisBottom(xScale) .tickSizeInner(-chartSize.height) .tickPadding(10); var xAxisGroup = plot .append('g') .attr('class', 'axis axis--x') .attr('transform', 'translate(0, ' + chartSize.height + ')'); xAxisGroup.call(xAxis); var host = createChartArea(plot); var datasource = formatDatasource(trades, map); var colorScale = createColorPalette(); // Create plots var getX = function (d) { return xScale(d.date); }; var getY = function (d) { return yScale(d.value); }; var items = host.selectAll('.data-item').data(datasource).enter() .append('circle') .attr('fill', function (d) { return colorScale(d.index); }) .attr('cx', getX) .attr('cy', getY) .attr('r', 4) .attr('title', function (d) { return d.name; }) .on('mouseenter', function (e) { tooltip .classed('hidden', false) .select('rect').attr('fill', function () { return colorScale(e.index); }); txt1.text(e.name); txt2.text(e.date.toLocaleString()); txt3.text('Revenue: ' + e.value); }) .on('mouseout', function () { tooltip.classed('hidden', true); }); var tooltip = svg.append('g').attr('class', 'svg--tooltip') .classed('hidden', true) .attr('width', 100).attr('height', 40) .attr('transform', 'translate(10, 10)'); tooltip.append('rect').attr('width', 120).attr('height', 60).attr('x', 0).attr('y', 0); var textArea = tooltip.append('g').attr('class', 'svg--labels'); var txt1 = textArea.append('text').attr('x', 10).attr('y', 10).attr('class', 'text--1'); appendTextAttrs(txt1); var txt2 = textArea.append('text').attr('x', 10).attr('y', 24).attr('class', 'text--2'); appendTextAttrs(txt2); var txt3 = textArea.append('text').attr('x', 10).attr('y', 38).attr('class', 'text--3'); appendTextAttrs(txt3); } function appendTextAttrs(text) { text.attr('stroke', 'black') .attr('font-family', 'calibri') .attr('font-size', 11) .attr('class', 'svg--label'); } function getDateRange(dates) { var minMaxDate = d3.extent(dates); var minDate = minMaxDate[0]; var maxDate = minMaxDate[1]; maxDate.setDate(maxDate.getDate() + 1); return [minDate, maxDate]; } function createChartArea(host) { return host.append('g').attr('class', 'chart--area') .attr('width', chartSize.width) .attr('height', chartSize.height); } function createPlotArea(host) { return host.append('g') .attr('width', chartSize.width) .attr('height', chartSize.height) .attr('class', 'chart--plot') .attr('transform', 'translate(' + margins.left + ', ' + margins.top + ')'); } function createColorPalette() { var colorScale = d3.scaleLinear() .domain([0, 1, 2, 3, 4, 5]) .range(['#2077B3', '#f03e3e', '#2f9e44', '#3bc9db', '#ffe066', '#f76707']); return colorScale; } function formatDatasource(trades, map) { var source = Object.keys(trades).map(function (key) { var byDate = trades[key]; var tradesByDate = Object.keys(byDate) .filter(function (securityKey) { return !!map[securityKey]; }) .map(function (securityKey) { return { date: new Date(key), value: byDate[securityKey], index: map[securityKey].index, name: securityKey }; }); return tradesByDate; }).reduce(function (p, c) { return p.concat(c); }, []); console.log(source); return source; } d3.json('trades.json', function (error, data) { if (error) { console.log(error); } getMap(data); }); function getMap(trades) { d3.json('map.json', function (error, map) { if (error) { console.log(error); } getData(trades, map); }); } function getData(trades, map) { d3.json('data.json', function (error, data) { if (error) { console.log(error); } createChart(data, trades, map); }); } })();