d3.js:在下拉更改上加载不同的JSON数据集 [英] d3.js: loading different JSON datasets on dropdown change

查看:137
本文介绍了d3.js:在下拉更改上加载不同的JSON数据集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在其他人的片段 / switch-between-two-datasets-in-this-d3-js-reusable-and-zoomable-line-chart>问题,这正是我想要的 - 带
a的折线图下拉框用于在多个数据集之间切换。事情是,我想从一个php生成的JSON文件外部加载,但我真的不知道我该怎么做。

  d3.taos = function(config){

//边距和图形格式化。
var margin = {
top:20,
right:20,
bottom:20,
left:60},

width = 960 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom,
x = d3.time.scale(),//不同缩放。
y = d3.scale.linear(),
xAxis = d3.svg.axis()。scale(x).orient(bottom)。ticks(5),
yAxis = d3.svg.axis()。scale(y).orient(left)。ticks(5),
line = d3.svg.line(),
color = d3.scale.category10 (),
zoom = d3.behavior.zoom()。scaleExtent([0.5,50]);


//图表本身。
var chart = function(selection){
dataset = selection.data()[0];

//选择svg元素(如果存在)。
var svg = selection.selectAll(svg)。data([dataset])
.attr(width,width + margin.left + margin.right)
.attr height,height + margin.top + margin.bottom);

//否则,创建骨架图。
var gEnter = svg.enter()。append(svg)
.append(g)
.attr(transform,translate(+ margin.left + ,+ margin.top +));

//渲染两个轴。
gEnter.append(g)。attr(class,x axis);
gEnter.append(g)。attr(class,y axis);

gEnter.append(defs)。append(clipPath)
.attr(id,clip)
.append b $ b .attr(id,clip-rect)
.attr(x,0)
.attr(y,0)
.attr(width,width)
.attr(height,height);

x.range([0,width])
.domain(d3.extent(d3.merge(dataset),function(d){
return dx;
}))

y.range([height,0])
.domain(d3.extent(d3.merge(dataset),function(d){
return dy;
}))

var g = svg.select(g);

//更新x轴。
g.select(。x.axis)
.attr(transform,translate(0,+ height +))
.call(xAxis)

//更新y轴。
g.select(。y.axis)
.call(yAxis);

//定义行
line = d3.svg.line()
.x(function(d){
return x(dx);

.y(function(d){
return y(dy);
})

var path = g.selectAll )
.data(dataset)
.enter()。append(path)
.style(stroke,function(d,i){
return color i)
});

path.attr(class,line)
.attr(d,line)
.attr(clip-path,url夹));

//更新剪辑矩形
g.select(#clip-rect)
.attr(width,width)
.attr高度,高度);

//更新线路路径。
g.selectAll(。line)
.attr(d,line);

zoom.x(x).y(y)
.on(zoom,draw);

//用于缩放的Rect。
gEnter.append(rect)
.attr(class,rectzoom)
.attr(width,width)
.attr ,height)
.call(zoom);

function draw(){
g.select(。x.axis)。call(xAxis);
g.select(。y.axis)。call(yAxis);
g.selectAll(path.line)。attr(d,line);
//g.select(\"#clip-rect\").attr(\"width\",width).attr(\"height\",height);
}

/ *
*方法
* /

chart.width = function(w){
if !arguments.length)return width;
width = w;
return this;
};

chart.height = function(h){
if(!arguments.length)return height;
height = h;
return this;
};

返回图表

} //图表

返回图表

}; // d3.taos





/ *
*主要
* /
$ b b // for json:


//新实例
var t = d3.taos();

var f = function(){}



