drawStream = function(data, params) {
const { height, margin } = params;
let columns = data.columns;
data = data.filter((item, index) => index % 3 === 0);
data.columns = columns;
const series = d3.stack()
.keys(data.columns.slice(1))
.offset(d3.stackOffsetWiggle)(data);
const y = d3.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([margin.top, height - margin.bottom])
const x = d3.scaleLinear()
.domain([
d3.min(series, d => d3.min(d, d => d[0])),
d3.max(series, d => d3.max(d, d => d[1]))
])
.range([margin.left, width - margin.right]);
const axisColor = 'rgb(166, 161, 158)'
const yAxis = g => g
.attr("transform", `translate(${margin.left} ,${margin.top})`)
.call(d3.axisLeft(y).ticks(d3.timeYear.every(1)))
.call(g => {
g.select(".domain").remove();
let ticks = g.selectAll(".tick");
ticks.select('line').remove();
ticks.select('text').attr('fill', axisColor);
ticks
.append('line')
.attr('x1', 0)
.attr('x2', width - margin.right)
.attr('y1', 0)
.attr('y2', 0)
.attr('stroke', axisColor)
.attr('stroke-dasharray', '5 5')
});
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
.style("background-color", "#FCF4EB")
.style("border-radius", "12px")
const area = d3.area()
.curve(d3.curveBasis)
.y(d => y(d.data.date))
.x0(d => x(d[0]))
.x1(d => x(d[1]));
const gradientColor = {
'Template': '#F8CD29',
'Design': '#1D95BB',
'Training': '#FAA9B2'
};
let defs = svg.append('defs')
.selectAll('linearGradient')
.data(Object.keys(gradientColor))
.join('linearGradient')
.attr('id', d => `color-${d.toLowerCase()}`)
.attr('x1', '0%')
.attr('y1', '0%')
.attr('x2', '0%')
.attr('y2', '100%')
defs.append('stop')
.attr('offset', '0%')
.attr('style', d => `stop-color:${gradientColor[d]}; stop-opacity:1`)
defs.append('stop')
.attr('offset', '100%')
.attr('style', d => `stop-color:${gradientColor[d]}; stop-opacity:0.6`)
svg.append("g").call(yAxis);
const desc = {
"Template": ["Sketch", "Tableau", "Power BI"],
"Design": ["Infographic", "Dashboard", "Screen"],
"Training": ["Study Case", "Data Visualization Theory"]
};
svg.append("g")
// area
let areas = svg.append("g")
.selectAll("path")
.data(series)
.join("path")
.attr("style", ({key}) => `fill:url(#color-${key.toLowerCase()})`) // style="fill:url(#orange_red)"
.attr("d", area);
let labels = svg.append("g")
.selectAll("text")
.data(series)
.join("text")
.text(d => d.key.toUpperCase())
.attr("font-size", 24)
.attr('transform', d => {
let p = Math.floor(d.length * 3 / 4);
let tx = x(d[p][0]) + (x(d[p][1]) - x(d[p][0])) / 2;
return `translate(${tx - 40}, ${height * 3 / 4})`
})
.attr('fill', d => d.key === 'Design'? '#fff': '#201E1F');
labels.selectAll("tspan")
.data(d => desc[d.key])
.join("tspan")
.text(d => d)
.attr('x', 0)
.attr('y', (d, i) => 30 + i * 20)
.attr("font-size", 14);
return svg.node();
}