FormidableLabs / victory

A collection of composable React components for building interactive data visualizations
http://commerce.nearform.com/open-source/victory/
Other
11.02k stars 524 forks source link

VictoryBoxPlot doesn't support multiple Box Plots #1328

Open mikeKane opened 5 years ago

mikeKane commented 5 years ago

Bugs and Questions

Checklist

The Problem

I am implementing multiple VictoryBoxPlot items on a single chart. The problem is they all stack on top of one another. I tried using a Victory group to space them out but that did not seem to work.

Describe the issue you're seeing, and what you expect the behavior to be. I expect to be able to set an offset and also a width separation between boxes.

Reproduction

 <VictoryChart>
          <VictoryBoxPlot
            dependentAxis
            data={cellPings}
            style={{
              min: { stroke: colorScale[0] },
              max: { stroke: colorScale[0] },
              q1: { fill: colorScale[0] },
              q3: { fill: colorScale[0] },
              median: { stroke: "black", strokeWidth: 1 },
              minLabels: { fill: "white" },
              maxLabels: { fill: "white" },
              marginLeft: 20
            }}
          />
          <VictoryBoxPlot
            dependentAxis
            minLabels
            maxLabels
            data={wifiPings}
            style={{
              min: { stroke: colorScale[1] },
              max: { stroke: colorScale[1] },
              q1: { fill: colorScale[1] },
              q3: { fill: colorScale[1] },
              median: { stroke: "black", strokeWidth: 1 },
              minLabels: { fill: "white" },
              maxLabels: { fill: "white" }
            }}
          />
          <VictoryBoxPlot
            dependentAxis
            minLabels
            maxLabels
            data={vpnPings}
            style={{
              min: { stroke: colorScale[2] },
              max: { stroke: colorScale[2] },
              q1: { fill: colorScale[2] },
              q3: { fill: colorScale[2] },
              median: { stroke: "black", strokeWidth: 1 },
              minLabels: { fill: "white" },
              maxLabels: { fill: "white"}
            }}
          />
        </VictoryChart>

Please note each box is a single color. IMG_3249

boygirl commented 5 years ago

@mikeKane You're right, this is an oversight on my part. I will correct VictoryGroup to make sure it correctly offsets VictoryBoxPlot children. In the meantime, you can add a manual x offset by doing something like this:

<VictoryChart>
  <VictoryBoxPlot
    x={(d) => d.x - 0.25}
    data={[
      { x: 1, y: [5, 10, 9, 2] },
      { x: 2, y: [1, 15, 6, 8] },
      { x: 3, y: [3, 5, 6, 9] },
      { x: 4, y: [5, 20, 8, 12] },
      { x: 5, y: [2, 11, 12, 13] }
    ]}
  />
  <VictoryBoxPlot
    x={(d) => d.x + 0.25}
    data={[
      { x: 1, y: [1, 2, 3, 2] },
      { x: 2, y: [1, 15, 6, 8] },
      { x: 3, y: [13, 15, 16, 19] },
      { x: 4, y: [5, 2, 8, 12] },
      { x: 5, y: [2, 1, 12, 13] }
    ]}
    style={{ q1: { fill: "red" }, q3: { fill: "red" }}}
  />
</VictoryChart>
mikeKane commented 5 years ago

@boygirl Adding the suggested prop

 x={(d) => d.x - 0.25}

so my component looks like this

 <VictoryBoxPlot
            x={d => d.x - 0.25}
            boxWidth={15}
            data={wifiPings}
            style={{
              min: { stroke: colorScale[1] },
              max: { stroke: colorScale[1] },
              q1: { fill: colorScale[1] },
              q3: { fill: colorScale[1] },
              median: { stroke: "black", strokeWidth: 1 },
              minLabels: { fill: "white" },
              maxLabels: { fill: "white" }
            }}
          />

I receive an error stating "Malformed calls from js: field sizes are different.

Malformed calls from JS: field sizes are different.