var data = d3.json(api.json?id = 1 (错误,数据){
if(error)return console.warn(error);
//创建
d3.select(svg#chart)
.datum数据)
.attr(x,function(d){x(dx)})
.call(t);
}

//更新
d3.select(select)。on(change,function(){

var val = $(select#数据集)。val();



val ==dataset1?dataset = dataset1:dataset = dataset2;

console.log (Dataset changed:+ val);

d3.select(svg#chart)
.datum(dataset)
.call(t.width );


});

和HTML代码...

 < select id =dataset> 
< option value =1selected>数据集1< / option>
< option value =2>数据集2< / option>
< option value =3>数据集3< / option>
< / select>

api.json?id = 1

  {

usability_index:[
{x:1397220093000,y:7},
{x:1397222093000,y:21},
{ x:1397224093000,y:13},
{x:1397226093000,y:23}
]

}

我用 d3.json()探索,但我不太确定如何去动态加载它默认数据集选项更改为数据集3,从 api.json?id = 1 api.json?id = 3



我真的很喜欢d3.js, >解决方案

您可以尝试这样的操作,而是使用可重复使用的图表库基于d3.js。



以下是有关如何通过API调用加载数据

  var chart = c3.generate({
data:{
url:'api.json?id = 1',
mimeType:'json'
}
});

请注意,c3.js要求您使用以下格式的JSON:

  {
line1:[220,240,270,250,280],
line2:[ 150,300,70,120],
line3:[200,310,150,100,180]
}

因此,您需要解析并重新格式化您的JSON数据,然后才能加载它。



处理程序,您可以选择重新生成或在图表中加载更多行。


I found this snippet in someone else's question which does exactly what I want - a line chart with a dropdown box for switching between multiple datasets. The thing is, I want to load externally from a php generated JSON file instead but I'm really not sure how I can do that.

d3.taos = function (config) {

    // Margins and graph formatting.
    var margin = {
        top: 20,
        right: 20,
        bottom: 20,
        left: 60 },

        width = 960 - margin.left - margin.right,
        height = 400 - margin.top - margin.bottom,
        x = d3.time.scale(),    // different scaling.
        y = d3.scale.linear(),
        xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(5),
        yAxis = d3.svg.axis().scale(y).orient("left").ticks(5),
        line = d3.svg.line(),
        color = d3.scale.category10(),
        zoom = d3.behavior.zoom().scaleExtent([0.5, 50]);


    // The chart itself.
    var chart = function (selection) {
        dataset = selection.data()[0];

        // Select the svg element, if it exists.
        var svg = selection.selectAll("svg").data([dataset])
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom);

        // Otherwise, create the skeletal chart.
        var gEnter = svg.enter().append("svg")
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        // Rendering both axes.
        gEnter.append("g").attr("class", "x axis");
        gEnter.append("g").attr("class", "y axis");

        gEnter.append("defs").append("clipPath")
            .attr("id", "clip")
            .append("rect")
            .attr("id", "clip-rect")
            .attr("x", "0")
            .attr("y", "0")
            .attr("width", width)
            .attr("height", height);

        x.range([0, width])
            .domain(d3.extent(d3.merge(dataset), function (d) {
                return d.x;
            }))

        y.range([height, 0])
            .domain(d3.extent(d3.merge(dataset), function (d) {
                return d.y;
            }))

        var g = svg.select("g");

        // Update the x-axis.
        g.select(".x.axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

        // Update the y-axis.
        g.select(".y.axis")
            .call(yAxis);

        // Define lines
        line = d3.svg.line()
            .x(function (d) {
                return x(d.x);
            })
            .y(function (d) {
                return y(d.y);
            })

        var path = g.selectAll(".line")
            .data(dataset)
            .enter().append("path")
            .style("stroke", function (d, i) {
                return color(i)
            });

        path.attr("class", "line")
            .attr("d", line)
            .attr("clip-path", "url(#clip)");

        // Update the clip rectangle
        g.select("#clip-rect")
            .attr("width", width)
            .attr("height", height);

        // Update the line path.
        g.selectAll(".line")
            .attr("d", line);

        zoom.x(x).y(y)
            .on("zoom", draw);

        // Rect for zoom.
        gEnter.append("rect")
            .attr("class", "rectzoom")
            .attr("width", width)
            .attr("height", height)
            .call(zoom);

        function draw() {
            g.select(".x.axis").call(xAxis);
            g.select(".y.axis").call(yAxis);
            g.selectAll("path.line").attr("d", line);
            //g.select("#clip-rect").attr("width",width).attr("height",height);
        }

        /*
         * Methods
         */

        chart.width = function (w) {
            if (!arguments.length) return width;
            width = w;
            return this;
        };

        chart.height = function (h) {
            if (!arguments.length) return height;
            height = h;
            return this;
        };

        return chart

    } // chart

    return chart

}; // d3.taos





/*
 * Main
 */

// for json: 


// New instance
var t = d3.taos();

var f = function () {}



var data = d3.json("api.json?id=1", function(error, data) {
    if (error) return console.warn(error);
    // Creation
    d3.select("svg#chart")
        .datum(data)
        .attr("x", function(d) { x(d.x) })
        .call(t);
});

// Update
d3.select("select").on("change", function () {

    var val = $("select#dataset").val();



    val == "dataset1" ? dataset = dataset1 : dataset = dataset2;

    console.log("Dataset changed: " + val);

    d3.select("svg#chart")
        .datum(dataset)
        .call(t.width(800));


});

And the HTML code...

    <select id="dataset">
        <option value="1" selected>Dataset 1</option>
        <option value="2">Dataset 2</option>
        <option value="3">Dataset 3</option>
    </select>

Sample JSON dataset from e.g. api.json?id=1

{

        "usability_index": [
            {"x": 1397220093000, "y": 7},
            {"x": 1397222093000, "y": 21},
            {"x": 1397224093000, "y": 13},
            {"x": 1397226093000, "y": 23}
        ]

}

I explored with d3.json() but I'm not quite sure how to go about loading it dynamically when e.g. the default dataset option is changed to Dataset 3, from api.json?id=1 to api.json?id=3.

I'm really new to d3.js and would really appreciate some guidance here!

解决方案

You could try something like this, but instead using a library that makes reusable charts based on d3.js.

The following is an example on how you could load data via API calls

 var chart = c3.generate({
    data: {
        url: 'api.json?id=1',
        mimeType: 'json'
    }
});

Note that c3.js requires you to have your JSON in the format:

  {
    "line1": [220, 240, 270, 250, 280],
    "line2": [180, 150, 300, 70, 120],
    "line3": [200, 310, 150, 100, 180]
}

Therefore, you need to parse and re-format your JSON data before you can load it in.

And attach event handlers which you can choose to regenerate or load more lines into the chart.

这篇关于d3.js:在下拉更改上加载不同的JSON数据集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