【问题标题】:Complex JSON to D3js stacked time series复杂的 JSON 到 D3js 堆叠时间序列
【发布时间】:2020-04-14 17:17:28
【问题描述】:

我必须使用 D3 创建一个可视化,如下图所示,时间序列,堆叠条:

数据集来自顾问,格式为嵌套的 json 对象数组:

[{
        "period": "6/2017",
        "data": [
            {
                "partner": "TR",
                "val": 5201888581
            },
            {
                "partner": "CH",
                "val": 8509470105
            },
            {
                "partner": "RU",
                "val": 10677690328
            },
            {
                "partner": "GB",
                "val": 16086915825
            },
            {
                "partner": "US",
                "val": 17817589838
            },
            {
                "partner": "CN",
                "val": 26120939253
            },
            {
                "partner": "TOTAL",
                "val": 145385348496
            }
        ]
    },
    {
        "period": "7/2017",
        "data": [
            {
                "partner": "TR",
                "val": 4832746886
            },
            {
                "partner": "CH",
                "val": 8194483975
            },
            {
                "partner": "RU",
                "val": 10082530447
            },
            {
                "partner": "US",
                "val": 15251181551
            },
            {
                "partner": "GB",
                "val": 15515343080
            },
            {
                "partner": "CN",
                "val": 27480148190
            },
            {
                "partner": "TOTAL",
                "val": 142118881451
            }
        ]
    },
    {
        "period": "8/2017",
        "data": [
            {
                "partner": "TR",
                "val": 4827335758
            },
            {
                "partner": "CH",
                "val": 7087004314
            },
            {
                "partner": "RU",
                "val": 10372167568
            },
            {
                "partner": "GB",
                "val": 14555013893
            },
            {
                "partner": "US",
                "val": 16838219917
            },
            {
                "partner": "CN",
                "val": 27876046083
            },
            {
                "partner": "TOTAL",
                "val": 143363806063
            }
        ]
    }
...
]

更准确地说,每个对象都包含句点和对象子数组、国家代码和值:

{ 
  period,
  data: [{country,value},{country,value},{country,value}...]
}

数据数组包含不同数量的对象(国家记录),从 3 到 10 以及不同的国家(可以是任何联合国国家)。

我尝试使用 D3 (v5) 中的标准布局,例如“堆栈”,但如您所见,我的数据与 d3 布局中所需的数据格式不匹配,即表格数据,例如:

time  field1  field2  field3
t1     v11     v12     v13
t2     v21     v22     v23
...

我不知道如何处理我的数据,请帮忙。发送。

LE:我也尝试使用 chart.js,但由于类似问题而失败。

【问题讨论】:

    标签: json d3.js nested time-series stacked-chart


    【解决方案1】:

    随着国家/地区数量的不同,您可以创建自己的函数来附加国家/地区的 rect 元素。该示例使用 d3.selection.each 调用新函数,并在此函数中创建一个新的数据数组,其中包含每个矩形的 y 偏移量。

        let data = [{
            "period": "6/2017",
            "data": [
                {
                    "partner": "TR",
                    "val": 5201888581
                },
                {
                    "partner": "CH",
                    "val": 8509470105
                },
                {
                    "partner": "RU",
                    "val": 10677690328
                },
                {
                    "partner": "GB",
                    "val": 16086915825
                },
                {
                    "partner": "US",
                    "val": 17817589838
                },
                {
                    "partner": "CN",
                    "val": 26120939253
                },
                {
                    "partner": "TOTAL",
                    "val": 145385348496
                }
            ]
        },
        {
            "period": "7/2017",
            "data": [
                {
                    "partner": "TR",
                    "val": 4832746886
                },
                {
                    "partner": "CH",
                    "val": 8194483975
                },
                {
                    "partner": "RU",
                    "val": 10082530447
                },
                {
                    "partner": "US",
                    "val": 15251181551
                },
                {
                    "partner": "GB",
                    "val": 15515343080
                },
                {
                    "partner": "CN",
                    "val": 27480148190
                },
                {
                    "partner": "TOTAL",
                    "val": 142118881451
                }
            ]
        },
        {
            "period": "8/2017",
            "data": [
                {
                    "partner": "TR",
                    "val": 4827335758
                },
                {
                    "partner": "CH",
                    "val": 7087004314
                },
                {
                    "partner": "RU",
                    "val": 10372167568
                },
                {
                    "partner": "GB",
                    "val": 14555013893
                },
                {
                    "partner": "US",
                    "val": 16838219917
                },
                {
                    "partner": "CN",
                    "val": 27876046083
                },
                {
                    "partner": "TOTAL",
                    "val": 143363806063
                }
            ]
        }]
        
        let width = 500
        let height = 500
        let margin = 50
        
        let x = d3.scaleBand()
        	.domain(["6/2017","7/2017","8/2017"])
        	.range([0, width])
        	.padding(0.3)
        
        let y = d3.scaleLinear()
        	.domain([0, 145385348496])
        	.range([height, 0])
          
        var svg = d3.select("body").append("svg")
          .attr("width", width + margin + margin)
          .attr("height", height + margin + margin)
    
        var g = svg.append("g")
          .attr("transform", "translate(" + margin + ", " + margin + ")")
        
        var periods = g.selectAll("g")
        	.data(data)
        	.enter()
        	.append("g")
        	.attr("class", "period")
        	.attr("transform", function(d){
            return "translate(" + x(d.period) + ", " + 0 + ")"
          })
        	.each(appendCountries)
        
        function appendCountries(period, i){
          
          let countries = []
          let offset = 0
          let colour = d3.scaleOrdinal(d3.schemeAccent);
          
          period.data.forEach(function(c){
            if (c.partner != "TOTAL") { //assuming that total should not be included
              
              offset = offset + c.val
              
              let obj = {}
              obj.y = offset
              obj.val = c.val
              obj.partner = c.partner
              countries.push(obj)
              
            }
          })
          
          let rects = d3.select(this).selectAll("rect")
          	.data(countries)
          	.enter()
          	.append("rect")
          	.attr("width", x.bandwidth)
          	.attr("x", 0)
          	.attr("y", d => y(d.y))
    				.attr("height", d => height - y(d.val))
          	.style("fill", d => colour(d.partner))
          	.style("stroke", "white")
        }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

    【讨论】:

    • 非常感谢,@Tom。你拯救了我的一天。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 2016-10-27
    • 2011-09-01
    • 1970-01-01
    相关资源
    最近更新 更多