[[88,44,28,28,28,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,28,28,28,44,44,34,34,34,34,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,34,34,34,34,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,44,15,59,73,73,73,73,73,73,73,60,60,69,60,60,60,60,60,60,45,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,34,34,34,34,45,45,44,15,73,73,73,73,73,73,73,60,60,69,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,44,15,73,73,73,73,73,73,73,69,34,34,34,34,44,15,73,73,73,73,73,73,73,9,28],[5,18,1,1,1,5,5,5,5,5,3,5,3,5,5,5,5,5,3,5,3,5,5,5,3,5,3,5,5,3,5,3,5,3,0,0,0,4,6,1,1,1,1,4,4,4,4,6,6,4,5,5,5,5,5,5,5,5,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,5,5,3,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,5,5,5,3,5,5,3,5,5,3,5,5,3,5,5,3,5,5,3,5,5,3,5,5,3,5,3,5,5,5,5,5,3,5,3,5,5,5,5,3,5,3,5,5,5,5,3,5,3,5,5,5,5,3,5,3,5,3,5,5,5,5,5,3,5,3,5,5,5,5,3,5,3,5,5,5,5,3,5,3,5,5,5,5,3,5,3,5,5,5,5,3,5,3,5,5,5,5,3,5,3,5,3,5,5,3,5,3,15,15,10,2,2,2,2,11,11,11,11,10,2,2,2,11,11,11,1,1,1,1,17,13,10,2,2,2,2,11,11,11,11,10,2,2,2,11,11,11,11,4,0,4,3,3,3,3,3,3,0,15,15,4,10,2,2,11,11,11,1,10,2,2,2,11,11,11,10,2,2,2,2,2,2,2,2,2,2,2,11,2,2,11,2,11,11,11,2,2,11,2,2,11,2,11,11,11,11,11,11,2,11,11,11,11,11,11,11,1,1,1,1,1,1,4,0,3,3,3,3,3,3,0,15,15,4,10,2,2,2,11,11,11,10,2,2,2,2,2,2,2,2,2,2,11,2,2,11,2,11,11,11,11,11,2,11,11,11,11,11,11,11,4,0,3,3,3,3,3,3,0,4,1,1,1,1,4,0,3,3,3,3,3,3,0,1,0],[[],[],[131],[130],[132],[9569,"RCTImageView",31,{"resizeMode":"cover","height":15,"source":[{"height":17,"scale":1,"uri":"http://192.168.202.66:8081/assets/src/components/Maps/images/checkedBox.png?platform=ios&hash=cfcab12ee668880a266a9509f575881e","width":17,"__packager_asset":true}],"width":15,"marginRight":4,"overflow":"hidden"}],[9573,"RCTRawText",31,{"text":" "}],[9575,"RCTRawText",31,{"text":"Cellular"}],[9577,"RCTRawText",31,{"text":" "}],[9579,"RCTText",31,{"fontSize":14,"allowFontScaling":true,"fontFamily":"IBMPlexSans-SemiBold","accessible":true,"ellipsizeMode":"tail","color":4280036162}],[9579,[9573,9575,9577]],[9583,"RCTView",31,{"flexDirection":"row","accessible":true}],[9583,[9569,9579]],[9585,"RCTImageView",31,{"resizeMode":"cover","height":15,"source":[{"height":17,"scale":1,"uri":"http://192.168.202.66:8081/assets/src/components/Maps/images/wifiChecked.png?platform=ios&hash=dc0c885a9a59f6161c6fb00bd54cf7df","width":17,"__packager_asset":true}],"width":15,"marginRight":4,"overflow":"hidden"}],[9587,"RCTRawText",31,{"text":" "}],[9589,"RCTRawText",31,{"text":"Wi-Fi"}],[9593,"RCTRawText",31,{"text":" "}],[9595,"RCTText",31,{"fontSize":14,"allowFontScaling":true,"fontFamily":"IBMPlexSans-SemiBold","accessible":true,"ellipsizeMode":"tail","color":4280036162}],[9595,[9587,9589,9593]],[9597,"RCTView",31,{"flexDirection":"row","accessible":true}],[9597,[9585,9595]],[9599,"RCTImageView",31,{"resizeMode":"cover","height":15,"source":[{"height":17,"scale":1,"uri":"http://192.168.202.66:8081/assets/src/components/Maps/images/vpnChecked.png?platform=ios&hash=92ba5c1c8a65dc3a0cfd38f59d9cc51c","width":17,"__packager_asset":true}],"width":15,"marginRight":4,"overflow":"hidden"}],[9603,"RCTRawText",31,{"text":" VPN "}],[9605,"RCTText",31,{"fontSize":14,"allowFontScaling":true,"fontFamily":"IBMPlexSans-SemiBold","accessible":true,"ellipsizeMode":"tail","color":4280036162}],[9605,[9603]],[9607,"RCTView",31,{"flexDirection":"row","accessible":true}],[9607,[9599,9605]],[9609,"RCTActivityIndicatorView",31,{"size":"large","animating":true,"hidesWhenStopped":true,"height":36,"width":36,"color":4285313016}],[9613,"RCTView",31,{"alignItems":"center","justifyContent":"center"}],[9613,[9609]],[9615,"RCTView",31,{"marginTop":100,"backgroundColor":4294901760,"flex":1}],[9615,[9613]],[9617,"RCTView",31,null],[9617,[9615]],[135,1,1560960813719,false],[136,1000,1560960813719,true],[137,1,1560960813720,false],[9169,[],[],[],[],[2]],[9103,"RCTRawText",{"text":"Candlestick"}],[1],[1],[1],[1],[9155,[],[],[],[],[0]],[9155,[],[],[9583],[0],[]],[9155,[],[],[9597],[1],[]],[9155,[],[],[9607],[2],[]],[9155,"RCTView",{"flexDirection":"row","justifyContent":"space-evenly","alignItems":"center","marginLeft":null,"backgroundColor":553648127,"marginRight":null}],[9157,"RCTView",{"backgroundColor":null}],[9169,[],[],[9617],[2],[]],[9619,"RNSVGRect",31,{"strokeMiterlimit":4,"stroke":null,"rx":0,"vectorEffect":1,"strokeLinejoin":0,"matrix":[1,0,0,1,0,0],"fill":[0,4294753304],"y":171.21212121212122,"strokeOpacity":1,"fillRule":1,"strokeDasharray":null,"ry":0,"propList":["fill"],"fillOpacity":1,"strokeLinecap":0,"strokeWidth":1,"strokeDashoffset":null,"x":42.5,"opacity":1,"height":0,"width":15}],[9623,"RNSVGRect",31,{"strokeMiterlimit":4,"stroke":null,"rx":0,"vectorEffect":1,"strokeLinejoin":0,"matrix":[1,0,0,1,0,0],"fill":[0,4294753304],"y":140.90909090909093,"strokeOpacity":1,"fillRule":1,"strokeDasharray":null,"ry":0,"propList":["fill"],"fillOpacity":1,"strokeLinecap":0,"strokeWidth":1,"strokeDashoffset":null,"x":134.16666666666666,"opacity":1,"height":0,"width":15}],[9625,"RNSVGRect",31,{"strokeMiterlimit":4,"stroke":null,"rx":0,"vectorEffect":1,"strokeLinejoin":0,"matrix":[1,0,0,1,0,0],"fill":[0,4294753304],"y":148.4848484848485,"strokeOpacity":1,"fillRule":1,"strokeDasharray":null,"ry":0,"propList":["fill"],"fillOpacity":1,"strokeLinecap":0,"strokeWidth":1,"strokeDashoffset":null,"x":225.83333333333331,"opacity":1,"height":0,"width":15}],[9627,"RNSVGRect",31,{"strokeMiterlimit":4,"stroke":null,"rx":0,"vectorEffect":1,"strokeLinejoin":0,"matrix":[1,0,0,1,0,0],"fill":[0,4294753304],"y":154.54545454545456,"strokeOpacity":1,"fillRule":1,"strokeDasharray":null,"ry":0,"propList":["fill"],"fillOpacity":1,"strokeLinecap":0,"strokeWidth":1,"strokeDashoffset":null,"x":317.5,"opacity":1,"height":1.5151515151515014,"width":15}],[9629,"RNSVGRect",31,{"strokeMiterlimit":4,"stroke":null,"rx":0,"vectorEffect":1,"strokeLinejoin":0,"matrix":[1,0,0,1,0,0],"fill":[0,4294753304],"y":50,"strokeOpacity":1,"fillRule":1,"strokeDasharray":null,"ry":0,"propList":["fill"],"fillOpacity":1,"strokeLinecap":0,"strokeWidth":1,"strokeDashoffset":null,"x":42.5,"opacity":1,"height":121.21212121212122,"width":15}],[9633,"RNSVGRect",31,{"strokeMiterlimit":4,"stroke":null,"rx":0,"vectorEffect":1,"strokeLinejoin":0,"matrix":[1,0,0,1,0,0],"fill":[0,4294753304],"y":133.33333333333331,"strokeOpacity":1,"fillRule":1,"strokeDasharray":null,"ry":0,"propList":["fill"],"fillOpacity":1,"strokeLinecap":0,"strokeWidth":1,"strokeDashoffset":null,"x":134.16666666666666,"opacity":1,"height":7.5757575757576205,"width":15}],[9635,"RNSVGRect",31,{"strokeMiterlimit":4,"stroke":null,"rx":0,"vectorEffect":1,"strokeLinejoin":0,"matrix":[1,0,0,1,0,0],"fill":[0,4294753304],"y":146.96969696969697,"strokeOpacity":1,"fillRule":1,"strokeDasharray":null,"ry":0,"propList":["fill"],"fillOpacity":1,"strokeLinecap":0,"strokeWidth":1,"strokeDashoffset":null,"x":225.83333333333331,"opacity":1,"height":1.5151515151515298,"width":15}],[9637,"RNSVGRect",31,{"strokeMiterlimit":4,"stroke":null,"rx":0,"vectorEffect":1,"strokeLinejoin":0,"matrix":[1,0,0,1,0,0],"fill":[0,4294753304],"y":150,"strokeOpacity":1,"fillRule":1,"strokeDasharray":null,"ry":0,"propList":["fill"],"fillOpacity":1,"strokeLinecap":0,"strokeWidth":1,"strokeDashoffset":null,"x":317.5,"opacity":1,"height":4.545454545454561,"width":15}],[9639,"RNSVGLine",31,{"stroke":[0,4294753304],"strokeMiterlimit":4,"vectorEffect":1,"strokeLinejoin":0,"x1":50,"strokeLinecap":0,"fillOpacity":1,"x2":50,"fillRule":1,"y1":50,"y2":50,"opacity":1,"fill":[0,4278190080],"strokeOpacity":1,"matrix":[1,0,0,1,0,0],"strokeDasharray":null,"propList":["stroke","strokeWidth"],"strokeDashoffset":null,"strokeWidth":1}],[9643,"RNSVGLine",31,{"stroke":[0,4294753304],"strokeMiterlimit":4,"vectorEffect":1,"strokeLinejoin":0,"x1":42.5,"strokeLinecap":0,"fillOpacity":1,"x2":57.5,"fillRule":1,"y1":50,"y2":50,"opacity":1,"fill":[0,4278190080],"strokeOpacity":1,"matrix":[1,0,0,1,0,0],"strokeDasharray":null,"propList":["stroke","strokeWidth"],"strokeDashoffset":null,"strokeWidth":1}],[9645,"RNSVGGroup",31,{"stroke":null,"strokeMiterlimit":4,"vectorEffect":0,"strokeLinejoin":0,"opacity":1,"strokeOpacity":1,"fill":[0,4278190080],"matrix":[1,0,0,1,0,0],"fillOpacity":1,"strokeLinecap":0,"strokeDasharray":null,"fillRule":1,"font":{},"propList":[],"strokeDashoffset":null,"strokeWidth":1}],[9645,[9639,9643]],[9647,"RNSVGLine",31,{"stroke":[0,4294753304],"strokeMiterlimit":4,"vectorEffect":1,"strokeLinejoin":0,"x1":141.66666666666666,"strokeLinecap":0,"fillOpacity":1,"x2":141.66666666666666,"fillRule":1,"y1":133.33333333333331,"y2":133.33333333333331,"opacity":1,"fill":[0,4278190080],"strokeOpacity":1,"matrix":[1,0,0,1,0,0],"strokeDasharray":null,"propList":["stroke","strokeWidth"],"strokeDashoffset":null,"strokeWidth":1}],[9649,"RNSVGLine",31,{"stroke":[0,4294753304],"strokeMiterlimit":4,"vectorEffect":1,"strokeLinejoin":0,"x1":134.16666666666666,"strokeLinecap":0,"fillOpacity":1,"x2":149.166666666

RCTFatal
-[RCTCxxBridge handleError:]
__34-[RCTCxxBridge _initializeBridge:]_block_invoke
facebook::react::RCTMessageThread::tryFunc(std::__1::function<void ()> const&)
facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1::operator()() const
decltype(std::__1::forward<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(fp)()) std::__1::__invoke<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&&&)
void std::__1::__invoke_void_return_wrapper<void>::__call<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&&&)
std::__1::__function::__func<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1, std::__1::allocator<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1>, void ()>::operator()()
std::__1::function<void ()>::operator()() const
invocation function for block in facebook::react::RCTMessageThread::runAsync(std::__1::function<void ()>)
<redacted>
<redacted>
<redacted>
CFRunLoopRunSpecific
+[RCTCxxBridge runRunLoop]
<redacted>
<redacted>
_pthread_start
thread_start
mikeKane commented 5 years ago

Ah sometimes it does seem to work if I leave out the

x={d => d.x - 0.25}

on the first box plot component.

The issue also is now the labels over lap.

Here is my component

  <VictoryChart>
          <VictoryBoxPlot
          //  x={d => d.x - 0.25}
            data={cellPings}
            style={{ q1: { fill: "#FCBC18" }, q3: { fill: "#FCBC18" } }}
          />
          <VictoryBoxPlot
            x={d => d.x + 0.25}
            data={wifiPings}
            style={{ q1: { fill: colorScale[1] }, q3: { fill: colorScale[1] } }}
          />
          <VictoryBoxPlot
            x={d => d.x + 0.25}
            data={vpnPings}
            style={{ q1: { fill: colorScale[2] }, q3: { fill: colorScale[2] } }}
          />
        </VictoryChart>

Here is the image result

IMG_3250

I would hope each box plot chart would fill the chart the same as a candlestick.