D3.js scaleOrdinal不支持rangeRoundBands方法

时间:2016-08-26 07:48:29

标签: d3.js

在使用D3.js版本4进行序数比例时,在rangeRoundBands方法上获取错误。 以下是D3.js第3版中的示例。

https://bl.ocks.org/mbostock/7440840

但是下面的版本4代码会抛出错误。

#include<type_traits>
#include<cstddef>

static const std::size_t N = 42;

template<std::size_t N>
struct choice: choice<N-1> {};

template<>
struct choice<0> {};

template<typename T, typename U>
struct types {
    using basic = T;
    using decorated = U;
};

template<typename T, typename U>
auto f(choice<0>) { return types<T, U>{}; }

template<typename T, typename U,
    typename = std::enable_if_t<std::is_pointer<T>::value>>
auto f(choice<1>) {
    auto t = f<std::remove_pointer_t<T>, U>(choice<N>{});
    using B = typename decltype(t)::basic;
    using D = typename decltype(t)::decorated;
    return types<B, std::add_pointer_t<D>>{};
}

template<typename T, typename U,
    typename = std::enable_if_t<std::is_lvalue_reference<T>::value>>
auto f(choice<2>) {
    auto t = f<std::remove_reference_t<T>, U>(choice<N>{});
    using B = typename decltype(t)::basic;
    using D = typename decltype(t)::decorated;
    return types<B, std::add_lvalue_reference_t<D>>{};
}

template<typename T, typename U,
    typename = std::enable_if_t<std::is_rvalue_reference<T>::value>>
auto f(choice<3>) {
    auto t = f<std::remove_reference_t<T>, U>(choice<N>{});
    using B = typename decltype(t)::basic;
    using D = typename decltype(t)::decorated;
    return types<B, std::add_rvalue_reference_t<D>>{};
}

template<typename T, typename U,
    typename = std::enable_if_t<std::is_array<T>::value>>
auto f(choice<4>) {
    auto t = f<std::remove_extent_t<T>, U>(choice<N>{});
    using B = typename decltype(t)::basic;
    using D = typename decltype(t)::decorated;
    return types<B, std::conditional_t<(0==std::extent<T>::value), D[], D[std::extent<T>::value]>>{};
}

template<typename T, typename U,
    typename = std::enable_if_t<std::is_const<T>::value>>
auto f(choice<5>) {
    auto t = f<std::remove_const_t<T>, U>(choice<N>{});
    using B = typename decltype(t)::basic;
    using D = typename decltype(t)::decorated;
    return types<B, std::add_const_t<D>>{};
}

template<typename T, typename U,
    typename = std::enable_if_t<std::is_volatile<T>::value>>
auto f(choice<6>) {
    auto t = f<std::remove_volatile_t<T>, U>(choice<N>{});
    using B = typename decltype(t)::basic;
    using D = typename decltype(t)::decorated;
    return types<B, std::add_volatile_t<D>>{};
}

template<typename T, typename U>
auto f() {
    return f<T, U>(choice<N>{});
}

template<typename T, typename U = char>
using my_type = decltype(f<T, U>());

template<typename T, typename U = char>
using my_type_basic_t = typename decltype(f<T, U>())::basic;

template<typename T, typename U = char>
using my_type_decorated_t = typename decltype(f<T, U>())::decorated;

int main() {
    int i = 42;
    my_type_decorated_t<char *, int> ptr = &i;
    // of course, it can still be used in a constant expression if needed
    // constexpr my_type_decorated_t<char *, int> ptr = nullptr;

}

2 个答案:

答案 0 :(得分:8)

而不是:

var x = d3.scaleOrdinal()
.domain(data.map(function(d) { return d.name; }))
.rangeRoundBands([0, width], 0.1);

在d3 v4中

应该是:

var x = d3.scaleBand()
    .rangeRound([0, width])
    .padding(0.1);

工作代码here

答案 1 :(得分:0)

感谢Cyril Cherian。这位先生回答的90%是正确的。

以下是鼓舞人心的答案。我已通过d3-5.7.2的测试。

// old v3 code
var x = d3.scaleOrdinal()
.domain(data.map(function(d) { return d.name; }))
.rangeRoundBands([0, width], 0.1);

// correct code
var x = d3.scaleBand()

//            pay attention here ! the next statement is necessary . It is not part of 【conversion from v3 to v4】
.domain(data.map(function(d) { return d.name; })) 

// below is the 【conversion from v3 to v4】
.rangeRound([0, width])
.padding(0.1);