堆栈图&曲线堆叠图

layout.stack()

  const width = 800, height = 500, padding = {top: 160, left: 130};
    const dataSet = [
        {
            name: "PC",
            sales: [
                {year: 2005, profit: 3000},
                {year: 2001, profit: 2000},
                {year: 2002, profit: 1000},
                {year: 2003, profit: 5000},
                {year: 2006, profit: 4000}
            ]
        }, {
            name: "Phone",
            sales: [
                {year: 2005, profit: 1000},
                {year: 2001, profit: 2000},
                {year: 2002, profit: 3000},
                {year: 2003, profit: 3000},
                {year: 2006, profit: 1000}
            ]
        }, {
            name: "SoftWare",
            sales: [
                {year: 2005, profit: 1600},
                {year: 2001, profit: 2600},
                {year: 2002, profit: 3600},
                {year: 2003, profit: 6600},
                {year: 2006, profit: 1600}
            ]
        }
    ];

    const stack = d3.layout.stack()
        .values(d => d.sales)
        .x(d => d.year)
        .y(d => d.profit);
    const data = stack(dataSet);
    const svg = d3.select("body").append("svg")
        .attr("width", width + padding.left * 2)
        .attr("height", height + padding.top * 2)
        .append("g");
    const xScale = d3.scale.ordinal()
        .domain(data[0].sales.map(d => d.year))
        .rangeBands([0, width], .3);
    const maxProfit = d3.max(data[data.length - 1].sales, d => d.y0 + d.y);
    const yRangeWidth = height - padding.top;
    const yScale = d3.scale.linear()
        .domain([0, maxProfit])
        .range([0, yRangeWidth]);
    const color = d3.scale.category20b();
    const groups = svg.selectAll("g")
        .data(data)
        .enter()
        .append("g")
        .style("fill", (d, i) => color(i));
    groups.selectAll("rect")
        .data(d => d.sales)
        .enter()
        .append("rect")
        .attr("x", d => xScale(d.year))
        .attr("y", d => yRangeWidth - yScale(d.y0 + d.y))
        .attr("width", xScale.rangeBand())
        .attr("height", d => yScale(d.y))
        .attr("transform", `translate(${padding.left},${padding.top})`);
    const xAxis = d3.svg.axis().scale(xScale).orient("bottom");
    svg.append("g").attr("class", "axis").attr("transform", `translate(${padding.left},${height})`).call(xAxis)
    const yAxis = d3.svg.axis().scale(yScale).orient("left");
    yScale.range([yRangeWidth, 0]);
    svg.append("g").attr("class", "axis").attr("transform", `translate(${padding.left},${padding.top})`).call(yAxis)
    const labHeight = 50;
    const labRadius = 10;
    const labelCircle = groups.append("circle")
        .attr("cx", d => (width + padding.left * .9))
        .attr("cy", (d,i) => (padding.top + labHeight*i))
        .style("fill", (d, i) => color(i))
        .attr("r", labRadius);
    const labelText = groups.append("text")
        .attr("x", d => width + padding.left )
        .attr("y", (d,i) => (padding.top + labHeight*i))
        .attr("dy", labRadius / 2)
        .text(d => d.name);

结果:


image.png

曲线堆叠图

  const width = 800, height = 500, padding = {top: 160, left: 130};
    const dataSet = [
        {
            name: "PC",
            sales: [
                {year: 2005, profit: 3000},
                {year: 2001, profit: 2000},
                {year: 2002, profit: 1000},
                {year: 2003, profit: 5000},
                {year: 2006, profit: 4000}
            ]
        }, {
            name: "Phone",
            sales: [
                {year: 2005, profit: 1000},
                {year: 2001, profit: 2000},
                {year: 2002, profit: 3000},
                {year: 2003, profit: 3000},
                {year: 2006, profit: 1000}
            ]
        }, {
            name: "SoftWare",
            sales: [
                {year: 2005, profit: 1600},
                {year: 2001, profit: 2600},
                {year: 2002, profit: 3600},
                {year: 2003, profit: 6600},
                {year: 2006, profit: 1600}
            ]
        }
    ];

    const stack = d3.layout.stack()
        .values(d => d.sales)
        .x(d => d.year)
        .y(d => d.profit);
    const data = stack(dataSet);
    const svg = d3.select("body").append("svg")
        .attr("width", width + padding.left * 2)
        .attr("height", height + padding.top * 2)
        .append("g");
    const xScale = d3.scale.ordinal()
        .domain(data[0].sales.map(d => d.year))
        .rangeBands([0, width], .3);
    const maxProfit = d3.max(data[data.length - 1].sales, d => d.y0 + d.y);
    const yRangeWidth = height - padding.top;
    const yScale = d3.scale.linear()
        .domain([0, maxProfit])
        .range([0, yRangeWidth]);
    const color = d3.scale.category20b();
    const groups = svg.selectAll("g")
        .data(data)
        .enter()
        .append("g")
        .style("fill", (d, i) => color(i));
    const areaPath = d3.svg.area()
        .x(d => xScale(d.year) + xScale.rangeBand() / 2)
        .y0(d => yRangeWidth - yScale(d.y0))
        .y1(d => yRangeWidth - yScale(d.y0 + d.y))
        .interpolate("basis");
    groups.selectAll(".area").data(data).enter().append("path")
        .attr("class", "area")
        .attr("d", function (d) {
            return areaPath(d.sales);
        })
        .style("fill", (d, i) => color(i))
        .attr("transform", `translate(${padding.left},${padding.top})`);
    const xAxis = d3.svg.axis().scale(xScale).orient("bottom");
    svg.append("g").attr("class", "axis").attr("transform", `translate(${padding.left},${height})`).call(xAxis)
    const yAxis = d3.svg.axis().scale(yScale).orient("left");
    yScale.range([yRangeWidth, 0]);
    svg.append("g").attr("class", "axis").attr("transform", `translate(${padding.left},${padding.top})`).call(yAxis)
    const labHeight = 50;
    const labRadius = 10;

    const labelCircle = groups.append("circle")
        .attr("cx", d => (width + padding.left * .9))
        .attr("cy", (d, i) => (padding.top + labHeight * i))
        .style("fill", (d, i) => color(i))
        .attr("r", labRadius);
    const labelText = groups.append("text")
        .attr("x", d => width + padding.left)
        .attr("y", (d, i) => (padding.top + labHeight * i))
        .attr("dy", labRadius / 2)
        .text(d => d.name);

结果:


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,276评论 4 61
  • 很多时候,我们会害怕一些事情,一些我们从未尝试过的事情。 小时候第一次自己一个人乘公交车,尽管我已十分明白该怎样投...
    goddess1223阅读 530评论 0 0
  • 日子一天天在做减法,生命在缓慢的消逝。 不想重头在来,只好屏气死撑。 殊不知,何时是个头?
    奋进的小之阅读 311评论 0 0
  • 7月22日的K线是很有意思的一根K线,所有的指数的MACD日线都走成了死叉状态。并且现在各个指数距离20日线已经很...
    大白雪球阅读 219评论 0 0
  • 文/孤鸟差鱼 发霉的悲伤 你可以汰旧换优的
    孤鸟差鱼阅读 119评论 0 2